From a2b72eaecd6da58b377d9eaa1de401d61c79a65c Mon Sep 17 00:00:00 2001 From: lucasgil-arranz <150254802+lucasgil-arranz@users.noreply.github.com> Date: Tue, 6 Aug 2024 16:59:25 +0200 Subject: [PATCH 01/60] i18n Crowdin integration (#880) * feat: add crowdin integration with github actions * feat: add platforms * feat: add extra ignored file paths and update crowdin copy script * feat: edit file to triger upload * feat: doc change * feat: new * udpate copy * feat: add download worflow * feat: update git ignore * update * update * update * New Crowdin translations by GitHub Action * remove copy file from workflow * New Crowdin translations by GitHub Action * Update README.mdx * New Crowdin translations by GitHub Action * feat: add copy workflow * update node version * chore: Copy ignored files using crowdin:copy * udpate copy * udpate copy * Update cb-retrieve-related-operations.api.mdx * update copy * Update cb-retrieve-related-operations.api.mdx * update copy * update copy * update copy * update copy * Update get-all-offers.api.mdx * chore: Copy ignored files using crowdin:copy * test upload * update links * update link * update link * update link * clean i18n * clean i18n * clean i18n * clean i18n * clean i18n * clean i18n * clean i18n * clean up --------- Co-authored-by: Lucas Gil-Arranz Co-authored-by: Crowdin Bot Co-authored-by: github-actions Co-authored-by: Elliot Voris --- .env.example | 2 + .github/workflows/copy-workflow.yml | 74 +++++++++++ .github/workflows/download-workflow.yml | 37 ++++++ .github/workflows/upload-workflow.yml | 24 ++++ .gitignore | 3 + copyIgnoredFiles.mjs | 123 ++++++++++++++++++ crowdin.yml | 18 +++ docs/build/apps/dapp-frontend.mdx | 2 +- docs/data/horizon/README.mdx | 4 +- docs/tokens/publishing-asset-info.mdx | 2 +- docusaurus.config.ts | 6 +- package.json | 6 +- .../admin-guide/30-getting-started.mdx | 2 +- yarn.lock | 85 +++++++++++- 14 files changed, 380 insertions(+), 8 deletions(-) create mode 100644 .env.example create mode 100644 .github/workflows/copy-workflow.yml create mode 100644 .github/workflows/download-workflow.yml create mode 100644 .github/workflows/upload-workflow.yml create mode 100644 copyIgnoredFiles.mjs create mode 100644 crowdin.yml diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..f42bf1347 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +CROWDIN_PROJECT_ID=123 +CROWDIN_PERSONAL_TOKEN="1a2b3c" \ No newline at end of file diff --git a/.github/workflows/copy-workflow.yml b/.github/workflows/copy-workflow.yml new file mode 100644 index 000000000..f5332140c --- /dev/null +++ b/.github/workflows/copy-workflow.yml @@ -0,0 +1,74 @@ +name: Crowdin Copy and Create PR + +on: + workflow_dispatch: + push: + paths: [ 'docs/**', 'platforms/**','i18n/en/**', 'src/pages/**', 'meeting-notes/**' ] + branches: [ main ] + +permissions: + contents: write + pull-requests: write + +jobs: + crowdin_copy_and_pr: + runs-on: ubuntu-latest + + steps: + - name: Checkout main branch + uses: actions/checkout@v3 + with: + ref: main + + - name: Merge latest changes from origin/main + run: | + git fetch origin + git checkout main + git merge origin/main + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Install dependencies + run: yarn install + + - name: Run crowdin:copy + run: yarn run crowdin:copy + + - name: Configure Git + run: | + git config --global user.name 'github-actions' + git config --global user.email 'github-actions@github.com' + + - name: Check for changes + id: changes + run: | + if git diff --quiet; then + echo "changes=false" >> $GITHUB_OUTPUT + else + echo "changes=true" >> $GITHUB_OUTPUT + fi + + - name: Create and push changes to branch + if: steps.changes.outputs.changes == 'true' + run: | + BRANCH_NAME="crowdin-copy-changes" + git push origin --delete $BRANCH_NAME || true + git checkout -b $BRANCH_NAME + git add . + git commit -m "chore: Copy ignored files using crowdin:copy" + git push --force --set-upstream origin $BRANCH_NAME + echo "branch_name=$BRANCH_NAME" >> $GITHUB_ENV + + - name: Install GitHub CLI + if: steps.changes.outputs.changes == 'true' + run: sudo apt-get install -y gh + + - name: Create Pull Request + if: steps.changes.outputs.changes == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr create --repo ${{ github.repository }} --base main --head ${{ env.branch_name }} --title "Copy ignored files using crowdin:copy" --body "This PR was created by GitHub Actions to copy ignored files using the crowdin:copy command." diff --git a/.github/workflows/download-workflow.yml b/.github/workflows/download-workflow.yml new file mode 100644 index 000000000..c7419880c --- /dev/null +++ b/.github/workflows/download-workflow.yml @@ -0,0 +1,37 @@ +name: Crowdin Download Action + +on: + workflow_dispatch: + ### Schedule currently disabled ### + # schedule: + # - cron: '0 9 * * *' + # - cron: '0 13 * * *' + # - cron: '0 17 * * *' + +permissions: + contents: write + pull-requests: write + +jobs: + crowdin: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Synchronize with Crowdin + uses: crowdin/github-action@v2 + with: + upload_sources: false + upload_translations: false + download_translations: true + localization_branch_name: l10n_crowdin_translations + + create_pull_request: true + pull_request_title: 'New Crowdin translations' + pull_request_body: 'New Crowdin pull request with translations' + pull_request_base_branch_name: 'main' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/upload-workflow.yml b/.github/workflows/upload-workflow.yml new file mode 100644 index 000000000..1d5149d0c --- /dev/null +++ b/.github/workflows/upload-workflow.yml @@ -0,0 +1,24 @@ +name: Crowdin Upload Action + +on: + workflow_dispatch: + push: + paths: [ 'docs/**', 'platforms/**','i18n/en/**', 'src/pages/**', 'meeting-notes/**' ] + branches: [ main ] + +jobs: + crowdin-upload: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Crowdin push + uses: crowdin/github-action@v2 + with: + upload_sources: true + upload_translations: false + download_translations: false + env: + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} diff --git a/.gitignore b/.gitignore index 7cf5e24ee..06ba49a55 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ yarn-error.log* # non-production openrpc.json files /openrpc/*openrpc.json + +# Environment variables +.env \ No newline at end of file diff --git a/copyIgnoredFiles.mjs b/copyIgnoredFiles.mjs new file mode 100644 index 000000000..1473b8f58 --- /dev/null +++ b/copyIgnoredFiles.mjs @@ -0,0 +1,123 @@ +import fs from 'fs'; +import path from 'path'; +import glob from 'glob'; +import yaml from 'js-yaml'; + +// Define the list of language codes +const languages = ['es']; + +/** + * Reads and parses the crowdin.yml file. + * @param {string} filePath - The path to the crowdin.yml file. + * @returns {Object} - The parsed configuration object. + */ +function readCrowdinConfig(filePath) { + try { + const fileContent = fs.readFileSync(filePath, 'utf8'); + return yaml.load(fileContent); + } catch (err) { + logMessage(`Error reading or parsing the file ${filePath}: ${err.message}`); + process.exit(1); + } +} + +/** + * Extracts the sources array from the configuration object. + * @param {Object} config - The parsed configuration object. + * @returns {string[]} - The array of source paths. + */ +function extractSources(config) { + return config.files.map(file => file.source.replace(/\/\*\*\/\*$/, '').replace(/^\//, '')); +} + +/** + * Logs a message to the console with a timestamp. + * @param {string} message - The message to log. + */ +function logMessage(message) { + console.log(`[${new Date().toISOString()}] ${message}`); +} + +/** + * Copies a file or directory from source to destination. + * @param {string} src - The source path. + * @param {string} dest - The destination path. + */ +function copyFileOrDirectory(src, dest) { + const destDir = path.dirname(dest); + fs.mkdirSync(destDir, { recursive: true }); + + const stat = fs.statSync(src); + if (stat.isDirectory()) { + fs.cpSync(src, dest, { recursive: true }); + logMessage(`Successfully copied directory ${src} to ${dest}`); + } else { + fs.copyFileSync(src, dest); + logMessage(`Successfully copied file ${src} to ${dest}`); + } +} + +/** + * Replaces placeholders in the translation path with actual values. + * @param {string} translationPath - The translation path template. + * @param {string} languageCode - The language code to replace placeholders. + * @param {string} srcPath - The source file path. + * @param {string[]} sources - The array of source paths. + * @returns {string} - The translation path with placeholders replaced. + */ +function getTranslationPath(translationPath, languageCode, srcPath, sources) { + let relativePath = srcPath; + + for (const source of sources) { + if (srcPath.startsWith(source)) { + relativePath = srcPath.replace(`${source}/`, ''); + break; + } + } + + const destPath = translationPath + .replace('%two_letters_code%', languageCode) + .replace('%original_file_name%', path.basename(srcPath)) + .replace('**', path.dirname(relativePath).replace(/\\/g, '/')); + + return path.join(process.cwd(), destPath); +} + +/** + * Copies ignored files for each language based on the configuration. + */ +function copyIgnoredFilesForLanguages(config) { + const sources = extractSources(config); + + config.files.forEach(({ source, translation, ignore = [] }) => { + ignore.forEach(ignorePattern => { + const srcPattern = ignorePattern.replace(/^\//, ''); // Strip the leading slash for the source path + + glob(srcPattern, (err, files) => { + if (err) { + logMessage(`Error processing pattern ${srcPattern}: ${err.message}`); + return; + } + + files.forEach(srcPath => { + languages.forEach(languageCode => { + const destPath = getTranslationPath(translation, languageCode, srcPath, sources); + copyFileOrDirectory(srcPath, destPath); + }); + }); + }); + }); + }); +} + +/** + * Main function to execute the workflow. + */ +function main() { + const config = readCrowdinConfig('crowdin.yml'); + copyIgnoredFilesForLanguages(config); + logMessage('Ignored files copied for all specified languages.'); +} + +// Execute the main function +main(); diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 000000000..f96c7960b --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,18 @@ +project_id_env: CROWDIN_PROJECT_ID +api_token_env: CROWDIN_PERSONAL_TOKEN +preserve_hierarchy: true +files: + - source: /src/pages/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-pages/**/%original_file_name% + ignore: ['/src/pages/**/*.js', '/src/pages/**/*.jsx', '/src/pages/**/*.ts', '/src/pages/**/*.tsx', '/src/pages/**/*.css'] + - source: /i18n/en/**/* + translation: /i18n/%two_letters_code%/**/%original_file_name% + - source: /docs/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name% + ignore : ['/docs/**/*.api.mdx', '/docs/**/*.info.mdx', '/docs/**/*.tag.mdx', '/docs/**/*.schema.mdx', '/docs/**/*.json'] + - source: /platforms/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs-platforms/current/**/%original_file_name% + ignore : ['/platforms/**/*.api.mdx', '/platforms/**/*.info.mdx', '/platforms/**/*.tag.mdx', '/platforms/**/*.schema.mdx', '/platforms/**/*.json'] + - source: /meeting-notes/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name% + ignore : ['/meeting-notes/**/*.api.mdx', '/meeting-notes/**/*.info.mdx', '/meeting-notes/**/*.tag.mdx', '/meeting-notes/**/*.schema.mdx', '/meeting-notes/**/*.json'] \ No newline at end of file diff --git a/docs/build/apps/dapp-frontend.mdx b/docs/build/apps/dapp-frontend.mdx index 18d2325e9..f4d0a1dcc 100644 --- a/docs/build/apps/dapp-frontend.mdx +++ b/docs/build/apps/dapp-frontend.mdx @@ -164,7 +164,7 @@ Let's see it in action! Start the dev server: npm run dev ``` -And open [http://localhost:4321](http://localhost:4321) in your browser. You should see the greeting from the contract! +And open [localhost:4321](http://localhost:4321) in your browser. You should see the greeting from the contract! You can try updating the `{ to: 'Soroban' }` argument. When you save the file, the page will automatically update. diff --git a/docs/data/horizon/README.mdx b/docs/data/horizon/README.mdx index 0f903c36d..ffaa3da86 100644 --- a/docs/data/horizon/README.mdx +++ b/docs/data/horizon/README.mdx @@ -26,8 +26,8 @@ Running Horizon within your own infrastructure provides a number of benefits. Yo The Stellar Development Foundation (SDF) runs two instances of Horizon: -- [https://horizon-testnet.stellar.org/](https://horizon-testnet.stellar.org/) for interacting with the [testnet](../../learn/fundamentals/networks.mdx) -- [https://horizon-futurenet.stellar.org/](https://horizon-futurenet.stellar.org/) for interacting with the [futurenet](../../learn/fundamentals/networks.mdx) +- [horizon-testnet.stellar.org](https://horizon-testnet.stellar.org/) for interacting with the [testnet](../../learn/fundamentals/networks.mdx) +- [horizon-futurenet.stellar.org](https://horizon-futurenet.stellar.org/) for interacting with the [futurenet](../../learn/fundamentals/networks.mdx) ## In These Docs diff --git a/docs/tokens/publishing-asset-info.mdx b/docs/tokens/publishing-asset-info.mdx index ee91a777f..0466e224a 100644 --- a/docs/tokens/publishing-asset-info.mdx +++ b/docs/tokens/publishing-asset-info.mdx @@ -41,7 +41,7 @@ Required field for all asset issuers: - `ACCOUNTS`: A list of public keys for all the Stellar accounts associated with your asset. -Listing your public keys lets users confirm that you own them. For example, when [https://google.com](https://google.com/) hosts a `stellar.toml` file, users can be sure that only the accounts listed on it belong to Google. If someone then says, "You need to pay your Google bill this month, send payment to address GIAMGOOGLEIPROMISE", but that key is not listed on Google's `stellar.toml`, then users know not to trust it. +Listing your public keys lets users confirm that you own them. For example, when [google.com](https://google.com/) hosts a `stellar.toml` file, users can be sure that only the accounts listed on it belong to Google. If someone then says, "You need to pay your Google bill this month, send payment to address GIAMGOOGLEIPROMISE", but that key is not listed on Google's `stellar.toml`, then users know not to trust it. There are several fields where you list information about your Stellar integration to aid in discoverability. If you are an anchor service, and you have set up infrastructure to interoperate with wallets and allow for in-app deposit and withdrawal of assets, make sure to include the locations of your servers on your `stellar.toml` file so those wallets know where to find relevant endpoints to query. In particular, list these: diff --git a/docusaurus.config.ts b/docusaurus.config.ts index e5a442107..a7299caaf 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -21,7 +21,7 @@ const config: Config = { projectName: "stellar-docs", i18n: { defaultLocale: "en", - locales: ["en"], + locales: ["en", "es"], }, plugins: [ "docusaurus-plugin-sass", @@ -178,6 +178,10 @@ const config: Config = { href: "/", }, items: [ + { + type: 'localeDropdown', + position: 'left', + }, { type: 'docSidebar', sidebarId: 'build', diff --git a/package.json b/package.json index 0f6741376..7346d1527 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,12 @@ "postinstall": "patch-package", "rpcspec:build": "node openrpc/scripts/build.mjs", "rpcspec:validate": "node openrpc/scripts/build.mjs && node openrpc/scripts/validate.mjs", - "stellar-cli:build": "node scripts/stellar_cli.mjs" + "stellar-cli:build": "node scripts/stellar_cli.mjs", + "crowdin": "crowdin", + "crowdin:copy": "node copyIgnoredFiles.mjs" }, "dependencies": { + "@crowdin/cli": "3", "@docusaurus/core": "3.4.0", "@docusaurus/preset-classic": "3.4.0", "@docusaurus/remark-plugin-npm2yarn": "3.4.0", @@ -45,6 +48,7 @@ "docusaurus-plugin-openapi-docs": "^3.0.1", "docusaurus-plugin-sentry": "^2.0.0", "docusaurus-theme-openapi-docs": "^3.0.1", + "js-yaml": "^4.1.0", "patch-package": "^8.0.0", "prism-react-renderer": "^2.3.1", "react": "^18.3.1", diff --git a/platforms/stellar-disbursement-platform/admin-guide/30-getting-started.mdx b/platforms/stellar-disbursement-platform/admin-guide/30-getting-started.mdx index 976933b69..f24b83c07 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/30-getting-started.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/30-getting-started.mdx @@ -191,7 +191,7 @@ Payments will start failing if the distribution account runs out of funds. To fi - The distribution account address can be found under `Distribution Account` on the frontend sidebar. Copy that address. - Access [https://horizon-testnet.stellar.org/accounts/:accountId](https://horizon-testnet.stellar.org/accounts/GARGKDIDH7WMKV5WWPK4BH4CKEQIZGWUCA4EUXCY5VICHTHLEBXVNVMW) in your browser and check the balance. - If the balance is indeed low, you can add more funds by creating a new account and sending funds to the distribution account. - - Access [https://demo-wallet.stellar.org/](https://demo-wallet.stellar.org/) in your browser. + - Access [demo-wallet.stellar.org](https://demo-wallet.stellar.org/) in your browser. - Click on `Generate Keypair for new account` to create a new testnet account. Your account comes with 10,000 XLM. - Click on `Send` and enter the distribution account public key and the amount you want to send. - Using Freighter or [Stellar Laboratory](https://laboratory.stellar.org/#account-creator?network=test), swap the XLM for USDC if you wish to test with USDC. diff --git a/yarn.lock b/yarn.lock index d745b42a6..fdd2dd583 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1248,6 +1248,17 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== +"@crowdin/cli@3": + version "3.19.4" + resolved "https://registry.yarnpkg.com/@crowdin/cli/-/cli-3.19.4.tgz#42c52c7a589c9aaf5c92503b4ba37e3f6a55612c" + integrity sha512-j0SiRGKOH/Pa/TdBeIxBBRrByHPqmVqWVo/LSjnri1lLPGywjcu9kB+pib7P4wmI00jgcVu+80yGdun5zRcDNQ== + dependencies: + command-exists-promise "^2.0.2" + node-fetch "2.7.0" + shelljs "^0.8.5" + tar "^6.2.0" + yauzl "^3.1.0" + "@discoveryjs/json-ext@0.5.7": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" @@ -4056,6 +4067,11 @@ browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^ node-releases "^2.0.14" update-browserslist-db "^1.0.16" +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -4299,6 +4315,11 @@ cheerio@^1.0.0-rc.12: optionalDependencies: fsevents "~2.3.2" +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chroma-js@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.4.2.tgz#dffc214ed0c11fa8eefca2c36651d8e57cbfb2b0" @@ -4456,6 +4477,11 @@ comma-separated-tokens@^2.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== +command-exists-promise@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/command-exists-promise/-/command-exists-promise-2.0.2.tgz#7beecc4b218299f3c61fa69a4047aa0b36a64a99" + integrity sha512-T6PB6vdFrwnHXg/I0kivM3DqaCGZLjjYSOe0a5WgFKcz1sOnmOeIjnhQPXVXX3QjVbLyTJ85lJkX6lUpukTzaA== + commander@2.20.3, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -6447,6 +6473,13 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + fs-monkey@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" @@ -9556,11 +9589,36 @@ minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mobx-react-lite@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-4.0.7.tgz#f4e21e18d05c811010dcb1d3007e797924c4d90b" @@ -9703,7 +9761,7 @@ node-fetch-h2@^2.3.0: dependencies: http2-client "^1.2.5" -node-fetch@^2.6.1: +node-fetch@2.7.0, node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -10301,6 +10359,11 @@ pbkdf2@^3.0.3, pbkdf2@^3.1.2: safe-buffer "^5.0.1" sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + perfect-scrollbar@^1.5.5: version "1.5.5" resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz#41a211a2fb52a7191eff301432134ea47052b27f" @@ -12603,6 +12666,18 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.9: version "5.3.10" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" @@ -13762,6 +13837,14 @@ yargs@^17.0.1: y18n "^5.0.5" yargs-parser "^21.1.1" +yauzl@^3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-3.1.3.tgz#f61c17ad1a09403bc7adb01dfb302a9e74bf4a50" + integrity sha512-JCCdmlJJWv7L0q/KylOekyRaUrdEoUxWkWVcgorosTROCFWiS9p2NNPE9Yb91ak7b1N5SxAZEliWpspbZccivw== + dependencies: + buffer-crc32 "~0.2.3" + pend "~1.2.0" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" From fb040e27330eb957d94e3729b69f5fe893ecc29c Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Thu, 22 Aug 2024 12:28:18 -0500 Subject: [PATCH 02/60] provide translation spots for custom react components --- .../AttributeTable/ListItem/index.js | 11 ++- src/components/CanvasFeeGraphs/index.tsx | 11 ++- src/components/CodeExample.js | 9 ++- src/components/EndpointsTable.js | 11 ++- src/components/ExampleResponse/index.js | 11 ++- src/components/ReadMore.js | 3 - src/components/ReaderFeedback/index.js | 25 ++++++- src/components/WalletCodeExample.tsx | 16 +++- src/components/WalletGuideWarn.tsx | 9 ++- src/components/WayfindingBoxes/index.js | 73 ++++++++++++++----- 10 files changed, 146 insertions(+), 33 deletions(-) delete mode 100644 src/components/ReadMore.js diff --git a/src/components/AttributeTable/ListItem/index.js b/src/components/AttributeTable/ListItem/index.js index bf98a5c24..7d06d4ae5 100644 --- a/src/components/AttributeTable/ListItem/index.js +++ b/src/components/AttributeTable/ListItem/index.js @@ -4,6 +4,7 @@ import Details from "@theme/Details"; import { combineAdjacentStrings, partition } from "@site/src/helpers"; import styles from "./styles.module.scss"; +import Translate from "@docusaurus/Translate"; export const ListItem = (props) => { const children = props.children.props.children.filter((child) => child !== "\n"); @@ -39,7 +40,15 @@ export const ListItem = (props) => {

{description}

{collapsedList.length > 0 && ( -
Show child attributes}> +
+ + Show child attributes + + + }> {collapsedList}
)} diff --git a/src/components/CanvasFeeGraphs/index.tsx b/src/components/CanvasFeeGraphs/index.tsx index a8f500d83..d387be451 100644 --- a/src/components/CanvasFeeGraphs/index.tsx +++ b/src/components/CanvasFeeGraphs/index.tsx @@ -2,11 +2,20 @@ import React from 'react'; import BrowserOnly from '@docusaurus/BrowserOnly'; import styles from './styles.module.css'; +import Translate from '@docusaurus/Translate'; + +const translatedLoading = ( + + Loading... + +) export default function CanvasEmbed() { return (
- Loading...
}> + {translatedLoading}}> {() => { const Canvas = require("canvas-embed").Canvas; return ; diff --git a/src/components/CodeExample.js b/src/components/CodeExample.js index 2e74da80e..29696d55e 100644 --- a/src/components/CodeExample.js +++ b/src/components/CodeExample.js @@ -3,6 +3,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; import { CODE_LANGS } from "../constants"; +import Translate from '@docusaurus/Translate'; export const CodeExample = ({ children }) => ( @@ -16,7 +17,13 @@ export const CodeExample = ({ children }) => ( + Example + + } > {codeProps.children} diff --git a/src/components/EndpointsTable.js b/src/components/EndpointsTable.js index 83fb0b418..a2db54903 100644 --- a/src/components/EndpointsTable.js +++ b/src/components/EndpointsTable.js @@ -1,6 +1,15 @@ import React from "react"; import { MethodTable } from "./MethodTable"; +import Translate from "@docusaurus/Translate"; -export const EndpointsTable = ({ children, title = "Endpoints" }) => ( +const transledEndpoints = ( + + Endpoints + +) + +export const EndpointsTable = ({ children, title = transledEndpoints }) => ( {children} ); diff --git a/src/components/ExampleResponse/index.js b/src/components/ExampleResponse/index.js index 69d987857..0c6558fe5 100644 --- a/src/components/ExampleResponse/index.js +++ b/src/components/ExampleResponse/index.js @@ -2,8 +2,17 @@ import React from "react"; import clsx from "clsx"; import styles from "./styles.module.scss"; +import Translate from "@docusaurus/Translate"; -export const ExampleResponse = ({ children, title = "Example" }) => { +const transledExample = ( + + Example + +) + +export const ExampleResponse = ({ children, title = transledExample }) => { const codeElement = children.props.children; return React.cloneElement(codeElement, { diff --git a/src/components/ReadMore.js b/src/components/ReadMore.js deleted file mode 100644 index 06b258a6a..000000000 --- a/src/components/ReadMore.js +++ /dev/null @@ -1,3 +0,0 @@ -import React from 'react'; - -export const ReadMore = ({ url }) => Read More; diff --git a/src/components/ReaderFeedback/index.js b/src/components/ReaderFeedback/index.js index 8f51ddc49..77fc242f1 100644 --- a/src/components/ReaderFeedback/index.js +++ b/src/components/ReaderFeedback/index.js @@ -3,6 +3,7 @@ import useIsBrowser from '@docusaurus/useIsBrowser'; import IconThumbsUp from '@site/static/icons/thumbs-up.svg'; import IconThumbsDown from '@site/static/icons/thumbs-down.svg'; +import Translate, { translate } from "@docusaurus/Translate"; const ReaderFeedback = ({ pageId }) => { const [feedbackGiven, setFeedbackGiven] = useState(false); @@ -18,18 +19,34 @@ const ReaderFeedback = ({ pageId }) => { return (
{feedbackGiven ? ( - 'Thanks for your feedback!' + + Thanks for your feedback! + ) : ( <> - Did you find this page helpful? + + Did you find this page helpful? + diff --git a/src/components/WalletCodeExample.tsx b/src/components/WalletCodeExample.tsx index 8e2710f45..ec7fcde7b 100644 --- a/src/components/WalletCodeExample.tsx +++ b/src/components/WalletCodeExample.tsx @@ -5,6 +5,7 @@ import CodeBlock from '@theme/CodeBlock'; import BrowserOnly from '@docusaurus/BrowserOnly'; import {getCookie, walletDefaultLang} from "./LanguageSpecific"; import {CODE_LANGS} from "../constants"; +import Translate from '@docusaurus/Translate'; // TODO: when TS docs are ready set to false const ALLOW_EMPTY_DOCS = true; @@ -38,7 +39,13 @@ const getTabs = (children: React.ReactElement, targetLanguage: String) => { + Example + + } default={defaultVal === CODE_LANGS[language]} > @@ -60,7 +67,12 @@ const getTabs = (children: React.ReactElement, targetLanguage: String) => { default={defaultVal === language} > - // There is no code example for {language} yet + + {'// There is no code example for {language} yet'} + ); } else { diff --git a/src/components/WalletGuideWarn.tsx b/src/components/WalletGuideWarn.tsx index ce6d793a8..c0fd396d4 100644 --- a/src/components/WalletGuideWarn.tsx +++ b/src/components/WalletGuideWarn.tsx @@ -3,6 +3,7 @@ import Admonition from '@theme/Admonition'; import {LanguageButtons} from "./LanguageButtons"; import {LanguageSpecific} from "./LanguageSpecific"; import {CODE_LANGS} from "../constants"; +import Translate from "@docusaurus/Translate"; type WalletGuideWarnProps = { WIPLangs?: String[]; @@ -10,7 +11,13 @@ type WalletGuideWarnProps = { export const WalletGuideWarn: React.FC = (props) => { const langs = (props.WIPLangs || []).map(v => CODE_LANGS[v.toLowerCase()]); - const admonition = Documentation for this language is currently work in progress. Some of information may not be applicable for this language, or missing. Code samples may be incomplete.; + const admonition = + + Documentation for this language is currently work in progress. Some of information may not be applicable for this language, or missing. Code samples may be incomplete. + + ; const kt = langs.indexOf("Kotlin") != -1 ? admonition : <>; const ts = langs.indexOf("TypeScript") != -1 ? admonition: <>; diff --git a/src/components/WayfindingBoxes/index.js b/src/components/WayfindingBoxes/index.js index e814a1191..a581363f2 100644 --- a/src/components/WayfindingBoxes/index.js +++ b/src/components/WayfindingBoxes/index.js @@ -3,20 +3,27 @@ import clsx from 'clsx'; import Heading from '@theme/Heading'; import Link from '@docusaurus/Link'; import styles from './styles.module.css'; +import Translate from '@docusaurus/Translate'; const WayfindingWays = [ { title: 'Stellar 101', image: require('@site/static/icons/stellar-101.png').default, description: ( - <> + Learn about the core concepts of Stellar in this educational section. - + ), link: ( - Dive In + + Dive In + ), }, @@ -24,15 +31,21 @@ const WayfindingWays = [ title: 'Write a Smart Contract', image: require('@site/static/icons/contract.png').default, description: ( - <> + Get set up and write your first smart contract on the Stellar network. - + ), // temporarily set this to /docs/soroban until "smart contracts" section is done link: ( - Get Started + + Get Started + ), }, @@ -40,14 +53,20 @@ const WayfindingWays = [ title: 'Issue an Asset', image: require('@site/static/icons/issue-assets.png').default, description: ( - <> + Issuing assets on Stellar is easy. Learn how in this tutorial. - + ), link: ( - Issue Asset + + Issue Asset + ), }, @@ -55,14 +74,20 @@ const WayfindingWays = [ title: 'Build an Application', image: require('@site/static/icons/build-applications.png').default, description: ( - <> + Build an application on Stellar using the Wallet SDK or JS SDK. - + ), link: ( - Get Building + + Get Building + ), }, @@ -70,14 +95,20 @@ const WayfindingWays = [ title: 'Developer Tools', image: require('@site/static/icons/dev-tools.png').default, description: ( - <> + Stellar has a myriad of community and SDF-maintained tools. Check them out! - + ), link: ( - See Tools + + See Tools + ), }, @@ -85,14 +116,20 @@ const WayfindingWays = [ title: 'Access Data', image: require('@site/static/icons/access-data.png').default, description: ( - <> + The RPC, Hubble, and Horizon offer all the data capabilities you could possibly need. - + ), link: ( - Get the Goods + + Get the Goods + ), }, From 40b0cb612069e466397bd5ec421f80fa736ade24 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 23 Aug 2024 13:34:40 -0500 Subject: [PATCH 03/60] update crowdin cli, modify/customize scripts --- crowdin.yaml | 37 ++++++++++++++++++ crowdin.yml | 18 --------- package.json | 5 ++- .../copyIgnoredFiles.mjs | 11 ++++-- yarn.lock | 39 ++++--------------- 5 files changed, 54 insertions(+), 56 deletions(-) create mode 100644 crowdin.yaml delete mode 100644 crowdin.yml rename copyIgnoredFiles.mjs => scripts/copyIgnoredFiles.mjs (90%) diff --git a/crowdin.yaml b/crowdin.yaml new file mode 100644 index 000000000..66881ff93 --- /dev/null +++ b/crowdin.yaml @@ -0,0 +1,37 @@ +# Crowdin credentials +project_id: '669532' +api_token_env: CROWDIN_PERSONAL_TOKEN + +# Choose file structure in Crowdin +# e.g. true or false +preserve_hierarchy: true + +# Files configuration +files: + # JSON translation files + - source: /i18n/en/**/* + translation: /i18n/%two_letters_code%/**/%original_file_name% + # Docs Markdown files + - source: /docs/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name% + ignore : ['**/*.api.mdx', '**/*.info.mdx', '**/*.tag.mdx', '**/*.schema.mdx', '**/*.json'] + # Stellar Disbursement Platform Docs Markdown files + - source: /platforms/stellar-disbursement-platform/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs-sdp/current/**/%original_file_name% + ignore : ['**/*.api.mdx', '**/*.info.mdx', '**/*.tag.mdx', '**/*.schema.mdx', '**/*.json'] + # Anchor Platform Docs Markdown files + - source: /platforms/anchor-platform/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs-ap/current/**/%original_file_name% + ignore : ['**/*.api.mdx', '**/*.info.mdx', '**/*.tag.mdx', '**/*.schema.mdx', '**/*.json'] + # Anchor Platform versioned docs + - source: /ap_versioned_docs/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs-ap/**/%original_file_name% + ignore : ['**/*.api.mdx', '**/*.info.mdx', '**/*.tag.mdx', '**/*.schema.mdx', '**/*.json'] + # Meeting Notes Blog Markdown files + - source: /meeting-notes/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name% + # Pages Markdown files + - source: /src/pages/**/* + translation: /i18n/%two_letters_code%/docusaurus-plugin-content-pages/**/%original_file_name% + ignore: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx', '**/*.css'] + type: 'mdx_v2' diff --git a/crowdin.yml b/crowdin.yml deleted file mode 100644 index f96c7960b..000000000 --- a/crowdin.yml +++ /dev/null @@ -1,18 +0,0 @@ -project_id_env: CROWDIN_PROJECT_ID -api_token_env: CROWDIN_PERSONAL_TOKEN -preserve_hierarchy: true -files: - - source: /src/pages/**/* - translation: /i18n/%two_letters_code%/docusaurus-plugin-content-pages/**/%original_file_name% - ignore: ['/src/pages/**/*.js', '/src/pages/**/*.jsx', '/src/pages/**/*.ts', '/src/pages/**/*.tsx', '/src/pages/**/*.css'] - - source: /i18n/en/**/* - translation: /i18n/%two_letters_code%/**/%original_file_name% - - source: /docs/**/* - translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name% - ignore : ['/docs/**/*.api.mdx', '/docs/**/*.info.mdx', '/docs/**/*.tag.mdx', '/docs/**/*.schema.mdx', '/docs/**/*.json'] - - source: /platforms/**/* - translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs-platforms/current/**/%original_file_name% - ignore : ['/platforms/**/*.api.mdx', '/platforms/**/*.info.mdx', '/platforms/**/*.tag.mdx', '/platforms/**/*.schema.mdx', '/platforms/**/*.json'] - - source: /meeting-notes/**/* - translation: /i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name% - ignore : ['/meeting-notes/**/*.api.mdx', '/meeting-notes/**/*.info.mdx', '/meeting-notes/**/*.tag.mdx', '/meeting-notes/**/*.schema.mdx', '/meeting-notes/**/*.json'] \ No newline at end of file diff --git a/package.json b/package.json index 56edeff6d..7b8173687 100644 --- a/package.json +++ b/package.json @@ -29,14 +29,15 @@ "rpcspec:validate": "node openrpc/scripts/build.mjs && node openrpc/scripts/validate.mjs", "stellar-cli:build": "node scripts/stellar_cli.mjs", "crowdin": "crowdin", - "crowdin:copy": "node copyIgnoredFiles.mjs", + "crowdin:fix": "node scripts/copyIgnoredFiles.mjs && ./scripts/fix_md_comments.sh", + "crowdin:sync": "docusaurus write-translations && crowdin upload && crowdin download", "ap:versions:clean": "docusaurus clean-api-docs:version -p ap-apis ap_platform:all && docusaurus clean-api-docs:version -p ap-apis ap_callbacks:all && docusaurus clean-api-docs:version -p ap-apis ap_custody:all", "ap:versions:gen": "docusaurus gen-api-docs:version -p ap-apis ap_platform:all && docusaurus gen-api-docs:version -p ap-apis ap_callbacks:all && docusaurus gen-api-docs:version -p ap-apis ap_custody:all && rm ap_versioned_docs/version-*/api-reference/{callbacks,custody,platform/transactions}/*.info.mdx", "ap:versions:regen": "yarn ap:versions:clean && yarn ap:versions:gen", "ap:versions:new": "docusaurus docs:version:ap $VERSION && node scripts/ap_new_version.mjs $VERSION" }, "dependencies": { - "@crowdin/cli": "3", + "@crowdin/cli": "^4.1.1", "@docusaurus/core": "3.4.0", "@docusaurus/preset-classic": "3.4.0", "@docusaurus/remark-plugin-npm2yarn": "3.4.0", diff --git a/copyIgnoredFiles.mjs b/scripts/copyIgnoredFiles.mjs similarity index 90% rename from copyIgnoredFiles.mjs rename to scripts/copyIgnoredFiles.mjs index 1473b8f58..022f52f9c 100644 --- a/copyIgnoredFiles.mjs +++ b/scripts/copyIgnoredFiles.mjs @@ -7,8 +7,8 @@ import yaml from 'js-yaml'; const languages = ['es']; /** - * Reads and parses the crowdin.yml file. - * @param {string} filePath - The path to the crowdin.yml file. + * Reads and parses the crowdin.yaml file. + * @param {string} filePath - The path to the crowdin.yaml file. * @returns {Object} - The parsed configuration object. */ function readCrowdinConfig(filePath) { @@ -91,7 +91,10 @@ function copyIgnoredFilesForLanguages(config) { config.files.forEach(({ source, translation, ignore = [] }) => { ignore.forEach(ignorePattern => { - const srcPattern = ignorePattern.replace(/^\//, ''); // Strip the leading slash for the source path + let srcPattern = source + .replace(/^\//, '') // Strip the leading slash for the source path + .replace(/\*\*\/\*$/, ''); // strips the glob patter from the end + srcPattern += ignorePattern glob(srcPattern, (err, files) => { if (err) { @@ -114,7 +117,7 @@ function copyIgnoredFilesForLanguages(config) { * Main function to execute the workflow. */ function main() { - const config = readCrowdinConfig('crowdin.yml'); + const config = readCrowdinConfig('crowdin.yaml'); copyIgnoredFilesForLanguages(config); logMessage('Ignored files copied for all specified languages.'); } diff --git a/yarn.lock b/yarn.lock index 074facc28..d5bf72057 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1248,10 +1248,10 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@crowdin/cli@3": - version "3.19.4" - resolved "https://registry.yarnpkg.com/@crowdin/cli/-/cli-3.19.4.tgz#42c52c7a589c9aaf5c92503b4ba37e3f6a55612c" - integrity sha512-j0SiRGKOH/Pa/TdBeIxBBRrByHPqmVqWVo/LSjnri1lLPGywjcu9kB+pib7P4wmI00jgcVu+80yGdun5zRcDNQ== +"@crowdin/cli@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@crowdin/cli/-/cli-4.1.1.tgz#1a2067e79a53639920121870ae488a38dd2513ff" + integrity sha512-OC5xJgaXM9eC9UgiAV17HZrCDP1gM1gs2yMdSRFjM6ydu9LddybntMKgWU3ffRHjCjK6wDTrC31jo932Czrs+A== dependencies: command-exists-promise "^2.0.2" node-fetch "2.7.0" @@ -12409,16 +12409,7 @@ stream-http@^3.2.0: readable-stream "^3.6.0" xtend "^4.0.2" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12495,14 +12486,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -13691,16 +13675,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From 863953838a4b6b79ce9a930508ae9ff24cf5eada Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 23 Aug 2024 13:36:14 -0500 Subject: [PATCH 04/60] config updates and changes --- .github/workflows/upload-workflow.yml | 20 ++++++++++++++++---- Dockerfile | 5 +++++ docusaurus.config.ts | 14 ++++++++------ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/.github/workflows/upload-workflow.yml b/.github/workflows/upload-workflow.yml index 1d5149d0c..bfba65eb7 100644 --- a/.github/workflows/upload-workflow.yml +++ b/.github/workflows/upload-workflow.yml @@ -1,18 +1,30 @@ -name: Crowdin Upload Action +name: Crowdin Upload on: workflow_dispatch: push: - paths: [ 'docs/**', 'platforms/**','i18n/en/**', 'src/pages/**', 'meeting-notes/**' ] branches: [ main ] jobs: crowdin-upload: runs-on: ubuntu-latest steps: - - name: Checkout + - name: Checkout Docs Repo uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'yarn' + cache-dependency-path: '**/yarn.lock' + + - name: Install Dependencies + run: yarn --prefer-offline + + - name: Write Translations + run: yarn write-translations + - name: Crowdin push uses: crowdin/github-action@v2 with: @@ -20,5 +32,5 @@ jobs: upload_translations: false download_translations: false env: - CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + CROWDIN_PROJECT_ID: '669532' CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} diff --git a/Dockerfile b/Dockerfile index f0fc36ecf..e568c9b5c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,6 +19,11 @@ COPY . /app/ RUN yarn install RUN yarn rpcspec:build RUN yarn stellar-cli:build +# TODO: This takes a bit of time, we should probably make sure it's only done +# for production builds +# See: https://docusaurus.io/docs/3.4.0/i18n/crowdin#automate-with-ci +RUN yarn crowdin download +RUN yarn crowdin:fix RUN NODE_OPTIONS="--max-old-space-size=4096" yarn build FROM nginx:1.17 diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 1047daac9..c247efafb 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -15,8 +15,10 @@ const config: Config = { url: "https://developers.stellar.org", baseUrl: "/", trailingSlash: false, - onBrokenLinks: "throw", - onBrokenMarkdownLinks: "throw", + onBrokenLinks: "log", + onBrokenMarkdownLinks: "log", + // onBrokenLinks: "throw", + // onBrokenMarkdownLinks: "throw", favicon: "img/favicon-96x96.png", organizationName: "stellar", projectName: "stellar-docs", @@ -125,10 +127,6 @@ const config: Config = { href: "/", }, items: [ - { - type: 'localeDropdown', - position: 'left', - }, { type: 'docSidebar', sidebarId: 'build', @@ -225,6 +223,10 @@ const config: Config = { label: 'Meetings', position: 'right', }, + { + type: 'localeDropdown', + position: 'right', + }, { href: "https://github.com/stellar/stellar-docs", position: "right", From a1255dc1cb9d3153786a6b251798ab9e13e7ff00 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 23 Aug 2024 13:37:35 -0500 Subject: [PATCH 05/60] modify version dropdown to display on localized URLs too --- src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx b/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx index a22224fcf..3e6802b74 100644 --- a/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx +++ b/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx @@ -21,7 +21,7 @@ export default function DocsVersionDropdownNavbarItemWrapper(props: Props): JSX. * version dropdown for each plugin in your navbarItems config property for * this to work well. */ - if (!(pathname.startsWith('/platforms/anchor-platform') && docsPluginId === 'ap')) { + if (!(pathname.match(/^(\/es)?\/platforms\/anchor-platform/) && docsPluginId === 'ap')) { return null } return ( From 8d5b8614c52fecc4a9d206e430c642b3c9b17ba8 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 23 Aug 2024 13:38:05 -0500 Subject: [PATCH 06/60] simple perl commands to fix some of the markdown parsing problems --- scripts/fix_md_comments.sh | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 scripts/fix_md_comments.sh diff --git a/scripts/fix_md_comments.sh b/scripts/fix_md_comments.sh new file mode 100755 index 000000000..fc99fd931 --- /dev/null +++ b/scripts/fix_md_comments.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +perl -i -pe's/{\/_/{\/\*/' i18n/es/docusaurus-plugin-content-pages/docs/learn/interactive/dapps/challenges/* +perl -i -pe's/_\/}/\*\/}/' i18n/es/docusaurus-plugin-content-pages/docs/learn/interactive/dapps/challenges/* +perl -i -pe's/<(http.*)>/[\1](\1)/' i18n/es/docusaurus-plugin-content-pages/docs/learn/interactive/dapps/challenges/* +perl -i -pe's/\s\{/ \\{/g' i18n/es/docusaurus-plugin-content-docs/current/learn/fundamentals/transactions/list-of-operations.mdx From bf184dd9d9e21528de24c06abd9553f2a3cede6f Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 23 Aug 2024 13:39:17 -0500 Subject: [PATCH 07/60] modify some URLs (silly markdown parsing stuff again) --- meeting-notes/2024-05-09.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meeting-notes/2024-05-09.mdx b/meeting-notes/2024-05-09.mdx index 616da31ed..bf4cf32a9 100644 --- a/meeting-notes/2024-05-09.mdx +++ b/meeting-notes/2024-05-09.mdx @@ -13,6 +13,6 @@ tags: [developer] 1. Tyler built a voting application using passkeys to sign the transaction, which is an implementation of the secp256r1 verification function. 2. He showed a cross-platform implementation (web and mobile) and demonstrated that passkeys are the perfect interface between web3 contracts and web2 authentication mechanisms that most end users are accostomed to. -3. Ecosystem members discussed the use of smart wallets that would use passkeys as a signer. Challenges were identified around fees requires for smart wallets, the need for a common implementation for a smart wallet, as well as how might it interface with existing password managers. -4. The voting application can be tried out at [https://passkey.sorobanbyexample.org/](https://passkey.sorobanbyexample.org/) -5. Code for the demo is here [https://github.com/kalepail/soroban-passkey](https://github.com/kalepail/soroban-passkey) +3. Ecosystem members discussed the use of smart wallets that would use passkeys as a signer. Challenges were identified around fees requires for smart wallets, the need for a common implementation for a smart wallet, as well as how might it interface with existing password managers. +4. The voting application can be tried out at [passkey.sorobanbyexample.org/](https://passkey.sorobanbyexample.org/) +5. Code for the demo is here [github.com/kalepail/soroban-passkey](https://github.com/kalepail/soroban-passkey) From 178d2b8fa909c5698ea109803f0337651c1a147f Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 23 Aug 2024 13:40:34 -0500 Subject: [PATCH 08/60] fixup markdown formatting --- docs/README.mdx | 14 +- .../conversions/address-conversions.mdx | 181 ++++++++---------- .../guides/conversions/bytes-conversions.mdx | 179 ++++++++--------- .../guides/conversions/scval-conversions.mdx | 108 +++++------ .../guides/conversions/string-conversions.mdx | 137 +++++++------ .../transactions/list-of-operations.mdx | 6 +- .../operations-and-transactions.mdx | 2 +- 7 files changed, 289 insertions(+), 338 deletions(-) diff --git a/docs/README.mdx b/docs/README.mdx index bf0897cdb..befea2d47 100644 --- a/docs/README.mdx +++ b/docs/README.mdx @@ -6,30 +6,30 @@ hide_table_of_contents: true ## Navigating the docs -### [Build](/docs/build/README.mdx) +### [Build](./build/README.mdx) Contains tutorials and how-to guides for writing smart contracts, building applications, interacting with the network, and more. -### [Learn](/docs/learn/fundamentals/README.mdx) +### [Learn](./learn/fundamentals/README.mdx) Find all informational and conceptual content here. Learn about Stellar fundamentals like how accounts and transactions function, dive deeper into the functionality of each operation, discover how fees work, and more. -### [Tokens](/docs/tokens/README.mdx) +### [Tokens](./tokens/README.mdx) Information on how to issue assets on the Stellar network and create custom smart contract tokens. -### [Data](/docs/data/README.mdx) +### [Data](./data/README.mdx) Discover various data availability options: RPC, Hubble, and Horizon. -### [Tools](/docs/tools/README.mdx) +### [Tools](./tools/README.mdx) Learn about all the available tools at your disposal for building on, interacting with, or just watching the Stellar network. Also, find information on how to use the Anchor Platform or Stellar Disbursement Platform. -### [Networks](/docs/networks/README.mdx) +### [Networks](./networks/README.mdx) Information about deployed networks (Mainnet, Testnet, and Futurenet), current software versions, and resource limitations and fees. -### [Validators](/docs/validators/README.mdx) +### [Validators](./validators/README.mdx) Everything you'll need to know if you want to run, operate, and maintain a core validator node on the Stellar network. diff --git a/docs/build/guides/conversions/address-conversions.mdx b/docs/build/guides/conversions/address-conversions.mdx index 26bc8ff79..82ef7b281 100644 --- a/docs/build/guides/conversions/address-conversions.mdx +++ b/docs/build/guides/conversions/address-conversions.mdx @@ -4,8 +4,7 @@ hide_table_of_contents: true description: Convert an address to other types --- -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; +import { CodeExample } from "@site/src/components/CodeExample"; The `Address` is an opaque type that could represent an "account" on the Stellar network (i.e., a keypair), or a "contract." From Soroban's point of view, it doesn't really matter which it is. The "account" variety of these addresses are typically displayed as a `G...` public address, and the "contract" variety is typically displayed as a `C...` address. An address may also be displayed in other formats such as a 32 byte array, a string, or an ScVal type. The Soroban SDKs provide methods that easily convert an address to any of these types. @@ -13,124 +12,104 @@ The `Address` is an opaque type that could represent an "account" on the Stellar Bytes are a more compact and efficient way to store data in terms of storage optimization and data transmission. In situations where you need to store or transmit an address in a fixed-size, such as for cryptographic operations or data serialization, you need to convert the address to a bytesN format - - - - ```rust - use soroban_sdk::{Address, BytesN, Env, FromVal}; + - pub fn address_to_bytes32(env: &Env, address: Address) -> BytesN<32> { - let address_to_bytes: BytesN<32> = BytesN::from_val(env, &address.to_val()); - address_to_bytes - } - ``` - +```rust +use soroban_sdk::{Address, BytesN, Env, FromVal}; - - ```js - const StellarSdk = require('@stellar/stellar-sdk'); +pub fn address_to_bytes32(env: &Env, address: Address) -> BytesN<32> { +let address_to_bytes: BytesN<32> = BytesN::from_val(env, &address.to_val()); + address_to_bytes +} +``` - // Example Stellar address - const stellarAddress = 'GCM5WPR4DDR24FSAX5LIEM4J7AI3KOWJYANSXEPKYXCSZOTAYXE75AFN'; - // Create an Address object - const address = new StellarSdk.Address(stellarAddress); - // Convert the Address to raw public key bytes (Buffer) - const buffer = address.toBuffer(); - ``` +```js +const StellarSdk = require("@stellar/stellar-sdk"); - +// Example Stellar address +const stellarAddress = + "GCM5WPR4DDR24FSAX5LIEM4J7AI3KOWJYANSXEPKYXCSZOTAYXE75AFN"; +// Create an Address object +const address = new StellarSdk.Address(stellarAddress); +// Convert the Address to raw public key bytes (Buffer) +const buffer = address.toBuffer(); +``` - +```python +from stellar_sdk.address import Address +from stellar_sdk.strkey import StrKey - ```python - from stellar_sdk.address import Address - from stellar_sdk.strkey import StrKey +# Example Stellar address +stellar_address = 'GCM5WPR4DDR24FSAX5LIEM4J7AI3KOWJYANSXEPKYXCSZOTAYXE75AFN' +# Convert the address to bytes +StrKey.decode_ed25519_public_key(stellar_address) +``` - # Example Stellar address - stellar_address = 'GCM5WPR4DDR24FSAX5LIEM4J7AI3KOWJYANSXEPKYXCSZOTAYXE75AFN' - # Convert the address to bytes - StrKey.decode_ed25519_public_key(stellar_address) - ``` - - - + ## Address to String When transferring data between different systems or over a network, using text-based formats like JSON and XML string formats are often required. Storing addresses as strings in databases can simplify database schema design and queries. Strings are easier to manipulate and are more compatible with user interfaces and APIs. - - - - ```rust - use soroban_sdk::{Address, String, Env}; - - pub fn address_to_string(address: Address) -> String { - address.to_string() - } - ``` - + - +```rust +use soroban_sdk::{Address, String, Env}; - ```js - const StellarSdk = require('@stellar/stellar-sdk'); +pub fn address_to_string(address: Address) -> String { + address.to_string() +} +``` - // Example Stellar address - const stellarAddress = 'GCM5WPR4DDR24FSAX5LIEM4J7AI3KOWJYANSXEPKYXCSZOTAYXE75AFN'; - // Create an Address object - const address = new StellarSdk.Address(stellarAddress); - // Convert the address to string - const addressToString = address.toString(); - ``` +```js +const StellarSdk = require("@stellar/stellar-sdk"); - +// Example Stellar address +const stellarAddress = + "GCM5WPR4DDR24FSAX5LIEM4J7AI3KOWJYANSXEPKYXCSZOTAYXE75AFN"; +// Create an Address object +const address = new StellarSdk.Address(stellarAddress); +// Convert the address to string +const addressToString = address.toString(); +``` - + # Address to ScVal Addresses are often passed as function parameters in Soroban smart contracts. These addresses must be in ScVal format because the Soroban virtual machine processes data in this format. Similarly, if a smart contract function returns an address, it will be returned as an ScVal. Converting to and from ScVal ensures that you can properly handle these return values. - - - - ```rust - use soroban_sdk::{Address, Val}; - - pub fn address_to_sc_val(address: Address) -> Val { - address.to_val() - } - ``` - - - - - ```js - // Example Stellar address - const stellarAddress = 'GCM5WPR4DDR24FSAX5LIEM4J7AI3KOWJYANSXEPKYXCSZOTAYXE75AFN'; - // Create an Address object - const address = new StellarSdk.Address(stellarAddress); - // Convert the Address to xdr.ScVal - const scVal = address.toScVal(); - // Convert the Address to xdr.ScAddress - const scAddress = address.toScAddress(); - ``` - - - - - - ```python - from stellar_sdk.address import Address - - # Example Stellar address - stellar_address = 'GBJCHUKZMTFSLOMNC7P4TS4VJJBTCYL3XKSOLXAUJSD56C4LHND5TWUC' - # Create an Address object - address = Address(stellar_address) - # Convert the Address object to an ScAddress - sc_address_xdr = address.to_xdr_sc_address() - ``` - - - + + +```rust +use soroban_sdk::{Address, Val}; + +pub fn address_to_sc_val(address: Address) -> Val { + address.to_val() +} +``` + +```js +// Example Stellar address +const stellarAddress = + "GCM5WPR4DDR24FSAX5LIEM4J7AI3KOWJYANSXEPKYXCSZOTAYXE75AFN"; +// Create an Address object +const address = new StellarSdk.Address(stellarAddress); +// Convert the Address to xdr.ScVal +const scVal = address.toScVal(); +// Convert the Address to xdr.ScAddress +const scAddress = address.toScAddress(); +``` + +```python +from stellar_sdk.address import Address + +# Example Stellar address +stellar_address = 'GBJCHUKZMTFSLOMNC7P4TS4VJJBTCYL3XKSOLXAUJSD56C4LHND5TWUC' +# Create an Address object +address = Address(stellar_address) +# Convert the Address object to an ScAddress +sc_address_xdr = address.to_xdr_sc_address() +``` + + diff --git a/docs/build/guides/conversions/bytes-conversions.mdx b/docs/build/guides/conversions/bytes-conversions.mdx index 22aea8d54..f04548b7e 100644 --- a/docs/build/guides/conversions/bytes-conversions.mdx +++ b/docs/build/guides/conversions/bytes-conversions.mdx @@ -4,8 +4,7 @@ hide_table_of_contents: true description: Convert from bytes to other types --- -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; +import { CodeExample } from "@site/src/components/CodeExample"; Bytes is a contiguous growable array type containing u8s. They may represent various types of data including strings, addresses, or other information. Converting any data type to bytes ensures that the data be consistently handled by the Soroban runtime and interacting systems. @@ -13,132 +12,112 @@ Bytes is a contiguous growable array type containing u8s. They may represent var When retrieving data stored on the blockchain, addresses might be stored in byte representation for compactness and efficiency. Off-chain systems, such as APIs, databases, or user interfaces, usually expect addresses in a human-readable format. In such cases, you need to convert the bytes to an address format to ensure compatibility. - - - - ```rust - use soroban_sdk::{Address, Bytes, Env}; + - pub fn bytes_to_address(bytes: Bytes) -> Address { - Address::from_string_bytes(&bytes) - } - ``` - +```rust +use soroban_sdk::{Address, Bytes, Env}; - - - ```js - const StellarSdk = require('@stellar/stellar-sdk'); +pub fn bytes_to_address(bytes: Bytes) -> Address { + Address::from_string_bytes(&bytes) +} +``` - // Example bytes value - const rawBytes = Buffer.from('99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe', 'hex'); - // Convert bytes to an account Address - const addressFromBytes = StellarSdk.Address.account(rawBytes); - addressFromBytes.toString(); - // Convert from bytes to a string address - const addressFromBytes = StellarSdk.Address.contract(rawBytes); - addressFromBytes.toString(); - ``` +```js +const StellarSdk = require("@stellar/stellar-sdk"); - +// Example bytes value +const rawBytes = Buffer.from( + "99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe", + "hex", +); +// Convert bytes to an account Address +const addressFromBytes = StellarSdk.Address.account(rawBytes); +addressFromBytes.toString(); +// Convert from bytes to a string address +const addressFromBytes = StellarSdk.Address.contract(rawBytes); +addressFromBytes.toString(); +``` - +```python +from stellar_sdk.address import Address - ```python - from stellar_sdk.address import Address +# Example bytes value +raw_bytes = bytes.fromhex('99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe') +bytes_to_address = Address.from_raw_account(raw_bytes) +``` - # Example bytes value - raw_bytes = bytes.fromhex('99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe') - bytes_to_address = Address.from_raw_account(raw_bytes) - ``` - - - + ## Bytes to String When dealing with binary data, you may need to convert certain portions of the data to a human-readable format like strings for logging, debugging, processing or display. - - - - ```rust - use soroban_sdk::{String, Bytes, Env, FromVal}; - - pub fn bytes_to_string(env: &Env, bytes: Bytes) -> String { - String::from_val(env, &bytes.to_val()) - } - ``` - - - - + - ```js - const StellarSdk = require('@stellar/stellar-sdk'); +```rust +use soroban_sdk::{String, Bytes, Env, FromVal}; - // Example bytes value - const rawBytes = Buffer.from('99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe', 'hex'); - // Convert bytes to string - const bytesToString = rawBytes.toString('hex'); - ``` +pub fn bytes_to_string(env: &Env, bytes: Bytes) -> String { + String::from_val(env, &bytes.to_val()) +} +``` - +```js +const StellarSdk = require("@stellar/stellar-sdk"); - +// Example bytes value +const rawBytes = Buffer.from( + "99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe", + "hex", +); +// Convert bytes to string +const bytesToString = rawBytes.toString("hex"); +``` - ```python - from stellar_sdk.address import Address +```python +from stellar_sdk.address import Address - # Example bytes - raw_bytes = b'99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe' - # Convert bytes to string - bytes_to_string = raw_bytes.decode('utf-8') - ``` - +# Example bytes +raw_bytes = b'99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe' +# Convert bytes to string +bytes_to_string = raw_bytes.decode('utf-8') +``` - + ## Bytes to ScVal In a Soroban smart contract that interacts with an external oracle service to provide price data in raw byte format, you would need to convert the bytes to ScVal to process and manipulate the data within your contract. - - - - ```rust - use soroban_sdk::{Bytes, Env, FromVal, Val}; - - pub fn bytes_to_val(env: &Env, bytes: Bytes) -> Val { - Val::from_val(env, &bytes.to_val()) - } - - ``` - - - + - ```js - const StellarSdk = require('@stellar/stellar-sdk'); +```rust +use soroban_sdk::{Bytes, Env, FromVal, Val}; - // Example bytes value - const rawBytes = Buffer.from('99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe', 'hex'); - // Convert bytes to xdr.ScVal - const bytesToScVal = StellarSdk.xdr.ScVal.scvBytes(rawBytes); - ``` +pub fn bytes_to_val(env: &Env, bytes: Bytes) -> Val { + Val::from_val(env, &bytes.to_val()) +} +``` - +```js +const StellarSdk = require("@stellar/stellar-sdk"); - +// Example bytes value +const rawBytes = Buffer.from( + "99db3e3c18e3ae1640bf56823389f811b53ac9c01b2b91eac5c52cba60c5c9fe", + "hex", +); +// Convert bytes to xdr.ScVal +const bytesToScVal = StellarSdk.xdr.ScVal.scvBytes(rawBytes); +``` - ```python - import stellar_sdk +```python +import stellar_sdk - # Example bytes value - raw_bytes = b'example_bytes_data' - # Convert bytes to ScVal - sc_val = stellar_sdk.scval.to_bytes(raw_bytes) - ``` +# Example bytes value +raw_bytes = b'example_bytes_data' +# Convert bytes to ScVal +sc_val = stellar_sdk.scval.to_bytes(raw_bytes) +``` - - + diff --git a/docs/build/guides/conversions/scval-conversions.mdx b/docs/build/guides/conversions/scval-conversions.mdx index bd61d122f..455945503 100644 --- a/docs/build/guides/conversions/scval-conversions.mdx +++ b/docs/build/guides/conversions/scval-conversions.mdx @@ -12,96 +12,90 @@ Soroban Contract Value (`ScVal`) is a custom type defined within the Soroban run ## ScVal to bytesN - + - ```js - const StellarSdk = require('@stellar/stellar-sdk'); +```js +const StellarSdk = require("@stellar/stellar-sdk"); - // Convert ScVal to bytes - const bytesFromScVal = scVal.bytes(); +/* Convert ScVal to bytes */ +const bytesFromScVal = StellarSdk.scVal.bytes(); +``` - ``` - `.bytes()` converts an ScVal value to bytes. - `scVal` is the ScVal value to be converted to bytes. +- `.bytes()` converts an ScVal value to bytes. +- `scVal` is the ScVal value to be converted to bytes. - + + - +```python +import stellar_sdk - ```python - import stellar_sdk +# Convert ScVal to bytes +sc_val_to_bytes = stellar_sdk.scval.from_bytes(sc_val) +``` - # Convert ScVal to bytes - sc_val_to_bytes = stellar_sdk.scval.from_bytes(sc_val) - - ``` - `stellar_sdk.scval.from_bytes()` converts an ScVal value to bytes. - `sc_val` is the ScVal value to be converted to bytes. - +- `stellar_sdk.scval.from_bytes()` converts an ScVal value to bytes. +- `sc_val` is the ScVal value to be converted to bytes. + ## ScVal to address - - - ```js - const StellarSdk = require('@stellar/stellar-sdk'); + - const addressFromScVal = StellarSdk.Address.fromScVal(scVal); - addressFromScVal.toString(); +```js +const StellarSdk = require("@stellar/stellar-sdk"); - ``` - `StellarSdk.Address.fromScVal()` converts an ScVal value to an address. - `scVal` is the ScVal value to be converted to an address. +const addressFromScVal = StellarSdk.Address.fromScVal(scVal); +addressFromScVal.toString(); +``` - +- `StellarSdk.Address.fromScVal()` converts an ScVal value to an address. +- `scVal` is the ScVal value to be converted to an address. - + + - ```python - import stellar_sdk +```python +import stellar_sdk - sc_to_address = Address.from_xdr_sc_address(sc_val) +sc_to_address = Address.from_xdr_sc_address(sc_val) +``` - ``` - `stellar_sdk.scval.from_xdr_sc_addres9()` converts an ScVal value to an address. - `sc_val` represents the ScVal value to be converted to an address. - - +- `stellar_sdk.scval.from_xdr_sc_addres9()` converts an ScVal value to an address. +- `sc_val` represents the ScVal value to be converted to an address. + ## ScVal to String - - - ```js - const StellarSdk = require('@stellar/stellar-sdk'); + - const stringFromScVal = scVal.toString('utf-8'); +```js +const StellarSdk = require("@stellar/stellar-sdk"); - ``` - `scVal.toString()` converts an ScVal value to a string. - `scVal` is the ScVal value to be converted to a string. - `utf-8` is the encoding format for the string. +const stringFromScVal = scVal.toString("utf-8"); +``` - +`scVal.toString()` converts an ScVal value to a string. `scVal` is the ScVal value to be converted to a string. `utf-8` is the encoding format for the string. - + + - ```python +```python - import stellar_sdk +import stellar_sdk - # scval to string - sc_val_to_string = stellar_sdk.scval.from_string(sc_val) +# scval to string +sc_val_to_string = stellar_sdk.scval.from_string(sc_val) +``` - ``` - `stellar_sdk.scval.from_string()` converts an ScVal value to a string. - `sc_val` represents the ScVal value to be converted to a string. - +- `stellar_sdk.scval.from_string()` converts an ScVal value to a string. +- `sc_val` represents the ScVal value to be converted to a string. + diff --git a/docs/build/guides/conversions/string-conversions.mdx b/docs/build/guides/conversions/string-conversions.mdx index f40ad6277..bbe4f9508 100644 --- a/docs/build/guides/conversions/string-conversions.mdx +++ b/docs/build/guides/conversions/string-conversions.mdx @@ -14,41 +14,41 @@ Strings are a sequence of characters used to represent readable text. They are u Some systems use binary formats where data needs to be represented as a fixed-length byte array for storage or processing. For example, fixed-length hashes or identifiers. Converting strings to a fixed byte size ensures that the data fits the required size constraints. - - - ```rust - use soroban_sdk::{String, BytesN, Env, FromVal}; + - pub fn string_to_bytesN(env: &Env, string: String) -> BytesN<32> { - BytesN::from_val(env, &string.to_val()) - } - ``` - +```rust +use soroban_sdk::{String, BytesN, Env, FromVal}; - +pub fn string_to_bytesN(env: &Env, string: String) -> BytesN<32> { + BytesN::from_val(env, &string.to_val()) +} +``` - ```js - import StellarSdk = require('@stellar/stellar-sdk'); + + - // Example string - const stringValue = 'Hello, Stellar!'; - // Convert the string to bytes format - const byteValue = Buffer.from(stringValue, 'utf-8'); - ``` - +```js +import StellarSdk = require('@stellar/stellar-sdk'); - +// Example string +const stringValue = 'Hello, Stellar!'; +// Convert the string to bytes format +const byteValue = Buffer.from(stringValue, 'utf-8'); +``` - ```python - import stellar_sdk + + - string_value.encode() - ``` - `string_value` is the string value to be converted to bytes. - `.encode()` is a method that converts the string to bytes. +```python +import stellar_sdk - +string_value.encode() +``` +- `string_value` is the string value to be converted to bytes. +- `.encode()` is a method that converts the string to bytes. + + ## String to address @@ -56,29 +56,29 @@ Some systems use binary formats where data needs to be represented as a fixed-le An address received in a user input may be of string type and you would need to convert it to an address type to perform validations, transactions, or other operations within your smart contract. - - - ```rust - use soroban_sdk::{Address, Env, String}; + + +```rust +use soroban_sdk::{Address, Env, String}; - pub fn string_to_address(string: String) -> Address { - Address::from_string(&string) - } - ``` - +pub fn string_to_address(string: String) -> Address { + Address::from_string(&string) +} +``` - + + - ```js - const StellarSdk = require('@stellar/stellar-sdk'); +```js +const StellarSdk = require("@stellar/stellar-sdk"); - const stringToAddress = StellarSdk.Address.fromString(stellarAddress); - ``` - `stellarAddress` is the string value to be converted to an address. - `StellarSdk.Address.fromString()` is a method that converts a string to an address. +const stringToAddress = StellarSdk.Address.fromString(stellarAddress); +``` - +- `stellarAddress` is the string value to be converted to an address. +- `StellarSdk.Address.fromString()` is a method that converts a string to an address. + ## String to ScVal @@ -86,40 +86,39 @@ An address received in a user input may be of string type and you would need to When calling functions or methods that expect ScVal types, you need to convert your string data to ScVal to make the call successful. For example, if your smart contract needs to store or manipulate a user input string within its state or use it as part of its logic, you would convert the string to an ScVal type to integrate it with the contract's operations. - - - ```rust - use soroban_sdk::{String, Env, Val}; + - pub fn string_to_val(env: &Env, string: String) -> Val { - string.to_val() - } - ``` - +```rust +use soroban_sdk::{String, Env, Val}; - +pub fn string_to_val(env: &Env, string: String) -> Val { + string.to_val() +} +``` - ```js - import StellarSdk from '@stellar/stellar-sdk'; + + - // Example string value - const stringValue = 'Hello, Stellar!'; - // Convert the string to ScVal - const stringToScVal = StellarSdk.xdr.ScVal.scvString(stringValue); - ``` +```js +import StellarSdk from "@stellar/stellar-sdk"; - +// Example string value +const stringValue = "Hello, Stellar!"; +// Convert the string to ScVal +const stringToScVal = StellarSdk.xdr.ScVal.scvString(stringValue); +``` - + + - ```python - import stellar_sdk +```python +import stellar_sdk - string_to_sc_val = stellar_sdk.scval.to_string(string_value) - ``` - `string_value` is the string value to be converted to an ScVal - `stellar_sdk.scval.to_string()` converts the string value to an ScVal +string_to_sc_val = stellar_sdk.scval.to_string(string_value) +``` - +- `string_value` is the string value to be converted to an ScVal +- `stellar_sdk.scval.to_string()` converts the string value to an ScVal + diff --git a/docs/learn/fundamentals/transactions/list-of-operations.mdx b/docs/learn/fundamentals/transactions/list-of-operations.mdx index 5b5395480..72bec0597 100644 --- a/docs/learn/fundamentals/transactions/list-of-operations.mdx +++ b/docs/learn/fundamentals/transactions/list-of-operations.mdx @@ -148,7 +148,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | Selling | asset | Asset the offer creator is selling. | | Buying | asset | Asset the offer creator is buying. | | Amount | integer | Amount of `buying` being bought. Set to `0` if you want to delete an existing offer. | -| Price | \{numerator, denominator} | Price of 1 unit of `buying` in terms of `selling`. For example, if you wanted to buy 30 XLM and sell 5 BTC, the price would be {5,30}. | +| Price | \{numerator, denominator} | Price of 1 unit of `buying` in terms of `selling`. For example, if you wanted to buy 30 XLM and sell 5 BTC, the price would be \{5,30}. | | Offer ID | unsigned integer | The ID of the offer. `0` for new offer. Set to existing offer ID to update or delete. | **Possible errors**: @@ -182,7 +182,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | Selling | asset | Asset the offer creator is selling. | | Buying | asset | Asset the offer creator is buying. | | Amount | integer | Amount of `selling` being sold. Set to `0` if you want to delete an existing offer. | -| Price | \{numerator, denominator} | Price of 1 unit of `selling` in terms of `buying`. For example, if you wanted to sell 30 XLM and buy 5 BTC, the price would be {5,30}. | +| Price | \{numerator, denominator} | Price of 1 unit of `selling` in terms of `buying`. For example, if you wanted to sell 30 XLM and buy 5 BTC, the price would be \{5,30}. | | Offer ID | unsigned integer | The ID of the offer. `0` for new offer. Set to existing offer ID to update or delete. | **Possible errors**: @@ -216,7 +216,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | Selling | asset | Asset the offer creator is selling. | | Buying | asset | Asset the offer creator is buying. | | Amount | integer | Amount of `selling` being sold. | -| Price | \{numerator, denominator} | Price of 1 unit of `selling` in terms of `buying`. For example, if you wanted to sell 30 XLM and buy 5 BTC, the price would be {5,30}. | +| Price | \{numerator, denominator} | Price of 1 unit of `selling` in terms of `buying`. For example, if you wanted to sell 30 XLM and buy 5 BTC, the price would be \{5,30}. | **Possible errors**: diff --git a/docs/learn/fundamentals/transactions/operations-and-transactions.mdx b/docs/learn/fundamentals/transactions/operations-and-transactions.mdx index b2f33197a..2692a3397 100644 --- a/docs/learn/fundamentals/transactions/operations-and-transactions.mdx +++ b/docs/learn/fundamentals/transactions/operations-and-transactions.mdx @@ -31,7 +31,7 @@ Transactions are atomic. Meaning if one operation in a transaction fails, all op Operations are executed for the source account of the transaction unless an operation override is defined. -Smart contract transactions also go through a simulation process where developers can test how the transaction would be executed on the network using the RPC endpoint `simulateTransaction`. Read more in the [Soroban docs](/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx). +Smart contract transactions also go through a simulation process where developers can test how the transaction would be executed on the network using the RPC endpoint `simulateTransaction`. Read more in the [Soroban docs](../../encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx). #### Transaction attributes From 128bd1dec6c95aa9cb786fc23c22e6764a9d6bd4 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 23 Aug 2024 14:13:08 -0500 Subject: [PATCH 09/60] test only the english version in github --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a0148b871..db39a7749 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,6 +29,6 @@ jobs: run: yarn check:mdx - name: Build app - run: yarn build + run: yarn build --locale en From 392d70a08e48306ea25905aea3668933e0d20b00 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 26 Aug 2024 09:49:06 -0500 Subject: [PATCH 10/60] make the copy action workflow run on-demand, fix npm script name --- .github/workflows/copy-workflow.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/copy-workflow.yml b/.github/workflows/copy-workflow.yml index f5332140c..c4c1b067c 100644 --- a/.github/workflows/copy-workflow.yml +++ b/.github/workflows/copy-workflow.yml @@ -2,9 +2,9 @@ name: Crowdin Copy and Create PR on: workflow_dispatch: - push: - paths: [ 'docs/**', 'platforms/**','i18n/en/**', 'src/pages/**', 'meeting-notes/**' ] - branches: [ main ] + # push: + # paths: [ 'docs/**', 'platforms/**','i18n/en/**', 'src/pages/**', 'meeting-notes/**' ] + # branches: [ main ] permissions: contents: write @@ -34,8 +34,8 @@ jobs: - name: Install dependencies run: yarn install - - name: Run crowdin:copy - run: yarn run crowdin:copy + - name: Run crowdin:fix + run: yarn run crowdin:fix - name: Configure Git run: | @@ -58,7 +58,7 @@ jobs: git push origin --delete $BRANCH_NAME || true git checkout -b $BRANCH_NAME git add . - git commit -m "chore: Copy ignored files using crowdin:copy" + git commit -m "chore: Copy ignored files using crowdin:fix" git push --force --set-upstream origin $BRANCH_NAME echo "branch_name=$BRANCH_NAME" >> $GITHUB_ENV @@ -71,4 +71,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - gh pr create --repo ${{ github.repository }} --base main --head ${{ env.branch_name }} --title "Copy ignored files using crowdin:copy" --body "This PR was created by GitHub Actions to copy ignored files using the crowdin:copy command." + gh pr create --repo ${{ github.repository }} --base main --head ${{ env.branch_name }} --title "Copy ignored files using crowdin:fix" --body "This PR was created by GitHub Actions to copy ignored files using the crowdin:fix command." From abb0da9062222afd84e0491d13ecf94ada147742 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 26 Aug 2024 10:44:13 -0500 Subject: [PATCH 11/60] gitignore the translation directory --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 06ba49a55..7237e0747 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,7 @@ yarn-error.log* /openrpc/*openrpc.json # Environment variables -.env \ No newline at end of file +.env + +# translation files +i18n From a59cdf228c28f162bb796bc7058329c8359aaa7e Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 26 Aug 2024 11:54:33 -0500 Subject: [PATCH 12/60] remove example env file --- .env.example | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .env.example diff --git a/.env.example b/.env.example deleted file mode 100644 index f42bf1347..000000000 --- a/.env.example +++ /dev/null @@ -1,2 +0,0 @@ -CROWDIN_PROJECT_ID=123 -CROWDIN_PERSONAL_TOKEN="1a2b3c" \ No newline at end of file From 3738004df8d8b1b971a8b301eaf5aac292b09c92 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 27 Aug 2024 10:28:59 -0500 Subject: [PATCH 13/60] add note about build command in dockerfile --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index e568c9b5c..b0ab48afa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,8 @@ RUN yarn stellar-cli:build # See: https://docusaurus.io/docs/3.4.0/i18n/crowdin#automate-with-ci RUN yarn crowdin download RUN yarn crowdin:fix +# TODO: It's actually this part that is more time-consuming. The best way to +# speed this up is to generate the preview for only `--locale en` RUN NODE_OPTIONS="--max-old-space-size=4096" yarn build FROM nginx:1.17 From fbf277dd6447e3fdeea6b7388ecab8d53f1ce65b Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 27 Aug 2024 11:02:03 -0500 Subject: [PATCH 14/60] pass crowdin token from makefile to dockerfile --- Dockerfile | 3 ++- Makefile | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index b0ab48afa..7de680ae4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y gpg curl git ma apt-get update && apt-get install -y nodejs yarn && apt-get clean COPY . /app/ +ARG CROWDIN_PERSONAL_TOKEN RUN yarn install RUN yarn rpcspec:build @@ -22,7 +23,7 @@ RUN yarn stellar-cli:build # TODO: This takes a bit of time, we should probably make sure it's only done # for production builds # See: https://docusaurus.io/docs/3.4.0/i18n/crowdin#automate-with-ci -RUN yarn crowdin download +RUN CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn crowdin download RUN yarn crowdin:fix # TODO: It's actually this part that is more time-consuming. The best way to # speed this up is to generate the preview for only `--locale en` diff --git a/Makefile b/Makefile index 0b53a9434..d0f21ebab 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ TAG ?= stellar/stellar-docs:$(LABEL) BUILD_DATE := $(shell date -u +%FT%TZ) docker-build: - $(SUDO) docker build --no-cache --pull --label org.opencontainers.image.created="$(BUILD_DATE)" -t $(TAG) . + $(SUDO) docker build --no-cache --pull --label org.opencontainers.image.created="$(BUILD_DATE)" -t $(TAG) . --build-arg CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} docker-push: $(SUDO) docker push $(TAG) From b358244dcca9d83f8150fca94536af8466d18ff4 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 27 Aug 2024 11:19:26 -0500 Subject: [PATCH 15/60] add dot-slash to links in AP RPC methods table --- .../platform/rpc/methods/README.mdx | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/platforms/anchor-platform/api-reference/platform/rpc/methods/README.mdx b/platforms/anchor-platform/api-reference/platform/rpc/methods/README.mdx index af6f30302..0a5a01606 100644 --- a/platforms/anchor-platform/api-reference/platform/rpc/methods/README.mdx +++ b/platforms/anchor-platform/api-reference/platform/rpc/methods/README.mdx @@ -16,26 +16,26 @@ Postman collection is available [here](https://documenter.getpostman.com/view/92 | | | | --- | --- | -| | [notify_interactive_flow_completed](notify_interactive_flow_completed.mdx) | -| | [request_offchain_funds](request_offchain_funds.mdx) | -| | [request_onchain_funds](request_onchain_funds.mdx) | -| | [notify_offchain_funds_received](notify_offchain_funds_received.mdx) | -| | [notify_onchain_funds_received](notify_onchain_funds_received.mdx) | -| | [notify_amounts_updated](notify_amounts_updated.mdx) | -| | [notify_refund_pending](notify_refund_pending.mdx) | -| | [notify_refund_sent](notify_refund_sent.mdx) | -| | [do_stellar_payment](do_stellar_payment.mdx) | -| | [do_stellar_refund](do_stellar_refund.mdx) | -| | [notify_onchain_funds_sent](notify_onchain_funds_sent.mdx) | -| | [notify_offchain_funds_sent](notify_offchain_funds_sent.mdx) | -| | [notify_offchain_funds_available](notify_offchain_funds_available.mdx) | -| | [notify_offchain_funds_pending](notify_offchain_funds_pending.mdx) | -| | [request_trust](request_trust.mdx) | -| | [notify_trust_set](notify_trust_set.mdx) | -| | [notify_customer_info_updated](notify_customer_info_updated.mdx) | -| | [notify_transaction_error](notify_transaction_error.mdx) | -| | [notify_transaction_expired](notify_transaction_expired.mdx) | -| | [notify_transaction_recovery](notify_transaction_recovery.mdx) | -| | [notify_transaction_on_hold](notify_transaction_on_hold.mdx) | +| | [notify_interactive_flow_completed](./notify_interactive_flow_completed.mdx) | +| | [request_offchain_funds](./request_offchain_funds.mdx) | +| | [request_onchain_funds](./request_onchain_funds.mdx) | +| | [notify_offchain_funds_received](./notify_offchain_funds_received.mdx) | +| | [notify_onchain_funds_received](./notify_onchain_funds_received.mdx) | +| | [notify_amounts_updated](./notify_amounts_updated.mdx) | +| | [notify_refund_pending](./notify_refund_pending.mdx) | +| | [notify_refund_sent](./notify_refund_sent.mdx) | +| | [do_stellar_payment](./do_stellar_payment.mdx) | +| | [do_stellar_refund](./do_stellar_refund.mdx) | +| | [notify_onchain_funds_sent](./notify_onchain_funds_sent.mdx) | +| | [notify_offchain_funds_sent](./notify_offchain_funds_sent.mdx) | +| | [notify_offchain_funds_available](./notify_offchain_funds_available.mdx) | +| | [notify_offchain_funds_pending](./notify_offchain_funds_pending.mdx) | +| | [request_trust](./request_trust.mdx) | +| | [notify_trust_set](./notify_trust_set.mdx) | +| | [notify_customer_info_updated](./notify_customer_info_updated.mdx) | +| | [notify_transaction_error](./notify_transaction_error.mdx) | +| | [notify_transaction_expired](./notify_transaction_expired.mdx) | +| | [notify_transaction_recovery](./notify_transaction_recovery.mdx) | +| | [notify_transaction_on_hold](./notify_transaction_on_hold.mdx) | From 6bd363c891cdd15e7e014ab9c297911e7a913447 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 28 Aug 2024 13:08:39 -0500 Subject: [PATCH 16/60] use localization-aware edit URLs for docs --- config/anchorPlatform.config.ts | 4 +++- config/constants.ts | 11 +++++++++++ config/disbursementPlatform.config.ts | 4 +++- docusaurus.config.ts | 5 +++-- 4 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 config/constants.ts diff --git a/config/anchorPlatform.config.ts b/config/anchorPlatform.config.ts index 687ae7165..65b926724 100644 --- a/config/anchorPlatform.config.ts +++ b/config/anchorPlatform.config.ts @@ -1,5 +1,7 @@ import type { PluginConfig } from '@docusaurus/types'; import versions from '../ap_versions.json' +import { makeEditUrl } from './constants'; + import type * as Plugin from '@docusaurus/types/src/plugin'; import type * as OpenApiPlugin from 'docusaurus-plugin-openapi-docs'; import type { APIVersionOptions } from 'docusaurus-plugin-openapi-docs/src/types'; @@ -54,7 +56,7 @@ export const anchorPlatformPluginInstances: PluginConfig[] = [ routeBasePath: "/platforms/anchor-platform", docItemComponent: "@theme/ApiItem", sidebarPath: "config/anchorPlatform.sidebar.ts", - editUrl: "https://github.com/stellar/stellar-docs/tree/main", + editUrl: makeEditUrl, exclude: ['**/component/**', '**/README.md'], showLastUpdateTime: true, showLastUpdateAuthor: true, diff --git a/config/constants.ts b/config/constants.ts new file mode 100644 index 000000000..abe262522 --- /dev/null +++ b/config/constants.ts @@ -0,0 +1,11 @@ +export const DEFAULT_LOCALE: string = 'en'; +export const LOCALE_FULL_CODE: Record = { + es: 'es-ES', +}; + +export const makeEditUrl = ({ locale, versionDocsDirPath, docPath }) => { + if (locale !== DEFAULT_LOCALE) { + return `https://crowdin.com/project/stellar-dev-docs/${LOCALE_FULL_CODE[locale]}` + } + return `https://github.com/stellar/stellar-docs/edit/main/${versionDocsDirPath}/${docPath}` +}; diff --git a/config/disbursementPlatform.config.ts b/config/disbursementPlatform.config.ts index 328aff5c5..6e729bc0d 100644 --- a/config/disbursementPlatform.config.ts +++ b/config/disbursementPlatform.config.ts @@ -1,3 +1,5 @@ +import { makeEditUrl } from './constants'; + import type { PluginConfig } from '@docusaurus/types'; import type * as Plugin from '@docusaurus/types/src/plugin'; import type * as OpenApiPlugin from 'docusaurus-plugin-openapi-docs'; @@ -29,7 +31,7 @@ export const disbursementPlatformPluginInstances: PluginConfig[] = [ routeBasePath: "/platforms/stellar-disbursement-platform", docItemComponent: "@theme/ApiItem", sidebarPath: "config/disbursementPlatform.sidebar.ts", - editUrl: "https://github.com/stellar/stellar-docs/tree/main", + editUrl: makeEditUrl, exclude: ['**/component/**', '**/README.md'], showLastUpdateTime: true, showLastUpdateAuthor: true, diff --git a/docusaurus.config.ts b/docusaurus.config.ts index c247efafb..0df766fca 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -2,6 +2,7 @@ import remarkMath from 'remark-math'; import rehypeKatex from 'rehype-katex'; import { themes as prismThemes } from 'prism-react-renderer'; +import { makeEditUrl, DEFAULT_LOCALE } from './config/constants'; import { anchorPlatformPluginInstances } from './config/anchorPlatform.config'; import { disbursementPlatformPluginInstances } from './config/disbursementPlatform.config'; @@ -23,7 +24,7 @@ const config: Config = { organizationName: "stellar", projectName: "stellar-docs", i18n: { - defaultLocale: "en", + defaultLocale: DEFAULT_LOCALE, locales: ["en", "es"], }, plugins: [ @@ -87,7 +88,7 @@ const config: Config = { rehypePlugins: [rehypeKatex], sidebarPath: "config/sidebars.ts", sidebarItemsGenerator: require("./src/sidebar-generator"), - editUrl: "https://github.com/stellar/stellar-docs/tree/main", + editUrl: makeEditUrl, exclude: ['**/component/**', '**/README.md'], }, theme: { From 3be34e1dcba068a65ac0868cf47e56ea79f71fcb Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 28 Aug 2024 13:27:31 -0500 Subject: [PATCH 17/60] update build and test workflow actions versions --- .github/workflows/copy-workflow.yml | 4 ++-- .github/workflows/download-workflow.yml | 6 +++--- .github/workflows/main.yml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/copy-workflow.yml b/.github/workflows/copy-workflow.yml index c4c1b067c..3c9e7a066 100644 --- a/.github/workflows/copy-workflow.yml +++ b/.github/workflows/copy-workflow.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout main branch - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: main @@ -27,7 +27,7 @@ jobs: git merge origin/main - name: Set up Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '20' diff --git a/.github/workflows/download-workflow.yml b/.github/workflows/download-workflow.yml index c7419880c..efd3b9258 100644 --- a/.github/workflows/download-workflow.yml +++ b/.github/workflows/download-workflow.yml @@ -5,7 +5,7 @@ on: ### Schedule currently disabled ### # schedule: # - cron: '0 9 * * *' - # - cron: '0 13 * * *' + # - cron: '0 13 * * *' # - cron: '0 17 * * *' permissions: @@ -33,5 +33,5 @@ jobs: pull_request_base_branch_name: 'main' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} - CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} \ No newline at end of file + CROWDIN_PROJECT_ID: '669532' + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index db39a7749..cb0143dad 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,10 +13,10 @@ jobs: steps: - name: Checkout App Repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '20' cache: 'yarn' From fdefef71db0e54e27776845056c584830ec3857e Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 28 Aug 2024 13:31:57 -0500 Subject: [PATCH 18/60] update docker and makefile config to pass token more securely --- Dockerfile | 4 ++-- Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7de680ae4..c80ca7ee8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,6 @@ RUN apt-get update && apt-get install --no-install-recommends -y gpg curl git ma apt-get update && apt-get install -y nodejs yarn && apt-get clean COPY . /app/ -ARG CROWDIN_PERSONAL_TOKEN RUN yarn install RUN yarn rpcspec:build @@ -23,7 +22,8 @@ RUN yarn stellar-cli:build # TODO: This takes a bit of time, we should probably make sure it's only done # for production builds # See: https://docusaurus.io/docs/3.4.0/i18n/crowdin#automate-with-ci -RUN CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn crowdin download +RUN --mount=type=secret,id=CROWDIN_PERSONAL_TOKEN \ + CROWDIN_PERSONAL_TOKEN=$(cat /run/secrets/CROWDIN_PERSONAL_TOKEN) yarn crowdin download --no-progress RUN yarn crowdin:fix # TODO: It's actually this part that is more time-consuming. The best way to # speed this up is to generate the preview for only `--locale en` diff --git a/Makefile b/Makefile index d0f21ebab..e4a76c644 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ TAG ?= stellar/stellar-docs:$(LABEL) BUILD_DATE := $(shell date -u +%FT%TZ) docker-build: - $(SUDO) docker build --no-cache --pull --label org.opencontainers.image.created="$(BUILD_DATE)" -t $(TAG) . --build-arg CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} + $(SUDO) docker build --secret id=CROWDIN_PERSONAL_TOKEN --no-cache --pull --label org.opencontainers.image.created="$(BUILD_DATE)" -t $(TAG) . docker-push: $(SUDO) docker push $(TAG) From 5881a48b5083d7af0974946cbcd8c8d41de67412 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Thu, 29 Aug 2024 12:30:44 -0500 Subject: [PATCH 19/60] Revert "update docker and makefile config to pass token more securely" This reverts commit fdefef71db0e54e27776845056c584830ec3857e. --- Dockerfile | 4 ++-- Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index c80ca7ee8..7de680ae4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y gpg curl git ma apt-get update && apt-get install -y nodejs yarn && apt-get clean COPY . /app/ +ARG CROWDIN_PERSONAL_TOKEN RUN yarn install RUN yarn rpcspec:build @@ -22,8 +23,7 @@ RUN yarn stellar-cli:build # TODO: This takes a bit of time, we should probably make sure it's only done # for production builds # See: https://docusaurus.io/docs/3.4.0/i18n/crowdin#automate-with-ci -RUN --mount=type=secret,id=CROWDIN_PERSONAL_TOKEN \ - CROWDIN_PERSONAL_TOKEN=$(cat /run/secrets/CROWDIN_PERSONAL_TOKEN) yarn crowdin download --no-progress +RUN CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn crowdin download RUN yarn crowdin:fix # TODO: It's actually this part that is more time-consuming. The best way to # speed this up is to generate the preview for only `--locale en` diff --git a/Makefile b/Makefile index e4a76c644..d0f21ebab 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ TAG ?= stellar/stellar-docs:$(LABEL) BUILD_DATE := $(shell date -u +%FT%TZ) docker-build: - $(SUDO) docker build --secret id=CROWDIN_PERSONAL_TOKEN --no-cache --pull --label org.opencontainers.image.created="$(BUILD_DATE)" -t $(TAG) . + $(SUDO) docker build --no-cache --pull --label org.opencontainers.image.created="$(BUILD_DATE)" -t $(TAG) . --build-arg CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} docker-push: $(SUDO) docker push $(TAG) From 501243e706b09980646c654d28326ad156fe6a69 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 8 Oct 2024 19:41:31 -0500 Subject: [PATCH 20/60] explicitly specify broken anchors behavior --- docusaurus.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 0df766fca..75c191ac0 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -18,6 +18,7 @@ const config: Config = { trailingSlash: false, onBrokenLinks: "log", onBrokenMarkdownLinks: "log", + onBrokenAnchors: "warn", // onBrokenLinks: "throw", // onBrokenMarkdownLinks: "throw", favicon: "img/favicon-96x96.png", From a99cf18384e315201a03c3870fe82d7de11b7bec Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 8 Oct 2024 21:00:00 -0500 Subject: [PATCH 21/60] sync both ways in Dockerfile build --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5e4eaedb0..953768226 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ RUN yarn stellar-cli:build # TODO: This takes a bit of time, we should probably make sure it's only done # for production builds # See: https://docusaurus.io/docs/3.4.0/i18n/crowdin#automate-with-ci -RUN CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn crowdin download +RUN CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn crowdin:sync RUN yarn crowdin:fix # TODO: It's actually this part that is more time-consuming. The best way to # speed this up is to generate the preview for only `--locale en` From 630acccb2de6a461487e14f76b71067852cbfb06 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 8 Oct 2024 21:33:36 -0500 Subject: [PATCH 22/60] put some problematic hubble data field notes into code tags --- docs/data/hubble/data-catalog/data-dictionary/accounts.mdx | 2 +- .../hubble/data-catalog/data-dictionary/claimable-balances.mdx | 2 +- docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx | 2 +- docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx | 2 +- .../data-dictionary/enriched-history-operations.mdx | 2 +- .../data/hubble/data-catalog/data-dictionary/history-assets.mdx | 2 +- .../hubble/data-catalog/data-dictionary/history-effects.mdx | 2 +- .../hubble/data-catalog/data-dictionary/history-ledgers.mdx | 2 +- .../hubble/data-catalog/data-dictionary/history-operations.mdx | 2 +- .../data/hubble/data-catalog/data-dictionary/history-trades.mdx | 2 +- .../data-catalog/data-dictionary/history-transactions.mdx | 2 +- .../hubble/data-catalog/data-dictionary/liquidity-pools.mdx | 2 +- docs/data/hubble/data-catalog/data-dictionary/offers.mdx | 2 +- docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx | 2 +- docs/data/hubble/data-catalog/data-dictionary/ttl.mdx | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx b/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx index 44763a700..6b60ee70b 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx @@ -21,7 +21,7 @@ sidebar_position: 10 | last_modified_ledger | The ledger sequence number when the ledger entry (this unique signer for the account) was modified. Deletions do not count as a modification and will report the prior modification sequence number | integer | | | Yes | cluster | Yes | If an account updates a signer's weight at sequence 1234 and then decides to delete the signer at 2345, the deleted record will still have a modified sequence of 1234. | | ledger_entry_change | Code that describes the ledger entry change type that was applied to the ledger entry. | integer | 0 - Ledger Entry Created 1 - Ledger Entry Updated 2 - Ledger Entry Deleted 3 - Ledger Entry State (value of the entry) | | Yes | | Yes | Valid entry change types are 0, 1, and 2 for ledger entries of type \`accounts\` | | deleted | Indicates whether the ledger entry (account id) has been deleted or not. Once an entry is deleted, it cannot be recovered. | boolean | | | | | Yes | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | MONTH partition | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | sponsor | The account address of the sponsor who is paying the reserves for this account. | string | | | | | No | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx b/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx index 034a1dc2f..fe7757c0a 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx @@ -22,7 +22,7 @@ sidebar_position: 20 | last_modified_ledger | The ledger sequence number when the ledger entry (this unique signer for the account) was modified. Deletions do not count as a modification and will report the prior modification sequence number | integer | | | Yes | cluster | Yes | | | ledger_entry_change | Code that describes the ledger entry change type that was applied to the ledger entry. | integer | 0 - Ledger Entry Created 1 - Ledger Entry Updated 2 - Ledger Entry Deleted 3 - Ledger Entry State (value of the entry) | | Yes | | Yes | Valid entry change types are 0, and 2 for ledger entries of type \`claimable_balances\`. Once created, a balance cannot be updated. | | deleted | Indicates whether the ledger entry (balance id) has been deleted or not. Once an entry is deleted, it cannot be recovered. | boolean | | | | | Yes | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | MONTH partition | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | asset_id | Unique identifier for asset_code, asset_issuer | integer | | | | cluster | No | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx b/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx index 612954143..5f8a01fd5 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx @@ -10,7 +10,7 @@ sidebar_position: 30 | last_modified_ledger | The ledger sequence number when the ledger entry (this unique signer for the account) was modified. Deletions do not count as a modification and will report the prior modification sequence number | integer | | | | Cluster | Yes | | | ledger_entry_change | Code that describes the ledger entry change type that was applied to the ledger entry. | integer | | | | | Yes | | | deleted | Indicates whether the ledger entry (balance id) has been deleted or not. Once an entry is deleted, it cannot be recovered. | boolean | | | | | Yes | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | | Yes | | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | closed_at | The UNIX timestamp of the sequence number's age | timestamp | | | | Partition | Yes | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx b/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx index b9377c1ed..115c4aa3d 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx @@ -16,7 +16,7 @@ sidebar_position: 40 | last_modified_ledger | The ledger sequence number when the ledger entry (this unique signer for the account) was modified. Deletions do not count as a modification and will report the prior modification sequence number | integer | | | Yes | Cluster | Yes | | | ledger_entry_change | Code that describes the ledger entry change type that was applied to the ledger entry. | integer | | | | | Yes | | | deleted | Indicates whether the ledger entry (balance id) has been deleted or not. Once an entry is deleted, it cannot be recovered. | boolean | | | | | Yes | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | | Yes | | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | closed_at | The UNIX timestamp of the sequence number's age | timestamp | | | | Partition | Yes | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx b/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx index 0a3d2e410..4466e9e42 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx @@ -116,7 +116,7 @@ sidebar_position: 150 | protocol_version | The protocol verstion that the Stellar network was running when this ledger was committed. Protocol versions are released ~every 6 months | integer | integers 1 - 19 (will increment) | | | | | history_ledgers | | | successful_transaction_count | The number of successful transactions submitted and completed by the network in this ledger | integer | | | | | | history_ledgers | | | failed_transaction_count | The number of failed transactions submitted to the network in this ledger. The transaction was still paid for but contained an error that prevented it from executing | integer | | | | | | history_ledgers | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | | history_operations | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | | history_operations | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | | | history_operations | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | | current timestamp | | | ledger_bounds | A transaction precondition that can be set to determine valid conditions for a transaction to be submitted to the network. Ledger bounds allow the user to specify a minimum and maxiumum ledger sequence number in which the transaction can successfully execute | string | | | | | | history_transactions | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx index 249c6f0f4..a9bd4cc17 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx @@ -9,7 +9,7 @@ sidebar_position: 90 | asset_type | The identifier for type of asset code, can be a alphanumeric with 4 characters, 12 characters or the native asset to the network, XLM. | string | credit_alphanum4 credit_alphanum12 native | | Yes | cluster | Yes | XLM is the native asset to the network. XLM has no asset code or issuer representation and will instead be displayed with an asset type of 'native' | | asset_code | The 4 or 12 character code representation of the asset on the network | string | | | Yes | cluster | No | Asset codes have no guarantees of uniqueness. The combination of asset code, issuer and type represents a distinct asset | | asset_issuer | The account address of the original asset issuer that created the asset | string | | | Yes | cluster | No | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | Yes | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | Yes | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | MONTH partition | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | asset_id | Unique identifier for asset_code, asset_issuer | integer | | | | | No | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx index 958dcff03..6704d9f18 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx @@ -155,6 +155,6 @@ sidebar_position: 100 | details.predicate.rel_before | A relative deadline for when the claimable balance can be claimed. The value represents the number of seconds since the close time of the ledger which created the claimable balance \#### Notes: This condition is useful when creating a timebounds based on creation conditions. If the creator wanted a balance only claimable one week after creation, this condition would satisfy that rule. | integer | | | | | | | | details.predicate.unconditional | If true it means this clause of the condition is always satisfied. \#### Notes: When the predicate is only unconditional = true, it means that the balance can be claimed under any conditions | boolean | | | | | | | | details.predicate.abs_before_epoch | A UNIX epoch value in seconds representing the same deadline date as abs_before. | integer | | | | | | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | MONTH partition | | | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx index 83254bd7c..b79e5dfe5 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx @@ -22,7 +22,7 @@ sidebar_position: 110 | successful_transaction_count | The number of successful transactions submitted and completed by the network in this ledger | integer | | | | | No | | | failed_transaction_count | The number of failed transactions submitted to the network in this ledger. The transaction was still paid for but contained an error that prevented it from executing | integer | | | | | No | | | tx_set_operation_count | The total number of operations in the transaction set for this ledger, including failed transactions. | integer | | | | | No | Transactions on Stellar are atomic. If one of the operations within a transaction set fails, the entire transaction will failed, including any other operations. | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | soroban_fee_write_1kb | Soroban write fee costs | integer | | | | | | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx index f7f5f232d..26850e4d8 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx @@ -129,7 +129,7 @@ sidebar_position: 120 | details.extend_to | The number of ledgers in which the Soroban ledger entry is extended | integer | | 25 - Extend Footprint Ttl | | | | No | | | details.contract_id | The unique identifier of the deployed contract instance. Each custom Soroban contract and deployed SAC token will have a unique contract_id. | string | | 24 - Invoke Host Function 25 - Extend Footprint Ttl 26 - Restore Footprint | | | | No | | | details.contract_code_hash | The hex-encoded SHA-256 hash that represents the contract code's XDR-encoded form | string | | 24 - Invoke Host Function 25 - Extend Footprint Ttl 26 - Restore Footprint | | | | No | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | | MONTH partition | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | | Yes | | | closed_at | Timestamp in UTC when this ledger closed and committed to the network. Ledgers are expected to close ~every 5 seconds | timestamp | | | | | | Yes | We are aiming to repartition this table on closed_at | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx index 282e7c0fe..6bdf47022 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx @@ -22,7 +22,7 @@ sidebar_position: 130 | price_d | The price ratio of the sold asset: bought asset. When taken with price_n, the price can be calculated by price_n/price_d | integer | | | | | No | | | selling_offer_id | The offer ID in the orderbook of the selling offer. If this offer was immediately and fully consumed, this will be a synthetic ID. | integer | | | | | No | | | buying_offer_id | The offer ID in the orderbook of the buying offer. If this offer was immediately and fully consumed, this will be a synthetic ID. | integer | | | | | No | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | No | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | No | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | | No | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | No | | | selling_liquidity_pool_id | The unique identifier for a liquidity pool if the trade was executed against a liquidity pool instead of the orderbook | string | | | | | No | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx index bb9e983f0..3933c7f20 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx @@ -33,7 +33,7 @@ sidebar_position: 140 | tx_result | base-64 encoded XDR blob | string | | | | | No | | | tx_meta | base-64 encoded XDR blob | string | | | | | No | | | tx_fee_meta | base-64 encoded XDR blob | string | | | | | No | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | MONTH partition | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | resource_fee | The fee charged less the inclusion fee for the Soroban transaction. This is calculated by the read/write operations and how process intensive the Soroban transaction is | integer | | | | | No | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx b/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx index 3225c9ec7..377e7a43f 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx @@ -21,7 +21,7 @@ sidebar_position: 50 | last_modified_ledger | The ledger sequence number when the ledger entry (this unique signer for the account) was modified. Deletions do not count as a modification and will report the prior modification sequence number | integer | | | Yes | cluster | Yes | | | ledger_entry_change | Code that describes the ledger entry change type that was applied to the ledger entry. | integer | 0 - Ledger Entry Created 1 - Ledger Entry Updated 2 - Ledger Entry Deleted 3 - Ledger Entry State (value of the entry) | | Yes | | Yes | Valid entry change types are 0, 1, and 2 for ledger entries of type \`liquidity_pools\`. | | deleted | Indicates whether the ledger entry (liquidity pool) has been deleted or not. Once an entry is deleted, it cannot be recovered. Liquidity pools are deleted once all pool shares are withdrawn from the pool | boolean | | | | | Yes | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | MONTH partition | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | asset_a_id | Unique identifier for asset_a_code, asset_a_issuer | integer | | | | cluster | No | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/offers.mdx b/docs/data/hubble/data-catalog/data-dictionary/offers.mdx index fa93fdc48..ac66b63fa 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/offers.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/offers.mdx @@ -22,7 +22,7 @@ sidebar_position: 60 | ledger_entry_change | Code that describes the ledger entry change type that was applied to the ledger entry. | integer | 0 - Ledger Entry Created 1 - Ledger Entry Updated 2 - Ledger Entry Deleted 3 - Ledger Entry State (value of the entry) | | Yes | | Yes | Valid entry change types are 0, 1, and 2 for ledger entries of type \`offers\`. | | deleted | Indicates whether the ledger entry (offer id) has been deleted or not. Once an entry is deleted, it cannot be recovered. | boolean | | | | | Yes | | | sponsor | The account address that is sponsoring the base reserves for the offer. | string | | | | | No | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | MONTH partition | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | selling_asset_id | Unique identifier for selling_asset_code, selling_asset_issuer | integer | | | | cluster | No | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx b/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx index ed250dce7..6462b1b21 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx @@ -19,7 +19,7 @@ sidebar_position: 70 | last_modified_ledger | The ledger sequence number when the ledger entry (this unique signer for the account) was modified. Deletions do not count as a modification and will report the prior modification sequence number | integer | | | Yes | cluster | Yes | | | ledger_entry_change | Code that describes the ledger entry change type that was applied to the ledger entry. | integer | 0 - Ledger Entry Created 1 - Ledger Entry Updated 2 - Ledger Entry Deleted 3 - Ledger Entry State (value of the entry) | | Yes | | Yes | Valid entry change types are 0, 1, and 2 for ledger entries of type \`trust_lines\`. | | deleted | Indicates whether the ledger entry (trust line) has been deleted or not. Once an entry is deleted, it cannot be recovered. | boolean | | | | | Yes | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | MONTH partition | Yes | The table is partitioned on batch_run_date. It is recommended to always include the batch_run_date in the filter if possible to help reduce query cost. | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | sponsor | The account address that is sponsoring the base reserves for the trust line. | string | | | | | No | | diff --git a/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx b/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx index 09efd6823..f7ac00ffd 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx @@ -10,7 +10,7 @@ sidebar_position: 80 | last_modified_ledger | The ledger sequence number when the ledger entry (this unique signer for the account) was modified. Deletions do not count as a modification and will report the prior modification sequence number | integer | | | Yes | Cluster | Yes | | | ledger_entry_change | Code that describes the ledger entry change type that was applied to the ledger entry. | integer | | | | | Yes | | | deleted | Indicates whether the ledger entry (balance id) has been deleted or not. Once an entry is deleted, it cannot be recovered. | boolean | | | | | Yes | | -| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of "scheduled\_\_\-\". Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | +| batch_id | String representation of the run id for a given DAG in Airflow. Takes the form of `scheduled__-`. Batch ids are unique to the batch and help with monitoring and rerun capabilities | string | | | | | Yes | | | batch_run_date | The start date for the batch interval. When taken with the date in the batch_id, the date represents the interval of ledgers processed. The batch run date can be seen as a proxy of closed_at for a ledger. | datetime | | | | | Yes | | | batch_insert_ts | The timestamp in UTC when a batch of records was inserted into the database. This field can help identify if a batch executed in real time or as part of a backfill | timestamp | | | | | Yes | | | closed_at | The UNIX timestamp of the sequence number's age | timestamp | | | Yes | Parition | Yes | | From 082d1b5770b5c96463d099c654f2011a4c216657 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 8 Oct 2024 22:22:09 -0500 Subject: [PATCH 23/60] include meeting notes pages in mdx formatting --- meeting-notes/2024-01-18.mdx | 4 +-- meeting-notes/2024-01-26.mdx | 2 +- meeting-notes/2024-02-01.mdx | 4 +-- meeting-notes/2024-02-09.mdx | 4 +-- meeting-notes/2024-02-15.mdx | 50 ++++++++++++++++++------------------ meeting-notes/2024-02-22.mdx | 2 +- meeting-notes/2024-02-29.mdx | 8 +++--- meeting-notes/2024-03-07.mdx | 2 +- meeting-notes/2024-03-14.mdx | 18 ++++++------- meeting-notes/2024-03-21.mdx | 2 +- meeting-notes/2024-03-28.mdx | 4 +-- meeting-notes/2024-04-04.mdx | 19 +++++++------- meeting-notes/2024-04-11.mdx | 2 +- meeting-notes/2024-04-18.mdx | 7 +++-- meeting-notes/2024-04-25.mdx | 12 +++++---- meeting-notes/2024-05-02.mdx | 12 ++++----- meeting-notes/2024-05-09.mdx | 2 +- meeting-notes/2024-06-13.mdx | 12 ++++----- meeting-notes/2024-06-20.mdx | 2 +- meeting-notes/2024-06-27.mdx | 10 ++++---- meeting-notes/2024-07-11.mdx | 5 ++-- meeting-notes/2024-07-18.mdx | 17 ++++-------- meeting-notes/2024-07-25.mdx | 15 ++++------- meeting-notes/2024-08-01.mdx | 3 +-- meeting-notes/2024-08-08.mdx | 6 +---- meeting-notes/2024-08-15.mdx | 14 +++++----- meeting-notes/2024-08-22.mdx | 30 ++++++++++++---------- meeting-notes/2024-08-29.mdx | 25 ++++++++++-------- meeting-notes/2024-09-05.mdx | 29 ++++++++++++--------- meeting-notes/2024-09-12.mdx | 25 ++++++++++-------- meeting-notes/2024-09-19.mdx | 13 +++++++--- meeting-notes/2024-09-26.mdx | 14 ++++++---- package.json | 4 +-- 33 files changed, 192 insertions(+), 186 deletions(-) diff --git a/meeting-notes/2024-01-18.mdx b/meeting-notes/2024-01-18.mdx index 0e5d48509..0b6c16e6f 100644 --- a/meeting-notes/2024-01-18.mdx +++ b/meeting-notes/2024-01-18.mdx @@ -1,5 +1,5 @@ --- -title: '2024-01-18' +title: "2024-01-18" authors: naman tags: [protocol] --- @@ -29,4 +29,4 @@ tags: [protocol] 1. What are the best practices for managing transactions in the frontend, with respect to transaction ordering. 1. Core devs confirmed that ordering is intentionally arbitrary. 1. Request for an API for current version of the environment/sdk -1. Github issue filed for the RPC to return versions of the current node. \ No newline at end of file +1. Github issue filed for the RPC to return versions of the current node. diff --git a/meeting-notes/2024-01-26.mdx b/meeting-notes/2024-01-26.mdx index 8eba6d26b..b019ef246 100644 --- a/meeting-notes/2024-01-26.mdx +++ b/meeting-notes/2024-01-26.mdx @@ -1,5 +1,5 @@ --- -title: '2024-01-26' +title: "2024-01-26" authors: kalepail tags: [developer] --- diff --git a/meeting-notes/2024-02-01.mdx b/meeting-notes/2024-02-01.mdx index 6378cb821..f581603ba 100644 --- a/meeting-notes/2024-02-01.mdx +++ b/meeting-notes/2024-02-01.mdx @@ -1,5 +1,5 @@ --- -title: '2024-02-01' +title: "2024-02-01" authors: naman tags: [protocol] --- @@ -24,4 +24,4 @@ tags: [protocol] 1. It is also costly to bundle decoding with verification in guest. 1. Soroban has always led with a batteries included mindset. Keeping in line with that approach, it makes sense to further investigate and determine whether a host function makes sense for these as well. 1. Leigh’s implementation may require further evaluation of the crates used for ecdsa and p256. -1. Brief discussion around proposed process for adding of a host function by a non-core dev. \ No newline at end of file +1. Brief discussion around proposed process for adding of a host function by a non-core dev. diff --git a/meeting-notes/2024-02-09.mdx b/meeting-notes/2024-02-09.mdx index 3042ee8b7..e26bb9038 100644 --- a/meeting-notes/2024-02-09.mdx +++ b/meeting-notes/2024-02-09.mdx @@ -1,5 +1,5 @@ --- -title: '2024-02-09' +title: "2024-02-09" authors: kalepail tags: [developer] --- @@ -17,4 +17,4 @@ tags: [developer] 1. [SEP draft](https://github.com/orbitlens/stellar-protocol/blob/sep-0042-token-lists/ecosystem/sep-0042.md) 2. [Discord discussion](https://discord.com/channels/897514728459468821/1162558946867953704) 2. Stellar + Soroban documentation survey - 1. [Take the survey](https://discord.com/channels/897514728459468821/1204462856037470248/1205196745877757962) \ No newline at end of file + 1. [Take the survey](https://discord.com/channels/897514728459468821/1204462856037470248/1205196745877757962) diff --git a/meeting-notes/2024-02-15.mdx b/meeting-notes/2024-02-15.mdx index 71c74b1c9..89ecc5dbb 100644 --- a/meeting-notes/2024-02-15.mdx +++ b/meeting-notes/2024-02-15.mdx @@ -1,5 +1,5 @@ --- -title: '2024-02-15' +title: "2024-02-15" authors: naman tags: [protocol] --- @@ -15,29 +15,29 @@ tags: [protocol] 1. The meeting was focused on the process of adding host functions, using WebAuthN as the example use case; continued from the previous meeting. 2. Discussion of remaining concerns with adding secp256r1 verification host function from previous meeting. - - What does it mean for secp256r1 to be added as a host function vs. as a signer type? - - As a host function, user can sign soroban auth entries. Need another stellar account to fund and submit tx to the chain. The latter can be done by a stellar account which may be operated by a wallet or a contract. - - __check_auth is invoked when the contract being interacted with calls require_auth + - What does it mean for secp256r1 to be added as a host function vs. as a signer type? + - As a host function, user can sign soroban auth entries. Need another stellar account to fund and submit tx to the chain. The latter can be done by a stellar account which may be operated by a wallet or a contract. + - \_\_check_auth is invoked when the contract being interacted with calls require_auth 3. CAP-52 was drafted to introduce encoding/decoding functions for Base64, which is needed by WebAuthN. Considerations discussed in the meeting: - - Performance: 1066 bytes that costs 1M instr to encode a 32byte hash; so the cost is very small and it’s questionable whether a host function is required. - - Interface required two functions (encode/decode) - - Implementation wise, WebAuthN requires url alphabet and padding, which decoder likely needs to support. Should we use symbols or ints? Do we need custom alphabets? - - Do we really need more encoding schemes? Isn’t XDR enough? - - Expensive auth mechanisms, i.e. webauthn, cannot be coupled with contracts with heavy business logic (which might be a lot of contracts), thus making adoption problematic. - - We should probably add building blocks to enable the ecosystem to add new use cases. -4. CAP-53 was drafted to introduce encoding/decoding functions for JSON, which is needed by WebAuthN. Considerations discussed in the meeting: - - Performance: 3.9Kb, 2.5M CPU instr. - - If the size of the input blob is unknown, execution time will increase. - - Valuable to have such a lightweight function that’ll be used in various place. - - Interface: 11 functions - - What to do with numbers and decimals? Add decimals and floats? - - We only have to extract one field for WebAuthN but what about the general case? - - The number type in JSON is decimal but soroban does not support that. How should this be handled? - - Discussion around alternative interface and implementations. + - Performance: 1066 bytes that costs 1M instr to encode a 32byte hash; so the cost is very small and it’s questionable whether a host function is required. + - Interface required two functions (encode/decode) + - Implementation wise, WebAuthN requires url alphabet and padding, which decoder likely needs to support. Should we use symbols or ints? Do we need custom alphabets? + - Do we really need more encoding schemes? Isn’t XDR enough? + - Expensive auth mechanisms, i.e. webauthn, cannot be coupled with contracts with heavy business logic (which might be a lot of contracts), thus making adoption problematic. + - We should probably add building blocks to enable the ecosystem to add new use cases. +4. CAP-53 was drafted to introduce encoding/decoding functions for JSON, which is needed by WebAuthN. Considerations discussed in the meeting: + - Performance: 3.9Kb, 2.5M CPU instr. + - If the size of the input blob is unknown, execution time will increase. + - Valuable to have such a lightweight function that’ll be used in various place. + - Interface: 11 functions + - What to do with numbers and decimals? Add decimals and floats? + - We only have to extract one field for WebAuthN but what about the general case? + - The number type in JSON is decimal but soroban does not support that. How should this be handled? + - Discussion around alternative interface and implementations. 5. Core dev concerns - - Maintainability: if you add a host function, you have to maintain it forever. If there are more versions, we have to keep it around. - - Expanded surface area for security bugs. - - Should define a path where core dev is not in the implementation loop, as their schedules are packed with stability work. How to prioritize against stability work, which may get derailed due to new functionality such as what’s being currently discussed. - - Next steps: - - Core team to put together a plan for adding Base64. This is an important exercise that helps determine even more challenges of doing so. The output of this exercise may be that base64 _shouldn’t_ in fact be implemented at this point. - - Discussion around the JSON interface is to be continued. + - Maintainability: if you add a host function, you have to maintain it forever. If there are more versions, we have to keep it around. + - Expanded surface area for security bugs. + - Should define a path where core dev is not in the implementation loop, as their schedules are packed with stability work. How to prioritize against stability work, which may get derailed due to new functionality such as what’s being currently discussed. + - Next steps: + - Core team to put together a plan for adding Base64. This is an important exercise that helps determine even more challenges of doing so. The output of this exercise may be that base64 _shouldn’t_ in fact be implemented at this point. + - Discussion around the JSON interface is to be continued. diff --git a/meeting-notes/2024-02-22.mdx b/meeting-notes/2024-02-22.mdx index e12a1363c..b91c1351c 100644 --- a/meeting-notes/2024-02-22.mdx +++ b/meeting-notes/2024-02-22.mdx @@ -1,5 +1,5 @@ --- -title: '2024-02-22' +title: "2024-02-22" authors: kalepail tags: [developer] --- diff --git a/meeting-notes/2024-02-29.mdx b/meeting-notes/2024-02-29.mdx index 2ec1f2661..3e28aed28 100644 --- a/meeting-notes/2024-02-29.mdx +++ b/meeting-notes/2024-02-29.mdx @@ -1,5 +1,5 @@ --- -title: '2024-02-29' +title: "2024-02-29" authors: naman tags: [protocol] --- @@ -13,9 +13,7 @@ tags: [protocol] [Discord agenda thread](https://discord.com/channels/897514728459468821/1212118102565855243) -1. Tommaso (@tdep) proposed a core change to allow for extending instance and code TTL with separate values on the host environment to allow for more cost-efficient designs - a. Proposal and discussion are captured in github discussions [stellar-core#1447](https://github.com/stellar/stellar-protocol/discussions/1447) -2. Tommaso receieved feedback on the proposal as well as implementation. Since it didn't require a metering change, core devs thought it to be a quick change. +1. Tommaso (@tdep) proposed a core change to allow for extending instance and code TTL with separate values on the host environment to allow for more cost-efficient designs a. Proposal and discussion are captured in github discussions [stellar-core#1447](https://github.com/stellar/stellar-protocol/discussions/1447) +2. Tommaso receieved feedback on the proposal as well as implementation. Since it didn't require a metering change, core devs thought it to be a quick change. 3. The ecosystem voted in favor of the proposal by upvoting the post on Github Discussions. 13 votes were [recorded](https://github.com/stellar/stellar-protocol/discussions/). 4. As next steps, a CAP will be authored to capture the proposal and put forth for approval from CAP Core Team. - diff --git a/meeting-notes/2024-03-07.mdx b/meeting-notes/2024-03-07.mdx index 4cd82f1ce..693e1fcdf 100644 --- a/meeting-notes/2024-03-07.mdx +++ b/meeting-notes/2024-03-07.mdx @@ -1,5 +1,5 @@ --- -title: '2024-03-07' +title: "2024-03-07" authors: kalepail tags: [developer] --- diff --git a/meeting-notes/2024-03-14.mdx b/meeting-notes/2024-03-14.mdx index 0bb955aed..d5894a841 100644 --- a/meeting-notes/2024-03-14.mdx +++ b/meeting-notes/2024-03-14.mdx @@ -1,5 +1,5 @@ --- -title: '2024-03-14' +title: "2024-03-14" authors: naman tags: [protocol] --- @@ -13,13 +13,11 @@ tags: [protocol] [Discord agenda thread](https://discord.com/channels/897514728459468821/1217193723612368926) -1. CAP Core Team deliberated over the latest proposals put forth by the Stellar ecosystem to advance stellar-core. -2. Nicholas and David from the CAP Core Team listened to the following proposals and discussed the proposals with the authors. - a. CAP Core team will deliver their vote over email. +1. CAP Core Team deliberated over the latest proposals put forth by the Stellar ecosystem to advance stellar-core. +2. Nicholas and David from the CAP Core Team listened to the following proposals and discussed the proposals with the authors. a. CAP Core team will deliver their vote over email. 3. Proposals discussed: - a. [CAP-51](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0051.md): add support for secp256r1 verification; by @leigh - b. [CAP-53](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0053.md): create separate functions for extending the time-to-live for contract instance and contract code; by @tdep - c. [CAP-54](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0054.md): lower total costs by refining the Soroban cost model used for VM instantiation into multiple separate and more-accurate costs; by @graydon - d. [CAP-55](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0055.md): lower total costs by linking fewer host functions during VM instantiation in Soroban; by @graydon - e. [CAP-56](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0056.md): lower total costs by caching parsed Wasm modules within a Soroban transaction; by @graydon - + a. [CAP-51](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0051.md): add support for secp256r1 verification; by @leigh + b. [CAP-53](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0053.md): create separate functions for extending the time-to-live for contract instance and contract code; by @tdep + c. [CAP-54](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0054.md): lower total costs by refining the Soroban cost model used for VM instantiation into multiple separate and more-accurate costs; by @graydon + d. [CAP-55](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0055.md): lower total costs by linking fewer host functions during VM instantiation in Soroban; by @graydon + e. [CAP-56](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0056.md): lower total costs by caching parsed Wasm modules within a Soroban transaction; by @graydon diff --git a/meeting-notes/2024-03-21.mdx b/meeting-notes/2024-03-21.mdx index 1a37e79d6..717ff5372 100644 --- a/meeting-notes/2024-03-21.mdx +++ b/meeting-notes/2024-03-21.mdx @@ -1,5 +1,5 @@ --- -title: '2024-03-21' +title: "2024-03-21" authors: kalepail tags: [developer] --- diff --git a/meeting-notes/2024-03-28.mdx b/meeting-notes/2024-03-28.mdx index 57054dec1..32dadf84e 100644 --- a/meeting-notes/2024-03-28.mdx +++ b/meeting-notes/2024-03-28.mdx @@ -1,5 +1,5 @@ --- -title: '2024-03-28' +title: "2024-03-28" authors: naman tags: [protocol] --- @@ -13,7 +13,7 @@ tags: [protocol] [Agenda thread](https://github.com/stellar/stellar-protocol/discussions/1475) -1. The Standards Working Group proposed changes to the SEP process that empower the ecosystem by making the current process more decentralized and ecosystem-friendly. +1. The Standards Working Group proposed changes to the SEP process that empower the ecosystem by making the current process more decentralized and ecosystem-friendly. 2. The process has already been used for several proposals over the last three months. 3. Esteblock from Soroswap shared their journey of participating in the proposal for Asset List ([SEP-42](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0042.md)) and implementing the proposed standard 4. Discussion continues in the proposal doc. diff --git a/meeting-notes/2024-04-04.mdx b/meeting-notes/2024-04-04.mdx index 3292f6121..d9310c7d7 100644 --- a/meeting-notes/2024-04-04.mdx +++ b/meeting-notes/2024-04-04.mdx @@ -1,21 +1,22 @@ --- -title: '2024-04-04' +title: "2024-04-04" authors: naman tags: [developer] --- -Today's recording has two parts. The first 12 minutes are audio-only. The next 45 minutes have video as well. -Please note the slides were shared in discord chat over screensharing, due to technical difficulties. +Today's recording has two parts. The first 12 minutes are audio-only. The next 45 minutes have video as well. Please note the slides were shared in discord chat over screensharing, due to technical difficulties. Part 1 (audio-only): + + frameborder="0" + width="500" + height="100" + src="https://drive.google.com/file/d/14ddYFIMDgsX70hTCv8C1tKaAGmJiprw7/preview" +> Part 2 (video): + -1. Garand discussed changes to the State Archival proposal based on feedback received at Meridian 2023. The proposed changes are: - - Previously, a downstream system called the ESS (Expired State Store) would store expired entries. In the new proposal, There is no ESS. All Archived entries, as well as all information required to generate restoration proofs for those entries, is stored directly in the History Archive. - - RPC nodes can generate proofs for archived state during preflight - - Captive-core can be directly queried for archived state, meaning that RPC/Horizon instances can potentially service queries for archival state +1. Garand discussed changes to the State Archival proposal based on feedback received at Meridian 2023. The proposed changes are: + +- Previously, a downstream system called the ESS (Expired State Store) would store expired entries. In the new proposal, There is no ESS. All Archived entries, as well as all information required to generate restoration proofs for those entries, is stored directly in the History Archive. +- RPC nodes can generate proofs for archived state during preflight +- Captive-core can be directly queried for archived state, meaning that RPC/Horizon instances can potentially service queries for archival state + 2. [The draft proposal](https://docs.google.com/document/d/1FAs3Yfo-o-gVqccrP29NSG8ysRvdEoyvuL7ywV4ijXI/edit#heading=h.1xwsoyifxbfm) 3. [Ongoing discussion](https://github.com/stellar/stellar-protocol/discussions/1480) 4. Snapshot size is TBD; it's a function of bucket list size as well as memory and historic demands placed on the RPC. diff --git a/meeting-notes/2024-05-02.mdx b/meeting-notes/2024-05-02.mdx index 2e9c7120c..a595895d2 100644 --- a/meeting-notes/2024-05-02.mdx +++ b/meeting-notes/2024-05-02.mdx @@ -1,5 +1,5 @@ --- -title: '2024-05-02' +title: "2024-05-02" authors: naman tags: [developer] --- @@ -14,9 +14,9 @@ tags: [developer] [Discord Agenda thread](https://discord.com/channels/897514728459468821/1234887262530048010/1234887262530048010) 1. Fifo presented [Stellar Plus](https://docs.cheesecakelabs.com/stellar-plus), which is a Javascript library to simplify the Stellar and Soroban development. -2. Ecosystem members found the design for Stellar Plus composable and encompassing of all Stellar related functionality including management of assets, accounts, wasm-related operations, as well as RPC utils. +2. Ecosystem members found the design for Stellar Plus composable and encompassing of all Stellar related functionality including management of assets, accounts, wasm-related operations, as well as RPC utils. 3. The links to Fifo's presentation and Stellar Plus are: - - [Miro Board showing Stellar Plus architecture](https://miro.com/app/board/uXjVKMDkMPI=/?share_link_id=643609701897) - - [Stellar Plus Repositore](https://discord.com/channels/897514728459468821/1234887262530048010/1235699608274079865) - - [Examples Repository](https://github.com/fazzatti/stellar-plus-examples) - - [Docs](https://docs.cheesecakelabs.com/stellar-plus) + - [Miro Board showing Stellar Plus architecture](https://miro.com/app/board/uXjVKMDkMPI=/?share_link_id=643609701897) + - [Stellar Plus Repositore](https://discord.com/channels/897514728459468821/1234887262530048010/1235699608274079865) + - [Examples Repository](https://github.com/fazzatti/stellar-plus-examples) + - [Docs](https://docs.cheesecakelabs.com/stellar-plus) diff --git a/meeting-notes/2024-05-09.mdx b/meeting-notes/2024-05-09.mdx index bf4cf32a9..12556769d 100644 --- a/meeting-notes/2024-05-09.mdx +++ b/meeting-notes/2024-05-09.mdx @@ -1,5 +1,5 @@ --- -title: '2024-05-09' +title: "2024-05-09" authors: naman tags: [developer] --- diff --git a/meeting-notes/2024-06-13.mdx b/meeting-notes/2024-06-13.mdx index a27324a3e..91c649959 100644 --- a/meeting-notes/2024-06-13.mdx +++ b/meeting-notes/2024-06-13.mdx @@ -1,5 +1,5 @@ --- -title: '2024-06-13' +title: "2024-06-13" authors: kalepail tags: [developer] --- @@ -12,13 +12,13 @@ tags: [developer] > 1. Tyler created Super Peach, a web3 application that uses passkeys to sign transactions. He demonstrated how passkeys can be used in authorization flows and how they can be used to sign transactions. - * Code: https://github.com/kalepail/superpeach - * Demo: https://superpeach.vercel.app + - Code: https://github.com/kalepail/superpeach + - Demo: https://superpeach.vercel.app 2. Introduced `passkey-kit`. A TypeScript SDK for creating and managing Smart Wallets via passkeys (includes the actual [Smart Wallet interface](https://github.com/kalepail/passkey-kit/tree/main/contracts)) - * Code: https://github.com/kalepail/passkey-kit - * Demo: https://passkey-kit-demo.pages.dev + - Code: https://github.com/kalepail/passkey-kit + - Demo: https://passkey-kit-demo.pages.dev 3. Introduced Launchtube, a service for submitting transactions onchain by covering both the transaction fee AND the sequence number. Wild! - * Code: https://github.com/kalepail/launchtube (ask in the `#passkeys` channel on Discord for a testnet token) + - Code: https://github.com/kalepail/launchtube (ask in the `#passkeys` channel on Discord for a testnet token) 4. He shared his vision for pushing the passkey implementation through to becoming a [standard for the ecosystem](https://docs.google.com/document/d/1c_Wom6eK1UpC3E7VuQZfOBCLc2d5lvqAhMN7VPieMBQ/edit). Join the `#passkeys` channel on the Discord to continue the discussion diff --git a/meeting-notes/2024-06-20.mdx b/meeting-notes/2024-06-20.mdx index 7cc11b52f..48ba43312 100644 --- a/meeting-notes/2024-06-20.mdx +++ b/meeting-notes/2024-06-20.mdx @@ -1,5 +1,5 @@ --- -title: '2024-06-20' +title: "2024-06-20" authors: naman tags: [developer] --- diff --git a/meeting-notes/2024-06-27.mdx b/meeting-notes/2024-06-27.mdx index 5148b9380..f98ddae9c 100644 --- a/meeting-notes/2024-06-27.mdx +++ b/meeting-notes/2024-06-27.mdx @@ -1,5 +1,5 @@ --- -title: '2024-06-27' +title: "2024-06-27" authors: naman tags: [developer] --- @@ -14,8 +14,8 @@ tags: [developer] 1. [Chad](https://github.com/chadoh) and [Willem](https://github.com/willemneal) from [Aha Labs](https://github.com/AhaLabs) discuss the updates to the new and improved [stellar-cli](https://github.com/stellar/stellar-cli) 2. Some highlights include the change from the name 'soroban' to 'stellar' when using the CLI tool and the addition of new commands. 3. They cover some cool functions like local network setup, account creation, and transaction signing. with the following commands: - - `stellar network container [start|logs]` - - `stellar keys [generate|fund|ls]` - - `stellar contract init` to get a whole new Soroban project - - and so much more! + - `stellar network container [start|logs]` + - `stellar keys [generate|fund|ls]` + - `stellar contract init` to get a whole new Soroban project + - and so much more! 4. They also discuss expected future updates including support for more Stellar operations and integration with Stellar Lab V2! diff --git a/meeting-notes/2024-07-11.mdx b/meeting-notes/2024-07-11.mdx index 7c0fc83f5..6b8f5e8be 100644 --- a/meeting-notes/2024-07-11.mdx +++ b/meeting-notes/2024-07-11.mdx @@ -1,5 +1,5 @@ --- -title: '2024-07-11' +title: "2024-07-11" authors: naman tags: [developer] --- @@ -12,7 +12,6 @@ tags: [developer] > 1. SDF Data team gave a crash course in analysis of Stellar data, and covered how to access Hubble, tips for efficient querying, and how to get started with data exploration. -2. [Slides](https://docs.google.com/presentation/d/1QsCwFLFcDF4RmNIwtSSnNrUfZb0RM0kLxOOxC7ENY5M/edit#slide=id.g2cb5821e4de_1_1143) are publicly available and legible async. +2. [Slides](https://docs.google.com/presentation/d/1QsCwFLFcDF4RmNIwtSSnNrUfZb0RM0kLxOOxC7ENY5M/edit#slide=id.g2cb5821e4de_1_1143) are publicly available and legible async. 3. Tips for data anlaysis are also covered in [docs](https://developers.stellar.org/docs/data/hubble/analyst-guide) 4. Share your queries and post questions in #hubble in Stellar discord, which is a dedicated channel for data-related topics. - diff --git a/meeting-notes/2024-07-18.mdx b/meeting-notes/2024-07-18.mdx index efcfcc879..59324c00b 100644 --- a/meeting-notes/2024-07-18.mdx +++ b/meeting-notes/2024-07-18.mdx @@ -1,5 +1,5 @@ --- -title: '2024-07-18' +title: "2024-07-18" authors: naman tags: [developer] --- @@ -11,17 +11,10 @@ tags: [developer] allow="autoplay" > +Note: the first part of the call was lost. The video posted above captures the second half of the call where various ecosystem developers shared their use cases and needs for a smart wallet on Stellar. -Note: the first part of the call was lost. The video posted above captures the second half of the call where various ecosystem developers shared their use cases and needs for a smart wallet on Stellar. - -1. Tyler put forward a [proposal](https://github.com/stellar/stellar-protocol/discussions/1499) for a smart wallet as a public good. Given that the native auth can be overloaded by using `__check_auth`, Stellar implementation of a smart wallet is fairly straightforward. The capability to customize the auth is already built into the core protocol. +1. Tyler put forward a [proposal](https://github.com/stellar/stellar-protocol/discussions/1499) for a smart wallet as a public good. Given that the native auth can be overloaded by using `__check_auth`, Stellar implementation of a smart wallet is fairly straightforward. The capability to customize the auth is already built into the core protocol. 2. See the [proposal](https://github.com/stellar/stellar-protocol/discussions/1499) here and implementation [here](https://github.com/kalepail/passkey-kit/blob/main/contracts/webauthn-wallet/src/lib.rs) -3. The proposal only uses WebAuthN-based signers i.e. passkeys. It does not use ed25519, which, perhaps it should given that ~100% of the accounts on Stellar use the scheme. It also introduces the notion of temporary and admin signers to illustrate the notion that the account can be managed by multiple signers, each with a different access policy. -4. The biggest unlock with custom auth is the ability to execute custom logic. We heard from various ecosystem members about how might they us it. -4a. A dev is building a perpetual protocol and thought smart wallets could be used to automatically manage defi positions, which would be a significant improvement over status quo where the user has to constantly track assets to determine _when_ to execute a trade. -4b. Folks are excited about foregoing the seed phrase for passkeys, which is especially meaningful when onboarding net new users to the blockchain. -4c. Authorizing a cross-chain message from a different chain, especially programmatic authorization, requires an implementation of custom accounts. -4d. Some apps have noted that users prefer not to have a wallet but simply experience the value of the app, especially games. For this, the app may assign a temprory account to the user and control access via check_auth. -4c. Microtransactions without needing user sign is super interesting for apps as well. +3. The proposal only uses WebAuthN-based signers i.e. passkeys. It does not use ed25519, which, perhaps it should given that ~100% of the accounts on Stellar use the scheme. It also introduces the notion of temporary and admin signers to illustrate the notion that the account can be managed by multiple signers, each with a different access policy. +4. The biggest unlock with custom auth is the ability to execute custom logic. We heard from various ecosystem members about how might they us it. 4a. A dev is building a perpetual protocol and thought smart wallets could be used to automatically manage defi positions, which would be a significant improvement over status quo where the user has to constantly track assets to determine _when_ to execute a trade. 4b. Folks are excited about foregoing the seed phrase for passkeys, which is especially meaningful when onboarding net new users to the blockchain. 4c. Authorizing a cross-chain message from a different chain, especially programmatic authorization, requires an implementation of custom accounts. 4d. Some apps have noted that users prefer not to have a wallet but simply experience the value of the app, especially games. For this, the app may assign a temprory account to the user and control access via check_auth. 4c. Microtransactions without needing user sign is super interesting for apps as well. 5. This has been a very insightful meeting and we learnt about how the Stellar ecosystem plans to leverage smart wallet. Let's continue the conversation in discord! - diff --git a/meeting-notes/2024-07-25.mdx b/meeting-notes/2024-07-25.mdx index a80b0bd59..299249ff7 100644 --- a/meeting-notes/2024-07-25.mdx +++ b/meeting-notes/2024-07-25.mdx @@ -1,10 +1,9 @@ --- -title: '2024-07-25' +title: "2024-07-25" authors: naman tags: [protocol] --- - -A Core Dev, Dima, discussed the proposal to add constructor support to Soroban, Stellar's smart contract system. - -Relevant links: [Draft CAP](https://github.com/stellar/stellar-protocol/blob/50dde0611440d6dc562a33462e6ba5f1504b2753/core/cap-0058.md), -[Ongoing discussion](https://github.com/stellar/stellar-protocol/discussions/1501), -[Motivating Discord Thread](https://discord.com/channels/897514728459468821/1067534037310255225) +A Core Dev, Dima, discussed the proposal to add constructor support to Soroban, Stellar's smart contract system. +Relevant links: [Draft CAP](https://github.com/stellar/stellar-protocol/blob/50dde0611440d6dc562a33462e6ba5f1504b2753/core/cap-0058.md), [Ongoing discussion](https://github.com/stellar/stellar-protocol/discussions/1501), [Motivating Discord Thread](https://discord.com/channels/897514728459468821/1067534037310255225) Key points discussed: + 1. The proposal improves usability of Soroban for contract and SDK developers. A constructor gaurantees contract initialization thus reducing overhead contract code that's usually added to ensure initialization. 2. There was general agreement for the proposal, questions were primarily implementation-focused like whether constructors should handle arguments, what should happen with upgrades, backwards comptability with contract creation functions, and behaviour on wasm update. -5. The high impact topic of naming is put to ecosystem vote, please cast yours [here](https://github.com/stellar/stellar-protocol/discussions/1507). - - +3. The high impact topic of naming is put to ecosystem vote, please cast yours [here](https://github.com/stellar/stellar-protocol/discussions/1507). diff --git a/meeting-notes/2024-08-01.mdx b/meeting-notes/2024-08-01.mdx index e03dd8b59..0c2f914ca 100644 --- a/meeting-notes/2024-08-01.mdx +++ b/meeting-notes/2024-08-01.mdx @@ -1,5 +1,5 @@ --- -title: '2024-08-01' +title: "2024-08-01" authors: naman tags: [developer] --- @@ -11,7 +11,6 @@ tags: [developer] allow="autoplay" > - 1. Piyal demonstrated that Freighter's swap functionality is now served by [Soroswap](https://soroswap.finance/). It was previously served by Stellar Dex. 2. Freighter has made integration instructions available [here](https://github.com/stellar/freighter/blob/d248f2ad0aa03da72ea6eeaf7907ac0454fdcc72/extension/INTEGRATING_SOROSWAP.MD?plain=1#L2). 3. Esteban shared that [Palta Labs](https://paltalabs.io/) has created a DEX aggregator and made it available to all via the [Router SDK](https://docs.soroswap.finance/03-technical-reference/07-optimal-route/01-soroswap-router-sdk). diff --git a/meeting-notes/2024-08-08.mdx b/meeting-notes/2024-08-08.mdx index 3e314a7f2..f4c12dd10 100644 --- a/meeting-notes/2024-08-08.mdx +++ b/meeting-notes/2024-08-08.mdx @@ -1,5 +1,5 @@ --- -title: '2024-08-12' +title: "2024-08-12" authors: naman tags: [developer] --- @@ -12,7 +12,3 @@ tags: [developer] > 1. Tdep discussed Zephyr, an execution env built on top of the indexer Mercury. He also walked through examples demonstrating how Zephyr can simplify dapp development. - - - - diff --git a/meeting-notes/2024-08-15.mdx b/meeting-notes/2024-08-15.mdx index d49e9b97c..0c3bf6b5c 100644 --- a/meeting-notes/2024-08-15.mdx +++ b/meeting-notes/2024-08-15.mdx @@ -1,5 +1,5 @@ --- -title: '2024-08-15' +title: "2024-08-15" authors: julian tags: [developer] --- @@ -15,11 +15,9 @@ tags: [developer] 2.[Link to the presentation](https://docs.google.com/presentation/d/1mDOrBLfe8-Bq6VCy7r5bb4w_uZjq-EOorbV3ZwYfs1k/edit?usp=sharing) -_Note_: The hosts microphone audio is not in the video so there is some silence during Q/A. -Here are the question asked during the Q/A: +_Note_: The hosts microphone audio is not in the video so there is some silence during Q/A. Here are the question asked during the Q/A: -1. (From ! markus_0) why do you always have an infinite amount of tokens in the pool? Wouldn't it be safer to start small and mint more as demand opens up -2.(From HunterIonize) What purpose does this serve exactly? Sorry to be blunt -3. How do you see the Orbit Protocol contributing to financial inclusion on a global scale, particularly in underbanked regions? What challenges do you anticipate in achieving this? -4. In 5-10 years, how do you see the landscape of Forex on blockchain evolving? What role do you believe Stellar will play in this evolution, and how will Blend and Orbit Protocol be at the forefront? -5. Are there any asks of the developer community? +1. (From ! markus_0) why do you always have an infinite amount of tokens in the pool? Wouldn't it be safer to start small and mint more as demand opens up 2.(From HunterIonize) What purpose does this serve exactly? Sorry to be blunt +2. How do you see the Orbit Protocol contributing to financial inclusion on a global scale, particularly in underbanked regions? What challenges do you anticipate in achieving this? +3. In 5-10 years, how do you see the landscape of Forex on blockchain evolving? What role do you believe Stellar will play in this evolution, and how will Blend and Orbit Protocol be at the forefront? +4. Are there any asks of the developer community? diff --git a/meeting-notes/2024-08-22.mdx b/meeting-notes/2024-08-22.mdx index 394d44f1b..c0ed92d54 100644 --- a/meeting-notes/2024-08-22.mdx +++ b/meeting-notes/2024-08-22.mdx @@ -1,26 +1,30 @@ --- -title: '2024-08-23' +title: "2024-08-23" authors: naman tags: [protocol] --- - + [Discord agenda thread](https://discord.com/channels/897514728459468821/900374272751591424/1275577430043525204) Core Developers discussed the latest proposals to advance Stellar Core in this week's Protocol Meeting. - -1. The proposal for addition of a constructor to Soroban’s flavor of Rust was introduced in a previous protocol meeting ([previous meeting](https://developers.stellar.org/meetings/2024/07/25)), documented in [CAP-58](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0058.md). A constructor is a function that will only be executed the first time the contract is created. +1. The proposal for addition of a constructor to Soroban’s flavor of Rust was introduced in a previous protocol meeting ([previous meeting](https://developers.stellar.org/meetings/2024/07/25)), documented in [CAP-58](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0058.md). A constructor is a function that will only be executed the first time the contract is created. 2. In this meeting, Dima discussed the updates made since the last meeting: - 1. Default constructor - if a constructor is not defined explicitly, the contract is treated as if it has a constructor - 2. Semantics of the return value - if the transactions succeeds, it is required to return a valid value - 3. Constructor interaction with custom accounts - custom accounts must be aware of the context that they are authorizing. + 1. Default constructor - if a constructor is not defined explicitly, the contract is treated as if it has a constructor + 2. Semantics of the return value - if the transactions succeeds, it is required to return a valid value + 3. Constructor interaction with custom accounts - custom accounts must be aware of the context that they are authorizing. 3. Graydon discussed the upgrade to the Wasmi virtual machine, documented in [CAP-60](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0060.md). Wasmi works by translating WebAssembly code to to an Internal Representation (IR) and then executing it. The upgrade is impactful in two ways. - 1. Translating from WebAssembly to IR takes longer but the execution of the resulting IR is performant. - 2. The upgrade introduces lazy compilation. Of all functions in a contract, only ones that are called in a given transaction will translated thus reducing both latency and fees. + 1. Translating from WebAssembly to IR takes longer but the execution of the resulting IR is performant. + 2. The upgrade introduces lazy compilation. Of all functions in a contract, only ones that are called in a given transaction will translated thus reducing both latency and fees. 4. Jay discussed addition of BLS12-381 cryptographic curve, documented in [CAP-59](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0059.md). - 1. Addition of pairing-friendly elliptic curves enables zk-based applications. 11 host functions have been added to expose mapping, pairing, and arithmetic on the BLS12-381 curve. - 2. Examples case of BLS signature verification was presented. It consumed 26M instructions (running natively), which is promising given the per-transaction limit is 100M. - 3. There was general agreement that the interface is the right one as it allows a contract developer to implement a wide variety of use cases. Discussion continues in discord. - 4. Jay requested that developers should build applications against the function and give feedback. + 1. Addition of pairing-friendly elliptic curves enables zk-based applications. 11 host functions have been added to expose mapping, pairing, and arithmetic on the BLS12-381 curve. + 2. Examples case of BLS signature verification was presented. It consumed 26M instructions (running natively), which is promising given the per-transaction limit is 100M. + 3. There was general agreement that the interface is the right one as it allows a contract developer to implement a wide variety of use cases. Discussion continues in discord. + 4. Jay requested that developers should build applications against the function and give feedback. diff --git a/meeting-notes/2024-08-29.mdx b/meeting-notes/2024-08-29.mdx index 41ebfac8d..257d09aa9 100644 --- a/meeting-notes/2024-08-29.mdx +++ b/meeting-notes/2024-08-29.mdx @@ -1,21 +1,26 @@ --- -title: '2024-08-29' +title: "2024-08-29" authors: naman tags: [protocol] --- - + Agenda: [Discord thread](https://discord.com/channels/897514728459468821/900374272751591424/1278045556211716171) CAP Core team deliberated on the proposed CAPs: 1. Addition of a constructor to Soroban's flavor of Rust. [CAP](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0058.md) - 1. Team's concern was about potential break in compatibility, which Dima had addressed. There were no further concerns. -3. Addition of BLS12-381 curve and required field arithmetics - [CAP](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0059.md) - 1. Team's concern was about providing functions to check invalid input. It's too computationally expensive to do the check at the contract layer so the it may need to be implemented as a host function. Jay is seeking ecosystem input around use cases that require strict input validation. - 2. There were no further concerns. -5. Increase performance by upgrading Soroban's VM. [CAP Discussion](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0060.md) - 1. Team's comments were about accuracy of the measurement method but the demonstrated benefits of wall clock time were thought to be promising. - 2. There was a suggestion to expose performance improvements to contract developers thus creating the incentive to optimize contracts to leverage the improvements. - 3. There were no further concerns. + 1. Team's concern was about potential break in compatibility, which Dima had addressed. There were no further concerns. +2. Addition of BLS12-381 curve and required field arithmetics - [CAP](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0059.md) + 1. Team's concern was about providing functions to check invalid input. It's too computationally expensive to do the check at the contract layer so the it may need to be implemented as a host function. Jay is seeking ecosystem input around use cases that require strict input validation. + 2. There were no further concerns. +3. Increase performance by upgrading Soroban's VM. [CAP Discussion](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0060.md) + 1. Team's comments were about accuracy of the measurement method but the demonstrated benefits of wall clock time were thought to be promising. + 2. There was a suggestion to expose performance improvements to contract developers thus creating the incentive to optimize contracts to leverage the improvements. + 3. There were no further concerns. diff --git a/meeting-notes/2024-09-05.mdx b/meeting-notes/2024-09-05.mdx index 0478e1a5e..3158556ec 100644 --- a/meeting-notes/2024-09-05.mdx +++ b/meeting-notes/2024-09-05.mdx @@ -1,24 +1,29 @@ --- -title: '2024-09-05' +title: "2024-09-05" authors: anataliocs tags: [developer] --- - + Agenda: [Discord thread](https://discord.com/channels/897514728459468821/900374272751591424/1280678171053789317) Platform team demonstrated Galexie, a part of CDP(Composable Data Platform): 1. Galexie - 1. Data Extraction: Extracts raw ledger data from the Stellar network - 2. Compression: Compresses raw data for efficient storage - 3. Storage Options: Supports runtime configuration through the Datastore abstraction to use various physical storage layers, starting with Google Cloud Storage (GCS) - 4. Modes of Operation: Can operate in either batch mode or streaming mode -2. Composable Data Platform - 1. Flexible Datastore: Multiple options for physical data storage layers - 2. Galexie: Used to extract, compress and export data to your chosen Datastore - 3. Transform: Structure data in a model suitable to your application + 1. Data Extraction: Extracts raw ledger data from the Stellar network + 2. Compression: Compresses raw data for efficient storage + 3. Storage Options: Supports runtime configuration through the Datastore abstraction to use various physical storage layers, starting with Google Cloud Storage (GCS) + 4. Modes of Operation: Can operate in either batch mode or streaming mode +2. Composable Data Platform + 1. Flexible Datastore: Multiple options for physical data storage layers + 2. Galexie: Used to extract, compress and export data to your chosen Datastore + 3. Transform: Structure data in a model suitable to your application 3. Pluggable Data Pipelines - 1. Workflows: Create ETL(extract, transform, load) pipelines - 2. Streaming: Fast, lightweight streaming data \ No newline at end of file + 1. Workflows: Create ETL(extract, transform, load) pipelines + 2. Streaming: Fast, lightweight streaming data diff --git a/meeting-notes/2024-09-12.mdx b/meeting-notes/2024-09-12.mdx index b07fa3191..7d7ab794a 100644 --- a/meeting-notes/2024-09-12.mdx +++ b/meeting-notes/2024-09-12.mdx @@ -1,22 +1,27 @@ --- -title: '2024-09-12' +title: "2024-09-12" authors: carstenjacobsen tags: [developer] --- - + Agenda: [Discord thread](https://discord.com/channels/897514728459468821/900374272751591424/1282934024892973077) Developer Experience team member Nando Vieira introduced the CLI features alias and snapshot: 1. Alias - 1. Install of Hello World example for showcasing alias - 2. Showed examples of how contract IDs are often passed as parameters in CLI commands like invoke (copying ID string or command substitution) - 3. How to deploy a smart contract and create an alias - 4. How to invoke the smart contract with the alias -2. Snapshot - 1. How to create a ledger snapshop - 2. How to use the snapshot in a test case + 1. Install of Hello World example for showcasing alias + 2. Showed examples of how contract IDs are often passed as parameters in CLI commands like invoke (copying ID string or command substitution) + 3. How to deploy a smart contract and create an alias + 4. How to invoke the smart contract with the alias +2. Snapshot + 1. How to create a ledger snapshop + 2. How to use the snapshot in a test case -Towards the end Nando went through the developer documentation, with focus on the added command line examples for Windows users, and a useful cookbook for CLI commands. \ No newline at end of file +Towards the end Nando went through the developer documentation, with focus on the added command line examples for Windows users, and a useful cookbook for CLI commands. diff --git a/meeting-notes/2024-09-19.mdx b/meeting-notes/2024-09-19.mdx index f24c9d9f9..a50cd29df 100644 --- a/meeting-notes/2024-09-19.mdx +++ b/meeting-notes/2024-09-19.mdx @@ -1,10 +1,15 @@ --- -title: '2024-09-19' +title: "2024-09-19" authors: carstenjacobsen tags: [developer] --- - + Agenda: [Discord thread](https://discord.com/channels/897514728459468821/900374272751591424/1285627254130610297) @@ -12,8 +17,8 @@ SDF DevRel team member Carsten Jacobsen showed how to build a simple Hello World 1. Create the default Hello World smart contract using the Stellar CLI 2. Create TypeScript bindings (package) using the Stellar CLI -3. Create the default Next.js using the npx create-next-app command -4. Add and link the TypeScript binding package to the Next.js project +3. Create the default Next.js using the npx create-next-app command +4. Add and link the TypeScript binding package to the Next.js project 5. Create a simple frontend with a form to submit a string 6. Import the package in the Next.js page, and setup a client 7. Create submit-function to send form value to the smart contract diff --git a/meeting-notes/2024-09-26.mdx b/meeting-notes/2024-09-26.mdx index 1fa53a6e4..dc009069a 100644 --- a/meeting-notes/2024-09-26.mdx +++ b/meeting-notes/2024-09-26.mdx @@ -1,17 +1,21 @@ --- -title: '2024-09-26' +title: "2024-09-26" authors: anataliocs tags: [developer] --- - + Agenda: [Discord thread](https://discord.com/channels/897514728459468821/900374272751591424/1288890126038208532) -Summary: Hoops Finance, a DeFi protocol, discussed their platform they are building. https://www.hoops.finance/ - +Summary: Hoops Finance, a DeFi protocol, discussed their platform they are building. https://www.hoops.finance/ 1. They abstract away the complexity of DeFi investments for normal users through a series of guided prompts. 2. Provides simplified access to LP liquidity provisioning abstraction 3. Public AMM API for read/write data on AMMs on Stellar -4. Hoops Finance API: https://api.v1.xlm.services/#overview +4. Hoops Finance API: https://api.v1.xlm.services/#overview diff --git a/package.json b/package.json index 7b8173687..2ccb7ac61 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "api": "yarn api:clean && yarn api:bundle && yarn api:gen", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "format:mdx": "prettier --write \"{docs,src/pages,platforms}/**/*.{md,mdx}\"", - "check:mdx": "prettier -c \"{docs,src/pages,platforms}/**/*.{md,mdx}\"", + "format:mdx": "prettier --write \"{docs,src/pages,platforms,meeting-notes}/**/*.{md,mdx}\"", + "check:mdx": "prettier -c \"{docs,src/pages,platforms,meeting-notes}/**/*.{md,mdx}\"", "lint:fix": "eslint \"src/**/*.{js,jsx,ts,tsx}\" --fix", "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"", "prepare": "husky", From 43a68798b79ec9d8295581cbaeeec4b881411d17 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 8 Oct 2024 23:20:57 -0500 Subject: [PATCH 24/60] delete package-lock.json file --- package-lock.json | 43118 -------------------------------------------- 1 file changed, 43118 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index da7899981..000000000 --- a/package-lock.json +++ /dev/null @@ -1,43118 +0,0 @@ -{ - "name": "stellar-docs", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "stellar-docs", - "version": "0.0.0", - "hasInstallScript": true, - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/preset-classic": "3.4.0", - "@docusaurus/remark-plugin-npm2yarn": "3.4.0", - "@docusaurus/theme-mermaid": "3.4.0", - "@mdx-js/react": "^3.0.0", - "@metamask/open-rpc-docs-react": "^0.1.2", - "@open-rpc/meta-schema": "^1.14.9", - "@open-rpc/schema-utils-js": "^1.16.2", - "ajv": "^8.16.0", - "axios": "^1.6.8", - "canvas-embed": "^1.0.80", - "clsx": "^2.0.0", - "docusaurus-plugin-openapi-docs": "^3.0.1", - "docusaurus-plugin-sentry": "^2.0.0", - "docusaurus-theme-openapi-docs": "^3.0.1", - "patch-package": "^8.0.0", - "prism-react-renderer": "^2.3.1", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "rehype-katex": "^7.0.0", - "remark-math": "^6.0.0", - "yarn": "^1.22.22" - }, - "devDependencies": { - "@docusaurus/eslint-plugin": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/tsconfig": "3.4.0", - "@docusaurus/types": "3.4.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.6.0", - "@redocly/cli": "^1.17.1", - "@stellar/prettier-config": "^1.2.0", - "eslint": "^9.6.0", - "husky": "^9.0.11", - "prettier": "^3.3.2", - "react-player": "^2.16.0", - "typescript": "~5.2.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", - "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", - "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", - "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/cache-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", - "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" - }, - "node_modules/@algolia/cache-in-memory": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", - "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/client-account": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", - "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", - "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", - "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/events": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" - }, - "node_modules/@algolia/logger-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", - "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" - }, - "node_modules/@algolia/logger-console": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", - "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", - "dependencies": { - "@algolia/logger-common": "4.24.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", - "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/requester-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", - "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" - }, - "node_modules/@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/transporter": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", - "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", - "dependencies": { - "@algolia/cache-common": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.6.4", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz", - "integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==", - "dependencies": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.15", - "js-yaml": "^4.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", - "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.7.tgz", - "integrity": "sha512-7LidzZfUXyfZ8/buRW6qIIHBY8wAZ1OrY9c/wTr8YhZ6vMPo+Uc/CVFLYY1spZrEQlD4w5u8wjqk5NQ3OVqQKA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", - "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", - "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", - "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", - "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", - "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", - "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", - "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.7", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.24.7", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.24.7", - "@babel/plugin-transform-class-properties": "^7.24.7", - "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.7", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.7", - "@babel/plugin-transform-dotall-regex": "^7.24.7", - "@babel/plugin-transform-duplicate-keys": "^7.24.7", - "@babel/plugin-transform-dynamic-import": "^7.24.7", - "@babel/plugin-transform-exponentiation-operator": "^7.24.7", - "@babel/plugin-transform-export-namespace-from": "^7.24.7", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.24.7", - "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.24.7", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-member-expression-literals": "^7.24.7", - "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-modules-systemjs": "^7.24.7", - "@babel/plugin-transform-modules-umd": "^7.24.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-new-target": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-object-super": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-property-literals": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-reserved-words": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.7", - "@babel/plugin-transform-unicode-escapes": "^7.24.7", - "@babel/plugin-transform-unicode-property-regex": "^7.24.7", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", - "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-transform-react-display-name": "^7.24.7", - "@babel/plugin-transform-react-jsx": "^7.24.7", - "@babel/plugin-transform-react-jsx-development": "^7.24.7", - "@babel/plugin-transform-react-pure-annotations": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, - "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.7.tgz", - "integrity": "sha512-eytSX6JLBY6PVAeQa2bFlDx/7Mmln/gaEpsit5a3WEvjGfiIytEsgAwuIXCPM0xvw0v0cJn3ilq0/TvXrW0kgA==", - "dependencies": { - "core-js-pure": "^3.30.2", - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@braintree/sanitize-url": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", - "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" - }, - "node_modules/@cfaester/enzyme-adapter-react-18": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cfaester/enzyme-adapter-react-18/-/enzyme-adapter-react-18-0.8.0.tgz", - "integrity": "sha512-3Z3ThTUouHwz8oIyhTYQljEMNRFtlVyc3VOOHCbxs47U6cnXs8K9ygi/c1tv49s7MBlTXeIcuN+Ttd9aPtILFQ==", - "dev": true, - "dependencies": { - "enzyme-shallow-equal": "^1.0.0", - "function.prototype.name": "^1.1.6", - "has": "^1.0.4", - "react-is": "^18.2.0", - "react-shallow-renderer": "^16.15.0" - }, - "peerDependencies": { - "enzyme": "^3.11.0", - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.0.tgz", - "integrity": "sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==" - }, - "node_modules/@docsearch/react": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.0.tgz", - "integrity": "sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==", - "dependencies": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.6.0", - "algoliasearch": "^4.19.1" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 19.0.0", - "react": ">= 16.8.0 < 19.0.0", - "react-dom": ">= 16.8.0 < 19.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@docusaurus/core": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.4.0.tgz", - "integrity": "sha512-g+0wwmN2UJsBqy2fQRQ6fhXruoEa62JDeEa5d8IdTJlMoaDaEDfHh7WjwGRn4opuTQWpjAwP/fbcgyHKlE+64w==", - "dependencies": { - "@babel/core": "^7.23.3", - "@babel/generator": "^7.23.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/preset-react": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "@babel/runtime": "^7.22.6", - "@babel/runtime-corejs3": "^7.22.6", - "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "autoprefixer": "^10.4.14", - "babel-loader": "^9.1.3", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.2", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.31.1", - "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^5.0.1", - "cssnano": "^6.1.2", - "del": "^6.1.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "eval": "^0.1.8", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "html-minifier-terser": "^7.2.0", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.5.3", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.7.6", - "p-map": "^4.0.0", - "postcss": "^8.4.26", - "postcss-loader": "^7.3.3", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "rtl-detect": "^1.0.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.5", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "url-loader": "^4.1.1", - "webpack": "^5.88.1", - "webpack-bundle-analyzer": "^4.9.0", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.9.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/cssnano-preset": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.4.0.tgz", - "integrity": "sha512-qwLFSz6v/pZHy/UP32IrprmH5ORce86BGtN0eBtG75PpzQJAzp9gefspox+s8IEOr0oZKuQ/nhzZ3xwyc3jYJQ==", - "dependencies": { - "cssnano-preset-advanced": "^6.1.2", - "postcss": "^8.4.38", - "postcss-sort-media-queries": "^5.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/eslint-plugin": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/eslint-plugin/-/eslint-plugin-3.4.0.tgz", - "integrity": "sha512-3Y9SwkxwY36TmsvZGyLZepifHbXIjZHMEFGuPcvtkFNnVgFIUkoAkf17GfwKKHnAloYVG/hpLV1m8q2BVKSLNQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "^5.62.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "eslint": ">=6" - } - }, - "node_modules/@docusaurus/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@docusaurus/eslint-plugin/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@docusaurus/eslint-plugin/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@docusaurus/logger": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.4.0.tgz", - "integrity": "sha512-bZwkX+9SJ8lB9kVRkXw+xvHYSMGG4bpYHKGXeXFvyVc79NMeeBSGgzd4TQLHH+DYeOJoCdl8flrFJVxlZ0wo/Q==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/mdx-loader": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.4.0.tgz", - "integrity": "sha512-kSSbrrk4nTjf4d+wtBA9H+FGauf2gCax89kV8SUSJu3qaTdSIKdWERlngsiHaCFgZ7laTJ8a67UFf+xlFPtuTw==", - "dependencies": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^1.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/module-type-aliases": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.4.0.tgz", - "integrity": "sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw==", - "dependencies": { - "@docusaurus/types": "3.4.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.4.0.tgz", - "integrity": "sha512-vv6ZAj78ibR5Jh7XBUT4ndIjmlAxkijM3Sx5MAAzC1gyv0vupDQNhzuFg1USQmQVj3P5I6bquk12etPV3LJ+Xw==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "cheerio": "^1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "reading-time": "^1.5.0", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.4.0.tgz", - "integrity": "sha512-HkUCZffhBo7ocYheD9oZvMcDloRnGhBMOZRyVcAQRFmZPmNqSyISlXA1tQCIxW+r478fty97XXAGjNYzBjpCsg==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.4.0.tgz", - "integrity": "sha512-h2+VN/0JjpR8fIkDEAoadNjfR3oLzB+v1qSXbIAKjQ46JAHx3X22n9nqS+BWSQnTnp1AjkjSvZyJMekmcwxzxg==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-debug": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.4.0.tgz", - "integrity": "sha512-uV7FDUNXGyDSD3PwUaf5YijX91T5/H9SX4ErEcshzwgzWwBtK37nUWPU3ZLJfeTavX3fycTOqk9TglpOLaWkCg==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^1.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.4.0.tgz", - "integrity": "sha512-mCArluxEGi3cmYHqsgpGGt3IyLCrFBxPsxNZ56Mpur0xSlInnIHoeLDH7FvVVcPJRPSQ9/MfRqLsainRw+BojA==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.4.0.tgz", - "integrity": "sha512-Dsgg6PLAqzZw5wZ4QjUYc8Z2KqJqXxHxq3vIoyoBWiLEEfigIs7wHR+oiWUQy3Zk9MIk6JTYj7tMoQU0Jm3nqA==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.4.0.tgz", - "integrity": "sha512-O9tX1BTwxIhgXpOLpFDueYA9DWk69WCbDRrjYoMQtFHSkTyE7RhNgyjSPREUWJb9i+YUg3OrsvrBYRl64FCPCQ==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.4.0.tgz", - "integrity": "sha512-+0VDvx9SmNrFNgwPoeoCha+tRoAjopwT0+pYO1xAbyLcewXSemq+eLxEa46Q1/aoOaJQ0qqHELuQM7iS2gp33Q==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/preset-classic": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.4.0.tgz", - "integrity": "sha512-Ohj6KB7siKqZaQhNJVMBBUzT3Nnp6eTKqO+FXO3qu/n1hJl3YLwVKTWBg28LF7MWrKu46UuYavwMRxud0VyqHg==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/plugin-debug": "3.4.0", - "@docusaurus/plugin-google-analytics": "3.4.0", - "@docusaurus/plugin-google-gtag": "3.4.0", - "@docusaurus/plugin-google-tag-manager": "3.4.0", - "@docusaurus/plugin-sitemap": "3.4.0", - "@docusaurus/theme-classic": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-search-algolia": "3.4.0", - "@docusaurus/types": "3.4.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/remark-plugin-npm2yarn": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/remark-plugin-npm2yarn/-/remark-plugin-npm2yarn-3.4.0.tgz", - "integrity": "sha512-MXcYAkKu6544h7J4vbKdeH+G5HZf6LF3qZORQqWzxOi2p82PTLRu0YM6ZgzfPjH5nZClgLBHypPbyO9qhkxPKw==", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "npm-to-yarn": "^2.2.1", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/theme-classic": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.4.0.tgz", - "integrity": "sha512-0IPtmxsBYv2adr1GnZRdMkEQt1YW6tpzrUPj02YxNpvJ5+ju4E13J5tB4nfdaen/tfR1hmpSPlTFPvTf4kwy8Q==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-translations": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.43", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.4.26", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-common": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.4.0.tgz", - "integrity": "sha512-0A27alXuv7ZdCg28oPE8nH/Iz73/IUejVaCazqu9elS4ypjiLhK3KfzdSQBnL/g7YfHSlymZKdiOHEo8fJ0qMA==", - "dependencies": { - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.4.0.tgz", - "integrity": "sha512-3w5QW0HEZ2O6x2w6lU3ZvOe1gNXP2HIoKDMJBil1VmLBc9PmpAG17VmfhI/p3L2etNmOiVs5GgniUqvn8AFEGQ==", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "mermaid": "^10.4.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.4.0.tgz", - "integrity": "sha512-aiHFx7OCw4Wck1z6IoShVdUWIjntC8FHCw9c5dR8r3q4Ynh+zkS8y2eFFunN/DL6RXPzpnvKCg3vhLQYJDmT9Q==", - "dependencies": { - "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-translations": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "algoliasearch": "^4.18.0", - "algoliasearch-helper": "^3.13.3", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-translations": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.4.0.tgz", - "integrity": "sha512-zSxCSpmQCCdQU5Q4CnX/ID8CSUUI3fvmq4hU/GNP/XoAWtXo9SAVnM3TzpU8Gb//H3WCsT8mJcTfyOk3d9ftNg==", - "dependencies": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/tsconfig": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.4.0.tgz", - "integrity": "sha512-0qENiJ+TRaeTzcg4olrnh0BQ7eCxTgbYWBnWUeQDc84UYkt/T3pDNnm3SiQkqPb+YQ1qtYFlC0RriAElclo8Dg==", - "dev": true - }, - "node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/utils": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.4.0.tgz", - "integrity": "sha512-fRwnu3L3nnWaXOgs88BVBmG1yGjcQqZNHG+vInhEa2Sz2oQB+ZjbEMO5Rh9ePFpZ0YDiDUhpaVjwmS+AU2F14g==", - "dependencies": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@svgr/webpack": "^8.1.0", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "prompts": "^2.4.2", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/utils-common": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.4.0.tgz", - "integrity": "sha512-NVx54Wr4rCEKsjOH5QEVvxIqVvm+9kh7q8aYTU5WzUU9/Hctd6aTrcZ3G0Id4zYJ+AeaG5K5qHA4CY5Kcm2iyQ==", - "dependencies": { - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/utils-validation": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.4.0.tgz", - "integrity": "sha512-hYQ9fM+AXYVTWxJOT1EuNaRnrR2WGpRdLDQG07O8UOpsvCPWUVOeo26Rbm0JWY2sGLfzAb+tvJ62yF+8F+TV0g==", - "dependencies": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "fs-extra": "^11.2.0", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", - "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", - "dev": true, - "dependencies": { - "@emotion/memoize": "^0.8.1" - } - }, - "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", - "dev": true - }, - "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", - "dev": true - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "devOptional": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "devOptional": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "devOptional": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.0.tgz", - "integrity": "sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA==", - "devOptional": true, - "dependencies": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "devOptional": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "devOptional": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "devOptional": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "devOptional": true - }, - "node_modules/@eslint/js": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.6.0.tgz", - "integrity": "sha512-D9B0/3vNg44ZeWbYMpBoXqNP4j6eQD5vNwIlGAuFRRzK/WtT/jvDQW3Bi9kkf3PMDMlM7Yi+73VLUsn5bJcl8A==", - "devOptional": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "devOptional": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@exodus/schemasafe": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", - "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==" - }, - "node_modules/@faker-js/faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==" - }, - "node_modules/@floating-ui/core": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", - "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", - "dependencies": { - "@floating-ui/utils": "^0.2.4" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz", - "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==", - "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.4" - } - }, - "node_modules/@floating-ui/react": { - "version": "0.26.19", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.19.tgz", - "integrity": "sha512-Jk6zITdjjIvjO/VdQFvpRaD3qPwOHH6AoDHxjhpy+oK4KFgaSP871HYWUAPdnLmx1gQ+w/pB312co3tVml+BXA==", - "dependencies": { - "@floating-ui/react-dom": "^2.1.1", - "@floating-ui/utils": "^0.2.4", - "tabbable": "^6.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", - "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", - "dependencies": { - "@floating-ui/dom": "^1.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", - "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" - }, - "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz", - "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==", - "hasInstallScript": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz", - "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==", - "hasInstallScript": true, - "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/react-fontawesome": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", - "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", - "dependencies": { - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "@fortawesome/fontawesome-svg-core": "~1 || ~6", - "react": ">=16.3" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@headlessui/react": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.1.tgz", - "integrity": "sha512-808gVNUbRDbDR3GMNPHy+ON0uvR8b9H7IA+Q2UbhOsNCIjgwuwb2Iuv8VPT/1AW0UzLX8g10tN6LhF15GaUJCQ==", - "dependencies": { - "@floating-ui/react": "^0.26.16", - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@tanstack/react-virtual": "3.5.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": "^18", - "react-dom": "^18" - } - }, - "node_modules/@hookform/error-message": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@hookform/error-message/-/error-message-2.0.1.tgz", - "integrity": "sha512-U410sAr92xgxT1idlu9WWOVjndxLdgPUHEB8Schr27C9eh7/xUnITWpCMF93s+lGiG++D4JnbSnrb5A21AdSNg==", - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0", - "react-hook-form": "^7.0.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "devOptional": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", - "devOptional": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsdevtools/ono": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" - }, - "node_modules/@json-schema-spec/json-pointer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@json-schema-spec/json-pointer/-/json-pointer-0.1.2.tgz", - "integrity": "sha512-BYY7IavBjwsWWSmVcMz2A9mKiDD9RvacnsItgmy1xV8cmgbtxFfKmKMtkVpD7pYtkx4mIW4800yZBXueVFIWPw==" - }, - "node_modules/@json-schema-tools/dereferencer": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@json-schema-tools/dereferencer/-/dereferencer-1.5.5.tgz", - "integrity": "sha512-ntnTXO47DOLTLmcU9yJ7Fu29L8Du9+ly4rwxLaYd/aWVhBDtvG8VIQRMJVrrTZOQo0Cv/wHHuEj47n43MFqIjA==", - "dependencies": { - "@json-schema-tools/reference-resolver": "^1.2.4", - "@json-schema-tools/traverse": "^1.7.8", - "fast-safe-stringify": "^2.0.7" - } - }, - "node_modules/@json-schema-tools/meta-schema": { - "version": "1.6.19", - "resolved": "https://registry.npmjs.org/@json-schema-tools/meta-schema/-/meta-schema-1.6.19.tgz", - "integrity": "sha512-55zuWFW7tr4tf/G5AYmybcPdGOkVAreQbt2JdnogX4I2r/zkxZiimYPJESDf5je9BI2oRveak2p296HzDppeaA==" - }, - "node_modules/@json-schema-tools/reference-resolver": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@json-schema-tools/reference-resolver/-/reference-resolver-1.2.4.tgz", - "integrity": "sha512-Oag20zDuapO6nBQp00k8Rd5sDTb8Gfz9uH43Tf7dHKNx7nHDK/WdeTe7OxkOmLQCL6aS+mCJx1Zv+fZBCD+tzQ==", - "dependencies": { - "@json-schema-spec/json-pointer": "^0.1.2", - "isomorphic-fetch": "^3.0.0" - } - }, - "node_modules/@json-schema-tools/traverse": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@json-schema-tools/traverse/-/traverse-1.10.4.tgz", - "integrity": "sha512-9e42zjhLIxzBONroNC4SGsTqdB877tzwH2S6lqgTav9K24kWJR9vNieeMVSuyqnY8FlclH21D8wsm/tuD9WA9Q==" - }, - "node_modules/@juggle/resize-observer": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", - "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" - }, - "node_modules/@mdx-js/mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", - "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-to-js": "^2.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/react": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", - "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "node_modules/@metamask/open-rpc-docs-react": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@metamask/open-rpc-docs-react/-/open-rpc-docs-react-0.1.2.tgz", - "integrity": "sha512-QQtU8doQo87n+o6K4N8MDBcrVl27NGrq9UrYhjLylryngSgU4eC8zSoDKhNIGEqx65Y7rpFZTys8L50KKn0Lng==", - "dependencies": { - "@json-schema-tools/traverse": "^1.10.1", - "@open-rpc/examples": "^1.6.1", - "@rjsf/core": "^5.6.2", - "@rjsf/utils": "^5.6.2", - "@rjsf/validator-ajv8": "^5.6.2", - "@stoplight/json-schema-viewer": "^4.9.1", - "@stoplight/markdown-viewer": "^5", - "@stoplight/mosaic": "^1.32", - "@stoplight/mosaic-code-viewer": "^1.32", - "hash-color-material": "^1.1.3", - "lodash": "^4.17.15", - "qs": "^6.11.1", - "react-markdown": "^8.0.7", - "react-syntax-highlighter": "^15.4.3" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "react": "^17.0.2", - "react-dom": "^17.0.2" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@open-rpc/examples": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@open-rpc/examples/-/examples-1.7.2.tgz", - "integrity": "sha512-wEvviOPc+gyBVmxvGQVl/hqYslEacxLe0UETupyp1JjXUAZxW27da+F1IxbP6NYdx6jt4RyLg+V0GBVTsN6RRA==" - }, - "node_modules/@open-rpc/meta-schema": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/@open-rpc/meta-schema/-/meta-schema-1.14.9.tgz", - "integrity": "sha512-2/CbDzOVpcaSnMs28TsRv8MKJwJi0TTYFlQ6q6qobAH26oIuhYgcZooKf4l71emgntU6MMcFQCA0h4mJ4dBCdA==" - }, - "node_modules/@open-rpc/schema-utils-js": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/@open-rpc/schema-utils-js/-/schema-utils-js-1.16.2.tgz", - "integrity": "sha512-55vQov3o8KkXD+wiw1nKZaYws2LHSntjK5Sfja4vfGN7A6Xis0r0d0MUDVj32E3pKF9Z2sTZL3sKO/nB0DKUDg==", - "dependencies": { - "@json-schema-tools/dereferencer": "1.5.5", - "@json-schema-tools/meta-schema": "1.6.19", - "@json-schema-tools/reference-resolver": "1.2.4", - "@open-rpc/meta-schema": "1.14.2", - "ajv": "^6.10.0", - "detect-node": "^2.0.4", - "fast-safe-stringify": "^2.0.7", - "fs-extra": "^10.1.0", - "is-url": "^1.2.4", - "isomorphic-fetch": "^3.0.0" - } - }, - "node_modules/@open-rpc/schema-utils-js/node_modules/@open-rpc/meta-schema": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/@open-rpc/meta-schema/-/meta-schema-1.14.2.tgz", - "integrity": "sha512-vD4Nbkrb7wYFRcSQf+j228LwOy1C6/KKpy5NADlpMElGrAWPRxhTa2yTi6xG+x88OHzg2+cydQ0GAD6o40KUcg==" - }, - "node_modules/@open-rpc/schema-utils-js/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@open-rpc/schema-utils-js/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@open-rpc/schema-utils-js/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "dependencies": { - "graceful-fs": "4.2.10" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "node_modules/@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.25", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", - "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==" - }, - "node_modules/@react-aria/focus": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.17.1.tgz", - "integrity": "sha512-FLTySoSNqX++u0nWZJPPN5etXY0WBxaIe/YuL/GTEeuqUIuC/2bJSaw5hlsM6T2yjy6Y/VAxBcKSdAFUlU6njQ==", - "dependencies": { - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", - "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, - "node_modules/@react-aria/interactions": { - "version": "3.21.3", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.3.tgz", - "integrity": "sha512-BWIuf4qCs5FreDJ9AguawLVS0lV9UU+sK4CCnbCNNmYqOWY+1+gRXCsnOM32K+oMESBxilAjdHW5n1hsMqYMpA==", - "dependencies": { - "@react-aria/ssr": "^3.9.4", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, - "node_modules/@react-aria/ssr": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz", - "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, - "node_modules/@react-aria/utils": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.24.1.tgz", - "integrity": "sha512-O3s9qhPMd6n42x9sKeJ3lhu5V1Tlnzhu6Yk8QOvDuXf7UGuUjXf9mzfHJt1dYzID4l9Fwm8toczBzPM9t0jc8Q==", - "dependencies": { - "@react-aria/ssr": "^3.9.4", - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", - "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, - "node_modules/@react-hook/debounce": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@react-hook/debounce/-/debounce-3.0.0.tgz", - "integrity": "sha512-ir/kPrSfAzY12Gre0sOHkZ2rkEmM4fS5M5zFxCi4BnCeXh2nvx9Ujd+U4IGpKCuPA+EQD0pg1eK2NGLvfWejag==", - "dependencies": { - "@react-hook/latest": "^1.0.2" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/@react-hook/event": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@react-hook/event/-/event-1.2.6.tgz", - "integrity": "sha512-JUL5IluaOdn5w5Afpe/puPa1rj8X6udMlQ9dt4hvMuKmTrBS1Ya6sb4sVgvfe2eU4yDuOfAhik8xhbcCekbg9Q==", - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/@react-hook/latest": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz", - "integrity": "sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==", - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/@react-hook/passive-layout-effect": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz", - "integrity": "sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==", - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/@react-hook/resize-observer": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@react-hook/resize-observer/-/resize-observer-1.2.6.tgz", - "integrity": "sha512-DlBXtLSW0DqYYTW3Ft1/GQFZlTdKY5VAFIC4+km6IK5NiPPDFchGbEJm1j6pSgMqPRHbUQgHJX7RaR76ic1LWA==", - "dependencies": { - "@juggle/resize-observer": "^3.3.1", - "@react-hook/latest": "^1.0.2", - "@react-hook/passive-layout-effect": "^1.2.0" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/@react-hook/size": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@react-hook/size/-/size-2.1.2.tgz", - "integrity": "sha512-BmE5asyRDxSuQ9p14FUKJ0iBRgV9cROjqNG9jT/EjCM+xHha1HVqbPoT+14FQg1K7xIydabClCibUY4+1tw/iw==", - "dependencies": { - "@react-hook/passive-layout-effect": "^1.2.0", - "@react-hook/resize-observer": "^1.2.1" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/@react-hook/throttle": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@react-hook/throttle/-/throttle-2.2.0.tgz", - "integrity": "sha512-LJ5eg+yMV8lXtqK3lR+OtOZ2WH/EfWvuiEEu0M3bhR7dZRfTyEJKxH1oK9uyBxiXPtWXiQggWbZirMCXam51tg==", - "dependencies": { - "@react-hook/latest": "^1.0.2" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/@react-hook/window-size": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@react-hook/window-size/-/window-size-3.1.1.tgz", - "integrity": "sha512-yWnVS5LKnOUIrEsI44oz3bIIUYqflamPL27n+k/PC//PsX/YeWBky09oPeAoc9As6jSH16Wgo8plI+ECZaHk3g==", - "dependencies": { - "@react-hook/debounce": "^3.0.0", - "@react-hook/event": "^1.2.1", - "@react-hook/throttle": "^2.2.0" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/@react-stately/utils": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.1.tgz", - "integrity": "sha512-VS/EHRyicef25zDZcM/ClpzYMC5i2YGN6uegOeQawmgfGjb02yaCX0F0zR69Pod9m2Hr3wunTbtpgVXvYbZItg==", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, - "node_modules/@react-types/checkbox": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.1.tgz", - "integrity": "sha512-5/oVByPw4MbR/8QSdHCaalmyWC71H/QGgd4aduTJSaNi825o+v/hsN2/CH7Fq9atkLKsC8fvKD00Bj2VGaKriQ==", - "dependencies": { - "@react-types/shared": "^3.23.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, - "node_modules/@react-types/shared": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.23.1.tgz", - "integrity": "sha512-5d+3HbFDxGZjhbMBeFHRQhexMFt4pUce3okyRtUVKbbedQFUrtXSBg9VszgF2RTeQDKDkMCIQDtz5ccP/Lk1gw==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, - "node_modules/@redocly/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-9GWx27t7xWhDIR02PA18nzBdLcKQRgc46xNQvjFkrYk4UOmvKhJ/dawwiX0cCOeetN5LcaaiqQbVOWYK62SGHw==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@redocly/cli": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.17.1.tgz", - "integrity": "sha512-a7OIlsGQT8OBRMPswqcJzCoub/nvm1zYvOCOBnaLt1cYeYK9nRzYCXA6Bnx0I7wMCXf5YmL7rVTMG8RJTC+3mA==", - "dev": true, - "dependencies": { - "@redocly/openapi-core": "1.17.1", - "abort-controller": "^3.0.0", - "chokidar": "^3.5.1", - "colorette": "^1.2.0", - "core-js": "^3.32.1", - "form-data": "^4.0.0", - "get-port-please": "^3.0.1", - "glob": "^7.1.6", - "handlebars": "^4.7.6", - "mobx": "^6.0.4", - "node-fetch": "^2.6.1", - "react": "^17.0.0 || ^18.2.0", - "react-dom": "^17.0.0 || ^18.2.0", - "redoc": "~2.1.5", - "semver": "^7.5.2", - "simple-websocket": "^9.0.0", - "styled-components": "^6.0.7", - "yargs": "17.0.1" - }, - "bin": { - "openapi": "bin/cli.js", - "redocly": "bin/cli.js" - }, - "engines": { - "node": ">=14.19.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@redocly/config": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.6.3.tgz", - "integrity": "sha512-hGWJgCsXRw0Ow4rplqRlUQifZvoSwZipkYnt11e3SeH1Eb23VUIDBcRuaQOUqy1wn0eevXkU2GzzQ8fbKdQ7Mg==" - }, - "node_modules/@redocly/openapi-core": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.17.1.tgz", - "integrity": "sha512-PQxDLLNk5cBatJBBxvfk49HFw/nVozw1XZ6Dw/GX0Tviq+WxeEjEuLAKfnLVvb5L0wgs4TNmVG4Y+JyofSPu1A==", - "dependencies": { - "@redocly/ajv": "^8.11.0", - "@redocly/config": "^0.6.2", - "colorette": "^1.2.0", - "https-proxy-agent": "^7.0.4", - "js-levenshtein": "^1.1.6", - "js-yaml": "^4.1.0", - "lodash.isequal": "^4.5.0", - "minimatch": "^5.0.1", - "node-fetch": "^2.6.1", - "pluralize": "^8.0.0", - "yaml-ast-parser": "0.0.43" - }, - "engines": { - "node": ">=14.19.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@redocly/openapi-core/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@redocly/openapi-core/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@reduxjs/toolkit": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", - "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", - "dependencies": { - "immer": "^9.0.21", - "redux": "^4.2.1", - "redux-thunk": "^2.4.2", - "reselect": "^4.1.8" - }, - "peerDependencies": { - "react": "^16.9.0 || ^17.0.0 || ^18", - "react-redux": "^7.2.1 || ^8.0.2" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-redux": { - "optional": true - } - } - }, - "node_modules/@rehooks/component-size": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rehooks/component-size/-/component-size-1.0.3.tgz", - "integrity": "sha512-pnYld+8SSF2vXwdLOqBGUyOrv/SjzwLjIUcs/4c1JJgR0q4E9eBtBfuZMD6zUD51fvSehSsbnlQMzotSmPTXPg==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@rjsf/core": { - "version": "5.18.6", - "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.18.6.tgz", - "integrity": "sha512-Jori6SvGbNUo4PD9dCudNyM/kBQdXMrg2dAT5AA3FH7ciqUS/nxSRZQdejLX86aX7iZDrbYmucpDHfNCQxV/uQ==", - "dependencies": { - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "markdown-to-jsx": "^7.4.1", - "nanoid": "^3.3.7", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "@rjsf/utils": "^5.18.x", - "react": "^16.14.0 || >=17" - } - }, - "node_modules/@rjsf/utils": { - "version": "5.18.6", - "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.18.6.tgz", - "integrity": "sha512-E/zTsbiCT5EOZL2K92Qhry712/87PyE4GPFQJvgYCT7wS1u6cvdAsJE1yNarAFK01JzaLPSS62Zq894RaBuApg==", - "dependencies": { - "json-schema-merge-allof": "^0.8.1", - "jsonpointer": "^5.0.1", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "react-is": "^18.2.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^16.14.0 || >=17" - } - }, - "node_modules/@rjsf/validator-ajv8": { - "version": "5.18.6", - "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.18.6.tgz", - "integrity": "sha512-rIDvJQmh3CirMFf4TeY8ggGil369BOyyEv6sqa+Dr4u4MU5jjSxYudMKqmPhK9fUzX7wEDCqH1BngrsIWWRCnQ==", - "dependencies": { - "ajv": "^8.12.0", - "ajv-formats": "^2.1.1", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "@rjsf/utils": "^5.18.x" - } - }, - "node_modules/@sentry/browser": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.19.7.tgz", - "integrity": "sha512-oDbklp4O3MtAM4mtuwyZLrgO1qDVYIujzNJQzXmi9YzymJCuzMLSRDvhY83NNDCRxf0pds4DShgYeZdbSyKraA==", - "dependencies": { - "@sentry/core": "6.19.7", - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/core": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.19.7.tgz", - "integrity": "sha512-tOfZ/umqB2AcHPGbIrsFLcvApdTm9ggpi/kQZFkej7kMphjT+SGBiQfYtjyg9jcRW+ilAR4JXC9BGKsdEQ+8Vw==", - "dependencies": { - "@sentry/hub": "6.19.7", - "@sentry/minimal": "6.19.7", - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/hub": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.19.7.tgz", - "integrity": "sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==", - "dependencies": { - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/hub/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/minimal": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.19.7.tgz", - "integrity": "sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==", - "dependencies": { - "@sentry/hub": "6.19.7", - "@sentry/types": "6.19.7", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/minimal/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/react": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-6.19.7.tgz", - "integrity": "sha512-VzJeBg/v41jfxUYPkH2WYrKjWc4YiMLzDX0f4Zf6WkJ4v3IlDDSkX6DfmWekjTKBho6wiMkSNy2hJ1dHfGZ9jA==", - "dependencies": { - "@sentry/browser": "6.19.7", - "@sentry/minimal": "6.19.7", - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "hoist-non-react-statics": "^3.3.2", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "react": "15.x || 16.x || 17.x || 18.x" - } - }, - "node_modules/@sentry/react/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/types": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.19.7.tgz", - "integrity": "sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/utils": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.19.7.tgz", - "integrity": "sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==", - "dependencies": { - "@sentry/types": "6.19.7", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/utils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "node_modules/@stellar/prettier-config": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@stellar/prettier-config/-/prettier-config-1.2.0.tgz", - "integrity": "sha512-oL9qJ7+7aWnImpbcldroQrvtMCZ9yx4JL/tmDZ860RpBQd2ahkc8bX6/k2ehFK8gpb9ltYu4mtU49wufUuYhGg==", - "dev": true, - "peerDependencies": { - "prettier": "^3.2.5" - } - }, - "node_modules/@stoplight/json": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.0.tgz", - "integrity": "sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==", - "dependencies": { - "@stoplight/ordered-object-literal": "^1.0.3", - "@stoplight/path": "^1.3.2", - "@stoplight/types": "^13.6.0", - "jsonc-parser": "~2.2.1", - "lodash": "^4.17.21", - "safe-stable-stringify": "^1.1" - }, - "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/@stoplight/json-schema-merge-allof": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@stoplight/json-schema-merge-allof/-/json-schema-merge-allof-0.8.0.tgz", - "integrity": "sha512-g8e0s43v96Xbzvd8d6KKUuJTO16CS2oJglJrviUi8ASIUxzFvAJqTHWLtGmpTryisQopqg1evXGJfi0+164+Qw==", - "dependencies": { - "compute-lcm": "^1.1.0", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.4" - } - }, - "node_modules/@stoplight/json-schema-tree": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@stoplight/json-schema-tree/-/json-schema-tree-4.0.0.tgz", - "integrity": "sha512-SAGtof+ihIdPqETR+7XXOaqZJcrbSih/xEahaw5t1nXk5sVW6ss2l5A1WCIuvtvnQiUKnBfanmZU4eoM1ZvItg==", - "dependencies": { - "@stoplight/json": "^3.12.0", - "@stoplight/json-schema-merge-allof": "^0.8.0", - "@stoplight/lifecycle": "^2.3.2", - "@types/json-schema": "^7.0.7", - "magic-error": "0.0.1" - }, - "engines": { - "node": ">=10.18" - } - }, - "node_modules/@stoplight/json-schema-viewer": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@stoplight/json-schema-viewer/-/json-schema-viewer-4.16.1.tgz", - "integrity": "sha512-gQ1v9/Dj1VP43zERuZoFMOr7RQDBZlgfF7QFh+R0sadP6W30oYFJtD7y2PG2gIQDohKElVuPjhFUbVH/81MnSg==", - "dependencies": { - "@stoplight/json": "^3.20.1", - "@stoplight/json-schema-tree": "^4.0.0", - "@stoplight/react-error-boundary": "^2.0.0", - "@types/json-schema": "^7.0.7", - "classnames": "^2.2.6", - "fnv-plus": "^1.3.1", - "jotai": "^1.4.5", - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "@stoplight/markdown-viewer": "^5", - "@stoplight/mosaic": "^1.32", - "@stoplight/mosaic-code-viewer": "^1.32", - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, - "node_modules/@stoplight/lifecycle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@stoplight/lifecycle/-/lifecycle-2.3.3.tgz", - "integrity": "sha512-JbPRTIzPZabeYPAk5+gdsnfwAxqW35G9e0ZjOG3toUmNViLOsEzuK4vpWd+Prv2Mw8HRmu+haiYizteZp6mk0w==", - "dependencies": { - "tslib": "^2.3.1", - "wolfy87-eventemitter": "~5.2.8" - }, - "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/@stoplight/markdown": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@stoplight/markdown/-/markdown-3.2.0.tgz", - "integrity": "sha512-Hhnrj7xb+f4iMQQeZBKLgfst3OJyV8T4BKr8BSYnKpp070B6fE63V/lkPuKqrpvidcv6kz3INDBU/GE7K2Q0uw==", - "dependencies": { - "@stoplight/types": "^12.3.0", - "@stoplight/yaml": "^4.2.2", - "github-slugger": "^1.3.0", - "hast-util-whitespace": "^2.0.0", - "lodash": "^4.17.21", - "mdast-util-to-string": "^3.1.0", - "remark-frontmatter": "^3.0.0", - "remark-gfm": "^1.0.0", - "remark-parse": "^9.0.0", - "remark-stringify": "^9.0.1", - "tslib": "^2.3.0", - "unified": "^9.2.1", - "unist-util-select": "^4.0.0", - "unist-util-visit": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@stoplight/markdown-viewer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@stoplight/markdown-viewer/-/markdown-viewer-5.7.0.tgz", - "integrity": "sha512-SOFmEapj/RAJ6fUqgZO41diB9ocEFxhrSL7C8aJKNoYoHme0xxk5DK53DvFNBayEEXnf9e/YmKPfwJjFdKUilA==", - "dependencies": { - "@rehooks/component-size": "^1.0.3", - "@stoplight/markdown": "^3.1.3", - "@stoplight/react-error-boundary": "^2.0.0", - "deepmerge": "^4.2.2", - "hast-to-hyperscript": "^10.0.1", - "hast-util-raw": "7.0.0", - "hast-util-sanitize": "^4.0.0", - "hastscript": "^7.0.2", - "mdast-util-to-hast": "^11.1.1", - "remark-parse": "^9.0.0", - "unified": "^9.2.1", - "unist-builder": "^3.0.0", - "unist-util-select": "^4.0.1", - "unist-util-visit": "^3.1.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "@stoplight/mosaic": "^1.24.4", - "@stoplight/mosaic-code-viewer": "^1.24.4", - "react": ">=16.14", - "react-dom": ">=16.14" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/@stoplight/markdown-viewer/node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/mdast-util-from-markdown": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", - "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-string": "^2.0.0", - "micromark": "~2.11.0", - "parse-entities": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/micromark": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", - "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "debug": "^4.0.0", - "parse-entities": "^2.0.0" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/remark-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", - "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", - "dependencies": { - "mdast-util-from-markdown": "^0.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/unified": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", - "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", - "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dependencies": { - "@types/unist": "^2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown-viewer/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/@stoplight/types": { - "version": "12.5.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", - "integrity": "sha512-dwqYcDrGmEyUv5TWrDam5TGOxU72ufyQ7hnOIIDdmW5ezOwZaBFoR5XQ9AsH49w7wgvOqB2Bmo799pJPWnpCbg==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@stoplight/markdown/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@stoplight/markdown/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/@stoplight/markdown/node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/ccount": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@stoplight/markdown/node_modules/longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "dependencies": { - "repeat-string": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-find-and-replace": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", - "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", - "dependencies": { - "escape-string-regexp": "^4.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-from-markdown": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", - "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-string": "^2.0.0", - "micromark": "~2.11.0", - "parse-entities": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-from-markdown/node_modules/mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-frontmatter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz", - "integrity": "sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==", - "dependencies": { - "micromark-extension-frontmatter": "^0.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-gfm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", - "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", - "dependencies": { - "mdast-util-gfm-autolink-literal": "^0.1.0", - "mdast-util-gfm-strikethrough": "^0.2.0", - "mdast-util-gfm-table": "^0.1.0", - "mdast-util-gfm-task-list-item": "^0.1.0", - "mdast-util-to-markdown": "^0.6.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-gfm-autolink-literal": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", - "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", - "dependencies": { - "ccount": "^1.0.0", - "mdast-util-find-and-replace": "^1.1.0", - "micromark": "^2.11.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-gfm-strikethrough": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", - "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", - "dependencies": { - "mdast-util-to-markdown": "^0.6.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-gfm-table": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", - "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", - "dependencies": { - "markdown-table": "^2.0.0", - "mdast-util-to-markdown": "~0.6.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-gfm-task-list-item": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", - "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", - "dependencies": { - "mdast-util-to-markdown": "~0.6.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-to-markdown": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", - "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", - "dependencies": { - "@types/unist": "^2.0.0", - "longest-streak": "^2.0.0", - "mdast-util-to-string": "^2.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.0.0", - "zwitch": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/micromark": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", - "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "debug": "^4.0.0", - "parse-entities": "^2.0.0" - } - }, - "node_modules/@stoplight/markdown/node_modules/micromark-extension-frontmatter": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz", - "integrity": "sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==", - "dependencies": { - "fault": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/micromark-extension-gfm": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", - "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", - "dependencies": { - "micromark": "~2.11.0", - "micromark-extension-gfm-autolink-literal": "~0.5.0", - "micromark-extension-gfm-strikethrough": "~0.6.5", - "micromark-extension-gfm-table": "~0.4.0", - "micromark-extension-gfm-tagfilter": "~0.3.0", - "micromark-extension-gfm-task-list-item": "~0.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/micromark-extension-gfm-autolink-literal": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", - "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", - "dependencies": { - "micromark": "~2.11.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/micromark-extension-gfm-strikethrough": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", - "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", - "dependencies": { - "micromark": "~2.11.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/micromark-extension-gfm-table": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", - "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", - "dependencies": { - "micromark": "~2.11.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/micromark-extension-gfm-tagfilter": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", - "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/micromark-extension-gfm-task-list-item": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", - "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", - "dependencies": { - "micromark": "~2.11.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/remark-frontmatter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz", - "integrity": "sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==", - "dependencies": { - "mdast-util-frontmatter": "^0.2.0", - "micromark-extension-frontmatter": "^0.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/remark-gfm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", - "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", - "dependencies": { - "mdast-util-gfm": "^0.1.0", - "micromark-extension-gfm": "^0.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/remark-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", - "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", - "dependencies": { - "mdast-util-from-markdown": "^0.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/markdown/node_modules/unified": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", - "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", - "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dependencies": { - "@types/unist": "^2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/unist-util-visit/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/unist-util-visit/node_modules/unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@stoplight/markdown/node_modules/zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@stoplight/mosaic": { - "version": "1.53.2", - "resolved": "https://registry.npmjs.org/@stoplight/mosaic/-/mosaic-1.53.2.tgz", - "integrity": "sha512-fhSU1jqXLP3+9DghzrAHBgL+TfzaRDCwwg9+6Xe9Iz2LikOguAMPfBriantrtKOoM0pfUBOjHEuTO8QPw6uLKw==", - "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.1.1", - "@fortawesome/react-fontawesome": "^0.2.0", - "@react-hook/size": "^2.1.1", - "@react-hook/window-size": "^3.0.7", - "@react-types/button": "3.4.1", - "@react-types/radio": "3.1.2", - "@react-types/shared": "3.9.0", - "@react-types/switch": "3.1.2", - "@react-types/textfield": "3.3.0", - "@stoplight/types": "^13.7.0", - "@types/react": "^17.0.3", - "@types/react-dom": "^17.0.3", - "clsx": "^1.1.1", - "copy-to-clipboard": "^3.3.1", - "dom-helpers": "^3.3.1", - "lodash.get": "^4.4.2", - "nano-memoize": "^1.2.1", - "polished": "^4.1.3", - "react-fast-compare": "^3.2.0", - "react-overflow-list": "^0.5.0", - "ts-keycode-enum": "^1.0.6", - "tslib": "^2.1.0", - "use-resize-observer": "^9.0.2", - "zustand": "^3.5.2" - }, - "peerDependencies": { - "react": ">= 16.14" - } - }, - "node_modules/@stoplight/mosaic-code-viewer": { - "version": "1.53.2", - "resolved": "https://registry.npmjs.org/@stoplight/mosaic-code-viewer/-/mosaic-code-viewer-1.53.2.tgz", - "integrity": "sha512-BtiAfotKmy4TtwrXTD2ktruFEwTLPwW3wt/KUQAWpGnwmTcJ9cXph2hsskFKAt1G866UzsKE3OKOAIv9GKHOdQ==", - "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.1.1", - "@fortawesome/react-fontawesome": "^0.2.0", - "@react-hook/size": "^2.1.1", - "@react-hook/window-size": "^3.0.7", - "@react-types/radio": "3.1.2", - "@react-types/shared": "3.9.0", - "@react-types/switch": "3.1.2", - "@stoplight/mosaic": "1.53.2", - "@stoplight/types": "^13.7.0", - "clsx": "^1.1.1", - "copy-to-clipboard": "^3.3.1", - "dom-helpers": "^3.3.1", - "lodash.get": "^4.4.2", - "nano-memoize": "^1.2.1", - "polished": "^4.1.3", - "prism-react-renderer": "^1.2.1", - "prismjs": "^1.23.0", - "react-fast-compare": "^3.2.0", - "react-overflow-list": "^0.5.0", - "ts-keycode-enum": "^1.0.6", - "tslib": "^2.1.0", - "use-resize-observer": "^9.0.2", - "zustand": "^3.5.2" - }, - "peerDependencies": { - "react": ">= 16.14" - } - }, - "node_modules/@stoplight/mosaic-code-viewer/node_modules/@react-types/radio": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.1.2.tgz", - "integrity": "sha512-vkIic8abrVUyl/YjKU3yTVwn8QgebzuadfV89PsaKc3hdmSiHhDsln5wYsfWOEotqMwPrG1aEv9yRMYO78OQXQ==", - "dependencies": { - "@react-types/shared": "^3.8.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1" - } - }, - "node_modules/@stoplight/mosaic-code-viewer/node_modules/@react-types/shared": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.9.0.tgz", - "integrity": "sha512-YYksINfR6q92P10AhPEGo47Hd7oz1hrnZ6Vx8Gsrq62IbqDdv1XOTzPBaj17Z1ymNY2pitLUSEXsLmozt4wxxQ==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1" - } - }, - "node_modules/@stoplight/mosaic-code-viewer/node_modules/@react-types/switch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.1.2.tgz", - "integrity": "sha512-EaYWoLvUCpOnt//Ov8VBxOjbs4hBpYE/rBAzzIknXaFvKOu867iZBFL7FJbcemOgC8/dwyaj6GUZ1Gw3Z1g59w==", - "dependencies": { - "@react-types/checkbox": "^3.2.3", - "@react-types/shared": "^3.8.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1" - } - }, - "node_modules/@stoplight/mosaic-code-viewer/node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@stoplight/mosaic-code-viewer/node_modules/prism-react-renderer": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz", - "integrity": "sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==", - "peerDependencies": { - "react": ">=0.14.9" - } - }, - "node_modules/@stoplight/mosaic/node_modules/@react-types/button": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.4.1.tgz", - "integrity": "sha512-B54M84LxdEppwjXNlkBEJyMfe9fd+bvFV7R6+NJvupGrZm/LuFNYjFcHk7yjMKWTdWm6DbpIuQz54n5qTW7Vlg==", - "dependencies": { - "@react-types/shared": "^3.8.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1" - } - }, - "node_modules/@stoplight/mosaic/node_modules/@react-types/radio": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.1.2.tgz", - "integrity": "sha512-vkIic8abrVUyl/YjKU3yTVwn8QgebzuadfV89PsaKc3hdmSiHhDsln5wYsfWOEotqMwPrG1aEv9yRMYO78OQXQ==", - "dependencies": { - "@react-types/shared": "^3.8.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1" - } - }, - "node_modules/@stoplight/mosaic/node_modules/@react-types/shared": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.9.0.tgz", - "integrity": "sha512-YYksINfR6q92P10AhPEGo47Hd7oz1hrnZ6Vx8Gsrq62IbqDdv1XOTzPBaj17Z1ymNY2pitLUSEXsLmozt4wxxQ==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1" - } - }, - "node_modules/@stoplight/mosaic/node_modules/@react-types/switch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.1.2.tgz", - "integrity": "sha512-EaYWoLvUCpOnt//Ov8VBxOjbs4hBpYE/rBAzzIknXaFvKOu867iZBFL7FJbcemOgC8/dwyaj6GUZ1Gw3Z1g59w==", - "dependencies": { - "@react-types/checkbox": "^3.2.3", - "@react-types/shared": "^3.8.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1" - } - }, - "node_modules/@stoplight/mosaic/node_modules/@react-types/textfield": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.3.0.tgz", - "integrity": "sha512-lOf0tx3c3dVaomH/uvKpOKFVTXQ232kLnMhOJTtj97JDX7fTr3SNhDUV0G8Zf4M0vr+l+xkTrJkywYE23rzliw==", - "dependencies": { - "@react-types/shared": "^3.9.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1" - } - }, - "node_modules/@stoplight/mosaic/node_modules/@types/react": { - "version": "17.0.80", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.80.tgz", - "integrity": "sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "^0.16", - "csstype": "^3.0.2" - } - }, - "node_modules/@stoplight/mosaic/node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@stoplight/ordered-object-literal": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.5.tgz", - "integrity": "sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@stoplight/path": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz", - "integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@stoplight/react-error-boundary": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@stoplight/react-error-boundary/-/react-error-boundary-2.0.0.tgz", - "integrity": "sha512-r9cyaaH2h0kFe5c0aP+yJuY9CyXgfbBaMO6660M/wRQXqM49K5Ul7kexE4ei2cqYgo+Cd6ALl6RXSZFYwf2kCA==", - "dependencies": { - "@sentry/react": "^6.13.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, - "node_modules/@stoplight/types": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.20.0.tgz", - "integrity": "sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - }, - "engines": { - "node": "^12.20 || >=14.13" - } - }, - "node_modules/@stoplight/yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.3.0.tgz", - "integrity": "sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==", - "dependencies": { - "@stoplight/ordered-object-literal": "^1.0.5", - "@stoplight/types": "^14.1.1", - "@stoplight/yaml-ast-parser": "0.0.50", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=10.8" - } - }, - "node_modules/@stoplight/yaml-ast-parser": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.50.tgz", - "integrity": "sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==" - }, - "node_modules/@stoplight/yaml/node_modules/@stoplight/types": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-14.1.1.tgz", - "integrity": "sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - }, - "engines": { - "node": "^12.20 || >=14.13" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "dependencies": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "dependencies": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@swc/helpers": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz", - "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@tanstack/react-virtual": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz", - "integrity": "sha512-rtvo7KwuIvqK9zb0VZ5IL7fiJAEnG+0EiFZz8FUOs+2mhGqdGmjKIaT1XU7Zq0eFqL0jonLlhbayJI/J2SA/Bw==", - "dependencies": { - "@tanstack/virtual-core": "3.5.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@tanstack/virtual-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.0.tgz", - "integrity": "sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@types/d3-scale-chromatic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" - }, - "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" - }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", - "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", - "dependencies": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/js-cookie": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", - "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "node_modules/@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==" - }, - "node_modules/@types/mdx": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/parse5": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", - "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" - }, - "node_modules/@types/prismjs": { - "version": "1.26.4", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.4.tgz", - "integrity": "sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" - }, - "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "17.0.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.25.tgz", - "integrity": "sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA==", - "dependencies": { - "@types/react": "^17" - } - }, - "node_modules/@types/react-dom/node_modules/@types/react": { - "version": "17.0.80", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.80.tgz", - "integrity": "sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "^0.16", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-redux": { - "version": "7.1.33", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.33.tgz", - "integrity": "sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg==", - "dependencies": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-config": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/stylis": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", - "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", - "dev": true - }, - "node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xobotyi/scrollbar-width": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", - "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/algoliasearch": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", - "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-account": "4.24.0", - "@algolia/client-analytics": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-personalization": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/recommend": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/algoliasearch-helper": { - "version": "3.22.2", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.2.tgz", - "integrity": "sha512-3YQ6eo7uYOCHeQ2ZpD+OoT3aJJwMNKEnwtu8WMzm81XmBOSCwRjQditH9CeSOQ38qhHkuGw23pbq+kULkIJLcw==", - "dependencies": { - "@algolia/events": "^4.0.1" - }, - "peerDependencies": { - "algoliasearch": ">= 3.1 < 6" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.filter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.4.tgz", - "integrity": "sha512-r+mCJ7zXgXElgR4IRC+fkvNCeoaavWBs6EdCso5Tbcf+iEMKzBU/His60lt34WEZ9vlb8wDkZvQGcVI5GwkfoQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-array-method-boxes-properly": "^1.0.0", - "es-object-atoms": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "node_modules/astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/boxen": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^6.2.0", - "chalk": "^4.1.2", - "cli-boxes": "^3.0.0", - "string-width": "^5.0.1", - "type-fest": "^2.5.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", - "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", - "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.5", - "hash-base": "~3.0", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.7", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/browserify-sign/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/browserify-sign/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelize": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001640", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", - "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/canvas-embed": { - "version": "1.0.80", - "resolved": "https://registry.npmjs.org/canvas-embed/-/canvas-embed-1.0.80.tgz", - "integrity": "sha512-/ezY4LOQIS+tDUy7UI5sma7tMUgg4XEhvofFaKyxWY+aFslNCLh//XNtzUdze4kKygX33Eg+FvGQGxFu5hr4aQ==", - "dependencies": { - "@headlessui/react": "^2.0.4", - "chroma-js": "^2.4.2", - "dompurify": "^3.1.0", - "lodash": "^4.17.21", - "lodash.debounce": "^4.0.8", - "luxon": "^3.4.4", - "moment": "^2.29.4", - "moment-timezone": "^0.5.43", - "postcss": "^8.4.32", - "zustand": "^4.4.7" - }, - "peerDependencies": { - "react": "^18.3.1", - "react-dom": "^18.3.1" - } - }, - "node_modules/canvas-embed/node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/canvas-embed/node_modules/zustand": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz", - "integrity": "sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==", - "dependencies": { - "use-sync-external-store": "1.2.0" - }, - "engines": { - "node": ">=12.7.0" - }, - "peerDependencies": { - "@types/react": ">=16.8", - "immer": ">=9.0.6", - "react": ">=16.8" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - } - } - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/charset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/charset/-/charset-1.0.1.tgz", - "integrity": "sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chroma-js": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", - "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" - }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==" - }, - "node_modules/combine-promises": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/compute-gcd": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", - "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", - "dependencies": { - "validate.io-array": "^1.0.3", - "validate.io-function": "^1.0.2", - "validate.io-integer-array": "^1.0.0" - } - }, - "node_modules/compute-lcm": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", - "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", - "dependencies": { - "compute-gcd": "^1.2.1", - "validate.io-array": "^1.0.3", - "validate.io-function": "^1.0.2", - "validate.io-integer-array": "^1.0.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "dependencies": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/yeoman/configstore?sponsor=1" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==" - }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", - "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/cose-base": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", - "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", - "dependencies": { - "layout-base": "^1.0.0" - } - }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" - }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "dependencies": { - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-in-js-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", - "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", - "dependencies": { - "hyphenate-style-name": "^1.0.3" - } - }, - "node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "cssnano": "^6.0.1", - "jest-worker": "^29.4.3", - "postcss": "^8.4.24", - "schema-utils": "^4.0.1", - "serialize-javascript": "^6.0.1" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "lightningcss": { - "optional": true - } - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-selector-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", - "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" - }, - "node_modules/css-to-react-native": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", - "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", - "dev": true, - "dependencies": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", - "dependencies": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "dependencies": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "dependencies": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/cytoscape": { - "version": "3.30.0", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.0.tgz", - "integrity": "sha512-l590mjTHT6/Cbxp13dGPC2Y7VXdgc+rUeF8AnF/JPzhjNevbDJfObnJgaSjlldOgBQZbue+X6IUZ7r5GAgvauQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/cytoscape-cose-bilkent": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", - "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", - "dependencies": { - "cose-base": "^1.0.0" - }, - "peerDependencies": { - "cytoscape": "^3.2.0" - } - }, - "node_modules/d3": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", - "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", - "dependencies": { - "d3-array": "3", - "d3-axis": "3", - "d3-brush": "3", - "d3-chord": "3", - "d3-color": "3", - "d3-contour": "4", - "d3-delaunay": "6", - "d3-dispatch": "3", - "d3-drag": "3", - "d3-dsv": "3", - "d3-ease": "3", - "d3-fetch": "3", - "d3-force": "3", - "d3-format": "3", - "d3-geo": "3", - "d3-hierarchy": "3", - "d3-interpolate": "3", - "d3-path": "3", - "d3-polygon": "3", - "d3-quadtree": "3", - "d3-random": "3", - "d3-scale": "4", - "d3-scale-chromatic": "3", - "d3-selection": "3", - "d3-shape": "3", - "d3-time": "3", - "d3-time-format": "4", - "d3-timer": "3", - "d3-transition": "3", - "d3-zoom": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "dependencies": { - "internmap": "1 - 2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-axis": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-brush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "3", - "d3-transition": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-chord": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", - "dependencies": { - "d3-path": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-contour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", - "dependencies": { - "d3-array": "^3.2.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "dependencies": { - "delaunator": "5" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "dependencies": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" - }, - "bin": { - "csv2json": "bin/dsv2json.js", - "csv2tsv": "bin/dsv2dsv.js", - "dsv2dsv": "bin/dsv2dsv.js", - "dsv2json": "bin/dsv2json.js", - "json2csv": "bin/json2dsv.js", - "json2dsv": "bin/json2dsv.js", - "json2tsv": "bin/json2dsv.js", - "tsv2csv": "bin/dsv2dsv.js", - "tsv2json": "bin/dsv2json.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dsv/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", - "dependencies": { - "d3-dsv": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-geo": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", - "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", - "dependencies": { - "d3-array": "2.5.0 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-polygon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-sankey": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", - "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", - "dependencies": { - "d3-array": "1 - 2", - "d3-shape": "^1.2.0" - } - }, - "node_modules/d3-sankey/node_modules/d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "dependencies": { - "internmap": "^1.0.0" - } - }, - "node_modules/d3-sankey/node_modules/d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" - }, - "node_modules/d3-sankey/node_modules/d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "dependencies": { - "d3-path": "1" - } - }, - "node_modules/d3-sankey/node_modules/internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" - }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", - "dependencies": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-selection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "dependencies": { - "d3-array": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "dependencies": { - "d3-time": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-transition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "dependencies": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "d3-selection": "2 - 3" - } - }, - "node_modules/d3-zoom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/dagre-d3-es": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", - "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", - "dependencies": { - "d3": "^7.8.2", - "lodash-es": "^4.17.21" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" - }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decko": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz", - "integrity": "sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==", - "dev": true - }, - "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "devOptional": true - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", - "dependencies": { - "robust-predicates": "^3.0.2" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "node_modules/detect-port": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", - "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port-alt/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port-alt/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/discontinuous-range": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", - "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", - "dev": true, - "peer": true - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/docusaurus-plugin-openapi-docs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/docusaurus-plugin-openapi-docs/-/docusaurus-plugin-openapi-docs-3.0.1.tgz", - "integrity": "sha512-6SRqwey/TXMNu2G02mbWgxrifhpjGOjDr30N+58AR0Ytgc+HXMqlPAUIvTe+e7sOBfAtBbiNlmOWv5KSYIjf3w==", - "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.5.4", - "@docusaurus/plugin-content-docs": "^3.0.1", - "@docusaurus/utils": "^3.0.1", - "@docusaurus/utils-validation": "^3.0.1", - "@redocly/openapi-core": "^1.10.5", - "chalk": "^4.1.2", - "clsx": "^1.1.1", - "fs-extra": "^9.0.1", - "json-pointer": "^0.6.2", - "json-schema-merge-allof": "^0.8.1", - "json5": "^2.2.3", - "lodash": "^4.17.20", - "mustache": "^4.2.0", - "openapi-to-postmanv2": "^4.21.0", - "postman-collection": "^4.4.0", - "slugify": "^1.6.5", - "swagger2openapi": "^7.0.8", - "xml-formatter": "^2.6.1" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/docusaurus-plugin-openapi-docs/node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/docusaurus-plugin-openapi-docs/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/docusaurus-plugin-sass": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/docusaurus-plugin-sass/-/docusaurus-plugin-sass-0.2.5.tgz", - "integrity": "sha512-Z+D0fLFUKcFpM+bqSUmqKIU+vO+YF1xoEQh5hoFreg2eMf722+siwXDD+sqtwU8E4MvVpuvsQfaHwODNlxJAEg==", - "dependencies": { - "sass-loader": "^10.1.1" - }, - "peerDependencies": { - "@docusaurus/core": "^2.0.0-beta || ^3.0.0-alpha", - "sass": "^1.30.0" - } - }, - "node_modules/docusaurus-plugin-sass/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/docusaurus-plugin-sass/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/docusaurus-plugin-sass/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/docusaurus-plugin-sass/node_modules/sass-loader": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.5.2.tgz", - "integrity": "sha512-vMUoSNOUKJILHpcNCCyD23X34gve1TS7Rjd9uXHeKqhvBG39x6XbswFDtpbTElj6XdMFezoWhkh5vtKudf2cgQ==", - "dependencies": { - "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", - "sass": "^1.3.0", - "webpack": "^4.36.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/docusaurus-plugin-sass/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/docusaurus-plugin-sentry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/docusaurus-plugin-sentry/-/docusaurus-plugin-sentry-2.0.0.tgz", - "integrity": "sha512-LiiQ90pbaJ4ztgmFegK3+p8ywX4m0XHNtKGIRY1UD6xVRFubIejFFGaDXWOVU5FuATcMmE0d+WPNRPHLyYlFFw==", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@docusaurus/core": ">=3", - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/docusaurus-theme-openapi-docs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/docusaurus-theme-openapi-docs/-/docusaurus-theme-openapi-docs-3.0.1.tgz", - "integrity": "sha512-tqypV91tC3wuWj9O+4n0M/e5AgHOeMT2nvPj1tjlPkC7/dLinZvpwQStT4YDUPYSoHRseqxd7lhivFQHcmlryg==", - "dependencies": { - "@docusaurus/theme-common": "^3.0.1", - "@hookform/error-message": "^2.0.1", - "@reduxjs/toolkit": "^1.7.1", - "clsx": "^1.1.1", - "copy-text-to-clipboard": "^3.1.0", - "crypto-js": "^4.1.1", - "docusaurus-plugin-openapi-docs": "^3.0.1", - "docusaurus-plugin-sass": "^0.2.3", - "file-saver": "^2.0.5", - "lodash": "^4.17.20", - "node-polyfill-webpack-plugin": "^2.0.1", - "postman-code-generators": "^1.10.1", - "postman-collection": "^4.4.0", - "prism-react-renderer": "^2.3.0", - "react-hook-form": "^7.43.8", - "react-live": "^4.0.0", - "react-magic-dropzone": "^1.0.1", - "react-markdown": "^8.0.1", - "react-modal": "^3.15.1", - "react-redux": "^7.2.0", - "rehype-raw": "^6.1.1", - "sass": "^1.58.1", - "sass-loader": "^13.3.2", - "webpack": "^5.61.0", - "xml-formatter": "^2.6.1" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/hast-util-raw": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", - "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/rehype-raw": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", - "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", - "dependencies": { - "@types/hast": "^2.0.0", - "hast-util-raw": "^7.2.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", - "dependencies": { - "@types/unist": "^2.0.0", - "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/docusaurus-theme-openapi-docs/node_modules/vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", - "dependencies": { - "@babel/runtime": "^7.1.2" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domain-browser": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", - "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://bevry.me/fund" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/dompurify": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.5.tgz", - "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==" - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.816", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz", - "integrity": "sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==" - }, - "node_modules/elkjs": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", - "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" - }, - "node_modules/elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", - "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" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/emoticon": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", - "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/enzyme": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", - "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", - "dev": true, - "peer": true, - "dependencies": { - "array.prototype.flat": "^1.2.3", - "cheerio": "^1.0.0-rc.3", - "enzyme-shallow-equal": "^1.0.1", - "function.prototype.name": "^1.1.2", - "has": "^1.0.3", - "html-element-map": "^1.2.0", - "is-boolean-object": "^1.0.1", - "is-callable": "^1.1.5", - "is-number-object": "^1.0.4", - "is-regex": "^1.0.5", - "is-string": "^1.0.5", - "is-subset": "^0.1.1", - "lodash.escape": "^4.0.1", - "lodash.isequal": "^4.5.0", - "object-inspect": "^1.7.0", - "object-is": "^1.0.2", - "object.assign": "^4.1.0", - "object.entries": "^1.1.1", - "object.values": "^1.1.1", - "raf": "^3.4.1", - "rst-selector-parser": "^2.2.3", - "string.prototype.trim": "^1.2.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/enzyme-shallow-equal": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.7.tgz", - "integrity": "sha512-/um0GFqUXnpM9SvKtje+9Tjoz3f1fpBC3eXRFrNs8kpYn69JljciYP7KZTqM/YQbUY9KUjvKB4jo/q+L6WGGvg==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0", - "object-is": "^1.1.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "dependencies": { - "stackframe": "^1.3.4" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true, - "peer": true - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "peer": true, - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==" - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.6.0.tgz", - "integrity": "sha512-ElQkdLMEEqQNM9Njff+2Y4q2afHk7JpkPvrd7Xh7xefwgQynqPxwf55J7di9+MEibWUGdNjFF9ITG9Pck5M84w==", - "devOptional": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/config-array": "^0.17.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.6.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.1", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/eslint-scope": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz", - "integrity": "sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==", - "devOptional": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "devOptional": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "devOptional": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "devOptional": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "devOptional": true - }, - "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", - "devOptional": true, - "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "devOptional": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-value-to-estree": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", - "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "url": "https://github.com/eta-dev/eta?sponsor=1" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "dependencies": { - "@types/node": "*", - "require-like": ">= 0.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exenv": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", - "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" - }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/express/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "devOptional": true - }, - "node_modules/fast-loops": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.4.tgz", - "integrity": "sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg==" - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fast-shallow-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", - "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" - }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "dependencies": { - "punycode": "^1.3.2" - } - }, - "node_modules/fast-url-parser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/fastest-stable-stringify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", - "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/feed": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "dependencies": { - "xml-js": "^1.6.11" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "devOptional": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/file-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/file-loader/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/file-saver": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", - "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" - }, - "node_modules/file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dependencies": { - "micromatch": "^4.0.2" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "devOptional": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "devOptional": true - }, - "node_modules/fnv-plus": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/fnv-plus/-/fnv-plus-1.3.1.tgz", - "integrity": "sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw==" - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreach": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", - "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==" - }, - "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "engines": { - "node": ">= 14.17" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "node_modules/get-port-please": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-3.1.2.tgz", - "integrity": "sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==", - "dev": true - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", - "dependencies": { - "lodash": "^4.17.15" - } - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-color-material": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash-color-material/-/hash-color-material-1.1.3.tgz", - "integrity": "sha512-SkyBUHHWqaLI5+wUWvEcvy0i4bvf/lrr7xauh6LB7Z/gkD8dYoQpemNA42Zy3KZ970GuuUYL+txRn1B+Xgaf0g==" - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-to-hyperscript": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-10.0.3.tgz", - "integrity": "sha512-NuBoUStp4fRwmvlfbidlEiRSTk0gSHm+97q4Xn9CJ10HO+Py7nlTuDi6RhM1qLOureukGrCXLG7AAxaGqqyslQ==", - "dependencies": { - "@types/unist": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.1", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-to-hyperscript/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/hast-util-from-dom": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", - "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", - "dependencies": { - "@types/hast": "^3.0.0", - "hastscript": "^8.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-dom/node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-dom/node_modules/hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", - "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.1.0", - "hast-util-from-parse5": "^8.0.0", - "parse5": "^7.0.0", - "vfile": "^6.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html-isomorphic": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", - "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-from-dom": "^5.0.0", - "hast-util-from-html": "^2.0.0", - "unist-util-remove-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html/node_modules/hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html/node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html/node_modules/hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html/node_modules/vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", - "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "hastscript": "^7.0.0", - "property-information": "^6.0.0", - "vfile": "^5.0.0", - "vfile-location": "^4.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/hast-util-from-parse5/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/hast-util-from-parse5/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", - "dependencies": { - "@types/hast": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/hast-util-parse-selector/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/hast-util-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.0.0.tgz", - "integrity": "sha512-3UKuYgaqakZrY916JfQzqSk8xZGyxpj9zwfPB3MctXLDorPdyqk1QZGZoCEqU2LMIEzVXBZukAQs7aAH9TJPIw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "@types/unist": "^2.0.3", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^3.0.0", - "vfile": "^4.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/hast-util-raw/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/hast-util-raw/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/hast-util-raw/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dependencies": { - "@types/unist": "^2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-sanitize": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-4.1.0.tgz", - "integrity": "sha512-Hd9tU0ltknMGRDv+d6Ro/4XKzBqQnP/EZrpiTbpFYfXv/uOhWeKc+2uajcbEvAEH98VZd7eII2PiXm13RihnLw==", - "dependencies": { - "@types/hast": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-sanitize/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/hast-util-sanitize/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree/node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree/node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", - "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz", - "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", - "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", - "dependencies": { - "inline-style-parser": "0.2.3" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", - "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/hast-util-to-parse5/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/hast-util-to-text": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", - "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", - "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/hastscript/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "engines": { - "node": "*" - } - }, - "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-element-map": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.1.tgz", - "integrity": "sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==", - "dev": true, - "peer": true, - "dependencies": { - "array.prototype.filter": "^1.0.0", - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "engines": { - "node": ">=14" - } - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/html-void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", - "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/http-proxy/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/http-reasons": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/http-reasons/-/http-reasons-0.1.0.tgz", - "integrity": "sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ==" - }, - "node_modules/http2-client": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", - "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==" - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" - }, - "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", - "dev": true, - "bin": { - "husky": "bin.mjs" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/hyphenate-style-name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", - "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==" - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", - "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", - "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=16.x" - } - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/immutable": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", - "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/infima": { - "version": "0.2.0-alpha.43", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.43.tgz", - "integrity": "sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "node_modules/inline-style-prefixer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.0.tgz", - "integrity": "sha512-I7GEdScunP1dQ6IM2mQWh6v0mOYdYmH3Bp31UecKdrcUgcURTcctSe1IECdUznSHKSmsHtjrT3CwCPI1pyxfUQ==", - "dependencies": { - "css-in-js-utils": "^3.1.0", - "fast-loops": "^1.1.3" - } - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-subset": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", - "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==", - "dev": true, - "peer": true - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "node_modules/jackspeak": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/jotai": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/jotai/-/jotai-1.13.1.tgz", - "integrity": "sha512-RUmH1S4vLsG3V6fbGlKzGJnLrDcC/HNb5gH2AeA9DzuJknoVxSGvvg8OBB7lke+gDc4oXmdVsaKn/xDUhWZ0vw==", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@babel/core": "*", - "@babel/template": "*", - "jotai-devtools": "*", - "jotai-immer": "*", - "jotai-optics": "*", - "jotai-redux": "*", - "jotai-tanstack-query": "*", - "jotai-urql": "*", - "jotai-valtio": "*", - "jotai-xstate": "*", - "jotai-zustand": "*", - "react": ">=16.8" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@babel/template": { - "optional": true - }, - "jotai-devtools": { - "optional": true - }, - "jotai-immer": { - "optional": true - }, - "jotai-optics": { - "optional": true - }, - "jotai-redux": { - "optional": true - }, - "jotai-tanstack-query": { - "optional": true - }, - "jotai-urql": { - "optional": true - }, - "jotai-valtio": { - "optional": true - }, - "jotai-xstate": { - "optional": true - }, - "jotai-zustand": { - "optional": true - } - } - }, - "node_modules/js-cookie": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" - }, - "node_modules/js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-pointer": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.2.tgz", - "integrity": "sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==", - "dependencies": { - "foreach": "^2.0.4" - } - }, - "node_modules/json-schema-compare": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", - "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", - "dependencies": { - "lodash": "^4.17.4" - } - }, - "node_modules/json-schema-merge-allof": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", - "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", - "dependencies": { - "compute-lcm": "^1.1.2", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.20" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/json-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", - "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", - "dependencies": { - "call-bind": "^1.0.5", - "isarray": "^2.0.5", - "jsonify": "^0.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "devOptional": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/katex": { - "version": "0.16.11", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", - "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/khroma": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", - "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "dependencies": { - "package-json": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/launch-editor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", - "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/layout-base": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", - "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "devOptional": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/liquid-json": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/liquid-json/-/liquid-json-0.3.1.tgz", - "integrity": "sha512-wUayTU8MS827Dam6MxgD72Ui+KOSF+u/eIqpatOtjnvgJ0+mnDq33uC2M7J0tPK+upe/DpUAuK4JUU89iBoNKQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==", - "dev": true - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.escape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", - "integrity": "sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==", - "dev": true, - "peer": true - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true, - "peer": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "devOptional": true - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lowlight": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", - "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", - "dependencies": { - "fault": "^1.0.0", - "highlight.js": "~10.7.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", - "dev": true - }, - "node_modules/luxon": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", - "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/magic-error": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/magic-error/-/magic-error-0.0.1.tgz", - "integrity": "sha512-1+N1ET8cbC5bfLQZcRojClzgK2gbUt9keTMr9OJeuXnQKWsfwRRRICuMA3HKaCIXFEgKzxivuMGCNKD7cdU5pg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/mark.js": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", - "dev": true - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/markdown-to-jsx": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.4.7.tgz", - "integrity": "sha512-0+ls1IQZdU6cwM1yu0ZjjiVWYtkbExSyUIFU2ZeDIFuZM1W42Mh4OlJ4nb4apX4H8smxDHRdFaoIVJGwfv5hkg==", - "engines": { - "node": ">= 10" - }, - "peerDependencies": { - "react": ">= 0.14.0" - } - }, - "node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/mdast-util-definitions": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", - "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/mdast-util-definitions/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-math": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", - "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "longest-streak": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.1.0", - "unist-util-remove-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz", - "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-11.3.0.tgz", - "integrity": "sha512-4o3Cli3hXPmm1LhB+6rqhfsIUBjnKFlIUZvudaermXB+4/KONdd/W4saWWkC+LBLbPMqhFSSTSRgafHsT5fVJw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "@types/mdurl": "^1.0.0", - "mdast-util-definitions": "^5.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^3.0.0", - "unist-util-generated": "^2.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/mdast-util-to-hast/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/mdast-util-to-hast/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/mdast-util-to-hast/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast/node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.6.0.tgz", - "integrity": "sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ==", - "deprecated": "this will be v4", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", - "dev": true - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/mermaid": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.1.tgz", - "integrity": "sha512-Mx45Obds5W1UkW1nv/7dHRsbfMM1aOKA2+Pxs/IGHNonygDHwmng8xTHyS9z4KWVi0rbko8gjiBmuwwXQ7tiNA==", - "dependencies": { - "@braintree/sanitize-url": "^6.0.1", - "@types/d3-scale": "^4.0.3", - "@types/d3-scale-chromatic": "^3.0.0", - "cytoscape": "^3.28.1", - "cytoscape-cose-bilkent": "^4.1.0", - "d3": "^7.4.0", - "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.10", - "dayjs": "^1.11.7", - "dompurify": "^3.0.5", - "elkjs": "^0.9.0", - "katex": "^0.16.9", - "khroma": "^2.0.0", - "lodash-es": "^4.17.21", - "mdast-util-from-markdown": "^1.3.0", - "non-layered-tidy-tree-layout": "^2.0.2", - "stylis": "^4.1.3", - "ts-dedent": "^2.2.0", - "uuid": "^9.0.0", - "web-worker": "^1.2.0" - } - }, - "node_modules/mermaid/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/mermaid/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/mermaid/node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mermaid/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mermaid/node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/mermaid/node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/mermaid/node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/mermaid/node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mermaid/node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mermaid/node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/mermaid/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mermaid/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", - "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-math": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.0.0.tgz", - "integrity": "sha512-iJ2Q28vBoEovLN5o3GO12CpqorQRYDPT+p4zW50tGwTfJB+iv/VnB6Ini+gqa24K97DwptMBBIvVX6Bjk49oyQ==", - "dependencies": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", - "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-factory-space/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-character/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", - "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-format": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mime-format/-/mime-format-2.0.1.tgz", - "integrity": "sha512-XxU3ngPbEnrYnNbIX+lYSaYg0M01v6p2ntd2YaFksTu0vayaw5OJvbdRyWs07EYRlLED5qadUZ+xo+XhOvFhwg==", - "dependencies": { - "charset": "^1.0.0" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mobx": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.13.0.tgz", - "integrity": "sha512-1laWODrBWmB7mDJ8EClCjUQTyLwJ0ydJgE4FtK7t9r3JnjXgc9OhmYs2P4RtHrY1co5+4T6cKP2UswX2SU29mA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mobx" - } - }, - "node_modules/mobx-react": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.1.1.tgz", - "integrity": "sha512-gVV7AdSrAAxqXOJ2bAbGa5TkPqvITSzaPiiEkzpW4rRsMhSec7C2NBCJYILADHKp2tzOAIETGRsIY0UaCV5aEw==", - "dev": true, - "dependencies": { - "mobx-react-lite": "^4.0.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mobx" - }, - "peerDependencies": { - "mobx": "^6.9.0", - "react": "^16.8.0 || ^17 || ^18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/mobx-react-lite": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.0.7.tgz", - "integrity": "sha512-RjwdseshK9Mg8On5tyJZHtGD+J78ZnCnRaxeQDSiciKVQDUbfZcXhmld0VMxAwvcTnPEHZySGGewm467Fcpreg==", - "dev": true, - "dependencies": { - "use-sync-external-store": "^1.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mobx" - }, - "peerDependencies": { - "mobx": "^6.9.0", - "react": "^16.8.0 || ^17 || ^18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", - "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", - "dependencies": { - "moment": "^2.29.4" - }, - "engines": { - "node": "*" - } - }, - "node_modules/moo": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", - "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", - "dev": true, - "peer": true - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/mustache": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", - "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", - "bin": { - "mustache": "bin/mustache" - } - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nano-css": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.6.1.tgz", - "integrity": "sha512-T2Mhc//CepkTa3X4pUhKgbEheJHYAxD0VptuqFhDbGMUWVV2m+lkNiW/Ieuj35wrfC8Zm0l7HvssQh7zcEttSw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "css-tree": "^1.1.2", - "csstype": "^3.1.2", - "fastest-stable-stringify": "^2.0.2", - "inline-style-prefixer": "^7.0.0", - "rtl-css-js": "^1.16.1", - "stacktrace-js": "^2.0.2", - "stylis": "^4.3.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/nano-memoize": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/nano-memoize/-/nano-memoize-1.3.1.tgz", - "integrity": "sha512-wQiW3xHptgGlec/Zbo7oq6Zz4kKoK8TaIIs1irTO9iJOGTIG3lnQRUJfH73bJ/rn7MOE4sTdSU+ALPGEidaijQ==" - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "devOptional": true - }, - "node_modules/nearley": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", - "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", - "dev": true, - "peer": true, - "dependencies": { - "commander": "^2.19.0", - "moo": "^0.5.0", - "railroad-diagrams": "^1.0.0", - "randexp": "0.4.6" - }, - "bin": { - "nearley-railroad": "bin/nearley-railroad.js", - "nearley-test": "bin/nearley-test.js", - "nearley-unparse": "bin/nearley-unparse.js", - "nearleyc": "bin/nearleyc.js" - }, - "funding": { - "type": "individual", - "url": "https://nearley.js.org/#give-to-nearley" - } - }, - "node_modules/nearley/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch-h2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", - "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", - "dependencies": { - "http2-client": "^1.2.5" - }, - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-polyfill-webpack-plugin": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-2.0.1.tgz", - "integrity": "sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A==", - "dependencies": { - "assert": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.12.0", - "domain-browser": "^4.22.0", - "events": "^3.3.0", - "filter-obj": "^2.0.2", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^4.0.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "^0.0.1", - "type-fest": "^2.14.0", - "url": "^0.11.0", - "util": "^0.12.4", - "vm-browserify": "^1.1.2" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "webpack": ">=5" - } - }, - "node_modules/node-readfiles": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", - "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", - "dependencies": { - "es6-promise": "^3.2.1" - } - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" - }, - "node_modules/non-layered-tidy-tree-layout": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", - "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm-to-yarn": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/npm-to-yarn/-/npm-to-yarn-2.2.1.tgz", - "integrity": "sha512-O/j/ROyX0KGLG7O6Ieut/seQ0oiTpHF2tXAcFbpdTLQFiaNtkyTXXocM1fwpaa60dg1qpWj0nHlbNhx6qwuENQ==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/nebrelbug/npm-to-yarn?sponsor=1" - } - }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/oas-kit-common": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", - "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", - "dependencies": { - "fast-safe-stringify": "^2.0.7" - } - }, - "node_modules/oas-linter": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", - "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", - "dependencies": { - "@exodus/schemasafe": "^1.0.0-rc.2", - "should": "^13.2.1", - "yaml": "^1.10.0" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-resolver": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", - "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", - "dependencies": { - "node-fetch-h2": "^2.3.0", - "oas-kit-common": "^1.0.8", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - }, - "bin": { - "resolve": "resolve.js" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-resolver-browser": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver-browser/-/oas-resolver-browser-2.5.6.tgz", - "integrity": "sha512-Jw5elT/kwUJrnGaVuRWe1D7hmnYWB8rfDDjBnpQ+RYY/dzAewGXeTexXzt4fGEo6PUE4eqKqPWF79MZxxvMppA==", - "dependencies": { - "node-fetch-h2": "^2.3.0", - "oas-kit-common": "^1.0.8", - "path-browserify": "^1.0.1", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - }, - "bin": { - "resolve": "resolve.js" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-schema-walker": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", - "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-validator": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", - "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", - "dependencies": { - "call-me-maybe": "^1.0.1", - "oas-kit-common": "^1.0.8", - "oas-linter": "^3.2.2", - "oas-resolver": "^2.5.6", - "oas-schema-walker": "^1.1.5", - "reftools": "^1.1.9", - "should": "^13.2.1", - "yaml": "^1.10.0" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/openapi-sampler": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.5.1.tgz", - "integrity": "sha512-tIWIrZUKNAsbqf3bd9U1oH6JEXo8LNYuDlXw26By67EygpjT+ArFnsxxyTMjFWRfbqo5ozkvgSQDK69Gd8CddA==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.7", - "json-pointer": "0.6.2" - } - }, - "node_modules/openapi-to-postmanv2": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/openapi-to-postmanv2/-/openapi-to-postmanv2-4.21.0.tgz", - "integrity": "sha512-UyHf2xOjDfl4bIaYrUP6w4UiR894gsiOt1HR93cWOxv33Ucw4rGG0B6ewQczSGBpvFMgri+KSSykNEVjsmB55w==", - "dependencies": { - "ajv": "8.11.0", - "ajv-draft-04": "1.0.0", - "ajv-formats": "2.1.1", - "async": "3.2.4", - "commander": "2.20.3", - "graphlib": "2.1.8", - "js-yaml": "4.1.0", - "json-schema-merge-allof": "0.8.1", - "lodash": "4.17.21", - "oas-resolver-browser": "2.5.6", - "object-hash": "3.0.0", - "path-browserify": "1.0.1", - "postman-collection": "4.2.1", - "swagger2openapi": "7.0.8", - "traverse": "0.6.6", - "yaml": "1.10.2" - }, - "bin": { - "openapi2postmanv2": "bin/openapi2postmanv2.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/openapi-to-postmanv2/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/openapi-to-postmanv2/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/openapi-to-postmanv2/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/openapi-to-postmanv2/node_modules/postman-collection": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.2.1.tgz", - "integrity": "sha512-DFLt3/yu8+ldtOTIzmBUctoupKJBOVK4NZO0t68K2lIir9smQg7OdQTBjOXYy+PDh7u0pSDvD66tm93eBHEPHA==", - "dependencies": { - "@faker-js/faker": "5.5.3", - "file-type": "3.9.0", - "http-reasons": "0.1.0", - "iconv-lite": "0.6.3", - "liquid-json": "0.3.1", - "lodash": "4.17.21", - "mime-format": "2.0.1", - "mime-types": "2.1.35", - "postman-url-encoder": "3.0.5", - "semver": "7.5.4", - "uuid": "8.3.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/openapi-to-postmanv2/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/openapi-to-postmanv2/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/openapi-to-postmanv2/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "devOptional": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "dependencies": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", - "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", - "dependencies": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "hash-base": "~3.0", - "pbkdf2": "^3.1.2", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-numeric-range": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "ci-info": "^3.7.0", - "cross-spawn": "^7.0.3", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", - "json-stable-stringify": "^1.0.2", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^7.5.3", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^2.2.2" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "node": ">=14", - "npm": ">5" - } - }, - "node_modules/patch-package/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/patch-package/node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", - "dependencies": { - "process": "^0.11.1", - "util": "^0.10.3" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", - "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/path-to-regexp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/path/node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/perfect-scrollbar": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz", - "integrity": "sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g==", - "dev": true - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "peer": true - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/polished": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", - "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", - "dependencies": { - "@babel/runtime": "^7.17.8" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "colord": "^2.9.3", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-convert-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-comments": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-empty": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-loader": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", - "dependencies": { - "cosmiconfig": "^8.3.5", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-merge-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-rules": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", - "dependencies": { - "colord": "^2.9.3", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-params": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", - "dependencies": { - "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-string": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-ordered-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-sort-media-queries": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", - "dependencies": { - "sort-css-media-queries": "2.2.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.4.23" - } - }, - "node_modules/postcss-svgo": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - }, - "engines": { - "node": "^14 || ^16 || >= 18" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "node_modules/postcss-zindex": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postman-code-generators": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/postman-code-generators/-/postman-code-generators-1.10.1.tgz", - "integrity": "sha512-VGjqIFezG6tZRP3GvSbYjLDq3bQtXUeNDnBrN5CUIbgc9siu5Ubkva9hZnFpk+/qfi+PXs3CUR5mvV+WzpMhsg==", - "hasInstallScript": true, - "dependencies": { - "async": "3.2.2", - "lodash": "4.17.21", - "path": "0.12.7", - "postman-collection": "4.0.0", - "shelljs": "0.8.5" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/postman-code-generators/node_modules/async": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", - "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==" - }, - "node_modules/postman-code-generators/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postman-code-generators/node_modules/mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/postman-code-generators/node_modules/mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", - "dependencies": { - "mime-db": "1.48.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/postman-code-generators/node_modules/postman-collection": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.0.0.tgz", - "integrity": "sha512-vDrXG/dclSu6RMqPqBz4ZqoQBwcj/a80sJYsQZmzWJ6dWgXiudPhwu6Vm3C1Hy7zX5W8A6am1Z6vb/TB4eyURA==", - "dependencies": { - "faker": "5.5.3", - "file-type": "3.9.0", - "http-reasons": "0.1.0", - "iconv-lite": "0.6.3", - "liquid-json": "0.3.1", - "lodash": "4.17.21", - "mime-format": "2.0.1", - "mime-types": "2.1.31", - "postman-url-encoder": "3.0.1", - "semver": "7.3.5", - "uuid": "8.3.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postman-code-generators/node_modules/postman-url-encoder": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.1.tgz", - "integrity": "sha512-dMPqXnkDlstM2Eya+Gw4MIGWEan8TzldDcUKZIhZUsJ/G5JjubfQPhFhVWKzuATDMvwvrWbSjF+8VmAvbu6giw==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postman-code-generators/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postman-code-generators/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/postman-code-generators/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/postman-collection": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.4.0.tgz", - "integrity": "sha512-2BGDFcUwlK08CqZFUlIC8kwRJueVzPjZnnokWPtJCd9f2J06HBQpGL7t2P1Ud1NEsK9NHq9wdipUhWLOPj5s/Q==", - "dependencies": { - "@faker-js/faker": "5.5.3", - "file-type": "3.9.0", - "http-reasons": "0.1.0", - "iconv-lite": "0.6.3", - "liquid-json": "0.3.1", - "lodash": "4.17.21", - "mime-format": "2.0.1", - "mime-types": "2.1.35", - "postman-url-encoder": "3.0.5", - "semver": "7.5.4", - "uuid": "8.3.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postman-collection/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postman-collection/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postman-collection/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/postman-collection/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/postman-url-encoder": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.5.tgz", - "integrity": "sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "devOptional": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/prism-react-renderer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", - "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", - "dependencies": { - "@types/prismjs": "^1.26.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.0.0" - } - }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/property-information": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", - "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", - "dependencies": { - "escape-goat": "^4.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/qs": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz", - "integrity": "sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dependencies": { - "inherits": "~2.0.3" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "dev": true, - "peer": true, - "dependencies": { - "performance-now": "^2.1.0" - } - }, - "node_modules/railroad-diagrams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", - "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==", - "dev": true, - "peer": true - }, - "node_modules/randexp": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", - "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", - "dev": true, - "peer": true, - "dependencies": { - "discontinuous-range": "1.0.0", - "ret": "~0.1.10" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/react-dev-utils/node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" - }, - "node_modules/react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-hook-form": { - "version": "7.52.1", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.1.tgz", - "integrity": "sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==", - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-hook-form" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17 || ^18 || ^19" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/react-json-view-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.4.0.tgz", - "integrity": "sha512-wh6F6uJyYAmQ4fK0e8dSQMEWuvTs2Wr3el3sLD9bambX1+pSWUVXIz1RFaoy3TI1mZ0FqdpKq9YgbgTTgyrmXA==", - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "node_modules/react-live": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/react-live/-/react-live-4.1.7.tgz", - "integrity": "sha512-NTzl0POOAW3dkp7+QL30duOrIu2Vzf2LHdx4TaQ0BqOAtQcSTKEXujfm9jR2VoCHko0oi35PYp38yKQBXz4mrg==", - "dependencies": { - "prism-react-renderer": "^2.0.6", - "sucrase": "^3.31.0", - "use-editable": "^2.3.3" - }, - "engines": { - "node": ">= 0.12.0", - "npm": ">= 2.0.0" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/react-loadable": { - "name": "@docusaurus/react-loadable", - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", - "dependencies": { - "@types/react": "*" - }, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "dependencies": { - "@babel/runtime": "^7.10.3" - }, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "react-loadable": "*", - "webpack": ">=4.41.1 || 5.x" - } - }, - "node_modules/react-magic-dropzone": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-magic-dropzone/-/react-magic-dropzone-1.0.1.tgz", - "integrity": "sha512-0BIROPARmXHpk4AS3eWBOsewxoM5ndk2psYP/JmbCq8tz3uR2LIV1XiroZ9PKrmDRMctpW+TvsBCtWasuS8vFA==" - }, - "node_modules/react-markdown": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz", - "integrity": "sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/prop-types": "^15.0.0", - "@types/unist": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^2.0.0", - "prop-types": "^15.0.0", - "property-information": "^6.0.0", - "react-is": "^18.0.0", - "remark-parse": "^10.0.0", - "remark-rehype": "^10.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unified": "^10.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "node_modules/react-markdown/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/react-markdown/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/react-markdown/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/react-markdown/node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/mdast-util-to-hast": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", - "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-definitions": "^5.0.0", - "micromark-util-sanitize-uri": "^1.1.0", - "trim-lines": "^3.0.0", - "unist-util-generated": "^2.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/react-markdown/node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/react-markdown/node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/react-markdown/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/react-markdown/node_modules/remark-parse": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", - "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/remark-rehype": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", - "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-to-hast": "^12.1.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", - "dependencies": { - "@types/unist": "^2.0.0", - "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-markdown/node_modules/vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-modal": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.1.tgz", - "integrity": "sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==", - "dependencies": { - "exenv": "^1.2.0", - "prop-types": "^15.7.2", - "react-lifecycles-compat": "^3.0.0", - "warning": "^4.0.3" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "react": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18", - "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18" - } - }, - "node_modules/react-overflow-list": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/react-overflow-list/-/react-overflow-list-0.5.0.tgz", - "integrity": "sha512-+UegukgQ10E4ll3txz4DJyrnCgZ3eDVuv5dvR8ziyG5FfgCDZcUKeKhIgbU90oyqQa21aH4oLOoGKt0TiYJRmg==", - "dependencies": { - "react-use": "^17.3.1" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=16" - } - }, - "node_modules/react-player": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.16.0.tgz", - "integrity": "sha512-mAIPHfioD7yxO0GNYVFD1303QFtI3lyyQZLY229UEAp/a10cSW+hPcakg0Keq8uWJxT2OiT/4Gt+Lc9bD6bJmQ==", - "dev": true, - "dependencies": { - "deepmerge": "^4.0.0", - "load-script": "^1.0.0", - "memoize-one": "^5.1.1", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.0.1" - }, - "peerDependencies": { - "react": ">=16.6.0" - } - }, - "node_modules/react-redux": { - "version": "7.2.9", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", - "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - }, - "peerDependencies": { - "react": "^16.8.3 || ^17 || ^18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/react-redux/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "node_modules/react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router-config": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "dependencies": { - "@babel/runtime": "^7.1.2" - }, - "peerDependencies": { - "react": ">=15", - "react-router": ">=5" - } - }, - "node_modules/react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/react-shallow-renderer": { - "version": "16.15.0", - "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", - "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-syntax-highlighter": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", - "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "highlight.js": "^10.4.1", - "lowlight": "^1.17.0", - "prismjs": "^1.27.0", - "refractor": "^3.6.0" - }, - "peerDependencies": { - "react": ">= 0.14.0" - } - }, - "node_modules/react-tabs": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.0.2.tgz", - "integrity": "sha512-aQXTKolnM28k3KguGDBSAbJvcowOQr23A+CUJdzJtOSDOtTwzEaJA+1U4KwhNL9+Obe+jFS7geuvA7ICQPXOnQ==", - "dev": true, - "dependencies": { - "clsx": "^2.0.0", - "prop-types": "^15.5.0" - }, - "peerDependencies": { - "react": "^18.0.0" - } - }, - "node_modules/react-universal-interface": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", - "integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==", - "peerDependencies": { - "react": "*", - "tslib": "*" - } - }, - "node_modules/react-use": { - "version": "17.5.0", - "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.5.0.tgz", - "integrity": "sha512-PbfwSPMwp/hoL847rLnm/qkjg3sTRCvn6YhUZiHaUa3FA6/aNoFX79ul5Xt70O1rK+9GxSVqkY0eTwMdsR/bWg==", - "dependencies": { - "@types/js-cookie": "^2.2.6", - "@xobotyi/scrollbar-width": "^1.9.5", - "copy-to-clipboard": "^3.3.1", - "fast-deep-equal": "^3.1.3", - "fast-shallow-equal": "^1.0.0", - "js-cookie": "^2.2.1", - "nano-css": "^5.6.1", - "react-universal-interface": "^0.6.2", - "resize-observer-polyfill": "^1.5.1", - "screenfull": "^5.1.0", - "set-harmonic-interval": "^1.0.1", - "throttle-debounce": "^3.0.1", - "ts-easing": "^0.2.0", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reading-time": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/redoc": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.1.5.tgz", - "integrity": "sha512-POSbVg+7WLf+/5/c6GWLxL7+9t2D+1WlZdLN0a6qaCQc+ih3XYzteRBkXEN5kjrYrRNjdspfxTZkDLN5WV3Tzg==", - "dev": true, - "dependencies": { - "@cfaester/enzyme-adapter-react-18": "^0.8.0", - "@redocly/openapi-core": "^1.4.0", - "classnames": "^2.3.2", - "decko": "^1.2.0", - "dompurify": "^3.0.6", - "eventemitter3": "^5.0.1", - "json-pointer": "^0.6.2", - "lunr": "^2.3.9", - "mark.js": "^8.11.1", - "marked": "^4.3.0", - "mobx-react": "^9.1.1", - "openapi-sampler": "^1.5.0", - "path-browserify": "^1.0.1", - "perfect-scrollbar": "^1.5.5", - "polished": "^4.2.2", - "prismjs": "^1.29.0", - "prop-types": "^15.8.1", - "react-tabs": "^6.0.2", - "slugify": "~1.4.7", - "stickyfill": "^1.1.1", - "swagger2openapi": "^7.0.8", - "url-template": "^2.0.8" - }, - "engines": { - "node": ">=6.9", - "npm": ">=3.0.0" - }, - "peerDependencies": { - "core-js": "^3.1.4", - "mobx": "^6.0.4", - "react": "^16.8.4 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0", - "styled-components": "^4.1.1 || ^5.1.1 || ^6.0.5" - } - }, - "node_modules/redoc/node_modules/slugify": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz", - "integrity": "sha512-tf+h5W1IrjNm/9rKKj0JU2MDMruiopx0jjVA5zCdBtcGjfp0+c5rHw/zADLC3IeKlGHtVbHtpfzvYA0OYT+HKg==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "dependencies": { - "@babel/runtime": "^7.9.2" - } - }, - "node_modules/redux-thunk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", - "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", - "peerDependencies": { - "redux": "^4" - } - }, - "node_modules/refractor": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", - "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", - "dependencies": { - "hastscript": "^6.0.0", - "parse-entities": "^2.0.0", - "prismjs": "~1.27.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/refractor/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/refractor/node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/refractor/node_modules/hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/refractor/node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/prismjs": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", - "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/refractor/node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "dependencies": { - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/reftools": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", - "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "dependencies": { - "rc": "1.2.8" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/rehype-katex": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz", - "integrity": "sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/katex": "^0.16.0", - "hast-util-from-html-isomorphic": "^2.0.0", - "hast-util-to-text": "^4.0.0", - "katex": "^0.16.0", - "unist-util-visit-parents": "^6.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/hast-util-raw": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", - "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/rehype-raw/node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remark-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", - "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-emoji": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", - "dependencies": { - "@types/mdast": "^4.0.2", - "emoticon": "^4.0.1", - "mdast-util-find-and-replace": "^3.0.1", - "node-emoji": "^2.1.0", - "unified": "^11.0.4" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm/node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-math": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", - "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-math": "^3.0.0", - "micromark-extension-math": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", - "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", - "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", - "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", - "dependencies": { - "mdast-util-to-markdown": "^0.6.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/remark-stringify/node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/mdast-util-to-markdown": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", - "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", - "dependencies": { - "@types/unist": "^2.0.0", - "longest-streak": "^2.0.0", - "mdast-util-to-string": "^2.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.0.0", - "zwitch": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify/node_modules/mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify/node_modules/parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-stringify/node_modules/zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/renderkid/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/renderkid/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", - "engines": { - "node": "*" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/reselect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", - "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" - }, - "node_modules/resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" - }, - "node_modules/rst-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", - "integrity": "sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==", - "dev": true, - "peer": true, - "dependencies": { - "lodash.flattendeep": "^4.4.0", - "nearley": "^2.7.10" - } - }, - "node_modules/rtl-css-js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", - "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", - "dependencies": { - "@babel/runtime": "^7.1.2" - } - }, - "node_modules/rtl-detect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", - "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" - }, - "node_modules/rtlcss": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", - "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0", - "postcss": "^8.4.21", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "rtlcss": "bin/rtlcss.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" - }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sass": { - "version": "1.77.6", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", - "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", - "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-loader": { - "version": "13.3.3", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz", - "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==", - "dependencies": { - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/screenfull": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", - "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/search-insights": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.15.0.tgz", - "integrity": "sha512-ch2sPCUDD4sbPQdknVl9ALSi9H7VyoeVbsxznYz6QV55jJ8CI3EtwpO1i84keN4+hF5IeHWIeGvc08530JkVXQ==", - "peer": true - }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/send/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-handler": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - } - }, - "node_modules/serve-handler/node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-handler/node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-harmonic-interval": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", - "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==", - "engines": { - "node": ">=6.9" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", - "dependencies": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" - } - }, - "node_modules/should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", - "dependencies": { - "should-type": "^1.4.0" - } - }, - "node_modules/should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", - "dependencies": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "node_modules/should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==" - }, - "node_modules/should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "dependencies": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "node_modules/should-util": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==" - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/simple-websocket": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/simple-websocket/-/simple-websocket-9.1.0.tgz", - "integrity": "sha512-8MJPnjRN6A8UCp1I+H/dSFyjwJhp6wta4hsVRhjf8w9qBHRzxYt14RaOcjvQnhD1N4yKOddEjflwMnQM4VtXjQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "debug": "^4.3.1", - "queue-microtask": "^1.2.2", - "randombytes": "^2.1.0", - "readable-stream": "^3.6.0", - "ws": "^7.4.2" - } - }, - "node_modules/simple-websocket/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/sitemap": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", - "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "bin": { - "sitemap": "dist/cli.js" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=5.6.0" - } - }, - "node_modules/sitemap/node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "node_modules/skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/slugify": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", - "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sockjs/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/sort-css-media-queries": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", - "engines": { - "node": ">= 6.3.0" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/spdy-transport/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stack-generator": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", - "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", - "dependencies": { - "stackframe": "^1.3.4" - } - }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" - }, - "node_modules/stacktrace-gps": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", - "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", - "dependencies": { - "source-map": "0.5.6", - "stackframe": "^1.3.4" - } - }, - "node_modules/stacktrace-gps/node_modules/source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stacktrace-js": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", - "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", - "dependencies": { - "error-stack-parser": "^2.0.6", - "stack-generator": "^2.0.5", - "stacktrace-gps": "^3.0.4" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" - }, - "node_modules/stickyfill": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stickyfill/-/stickyfill-1.1.1.tgz", - "integrity": "sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA==", - "dev": true - }, - "node_modules/stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dependencies": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "node_modules/stream-browserify/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/styled-components": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.11.tgz", - "integrity": "sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA==", - "dev": true, - "dependencies": { - "@emotion/is-prop-valid": "1.2.2", - "@emotion/unitless": "0.8.1", - "@types/stylis": "4.2.5", - "css-to-react-native": "3.2.0", - "csstype": "3.1.3", - "postcss": "8.4.38", - "shallowequal": "1.1.0", - "stylis": "4.3.2", - "tslib": "2.6.2" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/styled-components" - }, - "peerDependencies": { - "react": ">= 16.8.0", - "react-dom": ">= 16.8.0" - } - }, - "node_modules/styled-components/node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/styled-components/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, - "node_modules/stylehacks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/stylis": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/sucrase/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/sucrase/node_modules/glob": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sucrase/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/svgo/node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/svgo/node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" - }, - "node_modules/swagger2openapi": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", - "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", - "dependencies": { - "call-me-maybe": "^1.0.1", - "node-fetch": "^2.6.1", - "node-fetch-h2": "^2.3.0", - "node-readfiles": "^0.2.0", - "oas-kit-common": "^1.0.8", - "oas-resolver": "^2.5.6", - "oas-schema-walker": "^1.1.5", - "oas-validator": "^5.0.8", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - }, - "bin": { - "boast": "boast.js", - "oas-validate": "oas-validate.js", - "swagger2openapi": "swagger2openapi.js" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/tabbable": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", - "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/throttle-debounce": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", - "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", - "engines": { - "node": ">=6.10" - } - }, - "node_modules/ts-easing": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", - "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==" - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" - }, - "node_modules/ts-keycode-enum": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/ts-keycode-enum/-/ts-keycode-enum-1.0.6.tgz", - "integrity": "sha512-DF8+Cf/FJJnPRxwz8agCoDelQXKZWQOS/gnnwx01nZ106tPJdB3BgJ9QTtLwXgR82D8O+nTjuZzWgf0Rg4vuRA==" - }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "devOptional": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/uglify-js": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", - "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "dependencies": { - "crypto-random-string": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unist-builder": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-3.0.1.tgz", - "integrity": "sha512-gnpOw7DIpCA0vpr6NqdPvTWnlPTApCTRzr+38E6hCWx3rz/cjo83SsKIlS1Z+L5ttScQ2AwutNnb8+tAvpb6qQ==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-builder/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-generated": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", - "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", - "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-select": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-4.0.3.tgz", - "integrity": "sha512-1074+K9VyR3NyUz3lgNtHKm7ln+jSZXtLJM4E22uVuoFn88a/Go2pX8dusrt/W+KWH1ncn8jcd8uCQuvXb/fXA==", - "dependencies": { - "@types/unist": "^2.0.0", - "css-selector-parser": "^1.0.0", - "nth-check": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-select/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/update-notifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", - "dependencies": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", - "configstore": "^6.0.0", - "has-yarn": "^3.0.0", - "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", - "is-installed-globally": "^0.4.0", - "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", - "latest-version": "^7.0.0", - "pupa": "^3.1.0", - "semver": "^7.3.7", - "semver-diff": "^4.0.0", - "xdg-basedir": "^5.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - } - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/url-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/url-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/url-loader/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", - "dev": true - }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/use-editable": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/use-editable/-/use-editable-2.3.3.tgz", - "integrity": "sha512-7wVD2JbfAFJ3DK0vITvXBdpd9JAz5BcKAAolsnLBuBn6UDDwBGuCIAGvR3yA2BNKm578vAMVHFCWaOcA+BhhiA==", - "peerDependencies": { - "react": ">= 16.8.0" - } - }, - "node_modules/use-resize-observer": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz", - "integrity": "sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==", - "dependencies": { - "@juggle/resize-observer": "^3.3.1" - }, - "peerDependencies": { - "react": "16.8.0 - 18", - "react-dom": "16.8.0 - 18" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "dev": true, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "node_modules/utility-types": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/uvu": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", - "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", - "dependencies": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - }, - "bin": { - "uvu": "bin.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/uvu/node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/validate.io-array": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", - "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==" - }, - "node_modules/validate.io-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", - "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" - }, - "node_modules/validate.io-integer": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", - "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", - "dependencies": { - "validate.io-number": "^1.0.3" - } - }, - "node_modules/validate.io-integer-array": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", - "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", - "dependencies": { - "validate.io-array": "^1.0.3", - "validate.io-integer": "^1.0.4" - } - }, - "node_modules/validate.io-number": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", - "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" - }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", - "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", - "dependencies": { - "@types/unist": "^2.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/vfile-location/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location/node_modules/vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location/node_modules/vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, - "node_modules/warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/web-worker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", - "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "node_modules/webpack-dev-middleware/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "node_modules/webpack-dev-server/node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/webpack/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpackbar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", - "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.3", - "pretty-time": "^1.1.0", - "std-env": "^3.0.1" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "webpack": "3 || 4 || 5" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" - }, - "node_modules/wolfy87-eventemitter": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz", - "integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==" - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "devOptional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xml-formatter": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.1.tgz", - "integrity": "sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==", - "dependencies": { - "xml-parser-xo": "^3.2.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/xml-js": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "dependencies": { - "sax": "^1.2.4" - }, - "bin": { - "xml-js": "bin/cli.js" - } - }, - "node_modules/xml-parser-xo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.2.0.tgz", - "integrity": "sha512-8LRU6cq+d7mVsoDaMhnkkt3CTtAs4153p49fRo+HIB3I1FD1o5CeXRjRH29sQevIfVJIcPjKSsPU/+Ujhq09Rg==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yaml-ast-parser": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==" - }, - "node_modules/yargs": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", - "integrity": "sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yarn": { - "version": "1.22.22", - "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.22.tgz", - "integrity": "sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==", - "hasInstallScript": true, - "bin": { - "yarn": "bin/yarn.js", - "yarnpkg": "bin/yarn.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zustand": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", - "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", - "engines": { - "node": ">=12.7.0" - }, - "peerDependencies": { - "react": ">=16.8" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - } - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - }, - "dependencies": { - "@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", - "requires": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", - "requires": { - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", - "requires": { - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", - "requires": {} - }, - "@algolia/cache-browser-local-storage": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", - "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", - "requires": { - "@algolia/cache-common": "4.24.0" - } - }, - "@algolia/cache-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", - "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" - }, - "@algolia/cache-in-memory": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", - "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", - "requires": { - "@algolia/cache-common": "4.24.0" - } - }, - "@algolia/client-account": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", - "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/client-analytics": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", - "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "requires": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/client-personalization": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", - "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/events": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" - }, - "@algolia/logger-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", - "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" - }, - "@algolia/logger-console": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", - "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", - "requires": { - "@algolia/logger-common": "4.24.0" - } - }, - "@algolia/recommend": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", - "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", - "requires": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "requires": { - "@algolia/requester-common": "4.24.0" - } - }, - "@algolia/requester-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", - "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" - }, - "@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "requires": { - "@algolia/requester-common": "4.24.0" - } - }, - "@algolia/transporter": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", - "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", - "requires": { - "@algolia/cache-common": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/requester-common": "4.24.0" - } - }, - "@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@apidevtools/json-schema-ref-parser": { - "version": "11.6.4", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz", - "integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==", - "requires": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.15", - "js-yaml": "^4.1.0" - } - }, - "@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "requires": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - } - }, - "@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==" - }, - "@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "requires": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "requires": { - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "requires": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", - "requires": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "requires": { - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "requires": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "requires": { - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", - "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "requires": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", - "requires": { - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" - } - }, - "@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", - "requires": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" - } - }, - "@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", - "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "requires": { - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" - }, - "@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" - }, - "@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==" - }, - "@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", - "requires": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "requires": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "requires": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" - }, - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", - "requires": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" - } - }, - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", - "requires": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "requires": {} - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", - "requires": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", - "requires": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", - "requires": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", - "requires": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", - "requires": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", - "requires": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", - "requires": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", - "requires": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" - } - }, - "@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-react-constant-elements": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.7.tgz", - "integrity": "sha512-7LidzZfUXyfZ8/buRW6qIIHBY8wAZ1OrY9c/wTr8YhZ6vMPo+Uc/CVFLYY1spZrEQlD4w5u8wjqk5NQ3OVqQKA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", - "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", - "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", - "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", - "requires": { - "@babel/plugin-transform-react-jsx": "^7.24.7" - } - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", - "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "regenerator-transform": "^0.15.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", - "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", - "requires": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", - "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - } - }, - "@babel/preset-env": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", - "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", - "requires": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.7", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.24.7", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.24.7", - "@babel/plugin-transform-class-properties": "^7.24.7", - "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.7", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.7", - "@babel/plugin-transform-dotall-regex": "^7.24.7", - "@babel/plugin-transform-duplicate-keys": "^7.24.7", - "@babel/plugin-transform-dynamic-import": "^7.24.7", - "@babel/plugin-transform-exponentiation-operator": "^7.24.7", - "@babel/plugin-transform-export-namespace-from": "^7.24.7", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.24.7", - "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.24.7", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-member-expression-literals": "^7.24.7", - "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-modules-systemjs": "^7.24.7", - "@babel/plugin-transform-modules-umd": "^7.24.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-new-target": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-object-super": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-property-literals": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-reserved-words": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.7", - "@babel/plugin-transform-unicode-escapes": "^7.24.7", - "@babel/plugin-transform-unicode-property-regex": "^7.24.7", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-react": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", - "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-transform-react-display-name": "^7.24.7", - "@babel/plugin-transform-react-jsx": "^7.24.7", - "@babel/plugin-transform-react-jsx-development": "^7.24.7", - "@babel/plugin-transform-react-pure-annotations": "^7.24.7" - } - }, - "@babel/preset-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7" - } - }, - "@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, - "@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", - "requires": { - "regenerator-runtime": "^0.14.0" - } - }, - "@babel/runtime-corejs3": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.7.tgz", - "integrity": "sha512-eytSX6JLBY6PVAeQa2bFlDx/7Mmln/gaEpsit5a3WEvjGfiIytEsgAwuIXCPM0xvw0v0cJn3ilq0/TvXrW0kgA==", - "requires": { - "core-js-pure": "^3.30.2", - "regenerator-runtime": "^0.14.0" - } - }, - "@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "requires": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "requires": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "requires": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - } - }, - "@braintree/sanitize-url": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", - "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" - }, - "@cfaester/enzyme-adapter-react-18": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cfaester/enzyme-adapter-react-18/-/enzyme-adapter-react-18-0.8.0.tgz", - "integrity": "sha512-3Z3ThTUouHwz8oIyhTYQljEMNRFtlVyc3VOOHCbxs47U6cnXs8K9ygi/c1tv49s7MBlTXeIcuN+Ttd9aPtILFQ==", - "dev": true, - "requires": { - "enzyme-shallow-equal": "^1.0.0", - "function.prototype.name": "^1.1.6", - "has": "^1.0.4", - "react-is": "^18.2.0", - "react-shallow-renderer": "^16.15.0" - } - }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "optional": true - }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" - }, - "@docsearch/css": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.0.tgz", - "integrity": "sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==" - }, - "@docsearch/react": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.0.tgz", - "integrity": "sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==", - "requires": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.6.0", - "algoliasearch": "^4.19.1" - } - }, - "@docusaurus/core": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.4.0.tgz", - "integrity": "sha512-g+0wwmN2UJsBqy2fQRQ6fhXruoEa62JDeEa5d8IdTJlMoaDaEDfHh7WjwGRn4opuTQWpjAwP/fbcgyHKlE+64w==", - "requires": { - "@babel/core": "^7.23.3", - "@babel/generator": "^7.23.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/preset-react": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "@babel/runtime": "^7.22.6", - "@babel/runtime-corejs3": "^7.22.6", - "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "autoprefixer": "^10.4.14", - "babel-loader": "^9.1.3", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.2", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.31.1", - "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^5.0.1", - "cssnano": "^6.1.2", - "del": "^6.1.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "eval": "^0.1.8", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "html-minifier-terser": "^7.2.0", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.5.3", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.7.6", - "p-map": "^4.0.0", - "postcss": "^8.4.26", - "postcss-loader": "^7.3.3", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "rtl-detect": "^1.0.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.5", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "url-loader": "^4.1.1", - "webpack": "^5.88.1", - "webpack-bundle-analyzer": "^4.9.0", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.9.0", - "webpackbar": "^5.0.2" - } - }, - "@docusaurus/cssnano-preset": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.4.0.tgz", - "integrity": "sha512-qwLFSz6v/pZHy/UP32IrprmH5ORce86BGtN0eBtG75PpzQJAzp9gefspox+s8IEOr0oZKuQ/nhzZ3xwyc3jYJQ==", - "requires": { - "cssnano-preset-advanced": "^6.1.2", - "postcss": "^8.4.38", - "postcss-sort-media-queries": "^5.2.0", - "tslib": "^2.6.0" - } - }, - "@docusaurus/eslint-plugin": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/eslint-plugin/-/eslint-plugin-3.4.0.tgz", - "integrity": "sha512-3Y9SwkxwY36TmsvZGyLZepifHbXIjZHMEFGuPcvtkFNnVgFIUkoAkf17GfwKKHnAloYVG/hpLV1m8q2BVKSLNQ==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "^5.62.0", - "tslib": "^2.6.0" - }, - "dependencies": { - "@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "@docusaurus/logger": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.4.0.tgz", - "integrity": "sha512-bZwkX+9SJ8lB9kVRkXw+xvHYSMGG4bpYHKGXeXFvyVc79NMeeBSGgzd4TQLHH+DYeOJoCdl8flrFJVxlZ0wo/Q==", - "requires": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - } - }, - "@docusaurus/mdx-loader": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.4.0.tgz", - "integrity": "sha512-kSSbrrk4nTjf4d+wtBA9H+FGauf2gCax89kV8SUSJu3qaTdSIKdWERlngsiHaCFgZ7laTJ8a67UFf+xlFPtuTw==", - "requires": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^1.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - } - }, - "@docusaurus/module-type-aliases": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.4.0.tgz", - "integrity": "sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw==", - "requires": { - "@docusaurus/types": "3.4.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - } - }, - "@docusaurus/plugin-content-blog": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.4.0.tgz", - "integrity": "sha512-vv6ZAj78ibR5Jh7XBUT4ndIjmlAxkijM3Sx5MAAzC1gyv0vupDQNhzuFg1USQmQVj3P5I6bquk12etPV3LJ+Xw==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "cheerio": "^1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "reading-time": "^1.5.0", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - } - }, - "@docusaurus/plugin-content-docs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.4.0.tgz", - "integrity": "sha512-HkUCZffhBo7ocYheD9oZvMcDloRnGhBMOZRyVcAQRFmZPmNqSyISlXA1tQCIxW+r478fty97XXAGjNYzBjpCsg==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - } - }, - "@docusaurus/plugin-content-pages": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.4.0.tgz", - "integrity": "sha512-h2+VN/0JjpR8fIkDEAoadNjfR3oLzB+v1qSXbIAKjQ46JAHx3X22n9nqS+BWSQnTnp1AjkjSvZyJMekmcwxzxg==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - } - }, - "@docusaurus/plugin-debug": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.4.0.tgz", - "integrity": "sha512-uV7FDUNXGyDSD3PwUaf5YijX91T5/H9SX4ErEcshzwgzWwBtK37nUWPU3ZLJfeTavX3fycTOqk9TglpOLaWkCg==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^1.2.0", - "tslib": "^2.6.0" - } - }, - "@docusaurus/plugin-google-analytics": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.4.0.tgz", - "integrity": "sha512-mCArluxEGi3cmYHqsgpGGt3IyLCrFBxPsxNZ56Mpur0xSlInnIHoeLDH7FvVVcPJRPSQ9/MfRqLsainRw+BojA==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "tslib": "^2.6.0" - } - }, - "@docusaurus/plugin-google-gtag": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.4.0.tgz", - "integrity": "sha512-Dsgg6PLAqzZw5wZ4QjUYc8Z2KqJqXxHxq3vIoyoBWiLEEfigIs7wHR+oiWUQy3Zk9MIk6JTYj7tMoQU0Jm3nqA==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" - } - }, - "@docusaurus/plugin-google-tag-manager": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.4.0.tgz", - "integrity": "sha512-O9tX1BTwxIhgXpOLpFDueYA9DWk69WCbDRrjYoMQtFHSkTyE7RhNgyjSPREUWJb9i+YUg3OrsvrBYRl64FCPCQ==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "tslib": "^2.6.0" - } - }, - "@docusaurus/plugin-sitemap": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.4.0.tgz", - "integrity": "sha512-+0VDvx9SmNrFNgwPoeoCha+tRoAjopwT0+pYO1xAbyLcewXSemq+eLxEa46Q1/aoOaJQ0qqHELuQM7iS2gp33Q==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" - } - }, - "@docusaurus/preset-classic": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.4.0.tgz", - "integrity": "sha512-Ohj6KB7siKqZaQhNJVMBBUzT3Nnp6eTKqO+FXO3qu/n1hJl3YLwVKTWBg28LF7MWrKu46UuYavwMRxud0VyqHg==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/plugin-debug": "3.4.0", - "@docusaurus/plugin-google-analytics": "3.4.0", - "@docusaurus/plugin-google-gtag": "3.4.0", - "@docusaurus/plugin-google-tag-manager": "3.4.0", - "@docusaurus/plugin-sitemap": "3.4.0", - "@docusaurus/theme-classic": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-search-algolia": "3.4.0", - "@docusaurus/types": "3.4.0" - } - }, - "@docusaurus/remark-plugin-npm2yarn": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/remark-plugin-npm2yarn/-/remark-plugin-npm2yarn-3.4.0.tgz", - "integrity": "sha512-MXcYAkKu6544h7J4vbKdeH+G5HZf6LF3qZORQqWzxOi2p82PTLRu0YM6ZgzfPjH5nZClgLBHypPbyO9qhkxPKw==", - "requires": { - "mdast-util-mdx": "^3.0.0", - "npm-to-yarn": "^2.2.1", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0" - } - }, - "@docusaurus/theme-classic": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.4.0.tgz", - "integrity": "sha512-0IPtmxsBYv2adr1GnZRdMkEQt1YW6tpzrUPj02YxNpvJ5+ju4E13J5tB4nfdaen/tfR1hmpSPlTFPvTf4kwy8Q==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-translations": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.43", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.4.26", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - } - }, - "@docusaurus/theme-common": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.4.0.tgz", - "integrity": "sha512-0A27alXuv7ZdCg28oPE8nH/Iz73/IUejVaCazqu9elS4ypjiLhK3KfzdSQBnL/g7YfHSlymZKdiOHEo8fJ0qMA==", - "requires": { - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - } - }, - "@docusaurus/theme-mermaid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.4.0.tgz", - "integrity": "sha512-3w5QW0HEZ2O6x2w6lU3ZvOe1gNXP2HIoKDMJBil1VmLBc9PmpAG17VmfhI/p3L2etNmOiVs5GgniUqvn8AFEGQ==", - "requires": { - "@docusaurus/core": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "mermaid": "^10.4.0", - "tslib": "^2.6.0" - } - }, - "@docusaurus/theme-search-algolia": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.4.0.tgz", - "integrity": "sha512-aiHFx7OCw4Wck1z6IoShVdUWIjntC8FHCw9c5dR8r3q4Ynh+zkS8y2eFFunN/DL6RXPzpnvKCg3vhLQYJDmT9Q==", - "requires": { - "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-translations": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "algoliasearch": "^4.18.0", - "algoliasearch-helper": "^3.13.3", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - } - }, - "@docusaurus/theme-translations": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.4.0.tgz", - "integrity": "sha512-zSxCSpmQCCdQU5Q4CnX/ID8CSUUI3fvmq4hU/GNP/XoAWtXo9SAVnM3TzpU8Gb//H3WCsT8mJcTfyOk3d9ftNg==", - "requires": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - } - }, - "@docusaurus/tsconfig": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.4.0.tgz", - "integrity": "sha512-0qENiJ+TRaeTzcg4olrnh0BQ7eCxTgbYWBnWUeQDc84UYkt/T3pDNnm3SiQkqPb+YQ1qtYFlC0RriAElclo8Dg==", - "dev": true - }, - "@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "requires": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - } - }, - "@docusaurus/utils": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.4.0.tgz", - "integrity": "sha512-fRwnu3L3nnWaXOgs88BVBmG1yGjcQqZNHG+vInhEa2Sz2oQB+ZjbEMO5Rh9ePFpZ0YDiDUhpaVjwmS+AU2F14g==", - "requires": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@svgr/webpack": "^8.1.0", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "prompts": "^2.4.2", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - } - }, - "@docusaurus/utils-common": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.4.0.tgz", - "integrity": "sha512-NVx54Wr4rCEKsjOH5QEVvxIqVvm+9kh7q8aYTU5WzUU9/Hctd6aTrcZ3G0Id4zYJ+AeaG5K5qHA4CY5Kcm2iyQ==", - "requires": { - "tslib": "^2.6.0" - } - }, - "@docusaurus/utils-validation": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.4.0.tgz", - "integrity": "sha512-hYQ9fM+AXYVTWxJOT1EuNaRnrR2WGpRdLDQG07O8UOpsvCPWUVOeo26Rbm0JWY2sGLfzAb+tvJ62yF+8F+TV0g==", - "requires": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "fs-extra": "^11.2.0", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - } - }, - "@emotion/is-prop-valid": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", - "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", - "dev": true, - "requires": { - "@emotion/memoize": "^0.8.1" - } - }, - "@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", - "dev": true - }, - "@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", - "dev": true - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "devOptional": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "devOptional": true - } - } - }, - "@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "devOptional": true - }, - "@eslint/config-array": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.0.tgz", - "integrity": "sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA==", - "devOptional": true, - "requires": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - } - }, - "@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "devOptional": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "devOptional": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "devOptional": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "devOptional": true - } - } - }, - "@eslint/js": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.6.0.tgz", - "integrity": "sha512-D9B0/3vNg44ZeWbYMpBoXqNP4j6eQD5vNwIlGAuFRRzK/WtT/jvDQW3Bi9kkf3PMDMlM7Yi+73VLUsn5bJcl8A==", - "devOptional": true - }, - "@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "devOptional": true - }, - "@exodus/schemasafe": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", - "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==" - }, - "@faker-js/faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==" - }, - "@floating-ui/core": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", - "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", - "requires": { - "@floating-ui/utils": "^0.2.4" - } - }, - "@floating-ui/dom": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz", - "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==", - "requires": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.4" - } - }, - "@floating-ui/react": { - "version": "0.26.19", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.19.tgz", - "integrity": "sha512-Jk6zITdjjIvjO/VdQFvpRaD3qPwOHH6AoDHxjhpy+oK4KFgaSP871HYWUAPdnLmx1gQ+w/pB312co3tVml+BXA==", - "requires": { - "@floating-ui/react-dom": "^2.1.1", - "@floating-ui/utils": "^0.2.4", - "tabbable": "^6.0.0" - } - }, - "@floating-ui/react-dom": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", - "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", - "requires": { - "@floating-ui/dom": "^1.0.0" - } - }, - "@floating-ui/utils": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", - "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" - }, - "@fortawesome/fontawesome-common-types": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz", - "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==" - }, - "@fortawesome/fontawesome-svg-core": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz", - "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==", - "requires": { - "@fortawesome/fontawesome-common-types": "6.5.2" - } - }, - "@fortawesome/react-fontawesome": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", - "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", - "requires": { - "prop-types": "^15.8.1" - } - }, - "@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" - }, - "@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@headlessui/react": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.1.tgz", - "integrity": "sha512-808gVNUbRDbDR3GMNPHy+ON0uvR8b9H7IA+Q2UbhOsNCIjgwuwb2Iuv8VPT/1AW0UzLX8g10tN6LhF15GaUJCQ==", - "requires": { - "@floating-ui/react": "^0.26.16", - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@tanstack/react-virtual": "3.5.0" - } - }, - "@hookform/error-message": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@hookform/error-message/-/error-message-2.0.1.tgz", - "integrity": "sha512-U410sAr92xgxT1idlu9WWOVjndxLdgPUHEB8Schr27C9eh7/xUnITWpCMF93s+lGiG++D4JnbSnrb5A21AdSNg==", - "requires": {} - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "devOptional": true - }, - "@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", - "devOptional": true - }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "requires": { - "@sinclair/typebox": "^0.27.8" - } - }, - "@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "requires": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" - }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" - }, - "@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@jsdevtools/ono": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" - }, - "@json-schema-spec/json-pointer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@json-schema-spec/json-pointer/-/json-pointer-0.1.2.tgz", - "integrity": "sha512-BYY7IavBjwsWWSmVcMz2A9mKiDD9RvacnsItgmy1xV8cmgbtxFfKmKMtkVpD7pYtkx4mIW4800yZBXueVFIWPw==" - }, - "@json-schema-tools/dereferencer": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@json-schema-tools/dereferencer/-/dereferencer-1.5.5.tgz", - "integrity": "sha512-ntnTXO47DOLTLmcU9yJ7Fu29L8Du9+ly4rwxLaYd/aWVhBDtvG8VIQRMJVrrTZOQo0Cv/wHHuEj47n43MFqIjA==", - "requires": { - "@json-schema-tools/reference-resolver": "^1.2.4", - "@json-schema-tools/traverse": "^1.7.8", - "fast-safe-stringify": "^2.0.7" - } - }, - "@json-schema-tools/meta-schema": { - "version": "1.6.19", - "resolved": "https://registry.npmjs.org/@json-schema-tools/meta-schema/-/meta-schema-1.6.19.tgz", - "integrity": "sha512-55zuWFW7tr4tf/G5AYmybcPdGOkVAreQbt2JdnogX4I2r/zkxZiimYPJESDf5je9BI2oRveak2p296HzDppeaA==" - }, - "@json-schema-tools/reference-resolver": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@json-schema-tools/reference-resolver/-/reference-resolver-1.2.4.tgz", - "integrity": "sha512-Oag20zDuapO6nBQp00k8Rd5sDTb8Gfz9uH43Tf7dHKNx7nHDK/WdeTe7OxkOmLQCL6aS+mCJx1Zv+fZBCD+tzQ==", - "requires": { - "@json-schema-spec/json-pointer": "^0.1.2", - "isomorphic-fetch": "^3.0.0" - } - }, - "@json-schema-tools/traverse": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@json-schema-tools/traverse/-/traverse-1.10.4.tgz", - "integrity": "sha512-9e42zjhLIxzBONroNC4SGsTqdB877tzwH2S6lqgTav9K24kWJR9vNieeMVSuyqnY8FlclH21D8wsm/tuD9WA9Q==" - }, - "@juggle/resize-observer": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", - "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" - }, - "@mdx-js/mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", - "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", - "requires": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-to-js": "^2.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - } - }, - "@mdx-js/react": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", - "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", - "requires": { - "@types/mdx": "^2.0.0" - } - }, - "@metamask/open-rpc-docs-react": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@metamask/open-rpc-docs-react/-/open-rpc-docs-react-0.1.2.tgz", - "integrity": "sha512-QQtU8doQo87n+o6K4N8MDBcrVl27NGrq9UrYhjLylryngSgU4eC8zSoDKhNIGEqx65Y7rpFZTys8L50KKn0Lng==", - "requires": { - "@json-schema-tools/traverse": "^1.10.1", - "@open-rpc/examples": "^1.6.1", - "@rjsf/core": "^5.6.2", - "@rjsf/utils": "^5.6.2", - "@rjsf/validator-ajv8": "^5.6.2", - "@stoplight/json-schema-viewer": "^4.9.1", - "@stoplight/markdown-viewer": "^5", - "@stoplight/mosaic": "^1.32", - "@stoplight/mosaic-code-viewer": "^1.32", - "hash-color-material": "^1.1.3", - "lodash": "^4.17.15", - "qs": "^6.11.1", - "react-markdown": "^8.0.7", - "react-syntax-highlighter": "^15.4.3" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@open-rpc/examples": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@open-rpc/examples/-/examples-1.7.2.tgz", - "integrity": "sha512-wEvviOPc+gyBVmxvGQVl/hqYslEacxLe0UETupyp1JjXUAZxW27da+F1IxbP6NYdx6jt4RyLg+V0GBVTsN6RRA==" - }, - "@open-rpc/meta-schema": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/@open-rpc/meta-schema/-/meta-schema-1.14.9.tgz", - "integrity": "sha512-2/CbDzOVpcaSnMs28TsRv8MKJwJi0TTYFlQ6q6qobAH26oIuhYgcZooKf4l71emgntU6MMcFQCA0h4mJ4dBCdA==" - }, - "@open-rpc/schema-utils-js": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/@open-rpc/schema-utils-js/-/schema-utils-js-1.16.2.tgz", - "integrity": "sha512-55vQov3o8KkXD+wiw1nKZaYws2LHSntjK5Sfja4vfGN7A6Xis0r0d0MUDVj32E3pKF9Z2sTZL3sKO/nB0DKUDg==", - "requires": { - "@json-schema-tools/dereferencer": "1.5.5", - "@json-schema-tools/meta-schema": "1.6.19", - "@json-schema-tools/reference-resolver": "1.2.4", - "@open-rpc/meta-schema": "1.14.2", - "ajv": "^6.10.0", - "detect-node": "^2.0.4", - "fast-safe-stringify": "^2.0.7", - "fs-extra": "^10.1.0", - "is-url": "^1.2.4", - "isomorphic-fetch": "^3.0.0" - }, - "dependencies": { - "@open-rpc/meta-schema": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/@open-rpc/meta-schema/-/meta-schema-1.14.2.tgz", - "integrity": "sha512-vD4Nbkrb7wYFRcSQf+j228LwOy1C6/KKpy5NADlpMElGrAWPRxhTa2yTi6xG+x88OHzg2+cydQ0GAD6o40KUcg==" - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - } - } - }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true - }, - "@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==" - }, - "@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "requires": { - "graceful-fs": "4.2.10" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - } - } - }, - "@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "requires": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - } - }, - "@polka/url": { - "version": "1.0.0-next.25", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", - "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==" - }, - "@react-aria/focus": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.17.1.tgz", - "integrity": "sha512-FLTySoSNqX++u0nWZJPPN5etXY0WBxaIe/YuL/GTEeuqUIuC/2bJSaw5hlsM6T2yjy6Y/VAxBcKSdAFUlU6njQ==", - "requires": { - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", - "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" - } - }, - "@react-aria/interactions": { - "version": "3.21.3", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.3.tgz", - "integrity": "sha512-BWIuf4qCs5FreDJ9AguawLVS0lV9UU+sK4CCnbCNNmYqOWY+1+gRXCsnOM32K+oMESBxilAjdHW5n1hsMqYMpA==", - "requires": { - "@react-aria/ssr": "^3.9.4", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", - "@swc/helpers": "^0.5.0" - } - }, - "@react-aria/ssr": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz", - "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==", - "requires": { - "@swc/helpers": "^0.5.0" - } - }, - "@react-aria/utils": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.24.1.tgz", - "integrity": "sha512-O3s9qhPMd6n42x9sKeJ3lhu5V1Tlnzhu6Yk8QOvDuXf7UGuUjXf9mzfHJt1dYzID4l9Fwm8toczBzPM9t0jc8Q==", - "requires": { - "@react-aria/ssr": "^3.9.4", - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", - "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" - } - }, - "@react-hook/debounce": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@react-hook/debounce/-/debounce-3.0.0.tgz", - "integrity": "sha512-ir/kPrSfAzY12Gre0sOHkZ2rkEmM4fS5M5zFxCi4BnCeXh2nvx9Ujd+U4IGpKCuPA+EQD0pg1eK2NGLvfWejag==", - "requires": { - "@react-hook/latest": "^1.0.2" - } - }, - "@react-hook/event": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@react-hook/event/-/event-1.2.6.tgz", - "integrity": "sha512-JUL5IluaOdn5w5Afpe/puPa1rj8X6udMlQ9dt4hvMuKmTrBS1Ya6sb4sVgvfe2eU4yDuOfAhik8xhbcCekbg9Q==", - "requires": {} - }, - "@react-hook/latest": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz", - "integrity": "sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==", - "requires": {} - }, - "@react-hook/passive-layout-effect": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz", - "integrity": "sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==", - "requires": {} - }, - "@react-hook/resize-observer": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@react-hook/resize-observer/-/resize-observer-1.2.6.tgz", - "integrity": "sha512-DlBXtLSW0DqYYTW3Ft1/GQFZlTdKY5VAFIC4+km6IK5NiPPDFchGbEJm1j6pSgMqPRHbUQgHJX7RaR76ic1LWA==", - "requires": { - "@juggle/resize-observer": "^3.3.1", - "@react-hook/latest": "^1.0.2", - "@react-hook/passive-layout-effect": "^1.2.0" - } - }, - "@react-hook/size": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@react-hook/size/-/size-2.1.2.tgz", - "integrity": "sha512-BmE5asyRDxSuQ9p14FUKJ0iBRgV9cROjqNG9jT/EjCM+xHha1HVqbPoT+14FQg1K7xIydabClCibUY4+1tw/iw==", - "requires": { - "@react-hook/passive-layout-effect": "^1.2.0", - "@react-hook/resize-observer": "^1.2.1" - } - }, - "@react-hook/throttle": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@react-hook/throttle/-/throttle-2.2.0.tgz", - "integrity": "sha512-LJ5eg+yMV8lXtqK3lR+OtOZ2WH/EfWvuiEEu0M3bhR7dZRfTyEJKxH1oK9uyBxiXPtWXiQggWbZirMCXam51tg==", - "requires": { - "@react-hook/latest": "^1.0.2" - } - }, - "@react-hook/window-size": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@react-hook/window-size/-/window-size-3.1.1.tgz", - "integrity": "sha512-yWnVS5LKnOUIrEsI44oz3bIIUYqflamPL27n+k/PC//PsX/YeWBky09oPeAoc9As6jSH16Wgo8plI+ECZaHk3g==", - "requires": { - "@react-hook/debounce": "^3.0.0", - "@react-hook/event": "^1.2.1", - "@react-hook/throttle": "^2.2.0" - } - }, - "@react-stately/utils": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.1.tgz", - "integrity": "sha512-VS/EHRyicef25zDZcM/ClpzYMC5i2YGN6uegOeQawmgfGjb02yaCX0F0zR69Pod9m2Hr3wunTbtpgVXvYbZItg==", - "requires": { - "@swc/helpers": "^0.5.0" - } - }, - "@react-types/checkbox": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.1.tgz", - "integrity": "sha512-5/oVByPw4MbR/8QSdHCaalmyWC71H/QGgd4aduTJSaNi825o+v/hsN2/CH7Fq9atkLKsC8fvKD00Bj2VGaKriQ==", - "requires": { - "@react-types/shared": "^3.23.1" - } - }, - "@react-types/shared": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.23.1.tgz", - "integrity": "sha512-5d+3HbFDxGZjhbMBeFHRQhexMFt4pUce3okyRtUVKbbedQFUrtXSBg9VszgF2RTeQDKDkMCIQDtz5ccP/Lk1gw==", - "requires": {} - }, - "@redocly/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-9GWx27t7xWhDIR02PA18nzBdLcKQRgc46xNQvjFkrYk4UOmvKhJ/dawwiX0cCOeetN5LcaaiqQbVOWYK62SGHw==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "@redocly/cli": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.17.1.tgz", - "integrity": "sha512-a7OIlsGQT8OBRMPswqcJzCoub/nvm1zYvOCOBnaLt1cYeYK9nRzYCXA6Bnx0I7wMCXf5YmL7rVTMG8RJTC+3mA==", - "dev": true, - "requires": { - "@redocly/openapi-core": "1.17.1", - "abort-controller": "^3.0.0", - "chokidar": "^3.5.1", - "colorette": "^1.2.0", - "core-js": "^3.32.1", - "form-data": "^4.0.0", - "get-port-please": "^3.0.1", - "glob": "^7.1.6", - "handlebars": "^4.7.6", - "mobx": "^6.0.4", - "node-fetch": "^2.6.1", - "react": "^17.0.0 || ^18.2.0", - "react-dom": "^17.0.0 || ^18.2.0", - "redoc": "~2.1.5", - "semver": "^7.5.2", - "simple-websocket": "^9.0.0", - "styled-components": "^6.0.7", - "yargs": "17.0.1" - } - }, - "@redocly/config": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.6.3.tgz", - "integrity": "sha512-hGWJgCsXRw0Ow4rplqRlUQifZvoSwZipkYnt11e3SeH1Eb23VUIDBcRuaQOUqy1wn0eevXkU2GzzQ8fbKdQ7Mg==" - }, - "@redocly/openapi-core": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.17.1.tgz", - "integrity": "sha512-PQxDLLNk5cBatJBBxvfk49HFw/nVozw1XZ6Dw/GX0Tviq+WxeEjEuLAKfnLVvb5L0wgs4TNmVG4Y+JyofSPu1A==", - "requires": { - "@redocly/ajv": "^8.11.0", - "@redocly/config": "^0.6.2", - "colorette": "^1.2.0", - "https-proxy-agent": "^7.0.4", - "js-levenshtein": "^1.1.6", - "js-yaml": "^4.1.0", - "lodash.isequal": "^4.5.0", - "minimatch": "^5.0.1", - "node-fetch": "^2.6.1", - "pluralize": "^8.0.0", - "yaml-ast-parser": "0.0.43" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "@reduxjs/toolkit": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", - "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", - "requires": { - "immer": "^9.0.21", - "redux": "^4.2.1", - "redux-thunk": "^2.4.2", - "reselect": "^4.1.8" - } - }, - "@rehooks/component-size": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rehooks/component-size/-/component-size-1.0.3.tgz", - "integrity": "sha512-pnYld+8SSF2vXwdLOqBGUyOrv/SjzwLjIUcs/4c1JJgR0q4E9eBtBfuZMD6zUD51fvSehSsbnlQMzotSmPTXPg==", - "requires": {} - }, - "@rjsf/core": { - "version": "5.18.6", - "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.18.6.tgz", - "integrity": "sha512-Jori6SvGbNUo4PD9dCudNyM/kBQdXMrg2dAT5AA3FH7ciqUS/nxSRZQdejLX86aX7iZDrbYmucpDHfNCQxV/uQ==", - "requires": { - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "markdown-to-jsx": "^7.4.1", - "nanoid": "^3.3.7", - "prop-types": "^15.8.1" - } - }, - "@rjsf/utils": { - "version": "5.18.6", - "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.18.6.tgz", - "integrity": "sha512-E/zTsbiCT5EOZL2K92Qhry712/87PyE4GPFQJvgYCT7wS1u6cvdAsJE1yNarAFK01JzaLPSS62Zq894RaBuApg==", - "requires": { - "json-schema-merge-allof": "^0.8.1", - "jsonpointer": "^5.0.1", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "react-is": "^18.2.0" - } - }, - "@rjsf/validator-ajv8": { - "version": "5.18.6", - "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.18.6.tgz", - "integrity": "sha512-rIDvJQmh3CirMFf4TeY8ggGil369BOyyEv6sqa+Dr4u4MU5jjSxYudMKqmPhK9fUzX7wEDCqH1BngrsIWWRCnQ==", - "requires": { - "ajv": "^8.12.0", - "ajv-formats": "^2.1.1", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21" - } - }, - "@sentry/browser": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.19.7.tgz", - "integrity": "sha512-oDbklp4O3MtAM4mtuwyZLrgO1qDVYIujzNJQzXmi9YzymJCuzMLSRDvhY83NNDCRxf0pds4DShgYeZdbSyKraA==", - "requires": { - "@sentry/core": "6.19.7", - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@sentry/core": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.19.7.tgz", - "integrity": "sha512-tOfZ/umqB2AcHPGbIrsFLcvApdTm9ggpi/kQZFkej7kMphjT+SGBiQfYtjyg9jcRW+ilAR4JXC9BGKsdEQ+8Vw==", - "requires": { - "@sentry/hub": "6.19.7", - "@sentry/minimal": "6.19.7", - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@sentry/hub": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.19.7.tgz", - "integrity": "sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==", - "requires": { - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@sentry/minimal": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.19.7.tgz", - "integrity": "sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==", - "requires": { - "@sentry/hub": "6.19.7", - "@sentry/types": "6.19.7", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@sentry/react": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-6.19.7.tgz", - "integrity": "sha512-VzJeBg/v41jfxUYPkH2WYrKjWc4YiMLzDX0f4Zf6WkJ4v3IlDDSkX6DfmWekjTKBho6wiMkSNy2hJ1dHfGZ9jA==", - "requires": { - "@sentry/browser": "6.19.7", - "@sentry/minimal": "6.19.7", - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "hoist-non-react-statics": "^3.3.2", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@sentry/types": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.19.7.tgz", - "integrity": "sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==" - }, - "@sentry/utils": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.19.7.tgz", - "integrity": "sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==", - "requires": { - "@sentry/types": "6.19.7", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" - }, - "@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" - }, - "@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" - }, - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" - }, - "@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "@stellar/prettier-config": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@stellar/prettier-config/-/prettier-config-1.2.0.tgz", - "integrity": "sha512-oL9qJ7+7aWnImpbcldroQrvtMCZ9yx4JL/tmDZ860RpBQd2ahkc8bX6/k2ehFK8gpb9ltYu4mtU49wufUuYhGg==", - "dev": true, - "requires": {} - }, - "@stoplight/json": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.0.tgz", - "integrity": "sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==", - "requires": { - "@stoplight/ordered-object-literal": "^1.0.3", - "@stoplight/path": "^1.3.2", - "@stoplight/types": "^13.6.0", - "jsonc-parser": "~2.2.1", - "lodash": "^4.17.21", - "safe-stable-stringify": "^1.1" - } - }, - "@stoplight/json-schema-merge-allof": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@stoplight/json-schema-merge-allof/-/json-schema-merge-allof-0.8.0.tgz", - "integrity": "sha512-g8e0s43v96Xbzvd8d6KKUuJTO16CS2oJglJrviUi8ASIUxzFvAJqTHWLtGmpTryisQopqg1evXGJfi0+164+Qw==", - "requires": { - "compute-lcm": "^1.1.0", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.4" - } - }, - "@stoplight/json-schema-tree": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@stoplight/json-schema-tree/-/json-schema-tree-4.0.0.tgz", - "integrity": "sha512-SAGtof+ihIdPqETR+7XXOaqZJcrbSih/xEahaw5t1nXk5sVW6ss2l5A1WCIuvtvnQiUKnBfanmZU4eoM1ZvItg==", - "requires": { - "@stoplight/json": "^3.12.0", - "@stoplight/json-schema-merge-allof": "^0.8.0", - "@stoplight/lifecycle": "^2.3.2", - "@types/json-schema": "^7.0.7", - "magic-error": "0.0.1" - } - }, - "@stoplight/json-schema-viewer": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@stoplight/json-schema-viewer/-/json-schema-viewer-4.16.1.tgz", - "integrity": "sha512-gQ1v9/Dj1VP43zERuZoFMOr7RQDBZlgfF7QFh+R0sadP6W30oYFJtD7y2PG2gIQDohKElVuPjhFUbVH/81MnSg==", - "requires": { - "@stoplight/json": "^3.20.1", - "@stoplight/json-schema-tree": "^4.0.0", - "@stoplight/react-error-boundary": "^2.0.0", - "@types/json-schema": "^7.0.7", - "classnames": "^2.2.6", - "fnv-plus": "^1.3.1", - "jotai": "^1.4.5", - "lodash": "^4.17.19" - } - }, - "@stoplight/lifecycle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@stoplight/lifecycle/-/lifecycle-2.3.3.tgz", - "integrity": "sha512-JbPRTIzPZabeYPAk5+gdsnfwAxqW35G9e0ZjOG3toUmNViLOsEzuK4vpWd+Prv2Mw8HRmu+haiYizteZp6mk0w==", - "requires": { - "tslib": "^2.3.1", - "wolfy87-eventemitter": "~5.2.8" - } - }, - "@stoplight/markdown": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@stoplight/markdown/-/markdown-3.2.0.tgz", - "integrity": "sha512-Hhnrj7xb+f4iMQQeZBKLgfst3OJyV8T4BKr8BSYnKpp070B6fE63V/lkPuKqrpvidcv6kz3INDBU/GE7K2Q0uw==", - "requires": { - "@stoplight/types": "^12.3.0", - "@stoplight/yaml": "^4.2.2", - "github-slugger": "^1.3.0", - "hast-util-whitespace": "^2.0.0", - "lodash": "^4.17.21", - "mdast-util-to-string": "^3.1.0", - "remark-frontmatter": "^3.0.0", - "remark-gfm": "^1.0.0", - "remark-parse": "^9.0.0", - "remark-stringify": "^9.0.1", - "tslib": "^2.3.0", - "unified": "^9.2.1", - "unist-util-select": "^4.0.0", - "unist-util-visit": "^3.1.0" - }, - "dependencies": { - "@stoplight/types": { - "version": "12.5.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", - "integrity": "sha512-dwqYcDrGmEyUv5TWrDam5TGOxU72ufyQ7hnOIIDdmW5ezOwZaBFoR5XQ9AsH49w7wgvOqB2Bmo799pJPWnpCbg==", - "requires": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - } - }, - "@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" - }, - "ccount": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==" - }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" - }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" - }, - "longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" - }, - "markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "requires": { - "repeat-string": "^1.0.0" - } - }, - "mdast-util-find-and-replace": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", - "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", - "requires": { - "escape-string-regexp": "^4.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - } - }, - "mdast-util-from-markdown": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", - "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-to-string": "^2.0.0", - "micromark": "~2.11.0", - "parse-entities": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "dependencies": { - "mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" - } - } - }, - "mdast-util-frontmatter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz", - "integrity": "sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==", - "requires": { - "micromark-extension-frontmatter": "^0.2.0" - } - }, - "mdast-util-gfm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", - "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", - "requires": { - "mdast-util-gfm-autolink-literal": "^0.1.0", - "mdast-util-gfm-strikethrough": "^0.2.0", - "mdast-util-gfm-table": "^0.1.0", - "mdast-util-gfm-task-list-item": "^0.1.0", - "mdast-util-to-markdown": "^0.6.1" - } - }, - "mdast-util-gfm-autolink-literal": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", - "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", - "requires": { - "ccount": "^1.0.0", - "mdast-util-find-and-replace": "^1.1.0", - "micromark": "^2.11.3" - } - }, - "mdast-util-gfm-strikethrough": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", - "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", - "requires": { - "mdast-util-to-markdown": "^0.6.0" - } - }, - "mdast-util-gfm-table": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", - "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", - "requires": { - "markdown-table": "^2.0.0", - "mdast-util-to-markdown": "~0.6.0" - } - }, - "mdast-util-gfm-task-list-item": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", - "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", - "requires": { - "mdast-util-to-markdown": "~0.6.0" - } - }, - "mdast-util-to-markdown": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", - "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", - "requires": { - "@types/unist": "^2.0.0", - "longest-streak": "^2.0.0", - "mdast-util-to-string": "^2.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.0.0", - "zwitch": "^1.0.0" - }, - "dependencies": { - "mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" - } - } - }, - "mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "requires": { - "@types/mdast": "^3.0.0" - } - }, - "micromark": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", - "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", - "requires": { - "debug": "^4.0.0", - "parse-entities": "^2.0.0" - } - }, - "micromark-extension-frontmatter": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz", - "integrity": "sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==", - "requires": { - "fault": "^1.0.0" - } - }, - "micromark-extension-gfm": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", - "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", - "requires": { - "micromark": "~2.11.0", - "micromark-extension-gfm-autolink-literal": "~0.5.0", - "micromark-extension-gfm-strikethrough": "~0.6.5", - "micromark-extension-gfm-table": "~0.4.0", - "micromark-extension-gfm-tagfilter": "~0.3.0", - "micromark-extension-gfm-task-list-item": "~0.3.0" - } - }, - "micromark-extension-gfm-autolink-literal": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", - "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", - "requires": { - "micromark": "~2.11.3" - } - }, - "micromark-extension-gfm-strikethrough": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", - "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", - "requires": { - "micromark": "~2.11.0" - } - }, - "micromark-extension-gfm-table": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", - "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", - "requires": { - "micromark": "~2.11.0" - } - }, - "micromark-extension-gfm-tagfilter": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", - "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==" - }, - "micromark-extension-gfm-task-list-item": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", - "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", - "requires": { - "micromark": "~2.11.0" - } - }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "remark-frontmatter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz", - "integrity": "sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==", - "requires": { - "mdast-util-frontmatter": "^0.2.0", - "micromark-extension-frontmatter": "^0.2.0" - } - }, - "remark-gfm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", - "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", - "requires": { - "mdast-util-gfm": "^0.1.0", - "micromark-extension-gfm": "^0.3.0" - } - }, - "remark-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", - "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", - "requires": { - "mdast-util-from-markdown": "^0.8.0" - } - }, - "trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" - }, - "unified": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", - "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - } - }, - "unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" - }, - "unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "requires": { - "@types/unist": "^2.0.2" - } - }, - "unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - }, - "dependencies": { - "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - } - } - } - }, - "unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - } - }, - "vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - } - }, - "vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - } - }, - "zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" - } - } - }, - "@stoplight/markdown-viewer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@stoplight/markdown-viewer/-/markdown-viewer-5.7.0.tgz", - "integrity": "sha512-SOFmEapj/RAJ6fUqgZO41diB9ocEFxhrSL7C8aJKNoYoHme0xxk5DK53DvFNBayEEXnf9e/YmKPfwJjFdKUilA==", - "requires": { - "@rehooks/component-size": "^1.0.3", - "@stoplight/markdown": "^3.1.3", - "@stoplight/react-error-boundary": "^2.0.0", - "deepmerge": "^4.2.2", - "hast-to-hyperscript": "^10.0.1", - "hast-util-raw": "7.0.0", - "hast-util-sanitize": "^4.0.0", - "hastscript": "^7.0.2", - "mdast-util-to-hast": "^11.1.1", - "remark-parse": "^9.0.0", - "unified": "^9.2.1", - "unist-builder": "^3.0.0", - "unist-util-select": "^4.0.1", - "unist-util-visit": "^3.1.0" - }, - "dependencies": { - "@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" - }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" - }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" - }, - "mdast-util-from-markdown": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", - "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-to-string": "^2.0.0", - "micromark": "~2.11.0", - "parse-entities": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - } - }, - "mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" - }, - "micromark": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", - "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", - "requires": { - "debug": "^4.0.0", - "parse-entities": "^2.0.0" - } - }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "remark-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", - "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", - "requires": { - "mdast-util-from-markdown": "^0.8.0" - } - }, - "trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" - }, - "unified": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", - "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - } - }, - "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "requires": { - "@types/unist": "^2.0.2" - } - }, - "unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - } - }, - "unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - } - }, - "vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - } - }, - "vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - } - } - } - }, - "@stoplight/mosaic": { - "version": "1.53.2", - "resolved": "https://registry.npmjs.org/@stoplight/mosaic/-/mosaic-1.53.2.tgz", - "integrity": "sha512-fhSU1jqXLP3+9DghzrAHBgL+TfzaRDCwwg9+6Xe9Iz2LikOguAMPfBriantrtKOoM0pfUBOjHEuTO8QPw6uLKw==", - "requires": { - "@fortawesome/fontawesome-svg-core": "^6.1.1", - "@fortawesome/react-fontawesome": "^0.2.0", - "@react-hook/size": "^2.1.1", - "@react-hook/window-size": "^3.0.7", - "@react-types/button": "3.4.1", - "@react-types/radio": "3.1.2", - "@react-types/shared": "3.9.0", - "@react-types/switch": "3.1.2", - "@react-types/textfield": "3.3.0", - "@stoplight/types": "^13.7.0", - "@types/react": "^17.0.3", - "@types/react-dom": "^17.0.3", - "clsx": "^1.1.1", - "copy-to-clipboard": "^3.3.1", - "dom-helpers": "^3.3.1", - "lodash.get": "^4.4.2", - "nano-memoize": "^1.2.1", - "polished": "^4.1.3", - "react-fast-compare": "^3.2.0", - "react-overflow-list": "^0.5.0", - "ts-keycode-enum": "^1.0.6", - "tslib": "^2.1.0", - "use-resize-observer": "^9.0.2", - "zustand": "^3.5.2" - }, - "dependencies": { - "@react-types/button": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.4.1.tgz", - "integrity": "sha512-B54M84LxdEppwjXNlkBEJyMfe9fd+bvFV7R6+NJvupGrZm/LuFNYjFcHk7yjMKWTdWm6DbpIuQz54n5qTW7Vlg==", - "requires": { - "@react-types/shared": "^3.8.0" - } - }, - "@react-types/radio": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.1.2.tgz", - "integrity": "sha512-vkIic8abrVUyl/YjKU3yTVwn8QgebzuadfV89PsaKc3hdmSiHhDsln5wYsfWOEotqMwPrG1aEv9yRMYO78OQXQ==", - "requires": { - "@react-types/shared": "^3.8.0" - } - }, - "@react-types/shared": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.9.0.tgz", - "integrity": "sha512-YYksINfR6q92P10AhPEGo47Hd7oz1hrnZ6Vx8Gsrq62IbqDdv1XOTzPBaj17Z1ymNY2pitLUSEXsLmozt4wxxQ==", - "requires": {} - }, - "@react-types/switch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.1.2.tgz", - "integrity": "sha512-EaYWoLvUCpOnt//Ov8VBxOjbs4hBpYE/rBAzzIknXaFvKOu867iZBFL7FJbcemOgC8/dwyaj6GUZ1Gw3Z1g59w==", - "requires": { - "@react-types/checkbox": "^3.2.3", - "@react-types/shared": "^3.8.0" - } - }, - "@react-types/textfield": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.3.0.tgz", - "integrity": "sha512-lOf0tx3c3dVaomH/uvKpOKFVTXQ232kLnMhOJTtj97JDX7fTr3SNhDUV0G8Zf4M0vr+l+xkTrJkywYE23rzliw==", - "requires": { - "@react-types/shared": "^3.9.0" - } - }, - "@types/react": { - "version": "17.0.80", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.80.tgz", - "integrity": "sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "^0.16", - "csstype": "^3.0.2" - } - }, - "clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" - } - } - }, - "@stoplight/mosaic-code-viewer": { - "version": "1.53.2", - "resolved": "https://registry.npmjs.org/@stoplight/mosaic-code-viewer/-/mosaic-code-viewer-1.53.2.tgz", - "integrity": "sha512-BtiAfotKmy4TtwrXTD2ktruFEwTLPwW3wt/KUQAWpGnwmTcJ9cXph2hsskFKAt1G866UzsKE3OKOAIv9GKHOdQ==", - "requires": { - "@fortawesome/fontawesome-svg-core": "^6.1.1", - "@fortawesome/react-fontawesome": "^0.2.0", - "@react-hook/size": "^2.1.1", - "@react-hook/window-size": "^3.0.7", - "@react-types/radio": "3.1.2", - "@react-types/shared": "3.9.0", - "@react-types/switch": "3.1.2", - "@stoplight/mosaic": "1.53.2", - "@stoplight/types": "^13.7.0", - "clsx": "^1.1.1", - "copy-to-clipboard": "^3.3.1", - "dom-helpers": "^3.3.1", - "lodash.get": "^4.4.2", - "nano-memoize": "^1.2.1", - "polished": "^4.1.3", - "prism-react-renderer": "^1.2.1", - "prismjs": "^1.23.0", - "react-fast-compare": "^3.2.0", - "react-overflow-list": "^0.5.0", - "ts-keycode-enum": "^1.0.6", - "tslib": "^2.1.0", - "use-resize-observer": "^9.0.2", - "zustand": "^3.5.2" - }, - "dependencies": { - "@react-types/radio": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.1.2.tgz", - "integrity": "sha512-vkIic8abrVUyl/YjKU3yTVwn8QgebzuadfV89PsaKc3hdmSiHhDsln5wYsfWOEotqMwPrG1aEv9yRMYO78OQXQ==", - "requires": { - "@react-types/shared": "^3.8.0" - } - }, - "@react-types/shared": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.9.0.tgz", - "integrity": "sha512-YYksINfR6q92P10AhPEGo47Hd7oz1hrnZ6Vx8Gsrq62IbqDdv1XOTzPBaj17Z1ymNY2pitLUSEXsLmozt4wxxQ==", - "requires": {} - }, - "@react-types/switch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.1.2.tgz", - "integrity": "sha512-EaYWoLvUCpOnt//Ov8VBxOjbs4hBpYE/rBAzzIknXaFvKOu867iZBFL7FJbcemOgC8/dwyaj6GUZ1Gw3Z1g59w==", - "requires": { - "@react-types/checkbox": "^3.2.3", - "@react-types/shared": "^3.8.0" - } - }, - "clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" - }, - "prism-react-renderer": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz", - "integrity": "sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==", - "requires": {} - } - } - }, - "@stoplight/ordered-object-literal": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.5.tgz", - "integrity": "sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==" - }, - "@stoplight/path": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz", - "integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==" - }, - "@stoplight/react-error-boundary": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@stoplight/react-error-boundary/-/react-error-boundary-2.0.0.tgz", - "integrity": "sha512-r9cyaaH2h0kFe5c0aP+yJuY9CyXgfbBaMO6660M/wRQXqM49K5Ul7kexE4ei2cqYgo+Cd6ALl6RXSZFYwf2kCA==", - "requires": { - "@sentry/react": "^6.13.2" - } - }, - "@stoplight/types": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.20.0.tgz", - "integrity": "sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==", - "requires": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - } - }, - "@stoplight/yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.3.0.tgz", - "integrity": "sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==", - "requires": { - "@stoplight/ordered-object-literal": "^1.0.5", - "@stoplight/types": "^14.1.1", - "@stoplight/yaml-ast-parser": "0.0.50", - "tslib": "^2.2.0" - }, - "dependencies": { - "@stoplight/types": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-14.1.1.tgz", - "integrity": "sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==", - "requires": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - } - } - } - }, - "@stoplight/yaml-ast-parser": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.50.tgz", - "integrity": "sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==" - }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "requires": {} - }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "requires": {} - }, - "@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "requires": {} - }, - "@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "requires": {} - }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "requires": {} - }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "requires": {} - }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "requires": {} - }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "requires": {} - }, - "@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - } - }, - "@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "requires": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - } - }, - "@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "requires": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - } - }, - "@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "requires": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - } - }, - "@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "requires": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - } - }, - "@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "requires": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - } - }, - "@swc/helpers": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz", - "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==", - "requires": { - "tslib": "^2.4.0" - } - }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "requires": { - "defer-to-connect": "^2.0.1" - } - }, - "@tanstack/react-virtual": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz", - "integrity": "sha512-rtvo7KwuIvqK9zb0VZ5IL7fiJAEnG+0EiFZz8FUOs+2mhGqdGmjKIaT1XU7Zq0eFqL0jonLlhbayJI/J2SA/Bw==", - "requires": { - "@tanstack/virtual-core": "3.5.0" - } - }, - "@tanstack/virtual-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.0.tgz", - "integrity": "sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==" - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" - }, - "@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "requires": { - "@types/estree": "*" - } - }, - "@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "requires": { - "@types/d3-time": "*" - } - }, - "@types/d3-scale-chromatic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" - }, - "@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" - }, - "@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "requires": { - "@types/ms": "*" - } - }, - "@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" - }, - "@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "requires": { - "@types/estree": "*" - } - }, - "@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" - }, - "@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "requires": { - "@types/unist": "*" - } - }, - "@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" - }, - "@types/hoist-non-react-statics": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", - "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" - }, - "@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" - }, - "@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/js-cookie": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", - "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==" - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" - }, - "@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "requires": { - "@types/unist": "*" - } - }, - "@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==" - }, - "@types/mdx": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" - }, - "@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" - }, - "@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "@types/parse5": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", - "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" - }, - "@types/prismjs": { - "version": "1.26.4", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.4.tgz", - "integrity": "sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==" - }, - "@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" - }, - "@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" - }, - "@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "requires": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-dom": { - "version": "17.0.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.25.tgz", - "integrity": "sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA==", - "requires": { - "@types/react": "^17" - }, - "dependencies": { - "@types/react": { - "version": "17.0.80", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.80.tgz", - "integrity": "sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "^0.16", - "csstype": "^3.0.2" - } - } - } - }, - "@types/react-redux": { - "version": "7.1.33", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.33.tgz", - "integrity": "sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg==", - "requires": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - }, - "@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "requires": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "@types/react-router-config": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", - "requires": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" - } - }, - "@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "requires": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "requires": { - "@types/node": "*" - } - }, - "@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" - }, - "@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, - "@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "requires": { - "@types/express": "*" - } - }, - "@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "requires": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "requires": { - "@types/node": "*" - } - }, - "@types/stylis": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", - "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", - "dev": true - }, - "@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - } - }, - "@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - } - } - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "@xobotyi/scrollbar-width": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", - "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" - }, - "acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "requires": {} - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} - }, - "acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "requires": { - "acorn": "^8.11.0" - } - }, - "address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==" - }, - "agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "requires": { - "debug": "^4.3.4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", - "requires": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - } - }, - "ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "requires": {} - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "requires": { - "ajv": "^8.0.0" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "algoliasearch": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", - "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", - "requires": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-account": "4.24.0", - "@algolia/client-analytics": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-personalization": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/recommend": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "algoliasearch-helper": { - "version": "3.22.2", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.2.tgz", - "integrity": "sha512-3YQ6eo7uYOCHeQ2ZpD+OoT3aJJwMNKEnwtu8WMzm81XmBOSCwRjQditH9CeSOQ38qhHkuGw23pbq+kULkIJLcw==", - "requires": { - "@algolia/events": "^4.0.1" - } - }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "requires": { - "string-width": "^4.1.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array.prototype.filter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.4.tgz", - "integrity": "sha512-r+mCJ7zXgXElgR4IRC+fkvNCeoaavWBs6EdCso5Tbcf+iEMKzBU/His60lt34WEZ9vlb8wDkZvQGcVI5GwkfoQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-array-method-boxes-properly": "^1.0.0", - "es-object-atoms": "^1.0.0", - "is-string": "^1.0.7" - } - }, - "array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "requires": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==" - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "requires": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "requires": { - "possible-typed-array-names": "^1.0.0" - } - }, - "axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", - "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "requires": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", - "requires": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.6.2" - } - }, - "bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==" - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } - } - } - }, - "bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", - "requires": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "boxen": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "requires": { - "ansi-align": "^3.0.1", - "camelcase": "^6.2.0", - "chalk": "^4.1.2", - "cli-boxes": "^3.0.0", - "string-width": "^5.0.1", - "type-fest": "^2.5.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "requires": { - "fill-range": "^7.1.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", - "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", - "requires": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.5", - "hash-base": "~3.0", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.7", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", - "requires": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" - }, - "cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==" - }, - "cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "requires": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - } - }, - "call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - } - }, - "call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" - }, - "camelize": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", - "dev": true - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001640", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", - "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==" - }, - "canvas-embed": { - "version": "1.0.80", - "resolved": "https://registry.npmjs.org/canvas-embed/-/canvas-embed-1.0.80.tgz", - "integrity": "sha512-/ezY4LOQIS+tDUy7UI5sma7tMUgg4XEhvofFaKyxWY+aFslNCLh//XNtzUdze4kKygX33Eg+FvGQGxFu5hr4aQ==", - "requires": { - "@headlessui/react": "^2.0.4", - "chroma-js": "^2.4.2", - "dompurify": "^3.1.0", - "lodash": "^4.17.21", - "lodash.debounce": "^4.0.8", - "luxon": "^3.4.4", - "moment": "^2.29.4", - "moment-timezone": "^0.5.43", - "postcss": "^8.4.32", - "zustand": "^4.4.7" - }, - "dependencies": { - "use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "requires": {} - }, - "zustand": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz", - "integrity": "sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==", - "requires": { - "use-sync-external-store": "1.2.0" - } - } - } - }, - "ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==" - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" - }, - "character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" - }, - "character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==" - }, - "character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==" - }, - "character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==" - }, - "charset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/charset/-/charset-1.0.1.tgz", - "integrity": "sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==" - }, - "cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "requires": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - } - }, - "cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "requires": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - } - }, - "chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chroma-js": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", - "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" - }, - "chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==" - }, - "ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" - }, - "clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==" - }, - "cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "requires": { - "@colors/colors": "1.5.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" - }, - "collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==" - }, - "combine-promises": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==" - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" - }, - "common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "compute-gcd": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", - "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", - "requires": { - "validate.io-array": "^1.0.3", - "validate.io-function": "^1.0.2", - "validate.io-integer-array": "^1.0.0" - } - }, - "compute-lcm": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", - "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", - "requires": { - "compute-gcd": "^1.2.1", - "validate.io-array": "^1.0.3", - "validate.io-function": "^1.0.2", - "validate.io-integer-array": "^1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "requires": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - } - }, - "connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" - }, - "consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==" - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==" - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==" - }, - "copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "requires": { - "toggle-selection": "^1.0.6" - } - }, - "copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "requires": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "requires": { - "is-glob": "^4.0.3" - } - }, - "globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "requires": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - } - }, - "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" - } - } - }, - "core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==" - }, - "core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", - "requires": { - "browserslist": "^4.23.0" - } - }, - "core-js-pure": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", - "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==" - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "cose-base": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", - "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", - "requires": { - "layout-base": "^1.0.0" - } - }, - "cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "requires": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" - }, - "crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "requires": { - "type-fest": "^1.0.1" - }, - "dependencies": { - "type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==" - } - } - }, - "css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", - "dev": true - }, - "css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", - "requires": {} - }, - "css-in-js-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", - "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", - "requires": { - "hyphenate-style-name": "^1.0.3" - } - }, - "css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", - "requires": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - } - }, - "css-minimizer-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.18", - "cssnano": "^6.0.1", - "jest-worker": "^29.4.3", - "postcss": "^8.4.24", - "schema-utils": "^4.0.1", - "serialize-javascript": "^6.0.1" - } - }, - "css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - } - }, - "css-selector-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", - "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" - }, - "css-to-react-native": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", - "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", - "dev": true, - "requires": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", - "requires": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" - } - }, - "cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "requires": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" - } - }, - "cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "requires": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" - } - }, - "cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "requires": {} - }, - "csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "requires": { - "css-tree": "~2.2.0" - }, - "dependencies": { - "css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "requires": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - } - }, - "mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" - } - } - }, - "csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "cytoscape": { - "version": "3.30.0", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.0.tgz", - "integrity": "sha512-l590mjTHT6/Cbxp13dGPC2Y7VXdgc+rUeF8AnF/JPzhjNevbDJfObnJgaSjlldOgBQZbue+X6IUZ7r5GAgvauQ==" - }, - "cytoscape-cose-bilkent": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", - "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", - "requires": { - "cose-base": "^1.0.0" - } - }, - "d3": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", - "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", - "requires": { - "d3-array": "3", - "d3-axis": "3", - "d3-brush": "3", - "d3-chord": "3", - "d3-color": "3", - "d3-contour": "4", - "d3-delaunay": "6", - "d3-dispatch": "3", - "d3-drag": "3", - "d3-dsv": "3", - "d3-ease": "3", - "d3-fetch": "3", - "d3-force": "3", - "d3-format": "3", - "d3-geo": "3", - "d3-hierarchy": "3", - "d3-interpolate": "3", - "d3-path": "3", - "d3-polygon": "3", - "d3-quadtree": "3", - "d3-random": "3", - "d3-scale": "4", - "d3-scale-chromatic": "3", - "d3-selection": "3", - "d3-shape": "3", - "d3-time": "3", - "d3-time-format": "4", - "d3-timer": "3", - "d3-transition": "3", - "d3-zoom": "3" - } - }, - "d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "requires": { - "internmap": "1 - 2" - } - }, - "d3-axis": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==" - }, - "d3-brush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "3", - "d3-transition": "3" - } - }, - "d3-chord": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", - "requires": { - "d3-path": "1 - 3" - } - }, - "d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" - }, - "d3-contour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", - "requires": { - "d3-array": "^3.2.0" - } - }, - "d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "requires": { - "delaunator": "5" - } - }, - "d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==" - }, - "d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" - } - }, - "d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "requires": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - } - } - }, - "d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" - }, - "d3-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", - "requires": { - "d3-dsv": "1 - 3" - } - }, - "d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" - } - }, - "d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==" - }, - "d3-geo": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", - "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", - "requires": { - "d3-array": "2.5.0 - 3" - } - }, - "d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==" - }, - "d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "requires": { - "d3-color": "1 - 3" - } - }, - "d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==" - }, - "d3-polygon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==" - }, - "d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==" - }, - "d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==" - }, - "d3-sankey": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", - "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", - "requires": { - "d3-array": "1 - 2", - "d3-shape": "^1.2.0" - }, - "dependencies": { - "d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "requires": { - "internmap": "^1.0.0" - } - }, - "d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" - }, - "d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "requires": { - "d3-path": "1" - } - }, - "internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" - } - } - }, - "d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "requires": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - } - }, - "d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", - "requires": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" - } - }, - "d3-selection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==" - }, - "d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "requires": { - "d3-path": "^3.1.0" - } - }, - "d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "requires": { - "d3-array": "2 - 3" - } - }, - "d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "requires": { - "d3-time": "1 - 3" - } - }, - "d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==" - }, - "d3-transition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "requires": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - } - }, - "d3-zoom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" - } - }, - "dagre-d3-es": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", - "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", - "requires": { - "d3": "^7.8.2", - "lodash-es": "^4.17.21" - } - }, - "data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" - }, - "debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" - }, - "debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "requires": { - "ms": "2.1.2" - } - }, - "decko": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz", - "integrity": "sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==", - "dev": true - }, - "decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "requires": { - "character-entities": "^2.0.0" - } - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" - } - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "devOptional": true - }, - "deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" - }, - "default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "requires": { - "execa": "^5.0.0" - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" - }, - "define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - } - }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" - }, - "define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "requires": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - } - }, - "delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", - "requires": { - "robust-predicates": "^3.0.2" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" - }, - "des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "detect-port": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", - "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", - "requires": { - "address": "^1.0.1", - "debug": "4" - } - }, - "detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "requires": { - "dequal": "^2.0.0" - } - }, - "diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "discontinuous-range": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", - "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", - "dev": true, - "peer": true - }, - "dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" - } - }, - "docusaurus-plugin-openapi-docs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/docusaurus-plugin-openapi-docs/-/docusaurus-plugin-openapi-docs-3.0.1.tgz", - "integrity": "sha512-6SRqwey/TXMNu2G02mbWgxrifhpjGOjDr30N+58AR0Ytgc+HXMqlPAUIvTe+e7sOBfAtBbiNlmOWv5KSYIjf3w==", - "requires": { - "@apidevtools/json-schema-ref-parser": "^11.5.4", - "@docusaurus/plugin-content-docs": "^3.0.1", - "@docusaurus/utils": "^3.0.1", - "@docusaurus/utils-validation": "^3.0.1", - "@redocly/openapi-core": "^1.10.5", - "chalk": "^4.1.2", - "clsx": "^1.1.1", - "fs-extra": "^9.0.1", - "json-pointer": "^0.6.2", - "json-schema-merge-allof": "^0.8.1", - "json5": "^2.2.3", - "lodash": "^4.17.20", - "mustache": "^4.2.0", - "openapi-to-postmanv2": "^4.21.0", - "postman-collection": "^4.4.0", - "slugify": "^1.6.5", - "swagger2openapi": "^7.0.8", - "xml-formatter": "^2.6.1" - }, - "dependencies": { - "clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - } - } - }, - "docusaurus-plugin-sass": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/docusaurus-plugin-sass/-/docusaurus-plugin-sass-0.2.5.tgz", - "integrity": "sha512-Z+D0fLFUKcFpM+bqSUmqKIU+vO+YF1xoEQh5hoFreg2eMf722+siwXDD+sqtwU8E4MvVpuvsQfaHwODNlxJAEg==", - "requires": { - "sass-loader": "^10.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "sass-loader": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.5.2.tgz", - "integrity": "sha512-vMUoSNOUKJILHpcNCCyD23X34gve1TS7Rjd9uXHeKqhvBG39x6XbswFDtpbTElj6XdMFezoWhkh5vtKudf2cgQ==", - "requires": { - "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" - } - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "docusaurus-plugin-sentry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/docusaurus-plugin-sentry/-/docusaurus-plugin-sentry-2.0.0.tgz", - "integrity": "sha512-LiiQ90pbaJ4ztgmFegK3+p8ywX4m0XHNtKGIRY1UD6xVRFubIejFFGaDXWOVU5FuATcMmE0d+WPNRPHLyYlFFw==", - "requires": {} - }, - "docusaurus-theme-openapi-docs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/docusaurus-theme-openapi-docs/-/docusaurus-theme-openapi-docs-3.0.1.tgz", - "integrity": "sha512-tqypV91tC3wuWj9O+4n0M/e5AgHOeMT2nvPj1tjlPkC7/dLinZvpwQStT4YDUPYSoHRseqxd7lhivFQHcmlryg==", - "requires": { - "@docusaurus/theme-common": "^3.0.1", - "@hookform/error-message": "^2.0.1", - "@reduxjs/toolkit": "^1.7.1", - "clsx": "^1.1.1", - "copy-text-to-clipboard": "^3.1.0", - "crypto-js": "^4.1.1", - "docusaurus-plugin-openapi-docs": "^3.0.1", - "docusaurus-plugin-sass": "^0.2.3", - "file-saver": "^2.0.5", - "lodash": "^4.17.20", - "node-polyfill-webpack-plugin": "^2.0.1", - "postman-code-generators": "^1.10.1", - "postman-collection": "^4.4.0", - "prism-react-renderer": "^2.3.0", - "react-hook-form": "^7.43.8", - "react-live": "^4.0.0", - "react-magic-dropzone": "^1.0.1", - "react-markdown": "^8.0.1", - "react-modal": "^3.15.1", - "react-redux": "^7.2.0", - "rehype-raw": "^6.1.1", - "sass": "^1.58.1", - "sass-loader": "^13.3.2", - "webpack": "^5.61.0", - "xml-formatter": "^2.6.1" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" - }, - "hast-util-raw": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", - "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", - "requires": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "rehype-raw": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", - "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", - "requires": { - "@types/hast": "^2.0.0", - "hast-util-raw": "^7.2.0", - "unified": "^10.0.0" - } - }, - "unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", - "requires": { - "@types/unist": "^2.0.0", - "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^5.0.0" - } - }, - "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - } - }, - "unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - } - }, - "vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - } - }, - "vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - } - } - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "requires": { - "utila": "~0.4" - } - }, - "dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", - "requires": { - "@babel/runtime": "^7.1.2" - } - }, - "dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - } - }, - "domain-browser": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", - "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==" - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" - }, - "domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "requires": { - "domelementtype": "^2.3.0" - } - }, - "dompurify": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.5.tgz", - "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==" - }, - "domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "requires": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "requires": { - "is-obj": "^2.0.0" - }, - "dependencies": { - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - } - } - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "electron-to-chromium": { - "version": "1.4.816", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz", - "integrity": "sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==" - }, - "elkjs": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", - "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" - }, - "elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", - "requires": { - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "emoticon": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", - "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" - }, - "enzyme": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", - "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", - "dev": true, - "peer": true, - "requires": { - "array.prototype.flat": "^1.2.3", - "cheerio": "^1.0.0-rc.3", - "enzyme-shallow-equal": "^1.0.1", - "function.prototype.name": "^1.1.2", - "has": "^1.0.3", - "html-element-map": "^1.2.0", - "is-boolean-object": "^1.0.1", - "is-callable": "^1.1.5", - "is-number-object": "^1.0.4", - "is-regex": "^1.0.5", - "is-string": "^1.0.5", - "is-subset": "^0.1.1", - "lodash.escape": "^4.0.1", - "lodash.isequal": "^4.5.0", - "object-inspect": "^1.7.0", - "object-is": "^1.0.2", - "object.assign": "^4.1.0", - "object.entries": "^1.1.1", - "object.values": "^1.1.1", - "raf": "^3.4.1", - "rst-selector-parser": "^2.2.3", - "string.prototype.trim": "^1.2.1" - } - }, - "enzyme-shallow-equal": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.7.tgz", - "integrity": "sha512-/um0GFqUXnpM9SvKtje+9Tjoz3f1fpBC3eXRFrNs8kpYn69JljciYP7KZTqM/YQbUY9KUjvKB4jo/q+L6WGGvg==", - "dev": true, - "requires": { - "hasown": "^2.0.0", - "object-is": "^1.1.5" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "requires": { - "stackframe": "^1.3.4" - } - }, - "es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true, - "peer": true - }, - "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "requires": { - "get-intrinsic": "^1.2.4" - } - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" - }, - "es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" - }, - "es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "requires": { - "es-errors": "^1.3.0" - } - }, - "es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - } - }, - "es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "peer": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==" - }, - "escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" - }, - "escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - }, - "eslint": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.6.0.tgz", - "integrity": "sha512-ElQkdLMEEqQNM9Njff+2Y4q2afHk7JpkPvrd7Xh7xefwgQynqPxwf55J7di9+MEibWUGdNjFF9ITG9Pck5M84w==", - "devOptional": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/config-array": "^0.17.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.6.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.1", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "devOptional": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "devOptional": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "devOptional": true - } - } - }, - "eslint-scope": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz", - "integrity": "sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==", - "devOptional": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "devOptional": true - }, - "espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", - "devOptional": true, - "requires": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "devOptional": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" - }, - "estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "requires": { - "@types/estree": "^1.0.0" - } - }, - "estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - } - }, - "estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==" - }, - "estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - } - }, - "estree-util-value-to-estree": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", - "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", - "requires": { - "@types/estree": "^1.0.0" - } - }, - "estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - } - }, - "estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "requires": { - "@types/estree": "^1.0.0" - } - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "requires": { - "@types/node": "*", - "require-like": ">= 0.1.1" - } - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, - "eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exenv": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", - "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" - }, - "express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "devOptional": true - }, - "fast-loops": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.4.tgz", - "integrity": "sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg==" - }, - "fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "fast-shallow-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", - "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" - }, - "fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "requires": { - "punycode": "^1.3.2" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - } - } - }, - "fastest-stable-stringify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", - "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==" - }, - "fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "requires": { - "reusify": "^1.0.4" - } - }, - "fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "requires": { - "format": "^0.2.0" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "feed": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "requires": { - "xml-js": "^1.6.11" - } - }, - "file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "devOptional": true, - "requires": { - "flat-cache": "^4.0.0" - } - }, - "file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "file-saver": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", - "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" - }, - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==" - }, - "filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==" - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "requires": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "requires": { - "micromatch": "^4.0.2" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" - }, - "flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "devOptional": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - } - }, - "flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "devOptional": true - }, - "fnv-plus": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/fnv-plus/-/fnv-plus-1.3.1.tgz", - "integrity": "sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw==" - }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "foreach": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", - "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==" - }, - "foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "dependencies": { - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - } - } - }, - "fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - } - } - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==" - }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - } - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "get-port-please": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-3.1.2.tgz", - "integrity": "sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" - }, - "get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - } - }, - "github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "requires": { - "ini": "2.0.0" - }, - "dependencies": { - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" - } - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "requires": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "requires": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==" - } - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", - "requires": { - "lodash": "^4.17.15" - } - }, - "gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "requires": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, - "gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "requires": { - "duplexer": "^0.1.2" - } - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "dev": true - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "requires": { - "es-define-property": "^1.0.0" - } - }, - "has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "requires": { - "has-symbols": "^1.0.3" - } - }, - "has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==" - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash-color-material": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash-color-material/-/hash-color-material-1.1.3.tgz", - "integrity": "sha512-SkyBUHHWqaLI5+wUWvEcvy0i4bvf/lrr7xauh6LB7Z/gkD8dYoQpemNA42Zy3KZ970GuuUYL+txRn1B+Xgaf0g==" - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "hast-to-hyperscript": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-10.0.3.tgz", - "integrity": "sha512-NuBoUStp4fRwmvlfbidlEiRSTk0gSHm+97q4Xn9CJ10HO+Py7nlTuDi6RhM1qLOureukGrCXLG7AAxaGqqyslQ==", - "requires": { - "@types/unist": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.1", - "web-namespaces": "^2.0.0" - }, - "dependencies": { - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "hast-util-from-dom": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", - "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", - "requires": { - "@types/hast": "^3.0.0", - "hastscript": "^8.0.0", - "web-namespaces": "^2.0.0" - }, - "dependencies": { - "hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "requires": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - } - } - } - }, - "hast-util-from-html": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", - "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", - "requires": { - "@types/hast": "^3.0.0", - "devlop": "^1.1.0", - "hast-util-from-parse5": "^8.0.0", - "parse5": "^7.0.0", - "vfile": "^6.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "requires": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - } - }, - "hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "requires": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - } - }, - "vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "requires": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - } - } - } - }, - "hast-util-from-html-isomorphic": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", - "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", - "requires": { - "@types/hast": "^3.0.0", - "hast-util-from-dom": "^5.0.0", - "hast-util-from-html": "^2.0.0", - "unist-util-remove-position": "^5.0.0" - } - }, - "hast-util-from-parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", - "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "hastscript": "^7.0.0", - "property-information": "^6.0.0", - "vfile": "^5.0.0", - "vfile-location": "^4.0.0", - "web-namespaces": "^2.0.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - } - }, - "vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - } - } - } - }, - "hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", - "requires": { - "@types/hast": "^2.0.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "hast-util-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.0.0.tgz", - "integrity": "sha512-3UKuYgaqakZrY916JfQzqSk8xZGyxpj9zwfPB3MctXLDorPdyqk1QZGZoCEqU2LMIEzVXBZukAQs7aAH9TJPIw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "@types/unist": "^2.0.3", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^3.0.0", - "vfile": "^4.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "requires": { - "@types/unist": "^2.0.2" - } - }, - "unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - } - }, - "unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - } - }, - "vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - } - }, - "vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - } - } - } - }, - "hast-util-sanitize": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-4.1.0.tgz", - "integrity": "sha512-Hd9tU0ltknMGRDv+d6Ro/4XKzBqQnP/EZrpiTbpFYfXv/uOhWeKc+2uajcbEvAEH98VZd7eII2PiXm13RihnLw==", - "requires": { - "@types/hast": "^2.0.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "hast-util-to-estree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", - "requires": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "dependencies": { - "hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "requires": { - "@types/unist": "^3.0.0" - } - } - } - }, - "hast-util-to-jsx-runtime": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", - "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", - "requires": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "inline-style-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz", - "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" - }, - "style-to-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", - "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", - "requires": { - "inline-style-parser": "0.2.3" - } - }, - "unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "requires": { - "@types/unist": "^3.0.0" - } - } - } - }, - "hast-util-to-parse5": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", - "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", - "requires": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "hast-util-to-text": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", - "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", - "requires": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - } - }, - "hast-util-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", - "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==" - }, - "hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", - "requires": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" - }, - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "html-element-map": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.1.tgz", - "integrity": "sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==", - "dev": true, - "peer": true, - "requires": { - "array.prototype.filter": "^1.0.0", - "call-bind": "^1.0.2" - } - }, - "html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", - "requires": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "dependencies": { - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" - } - } - }, - "html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==" - }, - "html-void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", - "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==" - }, - "html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", - "requires": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" - }, - "html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "requires": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - } - } - } - }, - "htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "dependencies": { - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - } - } - }, - "http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" - } - } - }, - "http-reasons": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/http-reasons/-/http-reasons-0.1.0.tgz", - "integrity": "sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ==" - }, - "http2-client": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", - "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==" - }, - "http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" - }, - "https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, - "husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", - "dev": true - }, - "hyphenate-style-name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", - "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==" - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "requires": {} - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==" - }, - "image-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", - "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", - "requires": { - "queue": "6.0.2" - } - }, - "immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" - }, - "immutable": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", - "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==" - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "infima": { - "version": "0.2.0-alpha.43", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.43.tgz", - "integrity": "sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "inline-style-prefixer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.0.tgz", - "integrity": "sha512-I7GEdScunP1dQ6IM2mQWh6v0mOYdYmH3Bp31UecKdrcUgcURTcctSe1IECdUznSHKSmsHtjrT3CwCPI1pyxfUQ==", - "requires": { - "css-in-js-utils": "^3.1.0", - "fast-loops": "^1.1.3" - } - }, - "internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "requires": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - } - }, - "internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==" - }, - "is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==" - }, - "is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "requires": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - } - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" - }, - "is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "requires": { - "ci-info": "^3.2.0" - } - }, - "is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", - "requires": { - "hasown": "^2.0.2" - } - }, - "is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "requires": { - "is-typed-array": "^1.1.13" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==" - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==" - }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true - }, - "is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" - }, - "is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "requires": { - "@types/estree": "*" - } - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" - }, - "is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" - }, - "is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-subset": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", - "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==", - "dev": true, - "peer": true - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "requires": { - "which-typed-array": "^1.1.14" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "requires": { - "is-docker": "^2.0.0" - } - }, - "is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==" - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "jackspeak": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "requires": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==" - }, - "joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "requires": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "jotai": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/jotai/-/jotai-1.13.1.tgz", - "integrity": "sha512-RUmH1S4vLsG3V6fbGlKzGJnLrDcC/HNb5gH2AeA9DzuJknoVxSGvvg8OBB7lke+gDc4oXmdVsaKn/xDUhWZ0vw==", - "requires": {} - }, - "js-cookie": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" - }, - "js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json-pointer": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.2.tgz", - "integrity": "sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==", - "requires": { - "foreach": "^2.0.4" - } - }, - "json-schema-compare": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", - "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", - "requires": { - "lodash": "^4.17.4" - } - }, - "json-schema-merge-allof": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", - "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", - "requires": { - "compute-lcm": "^1.1.2", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.20" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "json-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", - "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", - "requires": { - "call-bind": "^1.0.5", - "isarray": "^2.0.5", - "jsonify": "^0.0.1", - "object-keys": "^1.1.1" - } - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "devOptional": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==" - }, - "jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" - }, - "katex": { - "version": "0.16.11", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", - "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", - "requires": { - "commander": "^8.3.0" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" - } - } - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "requires": { - "json-buffer": "3.0.1" - } - }, - "khroma": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", - "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "requires": { - "graceful-fs": "^4.1.11" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" - }, - "klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==" - }, - "latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "requires": { - "package-json": "^8.1.0" - } - }, - "launch-editor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", - "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", - "requires": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "layout-base": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", - "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "devOptional": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==" - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "liquid-json": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/liquid-json/-/liquid-json-0.3.1.tgz", - "integrity": "sha512-wUayTU8MS827Dam6MxgD72Ui+KOSF+u/eIqpatOtjnvgJ0+mnDq33uC2M7J0tPK+upe/DpUAuK4JUU89iBoNKQ==" - }, - "load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==", - "dev": true - }, - "loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" - }, - "loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "lodash.escape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", - "integrity": "sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==", - "dev": true, - "peer": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true, - "peer": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "devOptional": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "requires": { - "tslib": "^2.0.3" - } - }, - "lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==" - }, - "lowlight": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", - "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", - "requires": { - "fault": "^1.0.0", - "highlight.js": "~10.7.0" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", - "dev": true - }, - "luxon": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", - "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==" - }, - "magic-error": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/magic-error/-/magic-error-0.0.1.tgz", - "integrity": "sha512-1+N1ET8cbC5bfLQZcRojClzgK2gbUt9keTMr9OJeuXnQKWsfwRRRICuMA3HKaCIXFEgKzxivuMGCNKD7cdU5pg==" - }, - "mark.js": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", - "dev": true - }, - "markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==" - }, - "markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==" - }, - "markdown-to-jsx": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.4.7.tgz", - "integrity": "sha512-0+ls1IQZdU6cwM1yu0ZjjiVWYtkbExSyUIFU2ZeDIFuZM1W42Mh4OlJ4nb4apX4H8smxDHRdFaoIVJGwfv5hkg==", - "requires": {} - }, - "marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdast-util-definitions": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", - "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "unist-util-visit": "^4.0.0" - }, - "dependencies": { - "@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - } - }, - "unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - } - } - } - }, - "mdast-util-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", - "requires": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - } - }, - "mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", - "requires": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" - } - } - }, - "mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "requires": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "requires": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" - } - } - }, - "mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", - "requires": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", - "requires": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", - "requires": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - } - }, - "mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "requires": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "requires": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-math": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", - "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", - "requires": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "longest-streak": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.1.0", - "unist-util-remove-position": "^5.0.0" - } - }, - "mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "requires": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-mdx-jsx": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz", - "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - } - }, - "mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "requires": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - } - }, - "mdast-util-to-hast": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-11.3.0.tgz", - "integrity": "sha512-4o3Cli3hXPmm1LhB+6rqhfsIUBjnKFlIUZvudaermXB+4/KONdd/W4saWWkC+LBLbPMqhFSSTSRgafHsT5fVJw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "@types/mdurl": "^1.0.0", - "mdast-util-definitions": "^5.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^3.0.0", - "unist-util-generated": "^2.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - } - }, - "unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - } - } - } - }, - "mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "requires": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - } - }, - "mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "requires": { - "@types/mdast": "^4.0.0" - } - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "memfs": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.6.0.tgz", - "integrity": "sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ==", - "requires": { - "fs-monkey": "^1.0.4" - } - }, - "memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", - "dev": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "mermaid": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.1.tgz", - "integrity": "sha512-Mx45Obds5W1UkW1nv/7dHRsbfMM1aOKA2+Pxs/IGHNonygDHwmng8xTHyS9z4KWVi0rbko8gjiBmuwwXQ7tiNA==", - "requires": { - "@braintree/sanitize-url": "^6.0.1", - "@types/d3-scale": "^4.0.3", - "@types/d3-scale-chromatic": "^3.0.0", - "cytoscape": "^3.28.1", - "cytoscape-cose-bilkent": "^4.1.0", - "d3": "^7.4.0", - "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.10", - "dayjs": "^1.11.7", - "dompurify": "^3.0.5", - "elkjs": "^0.9.0", - "katex": "^0.16.9", - "khroma": "^2.0.0", - "lodash-es": "^4.17.21", - "mdast-util-from-markdown": "^1.3.0", - "non-layered-tidy-tree-layout": "^2.0.2", - "stylis": "^4.1.3", - "ts-dedent": "^2.2.0", - "uuid": "^9.0.0", - "web-worker": "^1.2.0" - }, - "dependencies": { - "@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - } - }, - "mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "requires": { - "@types/mdast": "^3.0.0" - } - }, - "micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "requires": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==" - }, - "micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==" - }, - "micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "requires": { - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" - }, - "unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "requires": { - "@types/unist": "^2.0.0" - } - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "requires": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", - "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", - "requires": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "requires": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "requires": { - "format": "^0.2.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "requires": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-extension-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", - "requires": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", - "requires": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", - "requires": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "requires": { - "micromark-util-types": "^2.0.0" - } - }, - "micromark-extension-gfm-task-list-item": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", - "requires": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-math": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.0.0.tgz", - "integrity": "sha512-iJ2Q28vBoEovLN5o3GO12CpqorQRYDPT+p4zW50tGwTfJB+iv/VnB6Ini+gqa24K97DwptMBBIvVX6Bjk49oyQ==", - "requires": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-mdx-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", - "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", - "requires": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", - "requires": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "requires": { - "micromark-util-types": "^2.0.0" - } - }, - "micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "requires": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "requires": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "requires": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", - "requires": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "dependencies": { - "micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" - } - } - }, - "micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "requires": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "requires": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "requires": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "dependencies": { - "micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" - } - } - }, - "micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "requires": { - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "requires": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "requires": { - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==" - }, - "micromark-util-events-to-acorn": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", - "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", - "requires": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==" - }, - "micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "requires": { - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "requires": { - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "requires": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==" - }, - "micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==" - }, - "micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "requires": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-format": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mime-format/-/mime-format-2.0.1.tgz", - "integrity": "sha512-XxU3ngPbEnrYnNbIX+lYSaYg0M01v6p2ntd2YaFksTu0vayaw5OJvbdRyWs07EYRlLED5qadUZ+xo+XhOvFhwg==", - "requires": { - "charset": "^1.0.0" - } - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==" - }, - "mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", - "requires": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==" - }, - "mobx": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.13.0.tgz", - "integrity": "sha512-1laWODrBWmB7mDJ8EClCjUQTyLwJ0ydJgE4FtK7t9r3JnjXgc9OhmYs2P4RtHrY1co5+4T6cKP2UswX2SU29mA==", - "dev": true - }, - "mobx-react": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.1.1.tgz", - "integrity": "sha512-gVV7AdSrAAxqXOJ2bAbGa5TkPqvITSzaPiiEkzpW4rRsMhSec7C2NBCJYILADHKp2tzOAIETGRsIY0UaCV5aEw==", - "dev": true, - "requires": { - "mobx-react-lite": "^4.0.7" - } - }, - "mobx-react-lite": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.0.7.tgz", - "integrity": "sha512-RjwdseshK9Mg8On5tyJZHtGD+J78ZnCnRaxeQDSiciKVQDUbfZcXhmld0VMxAwvcTnPEHZySGGewm467Fcpreg==", - "dev": true, - "requires": { - "use-sync-external-store": "^1.2.0" - } - }, - "moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==" - }, - "moment-timezone": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", - "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", - "requires": { - "moment": "^2.29.4" - } - }, - "moo": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", - "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", - "dev": true, - "peer": true - }, - "mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" - }, - "mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - } - }, - "mustache": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", - "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==" - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "nano-css": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.6.1.tgz", - "integrity": "sha512-T2Mhc//CepkTa3X4pUhKgbEheJHYAxD0VptuqFhDbGMUWVV2m+lkNiW/Ieuj35wrfC8Zm0l7HvssQh7zcEttSw==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "css-tree": "^1.1.2", - "csstype": "^3.1.2", - "fastest-stable-stringify": "^2.0.2", - "inline-style-prefixer": "^7.0.0", - "rtl-css-js": "^1.16.1", - "stacktrace-js": "^2.0.2", - "stylis": "^4.3.0" - } - }, - "nano-memoize": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/nano-memoize/-/nano-memoize-1.3.1.tgz", - "integrity": "sha512-wQiW3xHptgGlec/Zbo7oq6Zz4kKoK8TaIIs1irTO9iJOGTIG3lnQRUJfH73bJ/rn7MOE4sTdSU+ALPGEidaijQ==" - }, - "nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "devOptional": true - }, - "nearley": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", - "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", - "dev": true, - "peer": true, - "requires": { - "commander": "^2.19.0", - "moo": "^0.5.0", - "railroad-diagrams": "^1.0.0", - "randexp": "0.4.6" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true - } - } - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "requires": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - } - }, - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-fetch-h2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", - "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", - "requires": { - "http2-client": "^1.2.5" - } - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" - }, - "node-polyfill-webpack-plugin": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-2.0.1.tgz", - "integrity": "sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A==", - "requires": { - "assert": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.12.0", - "domain-browser": "^4.22.0", - "events": "^3.3.0", - "filter-obj": "^2.0.2", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^4.0.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "^0.0.1", - "type-fest": "^2.14.0", - "url": "^0.11.0", - "util": "^0.12.4", - "vm-browserify": "^1.1.2" - } - }, - "node-readfiles": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", - "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", - "requires": { - "es6-promise": "^3.2.1" - } - }, - "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" - }, - "non-layered-tidy-tree-layout": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", - "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" - }, - "normalize-url": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==" - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "npm-to-yarn": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/npm-to-yarn/-/npm-to-yarn-2.2.1.tgz", - "integrity": "sha512-O/j/ROyX0KGLG7O6Ieut/seQ0oiTpHF2tXAcFbpdTLQFiaNtkyTXXocM1fwpaa60dg1qpWj0nHlbNhx6qwuENQ==" - }, - "nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "requires": { - "boolbase": "^1.0.0" - } - }, - "oas-kit-common": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", - "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", - "requires": { - "fast-safe-stringify": "^2.0.7" - } - }, - "oas-linter": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", - "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", - "requires": { - "@exodus/schemasafe": "^1.0.0-rc.2", - "should": "^13.2.1", - "yaml": "^1.10.0" - } - }, - "oas-resolver": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", - "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", - "requires": { - "node-fetch-h2": "^2.3.0", - "oas-kit-common": "^1.0.8", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - } - }, - "oas-resolver-browser": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver-browser/-/oas-resolver-browser-2.5.6.tgz", - "integrity": "sha512-Jw5elT/kwUJrnGaVuRWe1D7hmnYWB8rfDDjBnpQ+RYY/dzAewGXeTexXzt4fGEo6PUE4eqKqPWF79MZxxvMppA==", - "requires": { - "node-fetch-h2": "^2.3.0", - "oas-kit-common": "^1.0.8", - "path-browserify": "^1.0.1", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - } - }, - "oas-schema-walker": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", - "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==" - }, - "oas-validator": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", - "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", - "requires": { - "call-me-maybe": "^1.0.1", - "oas-kit-common": "^1.0.8", - "oas-linter": "^3.2.2", - "oas-resolver": "^2.5.6", - "oas-schema-walker": "^1.1.5", - "reftools": "^1.1.9", - "should": "^13.2.1", - "yaml": "^1.10.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" - }, - "object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" - }, - "object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "requires": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - } - }, - "openapi-sampler": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.5.1.tgz", - "integrity": "sha512-tIWIrZUKNAsbqf3bd9U1oH6JEXo8LNYuDlXw26By67EygpjT+ArFnsxxyTMjFWRfbqo5ozkvgSQDK69Gd8CddA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "json-pointer": "0.6.2" - } - }, - "openapi-to-postmanv2": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/openapi-to-postmanv2/-/openapi-to-postmanv2-4.21.0.tgz", - "integrity": "sha512-UyHf2xOjDfl4bIaYrUP6w4UiR894gsiOt1HR93cWOxv33Ucw4rGG0B6ewQczSGBpvFMgri+KSSykNEVjsmB55w==", - "requires": { - "ajv": "8.11.0", - "ajv-draft-04": "1.0.0", - "ajv-formats": "2.1.1", - "async": "3.2.4", - "commander": "2.20.3", - "graphlib": "2.1.8", - "js-yaml": "4.1.0", - "json-schema-merge-allof": "0.8.1", - "lodash": "4.17.21", - "oas-resolver-browser": "2.5.6", - "object-hash": "3.0.0", - "path-browserify": "1.0.1", - "postman-collection": "4.2.1", - "swagger2openapi": "7.0.8", - "traverse": "0.6.6", - "yaml": "1.10.2" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "postman-collection": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.2.1.tgz", - "integrity": "sha512-DFLt3/yu8+ldtOTIzmBUctoupKJBOVK4NZO0t68K2lIir9smQg7OdQTBjOXYy+PDh7u0pSDvD66tm93eBHEPHA==", - "requires": { - "@faker-js/faker": "5.5.3", - "file-type": "3.9.0", - "http-reasons": "0.1.0", - "iconv-lite": "0.6.3", - "liquid-json": "0.3.1", - "lodash": "4.17.21", - "mime-format": "2.0.1", - "mime-types": "2.1.35", - "postman-url-encoder": "3.0.5", - "semver": "7.5.4", - "uuid": "8.3.2" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" - }, - "optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "devOptional": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" - }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==" - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "requires": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "requires": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - } - }, - "package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", - "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", - "requires": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "hash-base": "~3.0", - "pbkdf2": "^3.1.2", - "safe-buffer": "^5.2.1" - } - }, - "parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "requires": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "dependencies": { - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse-numeric-range": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" - }, - "parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "requires": { - "entities": "^4.4.0" - } - }, - "parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "requires": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "ci-info": "^3.7.0", - "cross-spawn": "^7.0.3", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", - "json-stable-stringify": "^1.0.2", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^7.5.3", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^2.2.2" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - }, - "yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==" - } - } - }, - "path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", - "requires": { - "process": "^0.11.1", - "util": "^0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "requires": { - "inherits": "2.0.3" - } - } - } - }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "requires": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", - "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==" - } - } - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - } - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "perfect-scrollbar": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz", - "integrity": "sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g==", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "peer": true - }, - "periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" - }, - "pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "requires": { - "find-up": "^6.3.0" - }, - "dependencies": { - "find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "requires": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - } - }, - "locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "requires": { - "p-locate": "^6.0.0" - } - }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "requires": { - "yocto-queue": "^1.0.0" - } - }, - "p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "requires": { - "p-limit": "^4.0.0" - } - }, - "path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==" - }, - "yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==" - } - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" - } - } - }, - "pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" - }, - "polished": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", - "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", - "requires": { - "@babel/runtime": "^7.17.8" - } - }, - "possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==" - }, - "postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", - "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" - } - }, - "postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "requires": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-colormin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", - "requires": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "colord": "^2.9.3", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-convert-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", - "requires": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-discard-comments": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", - "requires": {} - }, - "postcss-discard-duplicates": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", - "requires": {} - }, - "postcss-discard-empty": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", - "requires": {} - }, - "postcss-discard-overridden": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", - "requires": {} - }, - "postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "requires": { - "postcss-selector-parser": "^6.0.16" - } - }, - "postcss-loader": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", - "requires": { - "cosmiconfig": "^8.3.5", - "jiti": "^1.20.0", - "semver": "^7.5.4" - } - }, - "postcss-merge-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", - "requires": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-merge-longhand": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", - "requires": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.1.1" - } - }, - "postcss-merge-rules": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", - "requires": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" - } - }, - "postcss-minify-font-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-gradients": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", - "requires": { - "colord": "^2.9.3", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-params": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", - "requires": { - "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", - "requires": { - "postcss-selector-parser": "^6.0.16" - } - }, - "postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "requires": {} - }, - "postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-normalize-charset": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", - "requires": {} - }, - "postcss-normalize-display-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-positions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-string": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-unicode": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", - "requires": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-whitespace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-ordered-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", - "requires": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reduce-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reduce-initial": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", - "requires": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-sort-media-queries": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", - "requires": { - "sort-css-media-queries": "2.2.0" - } - }, - "postcss-svgo": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", - "requires": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - } - }, - "postcss-unique-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", - "requires": { - "postcss-selector-parser": "^6.0.16" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "postcss-zindex": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", - "requires": {} - }, - "postman-code-generators": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/postman-code-generators/-/postman-code-generators-1.10.1.tgz", - "integrity": "sha512-VGjqIFezG6tZRP3GvSbYjLDq3bQtXUeNDnBrN5CUIbgc9siu5Ubkva9hZnFpk+/qfi+PXs3CUR5mvV+WzpMhsg==", - "requires": { - "async": "3.2.2", - "lodash": "4.17.21", - "path": "0.12.7", - "postman-collection": "4.0.0", - "shelljs": "0.8.5" - }, - "dependencies": { - "async": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", - "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==" - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" - }, - "mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", - "requires": { - "mime-db": "1.48.0" - } - }, - "postman-collection": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.0.0.tgz", - "integrity": "sha512-vDrXG/dclSu6RMqPqBz4ZqoQBwcj/a80sJYsQZmzWJ6dWgXiudPhwu6Vm3C1Hy7zX5W8A6am1Z6vb/TB4eyURA==", - "requires": { - "faker": "5.5.3", - "file-type": "3.9.0", - "http-reasons": "0.1.0", - "iconv-lite": "0.6.3", - "liquid-json": "0.3.1", - "lodash": "4.17.21", - "mime-format": "2.0.1", - "mime-types": "2.1.31", - "postman-url-encoder": "3.0.1", - "semver": "7.3.5", - "uuid": "8.3.2" - } - }, - "postman-url-encoder": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.1.tgz", - "integrity": "sha512-dMPqXnkDlstM2Eya+Gw4MIGWEan8TzldDcUKZIhZUsJ/G5JjubfQPhFhVWKzuATDMvwvrWbSjF+8VmAvbu6giw==", - "requires": { - "punycode": "^2.1.1" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "postman-collection": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.4.0.tgz", - "integrity": "sha512-2BGDFcUwlK08CqZFUlIC8kwRJueVzPjZnnokWPtJCd9f2J06HBQpGL7t2P1Ud1NEsK9NHq9wdipUhWLOPj5s/Q==", - "requires": { - "@faker-js/faker": "5.5.3", - "file-type": "3.9.0", - "http-reasons": "0.1.0", - "iconv-lite": "0.6.3", - "liquid-json": "0.3.1", - "lodash": "4.17.21", - "mime-format": "2.0.1", - "mime-types": "2.1.35", - "postman-url-encoder": "3.0.5", - "semver": "7.5.4", - "uuid": "8.3.2" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "postman-url-encoder": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.5.tgz", - "integrity": "sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA==", - "requires": { - "punycode": "^2.1.1" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "devOptional": true - }, - "prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", - "dev": true - }, - "pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "requires": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" - }, - "prism-react-renderer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", - "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", - "requires": { - "@types/prismjs": "^1.26.0", - "clsx": "^2.0.0" - } - }, - "prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "property-information": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", - "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==" - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - } - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" - }, - "pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", - "requires": { - "escape-goat": "^4.0.0" - } - }, - "qs": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz", - "integrity": "sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==", - "requires": { - "side-channel": "^1.0.6" - } - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==" - }, - "queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "requires": { - "inherits": "~2.0.3" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" - }, - "raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "dev": true, - "peer": true, - "requires": { - "performance-now": "^2.1.0" - } - }, - "railroad-diagrams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", - "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==", - "dev": true, - "peer": true - }, - "randexp": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", - "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", - "dev": true, - "peer": true, - "requires": { - "discontinuous-range": "1.0.0", - "ret": "~0.1.10" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==" - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" - } - } - }, - "react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "requires": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==" - }, - "open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - } - } - }, - "react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - } - }, - "react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" - }, - "react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "requires": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - } - }, - "react-hook-form": { - "version": "7.52.1", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.1.tgz", - "integrity": "sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==", - "requires": {} - }, - "react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "react-json-view-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.4.0.tgz", - "integrity": "sha512-wh6F6uJyYAmQ4fK0e8dSQMEWuvTs2Wr3el3sLD9bambX1+pSWUVXIz1RFaoy3TI1mZ0FqdpKq9YgbgTTgyrmXA==", - "requires": {} - }, - "react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "react-live": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/react-live/-/react-live-4.1.7.tgz", - "integrity": "sha512-NTzl0POOAW3dkp7+QL30duOrIu2Vzf2LHdx4TaQ0BqOAtQcSTKEXujfm9jR2VoCHko0oi35PYp38yKQBXz4mrg==", - "requires": { - "prism-react-renderer": "^2.0.6", - "sucrase": "^3.31.0", - "use-editable": "^2.3.3" - } - }, - "react-loadable": { - "version": "npm:@docusaurus/react-loadable@6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", - "requires": { - "@types/react": "*" - } - }, - "react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "requires": { - "@babel/runtime": "^7.10.3" - } - }, - "react-magic-dropzone": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-magic-dropzone/-/react-magic-dropzone-1.0.1.tgz", - "integrity": "sha512-0BIROPARmXHpk4AS3eWBOsewxoM5ndk2psYP/JmbCq8tz3uR2LIV1XiroZ9PKrmDRMctpW+TvsBCtWasuS8vFA==" - }, - "react-markdown": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz", - "integrity": "sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ==", - "requires": { - "@types/hast": "^2.0.0", - "@types/prop-types": "^15.0.0", - "@types/unist": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^2.0.0", - "prop-types": "^15.0.0", - "property-information": "^6.0.0", - "react-is": "^18.0.0", - "remark-parse": "^10.0.0", - "remark-rehype": "^10.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unified": "^10.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - } - }, - "mdast-util-to-hast": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", - "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-definitions": "^5.0.0", - "micromark-util-sanitize-uri": "^1.1.0", - "trim-lines": "^3.0.0", - "unist-util-generated": "^2.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0" - } - }, - "mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "requires": { - "@types/mdast": "^3.0.0" - } - }, - "micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "requires": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==" - }, - "micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==" - }, - "micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "requires": { - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" - }, - "remark-parse": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", - "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "unified": "^10.0.0" - } - }, - "remark-rehype": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", - "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-to-hast": "^12.1.0", - "unified": "^10.0.0" - } - }, - "unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", - "requires": { - "@types/unist": "^2.0.0", - "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^5.0.0" - } - }, - "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - } - }, - "unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - } - }, - "vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - } - }, - "vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - } - } - } - }, - "react-modal": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.1.tgz", - "integrity": "sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==", - "requires": { - "exenv": "^1.2.0", - "prop-types": "^15.7.2", - "react-lifecycles-compat": "^3.0.0", - "warning": "^4.0.3" - } - }, - "react-overflow-list": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/react-overflow-list/-/react-overflow-list-0.5.0.tgz", - "integrity": "sha512-+UegukgQ10E4ll3txz4DJyrnCgZ3eDVuv5dvR8ziyG5FfgCDZcUKeKhIgbU90oyqQa21aH4oLOoGKt0TiYJRmg==", - "requires": { - "react-use": "^17.3.1" - } - }, - "react-player": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.16.0.tgz", - "integrity": "sha512-mAIPHfioD7yxO0GNYVFD1303QFtI3lyyQZLY229UEAp/a10cSW+hPcakg0Keq8uWJxT2OiT/4Gt+Lc9bD6bJmQ==", - "dev": true, - "requires": { - "deepmerge": "^4.0.0", - "load-script": "^1.0.0", - "memoize-one": "^5.1.1", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.0.1" - } - }, - "react-redux": { - "version": "7.2.9", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", - "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", - "requires": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - }, - "dependencies": { - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - } - } - }, - "react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "react-router-config": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "requires": { - "@babel/runtime": "^7.1.2" - } - }, - "react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-shallow-renderer": { - "version": "16.15.0", - "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", - "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" - } - }, - "react-syntax-highlighter": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", - "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", - "requires": { - "@babel/runtime": "^7.3.1", - "highlight.js": "^10.4.1", - "lowlight": "^1.17.0", - "prismjs": "^1.27.0", - "refractor": "^3.6.0" - } - }, - "react-tabs": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.0.2.tgz", - "integrity": "sha512-aQXTKolnM28k3KguGDBSAbJvcowOQr23A+CUJdzJtOSDOtTwzEaJA+1U4KwhNL9+Obe+jFS7geuvA7ICQPXOnQ==", - "dev": true, - "requires": { - "clsx": "^2.0.0", - "prop-types": "^15.5.0" - } - }, - "react-universal-interface": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", - "integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==", - "requires": {} - }, - "react-use": { - "version": "17.5.0", - "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.5.0.tgz", - "integrity": "sha512-PbfwSPMwp/hoL847rLnm/qkjg3sTRCvn6YhUZiHaUa3FA6/aNoFX79ul5Xt70O1rK+9GxSVqkY0eTwMdsR/bWg==", - "requires": { - "@types/js-cookie": "^2.2.6", - "@xobotyi/scrollbar-width": "^1.9.5", - "copy-to-clipboard": "^3.3.1", - "fast-deep-equal": "^3.1.3", - "fast-shallow-equal": "^1.0.0", - "js-cookie": "^2.2.1", - "nano-css": "^5.6.1", - "react-universal-interface": "^0.6.2", - "resize-observer-polyfill": "^1.5.1", - "screenfull": "^5.1.0", - "set-harmonic-interval": "^1.0.1", - "throttle-debounce": "^3.0.1", - "ts-easing": "^0.2.0", - "tslib": "^2.1.0" - } - }, - "readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "requires": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "reading-time": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "requires": { - "resolve": "^1.1.6" - } - }, - "recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "requires": { - "minimatch": "^3.0.5" - } - }, - "redoc": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.1.5.tgz", - "integrity": "sha512-POSbVg+7WLf+/5/c6GWLxL7+9t2D+1WlZdLN0a6qaCQc+ih3XYzteRBkXEN5kjrYrRNjdspfxTZkDLN5WV3Tzg==", - "dev": true, - "requires": { - "@cfaester/enzyme-adapter-react-18": "^0.8.0", - "@redocly/openapi-core": "^1.4.0", - "classnames": "^2.3.2", - "decko": "^1.2.0", - "dompurify": "^3.0.6", - "eventemitter3": "^5.0.1", - "json-pointer": "^0.6.2", - "lunr": "^2.3.9", - "mark.js": "^8.11.1", - "marked": "^4.3.0", - "mobx-react": "^9.1.1", - "openapi-sampler": "^1.5.0", - "path-browserify": "^1.0.1", - "perfect-scrollbar": "^1.5.5", - "polished": "^4.2.2", - "prismjs": "^1.29.0", - "prop-types": "^15.8.1", - "react-tabs": "^6.0.2", - "slugify": "~1.4.7", - "stickyfill": "^1.1.1", - "swagger2openapi": "^7.0.8", - "url-template": "^2.0.8" - }, - "dependencies": { - "slugify": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz", - "integrity": "sha512-tf+h5W1IrjNm/9rKKj0JU2MDMruiopx0jjVA5zCdBtcGjfp0+c5rHw/zADLC3IeKlGHtVbHtpfzvYA0OYT+HKg==", - "dev": true - } - } - }, - "redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "requires": { - "@babel/runtime": "^7.9.2" - } - }, - "redux-thunk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", - "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", - "requires": {} - }, - "refractor": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", - "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", - "requires": { - "hastscript": "^6.0.0", - "parse-entities": "^2.0.0", - "prismjs": "~1.27.0" - }, - "dependencies": { - "@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" - }, - "comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" - }, - "hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" - }, - "hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "requires": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - } - }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" - }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "prismjs": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", - "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==" - }, - "property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "requires": { - "xtend": "^4.0.0" - } - }, - "space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" - } - } - }, - "reftools": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", - "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==" - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - } - }, - "regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "requires": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - } - }, - "registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "requires": { - "@pnpm/npm-conf": "^2.1.0" - } - }, - "registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "requires": { - "rc": "1.2.8" - } - }, - "regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" - } - } - }, - "rehype-katex": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz", - "integrity": "sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q==", - "requires": { - "@types/hast": "^3.0.0", - "@types/katex": "^0.16.0", - "hast-util-from-html-isomorphic": "^2.0.0", - "hast-util-to-text": "^4.0.0", - "katex": "^0.16.0", - "unist-util-visit-parents": "^6.0.0", - "vfile": "^6.0.0" - } - }, - "rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "requires": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "dependencies": { - "hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "requires": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - } - }, - "hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "hast-util-raw": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", - "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", - "requires": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - } - }, - "hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "requires": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - } - }, - "hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "requires": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - } - }, - "html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==" - }, - "mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "requires": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - } - }, - "unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "requires": { - "@types/unist": "^3.0.0" - } - }, - "vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "requires": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - } - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" - }, - "remark-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", - "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - } - }, - "remark-emoji": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", - "requires": { - "@types/mdast": "^4.0.2", - "emoticon": "^4.0.1", - "mdast-util-find-and-replace": "^3.0.1", - "node-emoji": "^2.1.0", - "unified": "^11.0.4" - } - }, - "remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - } - }, - "remark-gfm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "dependencies": { - "remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - } - } - } - }, - "remark-math": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", - "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-math": "^3.0.0", - "micromark-extension-math": "^3.0.0", - "unified": "^11.0.0" - } - }, - "remark-mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", - "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", - "requires": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - } - }, - "remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - } - }, - "remark-rehype": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", - "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", - "requires": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "dependencies": { - "mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "requires": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - } - }, - "unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "requires": { - "@types/unist": "^3.0.0" - } - } - } - }, - "remark-stringify": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", - "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", - "requires": { - "mdast-util-to-markdown": "^0.6.0" - }, - "dependencies": { - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" - }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" - }, - "longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" - }, - "mdast-util-to-markdown": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", - "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", - "requires": { - "@types/unist": "^2.0.0", - "longest-streak": "^2.0.0", - "mdast-util-to-string": "^2.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.0.0", - "zwitch": "^1.0.0" - } - }, - "mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" - }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" - } - } - }, - "renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - }, - "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - } - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "reselect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", - "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" - }, - "resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, - "responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "requires": { - "lowercase-keys": "^3.0.0" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "peer": true - }, - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" - }, - "rst-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", - "integrity": "sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==", - "dev": true, - "peer": true, - "requires": { - "lodash.flattendeep": "^4.4.0", - "nearley": "^2.7.10" - } - }, - "rtl-css-js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", - "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", - "requires": { - "@babel/runtime": "^7.1.2" - } - }, - "rtl-detect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", - "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" - }, - "rtlcss": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", - "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0", - "postcss": "^8.4.21", - "strip-json-comments": "^3.1.1" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" - }, - "sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "requires": { - "mri": "^1.1.0" - } - }, - "safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - } - }, - "safe-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sass": { - "version": "1.77.6", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", - "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", - "requires": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - } - }, - "sass-loader": { - "version": "13.3.3", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz", - "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==", - "requires": { - "neo-async": "^2.6.2" - } - }, - "sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" - }, - "scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - } - }, - "screenfull": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", - "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==" - }, - "search-insights": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.15.0.tgz", - "integrity": "sha512-ch2sPCUDD4sbPQdknVl9ALSi9H7VyoeVbsxznYz6QV55jJ8CI3EtwpO1i84keN4+hF5IeHWIeGvc08530JkVXQ==", - "peer": true - }, - "section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "requires": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "requires": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - } - }, - "semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==" - }, - "semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "requires": { - "semver": "^7.3.5" - } - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - } - } - }, - "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-handler": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", - "requires": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - }, - "dependencies": { - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "requires": { - "mime-db": "~1.33.0" - } - }, - "path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" - } - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" - } - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - } - }, - "set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - } - }, - "set-harmonic-interval": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", - "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", - "requires": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" - } - }, - "should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", - "requires": { - "should-type": "^1.4.0" - } - }, - "should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", - "requires": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==" - }, - "should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "requires": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "should-util": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==" - }, - "side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "simple-websocket": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/simple-websocket/-/simple-websocket-9.1.0.tgz", - "integrity": "sha512-8MJPnjRN6A8UCp1I+H/dSFyjwJhp6wta4hsVRhjf8w9qBHRzxYt14RaOcjvQnhD1N4yKOddEjflwMnQM4VtXjQ==", - "dev": true, - "requires": { - "debug": "^4.3.1", - "queue-microtask": "^1.2.2", - "randombytes": "^2.1.0", - "readable-stream": "^3.6.0", - "ws": "^7.4.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "requires": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "sitemap": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", - "requires": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "dependencies": { - "@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - } - } - }, - "skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "requires": { - "unicode-emoji-modifier-base": "^1.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "slugify": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", - "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==" - }, - "snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - } - } - }, - "sort-css-media-queries": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==" - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" - }, - "source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==" - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==" - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==" - }, - "stack-generator": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", - "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", - "requires": { - "stackframe": "^1.3.4" - } - }, - "stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" - }, - "stacktrace-gps": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", - "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", - "requires": { - "source-map": "0.5.6", - "stackframe": "^1.3.4" - }, - "dependencies": { - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==" - } - } - }, - "stacktrace-js": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", - "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", - "requires": { - "error-stack-parser": "^2.0.6", - "stack-generator": "^2.0.5", - "stacktrace-gps": "^3.0.4" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" - }, - "stickyfill": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stickyfill/-/stickyfill-1.1.1.tgz", - "integrity": "sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA==", - "dev": true - }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - } - } - }, - "string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "requires": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, - "style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "requires": { - "inline-style-parser": "0.1.1" - } - }, - "styled-components": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.11.tgz", - "integrity": "sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA==", - "dev": true, - "requires": { - "@emotion/is-prop-valid": "1.2.2", - "@emotion/unitless": "0.8.1", - "@types/stylis": "4.2.5", - "css-to-react-native": "3.2.0", - "csstype": "3.1.3", - "postcss": "8.4.38", - "shallowequal": "1.1.0", - "stylis": "4.3.2", - "tslib": "2.6.2" - }, - "dependencies": { - "postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - } - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - } - } - }, - "stylehacks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", - "requires": { - "browserslist": "^4.23.0", - "postcss-selector-parser": "^6.0.16" - } - }, - "stylis": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" - }, - "sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" - }, - "glob": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - } - }, - "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - }, - "css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "requires": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - } - }, - "mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" - } - } - }, - "swagger2openapi": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", - "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", - "requires": { - "call-me-maybe": "^1.0.1", - "node-fetch": "^2.6.1", - "node-fetch-h2": "^2.3.0", - "node-readfiles": "^0.2.0", - "oas-kit-common": "^1.0.8", - "oas-resolver": "^2.5.6", - "oas-schema-walker": "^1.1.5", - "oas-validator": "^5.0.8", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - } - }, - "tabbable": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", - "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" - }, - "terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - } - } - }, - "terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, - "throttle-debounce": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", - "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==" - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "requires": { - "setimmediate": "^1.0.4" - } - }, - "tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" - }, - "trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" - }, - "trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==" - }, - "ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==" - }, - "ts-easing": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", - "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==" - }, - "ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" - }, - "ts-keycode-enum": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/ts-keycode-enum/-/ts-keycode-enum-1.0.6.tgz", - "integrity": "sha512-DF8+Cf/FJJnPRxwz8agCoDelQXKZWQOS/gnnwx01nZ106tPJdB3BgJ9QTtLwXgR82D8O+nTjuZzWgf0Rg4vuRA==" - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "devOptional": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==" - }, - "uglify-js": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", - "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", - "dev": true, - "optional": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" - }, - "unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==" - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" - }, - "unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" - }, - "unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "requires": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - } - }, - "unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "requires": { - "crypto-random-string": "^4.0.0" - } - }, - "unist-builder": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-3.0.1.tgz", - "integrity": "sha512-gnpOw7DIpCA0vpr6NqdPvTWnlPTApCTRzr+38E6hCWx3rz/cjo83SsKIlS1Z+L5ttScQ2AwutNnb8+tAvpb6qQ==", - "requires": { - "@types/unist": "^2.0.0" - }, - "dependencies": { - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - } - }, - "unist-util-generated": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", - "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==" - }, - "unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "requires": { - "@types/unist": "^3.0.0" - } - }, - "unist-util-position": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", - "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", - "requires": { - "@types/unist": "^2.0.0" - }, - "dependencies": { - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "requires": { - "@types/unist": "^3.0.0" - } - }, - "unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - } - }, - "unist-util-select": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-4.0.3.tgz", - "integrity": "sha512-1074+K9VyR3NyUz3lgNtHKm7ln+jSZXtLJM4E22uVuoFn88a/Go2pX8dusrt/W+KWH1ncn8jcd8uCQuvXb/fXA==", - "requires": { - "@types/unist": "^2.0.0", - "css-selector-parser": "^1.0.0", - "nth-check": "^2.0.0", - "zwitch": "^2.0.0" - }, - "dependencies": { - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "requires": { - "@types/unist": "^3.0.0" - } - }, - "unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - } - }, - "unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "requires": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - } - }, - "update-notifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", - "requires": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", - "configstore": "^6.0.0", - "has-yarn": "^3.0.0", - "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", - "is-installed-globally": "^0.4.0", - "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", - "latest-version": "^7.0.0", - "pupa": "^3.1.0", - "semver": "^7.3.7", - "semver-diff": "^4.0.0", - "xdg-basedir": "^5.1.0" - }, - "dependencies": { - "boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "requires": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - } - }, - "camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==" - }, - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==" - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "requires": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - } - } - }, - "url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "requires": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", - "dev": true - }, - "use-editable": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/use-editable/-/use-editable-2.3.3.tgz", - "integrity": "sha512-7wVD2JbfAFJ3DK0vITvXBdpd9JAz5BcKAAolsnLBuBn6UDDwBGuCIAGvR3yA2BNKm578vAMVHFCWaOcA+BhhiA==", - "requires": {} - }, - "use-resize-observer": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz", - "integrity": "sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==", - "requires": { - "@juggle/resize-observer": "^3.3.1" - } - }, - "use-sync-external-store": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "dev": true, - "requires": {} - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "utility-types": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" - }, - "uvu": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", - "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", - "requires": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - }, - "dependencies": { - "kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" - } - } - }, - "validate.io-array": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", - "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==" - }, - "validate.io-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", - "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" - }, - "validate.io-integer": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", - "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", - "requires": { - "validate.io-number": "^1.0.3" - } - }, - "validate.io-integer-array": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", - "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", - "requires": { - "validate.io-array": "^1.0.3", - "validate.io-integer": "^1.0.4" - } - }, - "validate.io-number": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", - "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" - }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - } - }, - "vfile-location": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", - "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", - "requires": { - "@types/unist": "^2.0.0", - "vfile": "^5.0.0" - }, - "dependencies": { - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - } - }, - "vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - } - } - } - }, - "vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==" - }, - "web-worker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", - "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "webpack-bundle-analyzer": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", - "requires": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - } - } - }, - "webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "requires": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "dependencies": { - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - } - } - }, - "webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "requires": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "dependencies": { - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "requires": {} - } - } - }, - "webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "requires": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" - }, - "webpackbar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", - "requires": { - "chalk": "^4.1.0", - "consola": "^2.15.3", - "pretty-time": "^1.1.0", - "std-env": "^3.0.1" - } - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" - }, - "whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - } - }, - "widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "requires": { - "string-width": "^5.0.1" - } - }, - "wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" - }, - "wolfy87-eventemitter": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz", - "integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==" - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "devOptional": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "requires": {} - }, - "xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==" - }, - "xml-formatter": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.1.tgz", - "integrity": "sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==", - "requires": { - "xml-parser-xo": "^3.2.0" - } - }, - "xml-js": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "requires": { - "sax": "^1.2.4" - } - }, - "xml-parser-xo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.2.0.tgz", - "integrity": "sha512-8LRU6cq+d7mVsoDaMhnkkt3CTtAs4153p49fRo+HIB3I1FD1o5CeXRjRH29sQevIfVJIcPjKSsPU/+Ujhq09Rg==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yaml-ast-parser": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==" - }, - "yargs": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", - "integrity": "sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" - }, - "yarn": { - "version": "1.22.22", - "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.22.tgz", - "integrity": "sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==" - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - }, - "zustand": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", - "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", - "requires": {} - }, - "zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==" - } - } -} From 0cf5ff7e90def87f0c2d5af397d579e7b04b6b3a Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 6 Nov 2024 09:29:59 -0600 Subject: [PATCH 25/60] trigger a new container build From d454324038ad9133664cde9e61fc734732e5d062 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 18 Nov 2024 09:33:56 -0600 Subject: [PATCH 26/60] trigger a new container build From 5fc758c479858dfe93db2492a56254a7460d8c73 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 18 Nov 2024 10:53:34 -0600 Subject: [PATCH 27/60] make crowdin upload workflow only on-demand --- .github/workflows/upload-workflow.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/upload-workflow.yml b/.github/workflows/upload-workflow.yml index bfba65eb7..324f856b7 100644 --- a/.github/workflows/upload-workflow.yml +++ b/.github/workflows/upload-workflow.yml @@ -2,8 +2,8 @@ name: Crowdin Upload on: workflow_dispatch: - push: - branches: [ main ] + # push: + # branches: [ main ] jobs: crowdin-upload: @@ -18,7 +18,7 @@ jobs: node-version: '20' cache: 'yarn' cache-dependency-path: '**/yarn.lock' - + - name: Install Dependencies run: yarn --prefer-offline From f0ea2f9550130d4dba2d4fdd6a2a7eda8578e91f Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 18 Nov 2024 11:01:46 -0600 Subject: [PATCH 28/60] remove IDs from docs frontmatter --- docs/data/hubble/data-catalog/data-lineage.mdx | 1 - ...gration-points.mdx => anchor-platform-integration-points.mdx} | 1 - .../admin-guide/{45-configuring-sdp.mdx => configuring-sdp.mdx} | 1 - .../admin-guide/{40-deploy-the-sdp.mdx => deploy-the-sdp.mdx} | 1 - ...0-design-and-architecture.mdx => design-and-architecture.mdx} | 1 - .../admin-guide/{30-getting-started.mdx => getting-started.mdx} | 1 - ...our-wallet-sdp-ready.mdx => making-your-wallet-sdp-ready.mdx} | 1 - .../admin-guide/{10-overview.mdx => overview.mdx} | 1 - ...2-secure-operation-manual.mdx => secure-operation-manual.mdx} | 1 - ...ti-tenant.mdx => single-tenant-to-multi-tenant-migration.mdx} | 0 .../{48-tenant-provisioning.mdx => tenant-provisioning.mdx} | 1 - .../user-interface/{60-analytics.mdx => analytics.mdx} | 1 - .../{70-circle-configutration.mdx => circle-configuration.mdx} | 1 - .../user-interface/{10-dashboard-home.mdx => dashboard-home.mdx} | 1 - .../user-interface/{20-disbursements.mdx => disbursements.mdx} | 1 - .../admin-guide/user-interface/{40-payments.mdx => payments.mdx} | 1 - .../user-interface/{30-receivers.mdx => receivers.mdx} | 1 - .../admin-guide/user-interface/{50-wallets.mdx => wallets.mdx} | 1 - 18 files changed, 17 deletions(-) rename platforms/stellar-disbursement-platform/admin-guide/{60-anchor-platform-integration-points.mdx => anchor-platform-integration-points.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/{45-configuring-sdp.mdx => configuring-sdp.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/{40-deploy-the-sdp.mdx => deploy-the-sdp.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/{20-design-and-architecture.mdx => design-and-architecture.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/{30-getting-started.mdx => getting-started.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/{50-making-your-wallet-sdp-ready.mdx => making-your-wallet-sdp-ready.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/{10-overview.mdx => overview.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/{42-secure-operation-manual.mdx => secure-operation-manual.mdx} (98%) rename platforms/stellar-disbursement-platform/admin-guide/{70-migrating-to-sdp-multi-tenant.mdx => single-tenant-to-multi-tenant-migration.mdx} (100%) rename platforms/stellar-disbursement-platform/admin-guide/{48-tenant-provisioning.mdx => tenant-provisioning.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/user-interface/{60-analytics.mdx => analytics.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/user-interface/{70-circle-configutration.mdx => circle-configuration.mdx} (97%) rename platforms/stellar-disbursement-platform/admin-guide/user-interface/{10-dashboard-home.mdx => dashboard-home.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/user-interface/{20-disbursements.mdx => disbursements.mdx} (98%) rename platforms/stellar-disbursement-platform/admin-guide/user-interface/{40-payments.mdx => payments.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/user-interface/{30-receivers.mdx => receivers.mdx} (99%) rename platforms/stellar-disbursement-platform/admin-guide/user-interface/{50-wallets.mdx => wallets.mdx} (99%) diff --git a/docs/data/hubble/data-catalog/data-lineage.mdx b/docs/data/hubble/data-catalog/data-lineage.mdx index f4cdf8766..45f51b7b2 100644 --- a/docs/data/hubble/data-catalog/data-lineage.mdx +++ b/docs/data/hubble/data-catalog/data-lineage.mdx @@ -1,5 +1,4 @@ --- -id: data-lineage title: Data Lineage --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/60-anchor-platform-integration-points.mdx b/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/60-anchor-platform-integration-points.mdx rename to platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx index 511e94363..7436ecf55 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/60-anchor-platform-integration-points.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx @@ -1,6 +1,5 @@ --- title: Anchor Platform Integration Points -id: anchor-platform-integration-points sidebar_position: 60 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/45-configuring-sdp.mdx b/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/45-configuring-sdp.mdx rename to platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx index 095e5fcb8..db5053e7c 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/45-configuring-sdp.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx @@ -1,5 +1,4 @@ --- -id: configuring-sdp title: Configuring the SDP description: Understand the configuration options available for the Stellar Disbursement Platform (SDP) keywords: [SDP, configuration] diff --git a/platforms/stellar-disbursement-platform/admin-guide/40-deploy-the-sdp.mdx b/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/40-deploy-the-sdp.mdx rename to platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx index 4ca82dc73..065ed096f 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/40-deploy-the-sdp.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx @@ -1,6 +1,5 @@ --- title: Deploy the SDP -id: deploy-the-sdp sidebar_position: 40 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/20-design-and-architecture.mdx b/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/20-design-and-architecture.mdx rename to platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx index 5288aca13..2dfef25d7 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/20-design-and-architecture.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx @@ -1,6 +1,5 @@ --- title: Design and Architecture -id: design-and-architecture sidebar_position: 20 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/30-getting-started.mdx b/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/30-getting-started.mdx rename to platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx index e7311791f..2937a2d9e 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/30-getting-started.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx @@ -1,6 +1,5 @@ --- title: Getting Started -id: getting-started sidebar_position: 30 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/50-making-your-wallet-sdp-ready.mdx b/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/50-making-your-wallet-sdp-ready.mdx rename to platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx index 97feaf712..1fdc652c0 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/50-making-your-wallet-sdp-ready.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx @@ -1,6 +1,5 @@ --- title: Making Your Wallet SDP-Ready -id: making-your-wallet-sdp-ready sidebar_position: 50 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/10-overview.mdx b/platforms/stellar-disbursement-platform/admin-guide/overview.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/10-overview.mdx rename to platforms/stellar-disbursement-platform/admin-guide/overview.mdx index 6e659499c..ef8b511e9 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/10-overview.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/overview.mdx @@ -1,6 +1,5 @@ --- title: Overview -id: overview sidebar_position: 10 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/42-secure-operation-manual.mdx b/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx similarity index 98% rename from platforms/stellar-disbursement-platform/admin-guide/42-secure-operation-manual.mdx rename to platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx index 7f155ae1f..ac7029ce6 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/42-secure-operation-manual.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx @@ -1,6 +1,5 @@ --- title: Secure Operation Manual -id: secure-operation-manual sidebar_position: 42 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/70-migrating-to-sdp-multi-tenant.mdx b/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx similarity index 100% rename from platforms/stellar-disbursement-platform/admin-guide/70-migrating-to-sdp-multi-tenant.mdx rename to platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx diff --git a/platforms/stellar-disbursement-platform/admin-guide/48-tenant-provisioning.mdx b/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/48-tenant-provisioning.mdx rename to platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx index 8511e0378..70c98e988 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/48-tenant-provisioning.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx @@ -1,5 +1,4 @@ --- -id: tenant-provisioning title: Provisioning a New Tenant description: Learn how to provision and configure a new tenant in the Stellar Disbursement Platform. keywords: diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/60-analytics.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/analytics.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/user-interface/60-analytics.mdx rename to platforms/stellar-disbursement-platform/admin-guide/user-interface/analytics.mdx index 8dade895e..d18660b26 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/60-analytics.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/analytics.mdx @@ -1,6 +1,5 @@ --- title: Analytics -id: analytics sidebar_position: 60 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/70-circle-configutration.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/circle-configuration.mdx similarity index 97% rename from platforms/stellar-disbursement-platform/admin-guide/user-interface/70-circle-configutration.mdx rename to platforms/stellar-disbursement-platform/admin-guide/user-interface/circle-configuration.mdx index c285b8adc..cdc19cb45 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/70-circle-configutration.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/circle-configuration.mdx @@ -1,6 +1,5 @@ --- title: Circle Configuration -id: circle-configutration sidebar_position: 70 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/10-dashboard-home.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/dashboard-home.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/user-interface/10-dashboard-home.mdx rename to platforms/stellar-disbursement-platform/admin-guide/user-interface/dashboard-home.mdx index f7fd22815..a140abb45 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/10-dashboard-home.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/dashboard-home.mdx @@ -1,6 +1,5 @@ --- title: Dashboard Home -id: dashboard-home sidebar_position: 10 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/20-disbursements.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/disbursements.mdx similarity index 98% rename from platforms/stellar-disbursement-platform/admin-guide/user-interface/20-disbursements.mdx rename to platforms/stellar-disbursement-platform/admin-guide/user-interface/disbursements.mdx index 407933cd3..31757f6db 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/20-disbursements.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/disbursements.mdx @@ -1,6 +1,5 @@ --- title: Disbursements -id: disbursements sidebar_position: 20 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/40-payments.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/payments.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/user-interface/40-payments.mdx rename to platforms/stellar-disbursement-platform/admin-guide/user-interface/payments.mdx index 5cf1bcb97..dedfd10f5 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/40-payments.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/payments.mdx @@ -1,6 +1,5 @@ --- title: Payments -id: payments sidebar_position: 40 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/30-receivers.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/receivers.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/user-interface/30-receivers.mdx rename to platforms/stellar-disbursement-platform/admin-guide/user-interface/receivers.mdx index b228d0490..4ab11b05b 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/30-receivers.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/receivers.mdx @@ -1,6 +1,5 @@ --- title: Receivers -id: receivers sidebar_position: 30 --- diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/50-wallets.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx similarity index 99% rename from platforms/stellar-disbursement-platform/admin-guide/user-interface/50-wallets.mdx rename to platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx index 1977dc6a2..28c9e8599 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/50-wallets.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx @@ -1,6 +1,5 @@ --- title: Wallets -id: wallets sidebar_position: 50 --- From af88bfa40e60fd11d7f1f0ab9af4e95a494171dc Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 20 Nov 2024 09:20:32 -0600 Subject: [PATCH 29/60] trigger a new container build From 3977e998fb8a5049a4d149fb624d96763a44ffcc Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 20 Nov 2024 09:57:03 -0600 Subject: [PATCH 30/60] fix some broken links from renaming SDP files --- platforms/stellar-disbursement-platform/README.mdx | 2 +- .../admin-guide/single-tenant-to-multi-tenant-migration.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/stellar-disbursement-platform/README.mdx b/platforms/stellar-disbursement-platform/README.mdx index 75dbf8d74..b94237416 100644 --- a/platforms/stellar-disbursement-platform/README.mdx +++ b/platforms/stellar-disbursement-platform/README.mdx @@ -13,4 +13,4 @@ This is an open-source project that is built on top of the Stellar network, and - [stellar/stellar-disbursement-platform-frontend](https://github.com/stellar/stellar-disbursement-platform-frontend): This repository contains the web frontend code for the Stellar Disbursement Platform. - [stellar/helm-charts](https://github.com/stellar/helm-charts/tree/main/charts/stellar-disbursement-platform): This repository contains the Helm chart for deploying the Stellar Disbursement Platform using kubernetes. -In this section, you'll find an [Admin Guide](./admin-guide/10-overview.mdx) that will teach you how to run the Stellar Disbursement Platform as well as an [API Reference](./api-reference/admin.tag.mdx). +In this section, you'll find an [Admin Guide](./admin-guide/overview.mdx) that will teach you how to run the Stellar Disbursement Platform as well as an [API Reference](./api-reference/admin.tag.mdx). diff --git a/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx b/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx index 67a2baeb7..d2faf86d6 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx @@ -151,7 +151,7 @@ On the Anchor Platform side, we must set the following envs: ### Seggregation of Funds -In the multi-tenant version, tenants funds are isolated from each other **unless the tenant is created with `"distribution_account_type": "DISTRIBUTION_ACCOUNT.STELLAR.ENV"`**. For more information on the distribution account types, please refer to the [Tenant Provisioning](48-tenant-provisioning.mdx#creating-tenants) section. +In the multi-tenant version, tenants funds are isolated from each other **unless the tenant is created with `"distribution_account_type": "DISTRIBUTION_ACCOUNT.STELLAR.ENV"`**. For more information on the distribution account types, please refer to the [Tenant Provisioning](./tenant-provisioning.mdx#creating-tenants) section. The channel accounts on the other hand are shared between tenants, and they are created by the HOST distribution account, set in the `DISTRIBUTION_SEED` environment variable. The channel accounts are encrypted using the `CHANNEL_ACCOUNT_ENCRYPTION_PASSPHRASE` environment variable, or the `DISTRIBUTION_SEED` if the former is not set. In the single-tenant version, the channel accounts were encrypted by the `DISTRIBUTION_SEED`. From cd829fc4202acf7c3246f1a6b2752f6681380a76 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 20 Nov 2024 09:59:15 -0600 Subject: [PATCH 31/60] add the announcement bar to translated pages --- docusaurus.config.ts | 4 ++++ src/css/custom.scss | 2 ++ src/theme/AnnouncementBar/index.tsx | 22 ++++++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 src/theme/AnnouncementBar/index.tsx diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 75c191ac0..7b2abd980 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -115,6 +115,10 @@ const config: Config = { }, ], themeConfig: { + announcementBar: { + id: 'announcementBar-translation', + content: 'Disclaimer: This documentation has been automatically translated and may contain inaccuracies. For the most accurate information, please refer to the original English version. We are not responsible for translation errors.', + }, docs: { sidebar: { autoCollapseCategories: false, diff --git a/src/css/custom.scss b/src/css/custom.scss index 54624bcf4..5082d0cd0 100644 --- a/src/css/custom.scss +++ b/src/css/custom.scss @@ -140,6 +140,8 @@ div[class^="announcementBar_"] { var(--site-announcement-bar-stripe-color2) 10px, var(--site-announcement-bar-stripe-color2) 40px ); + + height: fit-content; } /* Navbar customizations */ diff --git a/src/theme/AnnouncementBar/index.tsx b/src/theme/AnnouncementBar/index.tsx new file mode 100644 index 000000000..f3c15d39b --- /dev/null +++ b/src/theme/AnnouncementBar/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import AnnouncementBar from '@theme-original/AnnouncementBar'; +import type AnnouncementBarType from '@theme/AnnouncementBar'; +import type {WrapperProps} from '@docusaurus/types'; +import { useLocation } from '@docusaurus/router'; + +type Props = WrapperProps; + +export default function AnnouncementBarWrapper(props: Props): JSX.Element { + console.log('props', props) + const location = useLocation(); + + if (!location.pathname.startsWith('/es')) { + return null + } + + return ( + <> + + + ); +} From 7c6466fc7b3aecef877762f6cded0ae2799824ad Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 3 Dec 2024 11:25:58 -0600 Subject: [PATCH 32/60] remove unnecessary console log --- src/theme/AnnouncementBar/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/theme/AnnouncementBar/index.tsx b/src/theme/AnnouncementBar/index.tsx index f3c15d39b..378e605be 100644 --- a/src/theme/AnnouncementBar/index.tsx +++ b/src/theme/AnnouncementBar/index.tsx @@ -7,7 +7,6 @@ import { useLocation } from '@docusaurus/router'; type Props = WrapperProps; export default function AnnouncementBarWrapper(props: Props): JSX.Element { - console.log('props', props) const location = useLocation(); if (!location.pathname.startsWith('/es')) { From f2d99d67831a42285ee708ca7fbe58a8fbf6ed6b Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 4 Dec 2024 10:04:18 -0600 Subject: [PATCH 33/60] build spanish only for now --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 953768226..c2d138492 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn crowdin:sync RUN yarn crowdin:fix # TODO: It's actually this part that is more time-consuming. The best way to # speed this up is to generate the preview for only `--locale en` -RUN NODE_OPTIONS="--max-old-space-size=4096" yarn build +RUN NODE_OPTIONS="--max-old-space-size=4096" yarn build --locale es FROM nginx:1.27 From 68d7a3944588f1017ea9910e5e9d28be8bdde7d2 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 4 Dec 2024 10:54:18 -0600 Subject: [PATCH 34/60] trigger a new container build From dfa6ca701f08289847910d552555da34e7de1930 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 4 Dec 2024 11:13:23 -0600 Subject: [PATCH 35/60] trigger a new container build From 427873150c0466c27628f604149bbcd6e7b128ca Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 4 Dec 2024 11:33:04 -0600 Subject: [PATCH 36/60] add a test file --- docs/build/guides/conventions/test-your-stuff.mdx | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 docs/build/guides/conventions/test-your-stuff.mdx diff --git a/docs/build/guides/conventions/test-your-stuff.mdx b/docs/build/guides/conventions/test-your-stuff.mdx new file mode 100644 index 000000000..2b22b14d3 --- /dev/null +++ b/docs/build/guides/conventions/test-your-stuff.mdx @@ -0,0 +1,10 @@ +--- +title: Test your stuff +description: here is your description +--- + +Here's a test file of a guide in contract conventions. + +It's useful to test stuff, because then you know it's broken (which it always is). + +Happy failing! From 74a83cadfd6b0b6e42b67ad5d62d07a9f65ae8cd Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 4 Dec 2024 11:51:15 -0600 Subject: [PATCH 37/60] remove test file --- docs/build/guides/conventions/test-your-stuff.mdx | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 docs/build/guides/conventions/test-your-stuff.mdx diff --git a/docs/build/guides/conventions/test-your-stuff.mdx b/docs/build/guides/conventions/test-your-stuff.mdx deleted file mode 100644 index 2b22b14d3..000000000 --- a/docs/build/guides/conventions/test-your-stuff.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Test your stuff -description: here is your description ---- - -Here's a test file of a guide in contract conventions. - -It's useful to test stuff, because then you know it's broken (which it always is). - -Happy failing! From 417ff017334b50e1676fed7ffacb7a64381b918b Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 9 Dec 2024 10:44:13 -0600 Subject: [PATCH 38/60] modify crowdin upload/download commands --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ccb7ac61..56a3aa0db 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "stellar-cli:build": "node scripts/stellar_cli.mjs", "crowdin": "crowdin", "crowdin:fix": "node scripts/copyIgnoredFiles.mjs && ./scripts/fix_md_comments.sh", - "crowdin:sync": "docusaurus write-translations && crowdin upload && crowdin download", + "crowdin:sync": "docusaurus write-translations && crowdin upload --delete-obsolete --no-progress && crowdin download --no-progress", "ap:versions:clean": "docusaurus clean-api-docs:version -p ap-apis ap_platform:all && docusaurus clean-api-docs:version -p ap-apis ap_callbacks:all && docusaurus clean-api-docs:version -p ap-apis ap_custody:all", "ap:versions:gen": "docusaurus gen-api-docs:version -p ap-apis ap_platform:all && docusaurus gen-api-docs:version -p ap-apis ap_callbacks:all && docusaurus gen-api-docs:version -p ap-apis ap_custody:all && rm ap_versioned_docs/version-*/api-reference/{callbacks,custody,platform/transactions}/*.info.mdx", "ap:versions:regen": "yarn ap:versions:clean && yarn ap:versions:gen", From 5b420a173084a25332e19f023b7078fa47e15fc1 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 9 Dec 2024 10:51:23 -0600 Subject: [PATCH 39/60] write explicit heading ids for markdown docs --- .../version-2.10/admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../version-2.10/admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../admin-guide/sep24/example.mdx | 10 +- .../version-2.10/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 52 ++-- .../admin-guide/sep6/configuration.mdx | 12 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- .../version-2.11/admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../version-2.11/admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../admin-guide/sep24/example.mdx | 10 +- .../version-2.11/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 52 ++-- .../admin-guide/sep6/configuration.mdx | 12 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- .../version-2.8/admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../version-2.8/admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../version-2.8/admin-guide/sep24/example.mdx | 10 +- .../version-2.8/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 54 ++-- .../admin-guide/sep6/configuration.mdx | 12 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- .../version-2.9/admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../version-2.9/admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../version-2.9/admin-guide/sep24/example.mdx | 10 +- .../version-2.9/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 52 ++-- .../admin-guide/sep6/configuration.mdx | 12 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- docs/README.mdx | 16 +- docs/build/README.mdx | 6 +- .../application-design-considerations.mdx | 20 +- docs/build/apps/dapp-frontend.mdx | 32 +-- .../account-creation.mdx | 10 +- .../anchor-integration/sep10.mdx | 8 +- .../anchor-integration/sep24.mdx | 14 +- .../anchor-integration/sep6.mdx | 20 +- .../anchor-integration/setup.mdx | 2 +- .../confirmation-modal.mdx | 12 +- .../contacts-list.mdx | 12 +- .../manage-trust.mdx | 8 +- .../example-application-tutorial/overview.mdx | 12 +- .../path-payment.mdx | 8 +- .../example-application-tutorial/payment.mdx | 8 +- .../querying-data.mdx | 18 +- .../ingest-sdk/ingestion-pipeline-code.mdx | 8 +- docs/build/apps/ingest-sdk/overview.mdx | 22 +- .../moneygram-access-integration-guide.mdx | 42 +-- docs/build/apps/overview.mdx | 4 +- docs/build/apps/smart-wallets.mdx | 22 +- docs/build/apps/wallet/README.md | 14 +- .../wallet/component/dart/configClient.mdx | 2 +- .../apps/wallet/component/kt/configClient.mdx | 4 +- .../apps/wallet/component/ts/configClient.mdx | 2 +- docs/build/apps/wallet/intro.mdx | 8 +- docs/build/apps/wallet/sep10.mdx | 12 +- docs/build/apps/wallet/sep24.mdx | 18 +- docs/build/apps/wallet/sep30.mdx | 6 +- docs/build/apps/wallet/sep38.mdx | 14 +- docs/build/apps/wallet/sep6.mdx | 22 +- docs/build/apps/wallet/sep7.mdx | 4 +- docs/build/apps/wallet/stellar.mdx | 42 +-- .../create-restoration-footprint-js.mdx | 2 +- .../guides/archival/test-ttl-extension.mdx | 4 +- .../guides/basics/automate-reset-data.mdx | 16 +- docs/build/guides/basics/create-account.mdx | 4 +- .../basics/follow-received-payments.mdx | 12 +- .../basics/send-and-receive-payments.mdx | 8 +- .../conventions/check-auth-tutorials.mdx | 52 ++-- .../guides/conventions/cross-contract.mdx | 12 +- .../guides/conventions/deploy-contract.mdx | 18 +- .../conventions/deploy-sac-with-code.mdx | 8 +- .../guides/conventions/extending-wasm-ttl.mdx | 8 +- .../conventions/upgrading-contracts.mdx | 16 +- .../conversions/address-conversions.mdx | 4 +- .../guides/conversions/bytes-conversions.mdx | 6 +- .../guides/conversions/scval-conversions.mdx | 6 +- .../guides/conversions/string-conversions.mdx | 6 +- docs/build/guides/dapps/docker.mdx | 8 +- docs/build/guides/dapps/frontend-guide.mdx | 68 ++--- docs/build/guides/dapps/initialization.mdx | 8 +- docs/build/guides/dapps/react.mdx | 10 +- .../dapps/soroban-contract-init-template.mdx | 34 +-- docs/build/guides/dapps/state-archival.mdx | 24 +- .../dapps/working-with-contract-specs.mdx | 40 +-- docs/build/guides/events/consume.mdx | 12 +- docs/build/guides/events/ingest.mdx | 10 +- .../fees/analyzing-smart-contract-cost.mdx | 72 +++--- .../freighter/integrate-freighter-react.mdx | 2 +- .../storage/choosing-the-right-storage.mdx | 10 +- .../detecting-changes-with-test-snapshots.mdx | 4 +- docs/build/guides/tokens/deploying-a-sac.mdx | 14 +- .../guides/tokens/stellar-asset-contract.mdx | 6 +- .../install-deploy-contract-with-code.mdx | 20 +- .../transactions/install-wasm-bytecode.mdx | 8 +- .../simulateTransaction-Deep-Dive.mdx | 30 +-- .../example-contracts/TEMPLATE.mdx | 16 +- .../example-contracts/alloc.mdx | 8 +- .../example-contracts/atomic-swap.mdx | 12 +- .../example-contracts/auth.mdx | 18 +- .../example-contracts/cross-contract-call.mdx | 16 +- .../example-contracts/custom-account.mdx | 16 +- .../example-contracts/custom-types.mdx | 18 +- .../example-contracts/deployer.mdx | 24 +- .../example-contracts/errors.mdx | 22 +- .../example-contracts/events.mdx | 18 +- .../example-contracts/fuzzing.mdx | 18 +- .../example-contracts/liquidity-pool.mdx | 22 +- .../example-contracts/logging.mdx | 20 +- .../example-contracts/tokens.mdx | 16 +- .../example-contracts/workspace.mdx | 18 +- .../deploy-increment-contract.mdx | 6 +- .../getting-started/deploy-to-testnet.mdx | 6 +- .../getting-started/hello-world.mdx | 26 +- .../smart-contracts/getting-started/setup.mdx | 18 +- .../getting-started/storing-data.mdx | 18 +- docs/build/smart-contracts/overview.mdx | 8 +- docs/data/README.mdx | 12 +- docs/data/galexie/README.mdx | 10 +- docs/data/galexie/admin_guide/configuring.mdx | 2 +- docs/data/galexie/admin_guide/monitoring.mdx | 4 +- .../galexie/admin_guide/prerequisites.mdx | 8 +- docs/data/galexie/admin_guide/running.mdx | 8 +- docs/data/galexie/admin_guide/setup.mdx | 4 +- docs/data/horizon/README.mdx | 4 +- docs/data/horizon/admin-guide/configuring.mdx | 34 +-- .../admin-guide/ingestion-filtering.mdx | 14 +- docs/data/horizon/admin-guide/ingestion.mdx | 18 +- docs/data/horizon/admin-guide/installing.mdx | 16 +- docs/data/horizon/admin-guide/monitoring.mdx | 16 +- docs/data/horizon/admin-guide/overview.mdx | 2 +- .../horizon/admin-guide/prerequisites.mdx | 12 +- docs/data/horizon/admin-guide/running.mdx | 8 +- docs/data/horizon/admin-guide/scaling.mdx | 8 +- docs/data/horizon/admin-guide/upgrading.mdx | 12 +- .../api-reference/errors/error-handling.mdx | 24 +- .../api-reference/resources/effects/types.mdx | 18 +- docs/data/horizon/horizon-providers.mdx | 4 +- docs/data/hubble/README.mdx | 6 +- .../data-curation/architecture.mdx | 2 +- .../data-curation/getting-started.mdx | 16 +- .../admin-guide/data-curation/overview.mdx | 2 +- .../architecture.mdx | 2 +- .../getting-started.mdx | 20 +- .../scheduling-and-orchestration/overview.mdx | 2 +- .../source-system-ingestion/architecture.mdx | 2 +- .../getting-started.mdx | 30 +-- .../source-system-ingestion/overview.mdx | 2 +- .../visualization/getting-started.mdx | 6 +- docs/data/hubble/analyst-guide/connecting.mdx | 8 +- .../analyst-guide/creating-visualizations.mdx | 12 +- .../analyst-guide/optimizing-queries.mdx | 18 +- .../queries-for-horizon-like-data.mdx | 106 ++++---- .../hubble/analyst-guide/viewing-metadata.mdx | 4 +- docs/data/hubble/analytics-platforms.mdx | 6 +- .../data-catalog/data-dictionary/accounts.mdx | 4 +- .../data-dictionary/claimable-balances.mdx | 4 +- .../data-dictionary/contract-code.mdx | 4 +- .../data-dictionary/contract-data.mdx | 4 +- .../enriched-history-operations.mdx | 4 +- .../data-dictionary/history-assets.mdx | 4 +- .../data-dictionary/history-effects.mdx | 4 +- .../data-dictionary/history-ledgers.mdx | 4 +- .../data-dictionary/history-operations.mdx | 4 +- .../data-dictionary/history-trades.mdx | 4 +- .../data-dictionary/history-transactions.mdx | 4 +- .../data-dictionary/liquidity-pools.mdx | 4 +- .../data-catalog/data-dictionary/offers.mdx | 4 +- .../data-dictionary/trustlines.mdx | 4 +- .../data-catalog/data-dictionary/ttl.mdx | 4 +- docs/data/rpc/README.mdx | 2 +- docs/data/rpc/admin-guide.mdx | 30 +-- docs/data/rpc/api-reference/json-rpc.mdx | 2 +- .../methods/getLedgerEntries.mdx | 24 +- .../api-reference/methods/getTransaction.mdx | 2 +- .../api-reference/methods/sendTransaction.mdx | 2 +- docs/data/rpc/rpc-providers.mdx | 6 +- .../stellar-transaction.mdx | 20 +- .../contract-interactions/tests.mdx | 2 +- .../transaction-simulation.mdx | 4 +- .../contract-lifecycle.mdx | 10 +- .../environment-concepts.mdx | 10 +- .../contract-development/events.mdx | 18 +- .../contract-development/rust-dialect.mdx | 12 +- .../types/built-in-types.mdx | 26 +- .../types/custom-types.mdx | 8 +- .../types/fully-typed-contracts.mdx | 6 +- docs/learn/encyclopedia/data-format/xdr.mdx | 10 +- .../errors-and-debugging/debugging-errors.mdx | 12 +- .../errors-and-debugging/debugging.mdx | 4 +- .../errors-and-debugging/errors.mdx | 2 +- .../network-configuration/federation.mdx | 12 +- .../network-configuration/ledger-headers.mdx | 36 +-- ...uidity-on-stellar-sdex-liquidity-pools.mdx | 44 ++-- .../encyclopedia/security/authorization.mdx | 36 +-- .../security/securing-web-based-projects.mdx | 22 +- .../security/signatures-multisig.mdx | 22 +- .../encyclopedia/storage/persisting-data.mdx | 16 +- .../encyclopedia/storage/state-archival.mdx | 46 ++-- .../claimable-balances.mdx | 12 +- .../transactions-specialized/clawbacks.mdx | 20 +- .../fee-bump-transactions.mdx | 20 +- .../transactions-specialized/memos.mdx | 2 +- .../path-payments.mdx | 8 +- .../pooled-accounts-muxed-accounts-memos.mdx | 28 +- .../sponsored-reserves.mdx | 26 +- docs/learn/fundamentals/anchors.mdx | 2 +- .../fees-resource-limits-metering.mdx | 34 +-- docs/learn/fundamentals/lumens.mdx | 14 +- docs/learn/fundamentals/networks.mdx | 22 +- .../stellar-consensus-protocol.mdx | 20 +- .../stellar-data-structures/accounts.mdx | 8 +- .../stellar-data-structures/assets.mdx | 18 +- .../stellar-data-structures/contracts.mdx | 12 +- .../stellar-ecosystem-proposals.mdx | 22 +- docs/learn/fundamentals/stellar-stack.mdx | 10 +- .../transactions/list-of-operations.mdx | 52 ++-- .../operations-and-transactions.mdx | 46 ++-- .../transactions/transaction-lifecycle.mdx | 22 +- docs/learn/glossary.mdx | 150 +++++------ docs/learn/interactive/dapps/introduction.mdx | 6 +- .../interactive/dapps/scaffold-soroban.mdx | 18 +- .../evm/introduction-to-solidity-and-rust.mdx | 8 +- .../migrate/evm/smart-contract-deployment.mdx | 40 +-- .../solidity-and-rust-advanced-concepts.mdx | 72 +++--- .../migrate/evm/solidity-and-rust-basics.mdx | 42 +-- docs/networks/resource-limits-fees.mdx | 6 +- docs/networks/software-versions.mdx | 244 +++++++++--------- docs/tokens/README.mdx | 10 +- docs/tokens/anatomy-of-an-asset.mdx | 6 +- docs/tokens/control-asset-access.mdx | 28 +- docs/tokens/how-to-issue-an-asset.mdx | 32 +-- docs/tokens/publishing-asset-info.mdx | 32 +-- docs/tokens/stellar-asset-contract.mdx | 14 +- docs/tokens/token-interface.mdx | 16 +- docs/tools/README.mdx | 10 +- docs/tools/developer-tools/IDEs.mdx | 4 +- .../developer-tools/analytics-platforms.mdx | 4 +- docs/tools/developer-tools/anchor-tools.mdx | 6 +- docs/tools/developer-tools/asset-tools.mdx | 2 +- .../tools/developer-tools/block-explorers.mdx | 8 +- docs/tools/developer-tools/cli/README.mdx | 4 +- .../tools/developer-tools/cli/install-cli.mdx | 6 +- docs/tools/developer-tools/data-indexers.mdx | 12 +- .../developer-tools/jupyter-notebooks.mdx | 6 +- docs/tools/developer-tools/lab/README.mdx | 8 +- docs/tools/developer-tools/lab/account.mdx | 6 +- .../lab/quickstart-with-lab.mdx | 8 +- .../developer-tools/lab/transactions.mdx | 10 +- .../developer-tools/network-insights.mdx | 2 +- docs/tools/developer-tools/network-status.mdx | 6 +- .../developer-tools/node-operator-tools.mdx | 2 +- docs/tools/developer-tools/security-tools.mdx | 2 +- .../smart-contract-resources.mdx | 8 +- docs/tools/developer-tools/wallets.mdx | 8 +- docs/tools/sdks/build-your-own.mdx | 26 +- docs/tools/sdks/library.mdx | 28 +- docs/validators/README.mdx | 16 +- docs/validators/admin-guide/advanced.mdx | 10 +- docs/validators/admin-guide/commands.mdx | 16 +- docs/validators/admin-guide/configuring.mdx | 36 +-- .../admin-guide/environment-preparation.mdx | 14 +- docs/validators/admin-guide/installation.mdx | 12 +- docs/validators/admin-guide/maintenance.mdx | 4 +- docs/validators/admin-guide/monitoring.mdx | 44 ++-- .../admin-guide/network-upgrades.mdx | 6 +- docs/validators/admin-guide/prerequisites.mdx | 20 +- .../publishing-history-archives.mdx | 10 +- docs/validators/admin-guide/running-node.mdx | 14 +- .../admin-guide/soroban-settings.mdx | 22 +- docs/validators/tier-1-orgs.mdx | 16 +- platforms/anchor-platform/CONTRIBUTING.md | 38 +-- .../admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../admin-guide/sep24/example.mdx | 10 +- .../anchor-platform/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 48 ++-- .../admin-guide/sep6/configuration.mdx | 14 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- .../anchor-platform-integration-points.mdx | 6 +- .../admin-guide/configuring-sdp.mdx | 44 ++-- .../admin-guide/deploy-the-sdp.mdx | 12 +- .../admin-guide/design-and-architecture.mdx | 2 +- .../admin-guide/getting-started.mdx | 60 ++--- .../making-your-wallet-sdp-ready.mdx | 10 +- .../admin-guide/secure-operation-manual.mdx | 12 +- ...ingle-tenant-to-multi-tenant-migration.mdx | 50 ++-- .../admin-guide/tenant-provisioning.mdx | 20 +- .../admin-guide/user-interface/wallets.mdx | 2 +- .../challenges/challenge-0-crowdfund.mdx | 32 +-- .../dapps/challenges/challenge-1-payment.mdx | 32 +-- .../challenges/challenge-2-liquidity-pool.mdx | 42 +-- .../dapps/challenges/challenge-3-oracle.mdx | 38 +-- src/pages/index.mdx | 20 +- src/pages/platforms.mdx | 4 +- 349 files changed, 3049 insertions(+), 3049 deletions(-) diff --git a/ap_versioned_docs/version-2.10/admin-guide/architecture.mdx b/ap_versioned_docs/version-2.10/admin-guide/architecture.mdx index d9abf6435..7e1fd14b7 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/architecture.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture +## Architecture {#architecture} Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture +### Fundamental Architecture {#fundamental-architecture} The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client +#### Client {#client} The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server +#### SEP Server {#sep-server} The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server +#### Business Server {#business-server} The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server +#### Platform Server {#platform-server} The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database +#### Database {#database} The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture +### Complete Architecture {#complete-architecture} In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service +#### Event Service {#event-service} The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server +#### Custody Server {#custody-server} The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer +#### Stellar Observer {#stellar-observer} The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/ap_versioned_docs/version-2.10/admin-guide/custody-services/configuration.mdx b/ap_versioned_docs/version-2.10/admin-guide/custody-services/configuration.mdx index c6dd3abfb..e33184b64 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/custody-services/configuration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration +## Custody Server Configuration {#custody-server-configuration} If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:2.10.0 --custody-server -## Anchor Platform Configuration +## Anchor Platform Configuration {#anchor-platform-configuration} Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration +## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/ap_versioned_docs/version-2.10/admin-guide/custody-services/fireblocks/example.mdx b/ap_versioned_docs/version-2.10/admin-guide/custody-services/fireblocks/example.mdx index 613d31bca..9b3b8bf30 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/custody-services/fireblocks/example.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: +### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: +### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: +### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: +### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: +### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: +### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/ap_versioned_docs/version-2.10/admin-guide/events/delivery.mdx b/ap_versioned_docs/version-2.10/admin-guide/events/delivery.mdx index cd6d3148e..3c5f30142 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/events/delivery.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees +## Delivery Guarantees {#delivery-guarantees} Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees +### Client Delivery Guarantees {#client-delivery-guarantees} For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees +### Business Server Delivery Guarantees {#business-server-delivery-guarantees} The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/ap_versioned_docs/version-2.10/admin-guide/events/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/events/integration.mdx index b2638a348..15582d435 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/events/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements +## Requirements {#requirements} Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration +## Configuration {#configuration} First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events +## Receiving Events {#receiving-events} The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application +### As a Client Application {#as-a-client-application} Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing +#### Callback Signing {#callback-signing} Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server +### As a Business Server {#as-a-business-server} In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration +#### Configuration {#configuration-1} The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/ap_versioned_docs/version-2.10/admin-guide/getting-started.mdx b/ap_versioned_docs/version-2.10/admin-guide/getting-started.mdx index ebaccada2..89d0fa0ba 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/getting-started.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation +## Installation {#installation} import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:2.10.0 -## Set Up the Development Environment +## Set Up the Development Environment {#set-up-the-development-environment} In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration +## Configuration {#configuration} The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server +### Changing Port of the Platform Server {#changing-port-of-the-platform-server} For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets +### Specify Your Service's Assets {#specify-your-services-assets} Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence +### Add Data Persistence {#add-data-persistence} The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication +### Configure Platform API Authentication {#configure-platform-api-authentication} To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags +### Passing JVM flags {#passing-jvm-flags} Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep10/README.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep10/README.mdx index 1db24083f..fbd4a2a22 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep10/README.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication +## Enable Stellar Authentication {#enable-stellar-authentication} Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution +## Config With Client Attribution {#config-with-client-attribution} `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -131,7 +131,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/configuration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/configuration.mdx index 09c8dc709..906850f4f 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/configuration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals +## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -109,7 +109,7 @@ SECRET_SEP24_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busi `SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET` and `SECRET_SEP24_MORE_INFO_URL_JWT_SECRET` are encryption keys that the Anchor Platform will use to generate short-lived tokens it will add to the URLs provided to the wallet. Your business server must also have these keys in its environment so it can verify the token's signature. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/example.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/example.mdx index 3ec5be0e1..b1ddfa8d6 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/example.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience +## Building a Web-Based User Experience {#building-a-web-based-user-experience} The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication +### Authentication {#authentication} If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform +## Providing Updates to the Platform {#providing-updates-to-the-platform} Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform +## Fetching Updates from the Platform {#fetching-updates-from-the-platform} If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation +## Full Example Implementation {#full-example-implementation} Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/faq.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/faq.mdx index 5972a06cf..ee5eb71da 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/faq.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? +### How To Use JWTs? {#how-to-use-jwts} As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? +### How To Provide Fees? {#how-to-provide-fees} Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? +### How to identify the user account? {#how-to-identify-the-user-account} You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? +### How to identify the wallet? {#how-to-identify-the-wallet} Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/getting-started.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/getting-started.mdx index ce1d1dbf4..e77894428 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/getting-started.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience a deposit and withdrawal goes something like this: diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx index 865922840..bf3573895 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit Transaction Via JSON-RPC +## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information} :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction status to `expired`. @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction} In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC +## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information-1} This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction-1} Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/setting-up-production-server.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/setting-up-production-server.mdx index f631e5dbf..68c15d0bb 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/setting-up-production-server.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment +## Deploying a Secure Environment {#deploying-a-secure-environment} Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC +## Connecting to Real KYC {#connecting-to-real-kyc} Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form +## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails +## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases +## Testing Edge Cases {#testing-edge-cases} Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests +### General Tests {#general-tests} - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests +### KYC Tests {#kyc-tests} - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test +### Interactive Test {#interactive-test} - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests +### Security Tests {#security-tests} - Make sure platform endpoints are secured -## Polishing and Internationalization +## Polishing and Internationalization {#polishing-and-internationalization} Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets +## Connecting to Wallets {#connecting-to-wallets} All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep31/configuration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep31/configuration.mdx index d68d781de..7df1dde9b 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep31/configuration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments +## Enable Cross Border Payments {#enable-cross-border-payments} Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API +## Enable the Customer KYC API {#enable-the-customer-kyc-api} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API +## Enable the RFQ API {#enable-the-rfq-api} Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication +## Configure Callback API Authentication {#configure-callback-api-authentication} Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep31/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep31/integration.mdx index 12407473b..5fcaceb04 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep31/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep31/integration.mdx @@ -18,7 +18,7 @@ The following may also be required depending on your use case: - [`GET /unique_address`][get-unique-address] if your business uses a custody service for on-chain assets - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server +## Create a Business Server {#create-a-business-server} First, lets create a business server and add it to our docker compose file. @@ -71,11 +71,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints +## Customer Callback Endpoints {#customer-callback-endpoints} The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers +### Identifying Customers {#identifying-customers} Customers can be identified using two approaches. @@ -134,13 +134,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types +### Customer Types {#customer-types} Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet +### Test with the Demo Wallet {#test-with-the-demo-wallet} You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -157,33 +157,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint +## Rate Callback Endpoint {#rate-callback-endpoint} Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes +### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID +### Using the Client ID {#using-the-client-id} Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods +### Delivery Methods {#delivery-methods} It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates +## Fetching Transaction Status Updates {#fetching-transaction-status-updates} To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer +### Running the Stellar Observer {#running-the-stellar-observer} The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -203,7 +203,7 @@ services: -### Polling for Received Payments +### Polling for Received Payments {#polling-for-received-payments} The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -219,7 +219,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC +## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -239,7 +239,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} SEP-31 Transactions should initially be in the `pending_sender` status. The Receiving Anchor waits to receive the payment identified by the stellar_memo included in the POST /transactions response. @@ -286,7 +286,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -321,7 +321,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Verifying Customer Information +### Verifying Customer Information {#verifying-customer-information} In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -392,7 +392,7 @@ To execute this, you need to run: -### Do Stellar Refund +### Do Stellar Refund {#do-stellar-refund} Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -441,7 +441,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent +### Refund Sent {#refund-sent} There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -491,7 +491,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -530,7 +530,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -569,7 +569,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -602,11 +602,11 @@ To execute this, you need to run: -## Fee Callback Endpoint +## Fee Callback Endpoint {#fee-callback-endpoint} Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time the funds are paid out to the recipient. In this case, the Anchor Platform will not make a `GET /rate` request, but you will still need to provide the fee your business will charge for these types of transactions using the [`GET /fee`][get-fee] endpoint. -### Configuration +### Configuration {#configuration} You can enable these types of transactions by updating your `assets.yaml` file configuration: @@ -621,11 +621,11 @@ assets: -## Unique Address Callback Endpoint +## Unique Address Callback Endpoint {#unique-address-callback-endpoint} Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so that the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments. In this case, the business must request the custodian to generate the Stellar account & memo. This is done by using the [`GET /unique_address` endpoint][get-unique-address]. -### Configuration +### Configuration {#configuration-1} To configure the Anchor Platform to make these requests, add the following to your configuration: diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep6/configuration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep6/configuration.mdx index dea786738..8996dc626 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep6/configuration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals +## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File +### Modify a Stellar Info File {#modify-a-stellar-info-file} Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File +### Modify the Assets Configuration File {#modify-the-assets-configuration-file} Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts +### Managing Distribution Accounts {#managing-distribution-accounts} Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server +### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -177,7 +177,7 @@ SECRET_SEP6_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busin See the [KYC API][platform-api-kyc] and [Rates API][sep38] for details on the endpoints that must be implemented on your business server. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep6/getting-started.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep6/getting-started.mdx index 3a1d875e9..fb4e1293c 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep6/getting-started.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx index 87a6919b9..c358c8798 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information +### Customer Information {#customer-information} The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit (Exchange) Transaction Via JSON-RPC +## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information +### Verifying KYC Information {#verifying-kyc-information} Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -129,7 +129,7 @@ To execute this, you need to run: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -201,7 +201,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide updated transaction information. @@ -253,7 +253,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -288,7 +288,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -326,7 +326,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -369,7 +369,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -408,7 +408,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -450,7 +450,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent +### Refund Sent {#refund-sent} Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -500,11 +500,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -543,7 +543,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire transactions that have been abandoned by the user after some time. It's good practice to clean up inactive transactions in the `incomplete` status. To do so, make the following JSON-RPC request to expire a transaction. @@ -582,7 +582,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -615,7 +615,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -637,7 +637,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -718,7 +718,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -767,7 +767,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -812,7 +812,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -846,7 +846,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -880,7 +880,7 @@ To execute this, you need to run: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -915,11 +915,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent-1} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -968,19 +968,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/ap_versioned_docs/version-2.11/admin-guide/architecture.mdx b/ap_versioned_docs/version-2.11/admin-guide/architecture.mdx index d9abf6435..7e1fd14b7 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/architecture.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture +## Architecture {#architecture} Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture +### Fundamental Architecture {#fundamental-architecture} The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client +#### Client {#client} The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server +#### SEP Server {#sep-server} The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server +#### Business Server {#business-server} The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server +#### Platform Server {#platform-server} The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database +#### Database {#database} The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture +### Complete Architecture {#complete-architecture} In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service +#### Event Service {#event-service} The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server +#### Custody Server {#custody-server} The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer +#### Stellar Observer {#stellar-observer} The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/ap_versioned_docs/version-2.11/admin-guide/custody-services/configuration.mdx b/ap_versioned_docs/version-2.11/admin-guide/custody-services/configuration.mdx index d202cb386..db8a2a3b0 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/custody-services/configuration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration +## Custody Server Configuration {#custody-server-configuration} If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:2.11.0 --custody-server -## Anchor Platform Configuration +## Anchor Platform Configuration {#anchor-platform-configuration} Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration +## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/ap_versioned_docs/version-2.11/admin-guide/custody-services/fireblocks/example.mdx b/ap_versioned_docs/version-2.11/admin-guide/custody-services/fireblocks/example.mdx index 613d31bca..9b3b8bf30 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/custody-services/fireblocks/example.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: +### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: +### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: +### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: +### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: +### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: +### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/ap_versioned_docs/version-2.11/admin-guide/events/delivery.mdx b/ap_versioned_docs/version-2.11/admin-guide/events/delivery.mdx index cd6d3148e..3c5f30142 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/events/delivery.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees +## Delivery Guarantees {#delivery-guarantees} Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees +### Client Delivery Guarantees {#client-delivery-guarantees} For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees +### Business Server Delivery Guarantees {#business-server-delivery-guarantees} The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/ap_versioned_docs/version-2.11/admin-guide/events/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/events/integration.mdx index b2638a348..15582d435 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/events/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements +## Requirements {#requirements} Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration +## Configuration {#configuration} First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events +## Receiving Events {#receiving-events} The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application +### As a Client Application {#as-a-client-application} Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing +#### Callback Signing {#callback-signing} Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server +### As a Business Server {#as-a-business-server} In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration +#### Configuration {#configuration-1} The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/ap_versioned_docs/version-2.11/admin-guide/getting-started.mdx b/ap_versioned_docs/version-2.11/admin-guide/getting-started.mdx index 992e614b2..48a5d93a6 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/getting-started.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation +## Installation {#installation} import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:2.11.0 -## Set Up the Development Environment +## Set Up the Development Environment {#set-up-the-development-environment} In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration +## Configuration {#configuration} The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server +### Changing Port of the Platform Server {#changing-port-of-the-platform-server} For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets +### Specify Your Service's Assets {#specify-your-services-assets} Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence +### Add Data Persistence {#add-data-persistence} The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication +### Configure Platform API Authentication {#configure-platform-api-authentication} To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags +### Passing JVM flags {#passing-jvm-flags} Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep10/README.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep10/README.mdx index 1db24083f..fbd4a2a22 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep10/README.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication +## Enable Stellar Authentication {#enable-stellar-authentication} Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution +## Config With Client Attribution {#config-with-client-attribution} `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -131,7 +131,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/configuration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/configuration.mdx index 09c8dc709..906850f4f 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/configuration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals +## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -109,7 +109,7 @@ SECRET_SEP24_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busi `SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET` and `SECRET_SEP24_MORE_INFO_URL_JWT_SECRET` are encryption keys that the Anchor Platform will use to generate short-lived tokens it will add to the URLs provided to the wallet. Your business server must also have these keys in its environment so it can verify the token's signature. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/example.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/example.mdx index 1013eb596..762a16973 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/example.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience +## Building a Web-Based User Experience {#building-a-web-based-user-experience} The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication +### Authentication {#authentication} If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform +## Providing Updates to the Platform {#providing-updates-to-the-platform} Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform +## Fetching Updates from the Platform {#fetching-updates-from-the-platform} If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation +## Full Example Implementation {#full-example-implementation} Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/faq.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/faq.mdx index 5972a06cf..ee5eb71da 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/faq.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? +### How To Use JWTs? {#how-to-use-jwts} As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? +### How To Provide Fees? {#how-to-provide-fees} Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? +### How to identify the user account? {#how-to-identify-the-user-account} You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? +### How to identify the wallet? {#how-to-identify-the-wallet} Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/getting-started.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/getting-started.mdx index ce1d1dbf4..e77894428 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/getting-started.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience a deposit and withdrawal goes something like this: diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx index bb3a9f759..57db2d794 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit Transaction Via JSON-RPC +## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information} :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction status to `expired`. @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction} In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC +## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information-1} This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction-1} Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/setting-up-production-server.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/setting-up-production-server.mdx index f631e5dbf..68c15d0bb 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/setting-up-production-server.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment +## Deploying a Secure Environment {#deploying-a-secure-environment} Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC +## Connecting to Real KYC {#connecting-to-real-kyc} Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form +## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails +## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases +## Testing Edge Cases {#testing-edge-cases} Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests +### General Tests {#general-tests} - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests +### KYC Tests {#kyc-tests} - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test +### Interactive Test {#interactive-test} - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests +### Security Tests {#security-tests} - Make sure platform endpoints are secured -## Polishing and Internationalization +## Polishing and Internationalization {#polishing-and-internationalization} Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets +## Connecting to Wallets {#connecting-to-wallets} All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep31/configuration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep31/configuration.mdx index d68d781de..7df1dde9b 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep31/configuration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments +## Enable Cross Border Payments {#enable-cross-border-payments} Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API +## Enable the Customer KYC API {#enable-the-customer-kyc-api} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API +## Enable the RFQ API {#enable-the-rfq-api} Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication +## Configure Callback API Authentication {#configure-callback-api-authentication} Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep31/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep31/integration.mdx index b8fda8408..9811571c5 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep31/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep31/integration.mdx @@ -18,7 +18,7 @@ The following may also be required depending on your use case: - [`GET /unique_address`][get-unique-address] if your business uses a custody service for on-chain assets - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server +## Create a Business Server {#create-a-business-server} First, lets create a business server and add it to our docker compose file. @@ -71,11 +71,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints +## Customer Callback Endpoints {#customer-callback-endpoints} The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers +### Identifying Customers {#identifying-customers} Customers can be identified using two approaches. @@ -134,13 +134,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types +### Customer Types {#customer-types} Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet +### Test with the Demo Wallet {#test-with-the-demo-wallet} You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -157,33 +157,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint +## Rate Callback Endpoint {#rate-callback-endpoint} Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes +### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID +### Using the Client ID {#using-the-client-id} Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods +### Delivery Methods {#delivery-methods} It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates +## Fetching Transaction Status Updates {#fetching-transaction-status-updates} To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer +### Running the Stellar Observer {#running-the-stellar-observer} The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -203,7 +203,7 @@ services: -### Polling for Received Payments +### Polling for Received Payments {#polling-for-received-payments} The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -219,7 +219,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC +## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -239,7 +239,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} SEP-31 Transactions should initially be in the `pending_sender` status. The Receiving Anchor waits to receive the payment identified by the stellar_memo included in the POST /transactions response. @@ -286,7 +286,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -321,7 +321,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Verifying Customer Information +### Verifying Customer Information {#verifying-customer-information} In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -392,7 +392,7 @@ To execute this, you need to run: -### Do Stellar Refund +### Do Stellar Refund {#do-stellar-refund} Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -441,7 +441,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent +### Refund Sent {#refund-sent} There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -491,7 +491,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -530,7 +530,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -569,7 +569,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -602,11 +602,11 @@ To execute this, you need to run: -## Fee Callback Endpoint +## Fee Callback Endpoint {#fee-callback-endpoint} Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time the funds are paid out to the recipient. In this case, the Anchor Platform will not make a `GET /rate` request, but you will still need to provide the fee your business will charge for these types of transactions using the [`GET /fee`][get-fee] endpoint. -### Configuration +### Configuration {#configuration} You can enable these types of transactions by updating your `assets.yaml` file configuration: @@ -621,11 +621,11 @@ assets: -## Unique Address Callback Endpoint +## Unique Address Callback Endpoint {#unique-address-callback-endpoint} Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so that the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments. In this case, the business must request the custodian to generate the Stellar account & memo. This is done by using the [`GET /unique_address` endpoint][get-unique-address]. -### Configuration +### Configuration {#configuration-1} To configure the Anchor Platform to make these requests, add the following to your configuration: diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep6/configuration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep6/configuration.mdx index dea786738..8996dc626 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep6/configuration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals +## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File +### Modify a Stellar Info File {#modify-a-stellar-info-file} Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File +### Modify the Assets Configuration File {#modify-the-assets-configuration-file} Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts +### Managing Distribution Accounts {#managing-distribution-accounts} Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server +### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -177,7 +177,7 @@ SECRET_SEP6_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busin See the [KYC API][platform-api-kyc] and [Rates API][sep38] for details on the endpoints that must be implemented on your business server. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep6/getting-started.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep6/getting-started.mdx index 3a1d875e9..fb4e1293c 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep6/getting-started.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx index 5b4d53d58..42c276825 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information +### Customer Information {#customer-information} The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit (Exchange) Transaction Via JSON-RPC +## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information +### Verifying KYC Information {#verifying-kyc-information} Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -129,7 +129,7 @@ To execute this, you need to run: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -201,7 +201,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide updated transaction information. @@ -253,7 +253,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -288,7 +288,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -326,7 +326,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -369,7 +369,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -408,7 +408,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -450,7 +450,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent +### Refund Sent {#refund-sent} Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -500,11 +500,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -543,7 +543,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire transactions that have been abandoned by the user after some time. It's good practice to clean up inactive transactions in the `incomplete` status. To do so, make the following JSON-RPC request to expire a transaction. @@ -582,7 +582,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -615,7 +615,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -637,7 +637,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -718,7 +718,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -767,7 +767,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -812,7 +812,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -846,7 +846,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -880,7 +880,7 @@ To execute this, you need to run: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -915,11 +915,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent-1} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -968,19 +968,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/ap_versioned_docs/version-2.8/admin-guide/architecture.mdx b/ap_versioned_docs/version-2.8/admin-guide/architecture.mdx index d9abf6435..7e1fd14b7 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/architecture.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture +## Architecture {#architecture} Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture +### Fundamental Architecture {#fundamental-architecture} The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client +#### Client {#client} The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server +#### SEP Server {#sep-server} The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server +#### Business Server {#business-server} The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server +#### Platform Server {#platform-server} The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database +#### Database {#database} The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture +### Complete Architecture {#complete-architecture} In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service +#### Event Service {#event-service} The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server +#### Custody Server {#custody-server} The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer +#### Stellar Observer {#stellar-observer} The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/ap_versioned_docs/version-2.8/admin-guide/custody-services/configuration.mdx b/ap_versioned_docs/version-2.8/admin-guide/custody-services/configuration.mdx index a068caab1..8abcb8312 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/custody-services/configuration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration +## Custody Server Configuration {#custody-server-configuration} If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:2.8.4 --custody-server -## Anchor Platform Configuration +## Anchor Platform Configuration {#anchor-platform-configuration} Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration +## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/ap_versioned_docs/version-2.8/admin-guide/custody-services/fireblocks/example.mdx b/ap_versioned_docs/version-2.8/admin-guide/custody-services/fireblocks/example.mdx index 613d31bca..9b3b8bf30 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/custody-services/fireblocks/example.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: +### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: +### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: +### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: +### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: +### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: +### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/ap_versioned_docs/version-2.8/admin-guide/events/delivery.mdx b/ap_versioned_docs/version-2.8/admin-guide/events/delivery.mdx index cd6d3148e..3c5f30142 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/events/delivery.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees +## Delivery Guarantees {#delivery-guarantees} Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees +### Client Delivery Guarantees {#client-delivery-guarantees} For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees +### Business Server Delivery Guarantees {#business-server-delivery-guarantees} The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/ap_versioned_docs/version-2.8/admin-guide/events/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/events/integration.mdx index b2638a348..15582d435 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/events/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements +## Requirements {#requirements} Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration +## Configuration {#configuration} First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events +## Receiving Events {#receiving-events} The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application +### As a Client Application {#as-a-client-application} Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing +#### Callback Signing {#callback-signing} Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server +### As a Business Server {#as-a-business-server} In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration +#### Configuration {#configuration-1} The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/ap_versioned_docs/version-2.8/admin-guide/getting-started.mdx b/ap_versioned_docs/version-2.8/admin-guide/getting-started.mdx index c434ee9a4..5ca422da4 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/getting-started.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation +## Installation {#installation} import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:2.8.4 -## Set Up the Development Environment +## Set Up the Development Environment {#set-up-the-development-environment} In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration +## Configuration {#configuration} The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server +### Changing Port of the Platform Server {#changing-port-of-the-platform-server} For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets +### Specify Your Service's Assets {#specify-your-services-assets} Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence +### Add Data Persistence {#add-data-persistence} The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication +### Configure Platform API Authentication {#configure-platform-api-authentication} To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags +### Passing JVM flags {#passing-jvm-flags} Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep10/README.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep10/README.mdx index 485e404be..14cbfc8a4 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep10/README.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication +## Enable Stellar Authentication {#enable-stellar-authentication} Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution +## Config With Client Attribution {#config-with-client-attribution} `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -118,7 +118,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/configuration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/configuration.mdx index 3c6d294c8..6fe6c5501 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/configuration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals +## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -109,7 +109,7 @@ SECRET_SEP24_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busi `SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET` and `SECRET_SEP24_MORE_INFO_URL_JWT_SECRET` are encryption keys that the Anchor Platform will use to generate short-lived tokens it will add to the URLs provided to the wallet. Your business server must also have these keys in its environment so it can verify the token's signature. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/example.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/example.mdx index 7c424f535..bf906b32d 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/example.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience +## Building a Web-Based User Experience {#building-a-web-based-user-experience} The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication +### Authentication {#authentication} If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform +## Providing Updates to the Platform {#providing-updates-to-the-platform} Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform +## Fetching Updates from the Platform {#fetching-updates-from-the-platform} If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation +## Full Example Implementation {#full-example-implementation} Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/faq.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/faq.mdx index 5972a06cf..ee5eb71da 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/faq.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? +### How To Use JWTs? {#how-to-use-jwts} As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? +### How To Provide Fees? {#how-to-provide-fees} Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? +### How to identify the user account? {#how-to-identify-the-user-account} You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? +### How to identify the wallet? {#how-to-identify-the-wallet} Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/getting-started.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/getting-started.mdx index ce1d1dbf4..e77894428 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/getting-started.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience a deposit and withdrawal goes something like this: diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx index 099bd817d..6e2e6e081 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit Transaction Via JSON-RPC +## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information} :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction status to `expired`. @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction} In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC +## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information-1} This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction-1} Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/setting-up-production-server.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/setting-up-production-server.mdx index f631e5dbf..68c15d0bb 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/setting-up-production-server.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment +## Deploying a Secure Environment {#deploying-a-secure-environment} Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC +## Connecting to Real KYC {#connecting-to-real-kyc} Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form +## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails +## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases +## Testing Edge Cases {#testing-edge-cases} Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests +### General Tests {#general-tests} - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests +### KYC Tests {#kyc-tests} - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test +### Interactive Test {#interactive-test} - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests +### Security Tests {#security-tests} - Make sure platform endpoints are secured -## Polishing and Internationalization +## Polishing and Internationalization {#polishing-and-internationalization} Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets +## Connecting to Wallets {#connecting-to-wallets} All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep31/configuration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep31/configuration.mdx index d68d781de..7df1dde9b 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep31/configuration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments +## Enable Cross Border Payments {#enable-cross-border-payments} Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API +## Enable the Customer KYC API {#enable-the-customer-kyc-api} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API +## Enable the RFQ API {#enable-the-rfq-api} Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication +## Configure Callback API Authentication {#configure-callback-api-authentication} Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep31/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep31/integration.mdx index eb7f83f05..c564b7db9 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep31/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep31/integration.mdx @@ -18,7 +18,7 @@ The following may also be required depending on your use case: - [`GET /unique_address`][get-unique-address] if your business uses a custody service for on-chain assets - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server +## Create a Business Server {#create-a-business-server} First, lets create a business server and add it to our docker compose file. @@ -71,11 +71,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints +## Customer Callback Endpoints {#customer-callback-endpoints} The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers +### Identifying Customers {#identifying-customers} Customers can be identified using two approaches. @@ -134,13 +134,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types +### Customer Types {#customer-types} Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet +### Test with the Demo Wallet {#test-with-the-demo-wallet} You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -157,33 +157,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint +## Rate Callback Endpoint {#rate-callback-endpoint} Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes +### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID +### Using the Client ID {#using-the-client-id} Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods +### Delivery Methods {#delivery-methods} It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates +## Fetching Transaction Status Updates {#fetching-transaction-status-updates} To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer +### Running the Stellar Observer {#running-the-stellar-observer} The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -203,7 +203,7 @@ services: -### Polling for Received Payments +### Polling for Received Payments {#polling-for-received-payments} The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -219,7 +219,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC +## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -239,7 +239,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} SEP-31 Transactions should initially be in the `pending_sender` status. The Receiving Anchor waits to receive the payment identified by the stellar_memo included in the POST /transactions response. @@ -286,7 +286,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -321,7 +321,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Customer Info Needed +### Customer Info Needed {#customer-info-needed} In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -388,7 +388,7 @@ To execute this, you need to run: -### Customer Info Updated +### Customer Info Updated {#customer-info-updated} After the Sending Anchor has made another SEP-12 `PUT /customer` request to update customer info, the Receiving Anchor should change the status of the transaction to `pending_receiver`. @@ -421,7 +421,7 @@ To execute this, you need to run: -### Do Stellar Refund +### Do Stellar Refund {#do-stellar-refund} Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -470,7 +470,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent +### Refund Sent {#refund-sent} There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -520,7 +520,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -559,7 +559,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -598,7 +598,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -631,11 +631,11 @@ To execute this, you need to run: -## Fee Callback Endpoint +## Fee Callback Endpoint {#fee-callback-endpoint} Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time the funds are paid out to the recipient. In this case, the Anchor Platform will not make a `GET /rate` request, but you will still need to provide the fee your business will charge for these types of transactions using the [`GET /fee`][get-fee] endpoint. -### Configuration +### Configuration {#configuration} You can enable these types of transactions by updating your `assets.yaml` file configuration: @@ -650,11 +650,11 @@ assets: -## Unique Address Callback Endpoint +## Unique Address Callback Endpoint {#unique-address-callback-endpoint} Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so that the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments. In this case, the business must request the custodian to generate the Stellar account & memo. This is done by using the [`GET /unique_address` endpoint][get-unique-address]. -### Configuration +### Configuration {#configuration-1} To configure the Anchor Platform to make these requests, add the following to your configuration: diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep6/configuration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep6/configuration.mdx index dea786738..8996dc626 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep6/configuration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals +## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File +### Modify a Stellar Info File {#modify-a-stellar-info-file} Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File +### Modify the Assets Configuration File {#modify-the-assets-configuration-file} Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts +### Managing Distribution Accounts {#managing-distribution-accounts} Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server +### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -177,7 +177,7 @@ SECRET_SEP6_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busin See the [KYC API][platform-api-kyc] and [Rates API][sep38] for details on the endpoints that must be implemented on your business server. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep6/getting-started.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep6/getting-started.mdx index 3a1d875e9..fb4e1293c 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep6/getting-started.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx index 7e19260cc..ff79f84b5 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information +### Customer Information {#customer-information} The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit (Exchange) Transaction Via JSON-RPC +## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information +### Verifying KYC Information {#verifying-kyc-information} Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -125,7 +125,7 @@ To execute this, you need to run: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -197,7 +197,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide updated transaction information. @@ -249,7 +249,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -284,7 +284,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -322,7 +322,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -365,7 +365,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -404,7 +404,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -446,7 +446,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent +### Refund Sent {#refund-sent} Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -496,11 +496,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -539,7 +539,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire transactions that have been abandoned by the user after some time. It's good practice to clean up inactive transactions in the `incomplete` status. To do so, make the following JSON-RPC request to expire a transaction. @@ -578,7 +578,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -611,7 +611,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -633,7 +633,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -714,7 +714,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -763,7 +763,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -808,7 +808,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -842,7 +842,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -876,7 +876,7 @@ To execute this, you need to run: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -911,11 +911,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent-1} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -964,19 +964,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/ap_versioned_docs/version-2.9/admin-guide/architecture.mdx b/ap_versioned_docs/version-2.9/admin-guide/architecture.mdx index d9abf6435..7e1fd14b7 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/architecture.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture +## Architecture {#architecture} Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture +### Fundamental Architecture {#fundamental-architecture} The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client +#### Client {#client} The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server +#### SEP Server {#sep-server} The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server +#### Business Server {#business-server} The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server +#### Platform Server {#platform-server} The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database +#### Database {#database} The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture +### Complete Architecture {#complete-architecture} In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service +#### Event Service {#event-service} The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server +#### Custody Server {#custody-server} The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer +#### Stellar Observer {#stellar-observer} The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/ap_versioned_docs/version-2.9/admin-guide/custody-services/configuration.mdx b/ap_versioned_docs/version-2.9/admin-guide/custody-services/configuration.mdx index 611d9dfa5..3f21b7b8b 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/custody-services/configuration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration +## Custody Server Configuration {#custody-server-configuration} If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:2.9.0 --custody-server -## Anchor Platform Configuration +## Anchor Platform Configuration {#anchor-platform-configuration} Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration +## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/ap_versioned_docs/version-2.9/admin-guide/custody-services/fireblocks/example.mdx b/ap_versioned_docs/version-2.9/admin-guide/custody-services/fireblocks/example.mdx index 613d31bca..9b3b8bf30 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/custody-services/fireblocks/example.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: +### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: +### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: +### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: +### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: +### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: +### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/ap_versioned_docs/version-2.9/admin-guide/events/delivery.mdx b/ap_versioned_docs/version-2.9/admin-guide/events/delivery.mdx index cd6d3148e..3c5f30142 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/events/delivery.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees +## Delivery Guarantees {#delivery-guarantees} Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees +### Client Delivery Guarantees {#client-delivery-guarantees} For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees +### Business Server Delivery Guarantees {#business-server-delivery-guarantees} The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/ap_versioned_docs/version-2.9/admin-guide/events/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/events/integration.mdx index b2638a348..15582d435 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/events/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements +## Requirements {#requirements} Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration +## Configuration {#configuration} First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events +## Receiving Events {#receiving-events} The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application +### As a Client Application {#as-a-client-application} Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing +#### Callback Signing {#callback-signing} Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server +### As a Business Server {#as-a-business-server} In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration +#### Configuration {#configuration-1} The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/ap_versioned_docs/version-2.9/admin-guide/getting-started.mdx b/ap_versioned_docs/version-2.9/admin-guide/getting-started.mdx index d373ecaaa..650698e14 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/getting-started.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation +## Installation {#installation} import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:2.9.0 -## Set Up the Development Environment +## Set Up the Development Environment {#set-up-the-development-environment} In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration +## Configuration {#configuration} The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server +### Changing Port of the Platform Server {#changing-port-of-the-platform-server} For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets +### Specify Your Service's Assets {#specify-your-services-assets} Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence +### Add Data Persistence {#add-data-persistence} The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication +### Configure Platform API Authentication {#configure-platform-api-authentication} To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags +### Passing JVM flags {#passing-jvm-flags} Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep10/README.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep10/README.mdx index 1db24083f..fbd4a2a22 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep10/README.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication +## Enable Stellar Authentication {#enable-stellar-authentication} Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution +## Config With Client Attribution {#config-with-client-attribution} `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -131,7 +131,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/configuration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/configuration.mdx index 09c8dc709..906850f4f 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/configuration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals +## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -109,7 +109,7 @@ SECRET_SEP24_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busi `SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET` and `SECRET_SEP24_MORE_INFO_URL_JWT_SECRET` are encryption keys that the Anchor Platform will use to generate short-lived tokens it will add to the URLs provided to the wallet. Your business server must also have these keys in its environment so it can verify the token's signature. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/example.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/example.mdx index 77fb8b995..cf4dab925 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/example.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience +## Building a Web-Based User Experience {#building-a-web-based-user-experience} The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication +### Authentication {#authentication} If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform +## Providing Updates to the Platform {#providing-updates-to-the-platform} Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform +## Fetching Updates from the Platform {#fetching-updates-from-the-platform} If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation +## Full Example Implementation {#full-example-implementation} Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/faq.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/faq.mdx index 5972a06cf..ee5eb71da 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/faq.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? +### How To Use JWTs? {#how-to-use-jwts} As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? +### How To Provide Fees? {#how-to-provide-fees} Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? +### How to identify the user account? {#how-to-identify-the-user-account} You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? +### How to identify the wallet? {#how-to-identify-the-wallet} Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/getting-started.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/getting-started.mdx index ce1d1dbf4..e77894428 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/getting-started.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience a deposit and withdrawal goes something like this: diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx index f07b332a6..7f0c43bb6 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit Transaction Via JSON-RPC +## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information} :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction status to `expired`. @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction} In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC +## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information-1} This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction-1} Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/setting-up-production-server.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/setting-up-production-server.mdx index f631e5dbf..68c15d0bb 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/setting-up-production-server.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment +## Deploying a Secure Environment {#deploying-a-secure-environment} Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC +## Connecting to Real KYC {#connecting-to-real-kyc} Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form +## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails +## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases +## Testing Edge Cases {#testing-edge-cases} Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests +### General Tests {#general-tests} - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests +### KYC Tests {#kyc-tests} - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test +### Interactive Test {#interactive-test} - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests +### Security Tests {#security-tests} - Make sure platform endpoints are secured -## Polishing and Internationalization +## Polishing and Internationalization {#polishing-and-internationalization} Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets +## Connecting to Wallets {#connecting-to-wallets} All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep31/configuration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep31/configuration.mdx index d68d781de..7df1dde9b 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep31/configuration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments +## Enable Cross Border Payments {#enable-cross-border-payments} Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API +## Enable the Customer KYC API {#enable-the-customer-kyc-api} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API +## Enable the RFQ API {#enable-the-rfq-api} Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication +## Configure Callback API Authentication {#configure-callback-api-authentication} Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep31/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep31/integration.mdx index 7eb844390..eb14cf5f5 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep31/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep31/integration.mdx @@ -18,7 +18,7 @@ The following may also be required depending on your use case: - [`GET /unique_address`][get-unique-address] if your business uses a custody service for on-chain assets - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server +## Create a Business Server {#create-a-business-server} First, lets create a business server and add it to our docker compose file. @@ -71,11 +71,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints +## Customer Callback Endpoints {#customer-callback-endpoints} The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers +### Identifying Customers {#identifying-customers} Customers can be identified using two approaches. @@ -134,13 +134,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types +### Customer Types {#customer-types} Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet +### Test with the Demo Wallet {#test-with-the-demo-wallet} You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -157,33 +157,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint +## Rate Callback Endpoint {#rate-callback-endpoint} Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes +### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID +### Using the Client ID {#using-the-client-id} Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods +### Delivery Methods {#delivery-methods} It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates +## Fetching Transaction Status Updates {#fetching-transaction-status-updates} To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer +### Running the Stellar Observer {#running-the-stellar-observer} The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -203,7 +203,7 @@ services: -### Polling for Received Payments +### Polling for Received Payments {#polling-for-received-payments} The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -219,7 +219,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC +## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -239,7 +239,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} SEP-31 Transactions should initially be in the `pending_sender` status. The Receiving Anchor waits to receive the payment identified by the stellar_memo included in the POST /transactions response. @@ -286,7 +286,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -321,7 +321,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Verifying Customer Information +### Verifying Customer Information {#verifying-customer-information} In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -392,7 +392,7 @@ To execute this, you need to run: -### Do Stellar Refund +### Do Stellar Refund {#do-stellar-refund} Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -441,7 +441,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent +### Refund Sent {#refund-sent} There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -491,7 +491,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -530,7 +530,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -569,7 +569,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -602,11 +602,11 @@ To execute this, you need to run: -## Fee Callback Endpoint +## Fee Callback Endpoint {#fee-callback-endpoint} Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time the funds are paid out to the recipient. In this case, the Anchor Platform will not make a `GET /rate` request, but you will still need to provide the fee your business will charge for these types of transactions using the [`GET /fee`][get-fee] endpoint. -### Configuration +### Configuration {#configuration} You can enable these types of transactions by updating your `assets.yaml` file configuration: @@ -621,11 +621,11 @@ assets: -## Unique Address Callback Endpoint +## Unique Address Callback Endpoint {#unique-address-callback-endpoint} Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so that the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments. In this case, the business must request the custodian to generate the Stellar account & memo. This is done by using the [`GET /unique_address` endpoint][get-unique-address]. -### Configuration +### Configuration {#configuration-1} To configure the Anchor Platform to make these requests, add the following to your configuration: diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep6/configuration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep6/configuration.mdx index dea786738..8996dc626 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep6/configuration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals +## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File +### Modify a Stellar Info File {#modify-a-stellar-info-file} Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File +### Modify the Assets Configuration File {#modify-the-assets-configuration-file} Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts +### Managing Distribution Accounts {#managing-distribution-accounts} Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server +### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -177,7 +177,7 @@ SECRET_SEP6_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busin See the [KYC API][platform-api-kyc] and [Rates API][sep38] for details on the endpoints that must be implemented on your business server. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep6/getting-started.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep6/getting-started.mdx index 3a1d875e9..fb4e1293c 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep6/getting-started.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx index c1836b071..3faf043f5 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information +### Customer Information {#customer-information} The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit (Exchange) Transaction Via JSON-RPC +## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information +### Verifying KYC Information {#verifying-kyc-information} Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -129,7 +129,7 @@ To execute this, you need to run: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -201,7 +201,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide updated transaction information. @@ -253,7 +253,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -288,7 +288,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -326,7 +326,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -369,7 +369,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -408,7 +408,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -450,7 +450,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent +### Refund Sent {#refund-sent} Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -500,11 +500,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -543,7 +543,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire transactions that have been abandoned by the user after some time. It's good practice to clean up inactive transactions in the `incomplete` status. To do so, make the following JSON-RPC request to expire a transaction. @@ -582,7 +582,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -615,7 +615,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -637,7 +637,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -718,7 +718,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -767,7 +767,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -812,7 +812,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -846,7 +846,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -880,7 +880,7 @@ To execute this, you need to run: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -915,11 +915,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent-1} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -968,19 +968,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/docs/README.mdx b/docs/README.mdx index 5444a4dda..26cb4ec8f 100644 --- a/docs/README.mdx +++ b/docs/README.mdx @@ -4,32 +4,32 @@ displayed_sidebar: build hide_table_of_contents: true --- -## Navigating the docs +## Navigating the docs {#navigating-the-docs} -### [Build](./build/README.mdx) +### [Build](./build/README.mdx) {#build} Contains tutorials and how-to guides for writing smart contracts, building applications, interacting with the network, and more. -### [Learn](./learn/fundamentals/README.mdx) +### [Learn](./learn/fundamentals/README.mdx) {#learn} Find all informational and conceptual content here. Learn about Stellar fundamentals like how accounts and transactions function, dive deeper into the functionality of each operation, discover how fees work, and more. -### [Tokens](./tokens/README.mdx) +### [Tokens](./tokens/README.mdx) {#tokens} Information on how to issue assets on the Stellar network and create custom smart contract tokens. -### [Data](./data/README.mdx) +### [Data](./data/README.mdx) {#data} Discover various data availability options: RPC, Hubble, Horizon, and Galexie. -### [Tools](./tools/README.mdx) +### [Tools](./tools/README.mdx) {#tools} Learn about all the available tools at your disposal for building on, interacting with, or just watching the Stellar network. Also, find information on how to use the Anchor Platform or Stellar Disbursement Platform. -### [Networks](./networks/README.mdx) +### [Networks](./networks/README.mdx) {#networks} Information about deployed networks (Mainnet, Testnet, and Futurenet), current software versions, and resource limitations and fees. -### [Validators](./validators/README.mdx) +### [Validators](./validators/README.mdx) {#validators} Everything you'll need to know if you want to run, operate, and maintain a core validator node on the Stellar network. diff --git a/docs/build/README.mdx b/docs/build/README.mdx index 473f1e882..863310c96 100644 --- a/docs/build/README.mdx +++ b/docs/build/README.mdx @@ -8,13 +8,13 @@ The Build section is split into three parts: 1) writing smart contracts, 2) buil Find explanations on what each section contains below. -## Smart contracts +## Smart contracts {#smart-contracts} Smart contracts are self-executing programs with the terms of an agreement written directly into the code. They automatically enforce and execute the terms of the contract when predefined conditions are met. Developers must define the rules and logic of the contract while also ensuring security. Once written and tested, smart contracts are deployed to the blockchain, where they become immutable and publicly accessible. This section will walk you through how to get set up to write smart contracts on Stellar, plus an introduction to testing, storing data, and deploying your contracts. It also provides an array of example contracts for use. -## Applications +## Applications {#applications} Applications interact with the blockchain and can use smart contracts as the backend. They provide user interfaces, manage user interactions, and can integrate with smart contracts to operate. Users can interact with the blockchain using the application interface. Writing smart contracts focuses on the backend logic and rules enforced on the blockchain while building applications involves creating the front end and integrating it with these smart contracts to provide a complete user experience. @@ -26,7 +26,7 @@ You can create applications on Stellar without using smart contracts, as demonst This section walks you through design considerations for applications and tutorials for building applications with or without smart contracts. -## How-To Guides +## How-To Guides {#how-to-guides} This section provides step-by-step instructions to help users complete specific tasks associated with developing on Stellar. These tasks can include instructions for aspects of writing contracts, interacting with contracts, building applications, using Stellar operations, setting up infrastructure, and more. diff --git a/docs/build/apps/application-design-considerations.mdx b/docs/build/apps/application-design-considerations.mdx index 2ccedc965..6b5be6608 100644 --- a/docs/build/apps/application-design-considerations.mdx +++ b/docs/build/apps/application-design-considerations.mdx @@ -3,7 +3,7 @@ title: Application Design Considerations sidebar_position: 10 --- -## Custody models +## Custody models {#custody-models} When building an application, one of the first things you have to decide is how your users’ secret keys will be secured and stored. Stellar applications give users access to their accounts that are stored on the ledger, and access to these accounts is controlled by the account’s secret key. That secret key proves that the user has custody or “owns” the account. @@ -14,23 +14,23 @@ There are four custody options to consider: - Mixture of both - with the use of [multisig](../../learn/encyclopedia/security/signatures-multisig.mdx), this option is useful for maintaining non-custodial status while still allowing for account recovery - Third-party key management services - integrate a third-party custodial service into your application that can store your users’ secret keys -### Non-custodial service +### Non-custodial service {#non-custodial-service} In a non-custodial service, the user of the application stores the secret key for their account and permissions the application to send requests to delegate transaction signing. There are some potential usability issues as the user has to know how to securely store their own account credentials and safely navigate transaction signing on their end. If they lose their secret key, they will also lose access to their account. Typically, non-custodial applications create or import a pre-existing Stellar account for each user. -### Custodial service +### Custodial service {#custodial-service} With a custodial service, the service provider (an application such as a centralized exchange) stores the users’ secret keys and delegates usage rights to the user. Many custodial services choose to use a single pooled Stellar account (called shared, omnibus, or [pooled accounts](../../learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx)) to handle transactions on behalf of their users instead of creating a new Stellar account for each user. To distinguish between individual users in a pooled account, we encourage the implementation of [muxed accounts](../../learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx#muxed-accounts). -### A mixture of non-custodial and custodial +### A mixture of non-custodial and custodial {#a-mixture-of-non-custodial-and-custodial} Building an application with [multi-signature](../../learn/encyclopedia/security/signatures-multisig.mdx) capabilities allows you to have a non-custodial service with account recovery. If the user loses their secret key, they can still sign transactions with other authorized signatures, granted the signature threshold is high enough. -### Third-party key management services​ +### Third-party key management services​ {#third-party-key-management-services} There are several apps and services that specialize in adding additional security layers to users' accounts. Check them out if you're interested in integrating a third-party key management service: @@ -40,26 +40,26 @@ There are several apps and services that specialize in adding additional securit - [StellarGuard](https://stellarguard.me/) - [LobstrVault](https://vault.lobstr.co/) -## Application security +## Application security {#application-security} Even though wallets can operate client-side, they deal with a user’s secret keys, which give direct access to their account, and to any value they hold. That’s why it’s essential to require all web traffic to flow over strong TLS methods. Even when developing locally, use a non-signed localhost certificate to develop secure habits from the very beginning. Stellar is a powerful money-moving software — don’t skimp on security. For more information, check out our guide to [securing web-based products](https://www.stellar.org/developers/guides/walkthroughs/securing-web-projects.html). -## Wallet services +## Wallet services {#wallet-services} A wallet typically has these basic functions: key storage, account creation, transaction signing, and queries to the Stellar database. There are some services that take care of all of these functions for you, so you can build whatever you’d like around it. Check out some of these wallet services below. - [Albedo](https://albedo.link/) - [Freighter](https://www.freighter.app/) -## Account creation strategies +## Account creation strategies {#account-creation-strategies} In this section, we will go over the new user account creation flow between non-custodial wallets and anchors with SEP-24 and/or SEP-6 implementations. A Stellar account is created with a keypair (a public key and private key) and the minimum balance of XLM. When a new customer downloads the wallet application and goes through the deposit flow for the first time, their Stellar account can be created by either the user’s wallet application or the anchor facilitating the first deposit. This section describes each of these strategies. -### Option 1: The anchor creates and funds the Stellar account​ +### Option 1: The anchor creates and funds the Stellar account​ {#option-1-the-anchor-creates-and-funds-the-stellar-account} For this option, the wallet needs to allow users to initiate their first deposit without having to add an asset/establish a trustline. The wallet then prompts the user to add the trustline once funds are received by the anchor. The flow looks like this: @@ -90,7 +90,7 @@ The flow with Claimable Balances looks like this: 6. The anchor creates a Claimable Balance. 7. The wallet detects the Claimable Balance for the account, claims the funds, and posts it in the wallet. -### Option 2: the wallet creates and funds the Stellar account upon user sign-up​ +### Option 2: the wallet creates and funds the Stellar account upon user sign-up​ {#option-2-the-wallet-creates-and-funds-the-stellar-account-upon-user-sign-up} For this option, the wallet creates and funds the Stellar account upon every new user sign-up with the minimum requirement of 1XLM, plus the .5XLM reserve for establishing the first trustline, plus a bit more to cover transaction fees. For more information on minimum balances, check out the [Lumens section](../../learn/fundamentals/lumens.mdx#minimum-balance). diff --git a/docs/build/apps/dapp-frontend.mdx b/docs/build/apps/dapp-frontend.mdx index 4479adbbb..4fc37f0db 100644 --- a/docs/build/apps/dapp-frontend.mdx +++ b/docs/build/apps/dapp-frontend.mdx @@ -9,7 +9,7 @@ This is a continuation of the [Getting Started tutorial](../smart-contracts/gett Let's get started. -## Initialize a frontend toolchain +## Initialize a frontend toolchain {#initialize-a-frontend-toolchain} You can build a Soroban app with any frontend toolchain or integrate it into any existing full-stack app. For this tutorial, we're going to use [Astro](https://astro.build/). Astro works with React, Vue, Svelte, any other UI library, or no UI library at all. In this tutorial, we're not using a UI library. The Soroban-specific parts of this tutorial will be similar no matter what frontend toolchain you use. @@ -49,7 +49,7 @@ This will add the following to your project, which we'll go over in more detail └── tsconfig.json ``` -## Generate an NPM package for the Hello World contract +## Generate an NPM package for the Hello World contract {#generate-an-npm-package-for-the-hello-world-contract} Before we open the new frontend files, let's generate an NPM package for the Hello World contract. This is our suggested way to interact with contracts from frontends. These generated libraries work with any JavaScript project (not a specific UI like React), and make it easy to work with some of the trickiest bits of Soroban, like encoding [XDR](../../learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx). @@ -66,7 +66,7 @@ This project is set up as an NPM Workspace, and so the `hello_world` client libr We attempt to keep the code in these generated libraries readable, so go ahead and look around. Open up the new `packages/hello_world` directory in your editor. If you've built or contributed to Node projects, it will all look familiar. You'll see a `package.json` file, a `src` directory, a `tsconfig.json`, and even a README. -## Generate an NPM package for the Increment contract +## Generate an NPM package for the Increment contract {#generate-an-npm-package-for-the-increment-contract} Though we can run `soroban contract bindings typescript` for each of our contracts individually, the [soroban-template-astro](https://github.com/stellar/soroban-astro-template) that we used as our template includes a very handy `initialize.js` script that will handle this for all of the contracts in our `contracts` directory. @@ -79,7 +79,7 @@ In addition to generating the NPM packages, `initialize.js` will also: We have already taken care of the first three bullet points in earlier steps of this tutorial, so those tasks will be noops when we run `initialize.js`. -### Configure initialize.js +### Configure initialize.js {#configure-initializejs} We need to make sure that `initialize.js` has all of the environment variables it needs before we do anything else. Copy the `.env.example` file over to `.env`. The environment variables set in `.env` are used by the `initialize.js` script. @@ -122,7 +122,7 @@ This `.env` file is used in the `initialize.js` script. When using the CLI, we c ::: -### Run `initialize.js` +### Run `initialize.js` {#run-initializejs} First let's install the Javascript dependencies: @@ -138,7 +138,7 @@ npm run init As mentioned above, this script attempts to build and deploy our contracts, which we have already done. The script is smart enough to check if a step has already been taken care of, and is a no-op in that case, so it is safe to run more than once. -### Call the contract from the frontend +### Call the contract from the frontend {#call-the-contract-from-the-frontend} Now let's open up `src/pages/index.astro` and take a look at how the frontend code integrates with the NPM package we created for our contracts. @@ -174,7 +174,7 @@ When you start up the dev server with `npm run dev`, you will see similar output ::: -### What's happening here? +### What's happening here? {#whats-happening-here} If you inspect the page (right-click, inspect) and refresh, you'll see a couple interesting things: @@ -195,13 +195,13 @@ Then check the `dist` folder. You'll see that it built an HTML and CSS file, but During the build, Astro made a single call to your contract, then injected the static result into the page. This is great for contract methods that don't change, but probably won't work for most contract methods. Let's integrate with the `incrementor` contract to see how to handle interactive methods in Astro. --> -## Call the incrementor contract from the frontend +## Call the incrementor contract from the frontend {#call-the-incrementor-contract-from-the-frontend} While `hello` is a simple view-only/read method, `increment` changes on-chain state. This means that someone needs to sign the transaction. So we'll need to add transaction-signing capabilities to the frontend. The way signing works in a browser is with a _wallet_. Wallets can be web apps, browser extensions, standalone apps, or even separate hardware devices. -### Install Freighter Extension +### Install Freighter Extension {#install-freighter-extension} Right now, the wallet that best supports Soroban is [Freighter](../guides/freighter/README.mdx). It is available as a Firefox Add-on, as well as extensions for Chrome and Brave. Go ahead and [install it now](https://freighter.app). @@ -211,7 +211,7 @@ Go to Settings (the gear icon) → Preferences and toggle the switch to Enable E Now you're all set up to use Freighter as a user, and you can add it to your app. -### Add the StellarWalletsKit and set it up +### Add the StellarWalletsKit and set it up {#add-the-stellarwalletskit-and-set-it-up} Even though we're using Freighter to test our app, there are more wallets that support signing smart contract transactions. To make their integration easier, we are using the `StellarWalletsKit` library which allows us support all Stellar Wallets with a single library. @@ -355,7 +355,7 @@ Then open the page and click the "Connect" button. You should see Freighter pop Now you're ready to sign the call to `increment`! -### Call `increment` +### Call `increment` {#call-increment} Now we can import the `increment` contract client from `soroban_increment_contract` and start using it. We'll again create a new Astro component. Create a new file at `src/components/Counter.astro` with the following contents: @@ -454,7 +454,7 @@ There's obviously some functionality missing, though. For example, that `???` is Before you try to update it, let's streamline the process around building, deploying, and generating clients for contracts. -## Take it further +## Take it further {#take-it-further} If you want to take it a bit further and make sure you understand all the pieces here, try the following: @@ -465,13 +465,13 @@ If you want to take it a bit further and make sure you understand all the pieces - Rather than using NPM scripts for everything, try using a more elegant script runner such as [just](https://github.com/casey/just). The existing npm `scripts` can then call `just`, such as `"setup": "just setup"`. - Update the README to explain what this project is and how to use it to potential collaborators and employers 😉 -## Troubleshooting +## Troubleshooting {#troubleshooting} Sometimes things go wrong. As a first step when troubleshooting, you may want to [clone our tutorial repository](https://github.com/AhaLabs/soroban-tutorial-project) and see if the problem happens there, too. If it happens there, too, then it may be a temporary problem with the Soroban network. Here are some common issues and how to fix them. -### Call to `hello` fails +### Call to `hello` fails {#call-to-hello-fails} Sometimes the call to `hello` can start failing. You can obviously stub out the call and define `result` some other way to troubleshoot. @@ -479,11 +479,11 @@ One of the common problems here is that the contract becomes [archived](../../le If you're still having problems, join our Discord (link above) or [open an issue in GitHub](https://github.com/stellar/stellar-docs/issues/new/choose). -### All contract calls start throwing `403` errors +### All contract calls start throwing `403` errors {#all-contract-calls-start-throwing-403-errors} This means that Testnet is down, and you probably just need to wait a while and try again. -## Wrapping up +## Wrapping up {#wrapping-up} Some of the things we did in this section: diff --git a/docs/build/apps/example-application-tutorial/account-creation.mdx b/docs/build/apps/example-application-tutorial/account-creation.mdx index 43776881e..ca791f5da 100644 --- a/docs/build/apps/example-application-tutorial/account-creation.mdx +++ b/docs/build/apps/example-application-tutorial/account-creation.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 Accounts are the central data structure in Stellar and can only exist with a valid keypair (a public and secret key) and the required minimum balance of XLM. Read more in the [Accounts section]. -## User experience +## User experience {#user-experience} To start, we'll have our user create an account. In BasicPay, the signup page will display a randomized public and secret keypair that the user can select with the option to choose a new set if preferred. @@ -25,11 +25,11 @@ With BasicPay, when the user clicks the “Signup” button, they will be asked When you're ready to move the application to Pubnet, accounts will need to be funded with real XLM. This is something the application can cover itself by depositing XLM into the user's account, with the use of [sponsored reserves], or the user can cover the required balance with their own XLM. -## Code implementation +## Code implementation {#code-implementation} We will create a Svelte `store` to interact with our user's randomly generated keypair. The store will take advantage of some of the `js-stellar-wallets` SDK to encrypt/decrypt the keypair, as well as sign transactions. -### Creating the `walletStore` store +### Creating the `walletStore` store {#creating-the-walletstore-store} Our `walletStore` will make a few things possible throughout our application. @@ -170,7 +170,7 @@ const setupKeyManager = () => { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/walletStore.js -### Creating the account on the Stellar network +### Creating the account on the Stellar network {#creating-the-account-on-the-stellar-network} After we've registered the user, we need to fund the account on the Stellar network. As discussed previously, there are multiple ways to accomplish this task, but we are using Friendbot to ensure the user has some Testnet XLM to experiment with. @@ -184,7 +184,7 @@ export async function fundWithFriendbot(publicKey) { Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -### Using the `walletStore` store +### Using the `walletStore` store {#using-the-walletstore-store} Our `walletStore` is used in a ton of places in our application, especially in the confirmation modal when asking a user to input their pincode. Read on to see how we've done that. diff --git a/docs/build/apps/example-application-tutorial/anchor-integration/sep10.mdx b/docs/build/apps/example-application-tutorial/anchor-integration/sep10.mdx index 114d853a0..9a584bb0f 100644 --- a/docs/build/apps/example-application-tutorial/anchor-integration/sep10.mdx +++ b/docs/build/apps/example-application-tutorial/anchor-integration/sep10.mdx @@ -9,7 +9,7 @@ Similar to the SEP-1 information, both SEP-6 and SEP-24 protocols make use of SE Since we have the `stellar.toml` file information already, we can use that to display some interactive elements to the user. -## Prompt for authentication +## Prompt for authentication {#prompt-for-authentication} :::note @@ -54,7 +54,7 @@ The `/src/routes/dashboard/transfers/+page.svelte` is doing **a lot** of work th **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## Requesting a challenge transaction +## Requesting a challenge transaction {#requesting-a-challenge-transaction} Now, when the user clicks the "authenticate" button, it triggers the `auth` function. @@ -192,7 +192,7 @@ function validateChallengeTransaction({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js -## Sign and submit the challenge transaction +## Sign and submit the challenge transaction {#sign-and-submit-the-challenge-transaction} In response, the user signs the transaction. You may have noticed we present this challenge transaction to the user with our regular confirmation modal. Once they've signed the transaction, the application sends it back to the anchor with a `POST` request. If the signature checks out, the success response will contain a [JSON Web Token (JWT)](https://jwt.io/), which BasicPay stores in the `webAuthStore` store to use for future interactions with the anchor. @@ -271,7 +271,7 @@ export async function submitChallengeTransaction({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js -## About the `webAuthStore` store +## About the `webAuthStore` store {#about-the-webauthstore-store} Like so much of our BasicPay application, the various authentication tokens the user may have accumulated over time are stored in the browser's `localStorage`. There's not much special about this particular store, but here's how we put it together: diff --git a/docs/build/apps/example-application-tutorial/anchor-integration/sep24.mdx b/docs/build/apps/example-application-tutorial/anchor-integration/sep24.mdx index d06cf5661..e1b7a5c44 100644 --- a/docs/build/apps/example-application-tutorial/anchor-integration/sep24.mdx +++ b/docs/build/apps/example-application-tutorial/anchor-integration/sep24.mdx @@ -13,7 +13,7 @@ Remember, SEP-24 depends on [SEP-10 authentication]. Everything below assumes th ::: -## Find the anchor's `TRANSFER_SERVER_SEP0024` +## Find the anchor's `TRANSFER_SERVER_SEP0024` {#find-the-anchors-transfer_server_sep0024} Before we can ask anything about _how_ to make a SEP-24 transfer, we have to figure out _where_ to discover that information. Fortunately, the SEP-1 protocol describes standardized fields to find out what we need. @@ -27,7 +27,7 @@ export async function getTransferServerSep24(domain) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js -## Get `/info` +## Get `/info` {#get-info} Our application will request the `/info` endpoint from the anchor's transfer server to understand the supported transfer methods (deposit, withdraw) and available endpoints, as well as additional features that may be available during transfers. @@ -53,7 +53,7 @@ export async function getSep24Info(domain) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep24.js -## The user clicks "deposit" or "withdraw" +## The user clicks "deposit" or "withdraw" {#the-user-clicks-deposit-or-withdraw} Now that we have all the SEP-24 information the anchor has made available to us, it's up to the user to actually begin the initiation process. In BasicPay, they do that by simply clicking a button that will then trigger the `launchTransferWindowSep24` function. @@ -95,7 +95,7 @@ This file was pretty heavily covered in the [SEP-6 section]. We'll be presenting **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## Retrieve the interactive URL +## Retrieve the interactive URL {#retrieve-the-interactive-url} BasicPay then initiates a transfer method by sending a `POST` request to either the “SEP-24 Deposit” or “SEP-24 Withdraw” endpoint. The anchor then sends an interactive URL that BasicPay will open as a popup for the user to complete and confirm the transfer. @@ -135,7 +135,7 @@ export async function initiateTransfer24({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep24.js -## Launch the popup window and listen for a callback +## Launch the popup window and listen for a callback {#launch-the-popup-window-and-listen-for-a-callback} BasicPay doesn't really need (or want) to know everything that's happening between the user and the anchor during a SEP-24 transfer. However, we _do_ want to know when the interaction is over, since we may need to take some action at that point. So, we add a callback to the interactive URL and open the popup window. @@ -175,7 +175,7 @@ Since BasicPay is an entirely client-side application, we can't provide a callba **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## Complete transfer +## Complete transfer {#complete-transfer} Once the user is finished with the interactive window from the anchor, they'll be brought back to BasicPay. We store the details of the transfer in the `transfersStore` store (remember, this is just so we can track which anchors to query for transfers later on). @@ -215,7 +215,7 @@ Once the user is finished with the interactive window from the anchor, they'll b **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## (Sometimes) Send a Stellar payment +## (Sometimes) Send a Stellar payment {#sometimes-send-a-stellar-payment} In a withdrawal transaction, BasicPay will also build and present to the user a Stellar transaction for them to sign with their pincode. diff --git a/docs/build/apps/example-application-tutorial/anchor-integration/sep6.mdx b/docs/build/apps/example-application-tutorial/anchor-integration/sep6.mdx index 7605c70f0..7b3eac8f0 100644 --- a/docs/build/apps/example-application-tutorial/anchor-integration/sep6.mdx +++ b/docs/build/apps/example-application-tutorial/anchor-integration/sep6.mdx @@ -7,7 +7,7 @@ import useBaseUrl from "@docusaurus/useBaseUrl"; SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. In this integration, a user’s KYC information is gathered and handled by the wallet and submitted to the anchor _on behalf of_ the user. -## Find the anchor's `TRANSFER_SERVER` +## Find the anchor's `TRANSFER_SERVER` {#find-the-anchors-transfer_server} Before we can ask anything about _how_ to make a SEP-6 transfer, we have to figure out _where_ to discover that information. Fortunately, the SEP-1 protocol describes standardized fields to find out what we need. @@ -21,7 +21,7 @@ export async function getTransferServerSep6(domain) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js -## Get `/info` +## Get `/info` {#get-info} Now that we know where the transfer server is located, BasicPay needs to fetch the `/info` endpoint from the anchor's transfer server to understand the supported transfer methods ([deposit, withdraw, deposit-exchange, and withdraw-exchange](https://stellar.org/protocol/sep-6#info)) and available endpoints, as well as additional features that may be available during transfers. @@ -45,7 +45,7 @@ export async function getSep6Info(domain) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep6.js -## Display interactive elements +## Display interactive elements {#display-interactive-elements} Since many of the SEP-6 (and SEP-24) endpoints require authentication, we wait until our user is [authenticated with SEP-10](./sep10.mdx) before we display what kinds of transfers are available. When they have a valid authentication token, we can display some buttons the user can use to begin a transfer. @@ -75,13 +75,13 @@ The user can then initiate one of the transfer methods (in BasicPay, only deposi **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## A special SEP-6 modal component +## A special SEP-6 modal component {#a-special-sep-6-modal-component} If you recall back to our [confirmation modal section](../confirmation-modal.mdx), we designed our modal component to be useful for anything we might require. Well, that's _almost_ true. The fact is that SEP-6 interactions are just plain complex. To facilitate that complexity, we've created a purpose-built SEP-6 transfer modal. There is **so much** to it, that we couldn't possibly cover everything it does here. However, we'll cover the main bits and link to the relevant source files. The modal component itself has been broken into several smaller Svelte components. Check out this source file to start looking through how we've put it together: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferModalSep6.svelte -### Launching the SEP-6 modal +### Launching the SEP-6 modal {#launching-the-sep-6-modal} The above buttons will use the `launchTransferModalSep6` function to display the modal to the user. Here's how it's defined in that same file. @@ -126,7 +126,7 @@ The above buttons will use the `launchTransferModalSep6` function to display the Once launched, the `TransferModalSep6` will walk the user through a "wizard" to gather all the required information and ultimately create the transfer. -### Modal step 1: Transfer details +### Modal step 1: Transfer details {#modal-step-1-transfer-details} BasicPay prompts the user to input additional information such as transfer type, destination, and amount. Some of this is prepopulated based on which button the user clicked. However, the user can change any of the fields if they so choose. @@ -134,7 +134,7 @@ We'll spare the code sample in this section, since it's mostly Svelte things goi -### Modal step 2: Gather KYC information +### Modal step 2: Gather KYC information {#modal-step-2-gather-kyc-information} To find out what infrastructure the anchor has made available for us to use, we need to query the anchor's SEP-1 `stellar.toml` file for the `KYC_SERVER` field. If this is not defined, BasicPay will fallback to using the `TRANSFER_SERVER` for these requests. @@ -178,7 +178,7 @@ export async function getSep12Fields({ authToken, homeDomain }) { Again, the presentation of the fields the user must complete is more on the Svelte side of things, so we won't share those details here. However, the source for this component is available here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCInformation.svelte -### Modal step 3: Put KYC fields and report status +### Modal step 3: Put KYC fields and report status {#modal-step-3-put-kyc-fields-and-report-status} Now that the user has provided the necessary information for the KYC requirements of the anchor, we can submit them to the anchor's KYC server with a `PUT` request. @@ -210,7 +210,7 @@ BasicPay receives back from the anchor a status message for the user to see. Onc This component of the SEP-6 modal, like most of them, is almost entirely Svelte-related. So as to keep this tutorial (somewhat) uncluttered, we'll refer you to the source for the component, which you can find here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCStatus.svelte -### Modal step 4: Submit transfer +### Modal step 4: Submit transfer {#modal-step-4-submit-transfer} BasicPay makes this request by taking all the fields that have been collected during this process and wrapping them into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J&asset_code=SRT&type=bank_account&amount=11) @@ -257,7 +257,7 @@ The only reason we're storing anything about the transfer in BasicPay is to help ::: -### (Sometimes) Modal step 5: Send a Stellar payment +### (Sometimes) Modal step 5: Send a Stellar payment {#sometimes-modal-step-5-send-a-stellar-payment} In a withdrawal transaction, BasicPay will also build and present to the user a Stellar transaction for them to sign with their pincode. Here we will finally get to move back to our "regular" modal that _is_ so good at so many things! diff --git a/docs/build/apps/example-application-tutorial/anchor-integration/setup.mdx b/docs/build/apps/example-application-tutorial/anchor-integration/setup.mdx index 0890e73a5..3f31d6e84 100644 --- a/docs/build/apps/example-application-tutorial/anchor-integration/setup.mdx +++ b/docs/build/apps/example-application-tutorial/anchor-integration/setup.mdx @@ -22,7 +22,7 @@ Our integrations will also use the following SEPs: - [SEP-10: Stellar Web Authentication](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) - defines the standard way for clients to create authenticated web sessions on behalf of a user who holds a Stellar account - [SEP-12: KYC API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md) - defines a standard way for Stellar clients to upload KYC information to anchors -## Finding anchored assets +## Finding anchored assets {#finding-anchored-assets} BasicPay takes care of all the anchor transfer details on the `/dashboard/transfers` page. See it in action here: https://basicpay.pages.dev/dashboard/transfers diff --git a/docs/build/apps/example-application-tutorial/confirmation-modal.mdx b/docs/build/apps/example-application-tutorial/confirmation-modal.mdx index 84c269eee..bb99ba49b 100644 --- a/docs/build/apps/example-application-tutorial/confirmation-modal.mdx +++ b/docs/build/apps/example-application-tutorial/confirmation-modal.mdx @@ -5,7 +5,7 @@ sidebar_position: 22 Since the user's keypair is encrypted with a pincode and stored in their browser, we will occasionally need to prompt them for that pincode to sign a transaction or otherwise prove that they should be permitted to perform some action or view some data. -## User Experience +## User Experience {#user-experience} The user should be informed about any actions that may take place, especially when funds are on the line. To ensure this, we will overtly request their confirmation via pincode before anything is done. The application has no way of knowing a user's pincode, so it can't decrypt their keypair without their confirmation. @@ -13,7 +13,7 @@ The modal window we've implemented facilitates this confirmation flow whenever w ![confirmation modal](/assets/confirm-pincode.png) -## Code implementation +## Code implementation {#code-implementation} Our modal function uses the `svelte-simple-modal` package to give us a versatile starting point. If you need to, install it now. @@ -21,7 +21,7 @@ Our modal function uses the `svelte-simple-modal` package to give us a versatile npm install --save-dev svelte-simple-modal ``` -### Wrapping the rest of our app in the modal +### Wrapping the rest of our app in the modal {#wrapping-the-rest-of-our-app-in-the-modal} On the Svelte side, this modal component will be a "wrapper" around the rest of our application, which allows us to trigger the modal from anywhere we need, and it should behave similarly no matter what. @@ -54,7 +54,7 @@ On the Svelte side, this modal component will be a "wrapper" around the rest of **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/+layout.svelte -### Creating a reusable modal Svelte component +### Creating a reusable modal Svelte component {#creating-a-reusable-modal-svelte-component} To avoid reinventing the wheel every time we need a modal, we will create a reusable component that can accomodate most of our needs. Then, when we need the confirmation modal, we can pass an object of props to customize the modal's behavior. @@ -104,7 +104,7 @@ The basic parts of this component look like this: **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/components/ConfirmationModal.svelte -### Trigger the modal component at signup +### Trigger the modal component at signup {#trigger-the-modal-component-at-signup} We can now use this modal component whenever we need to confirm something from the user. For example, here is how the modal is triggered when someone signs up. @@ -146,7 +146,7 @@ We can now use this modal component whenever we need to confirm something from t **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/signup/+page.svelte -### Customizing confirmation and rejection behavior +### Customizing confirmation and rejection behavior {#customizing-confirmation-and-rejection-behavior} Now, as these components have been written so far, they don't actually _do_ anything when the user inputs their pincode or clicks on a button. Let's change that! diff --git a/docs/build/apps/example-application-tutorial/contacts-list.mdx b/docs/build/apps/example-application-tutorial/contacts-list.mdx index 3916150d6..151019ace 100644 --- a/docs/build/apps/example-application-tutorial/contacts-list.mdx +++ b/docs/build/apps/example-application-tutorial/contacts-list.mdx @@ -5,7 +5,7 @@ sidebar_position: 25 One central feature of BasicPay is a list of contacts containing a user's name and associated Stellar addresses. -## User experience +## User experience {#user-experience} There are a few ways for a user to interact with the contact list. One way is that they can add a user and address on the `/dashboard/contacts` page (which also checks for a valid public key!). @@ -13,11 +13,11 @@ There are a few ways for a user to interact with the contact list. One way is th See it in action here: https://basicpay.pages.dev/dashboard/contacts -## Code implementation +## Code implementation {#code-implementation} We will create a Svelte `store` to keep track of a user's contact list. -### Creating the `contacts` store +### Creating the `contacts` store {#creating-the-contacts-store} As with the rest of our user-data, the contacts list will live in the browser's `localStorage`. We are using the [`svelt-local-storage-store` package] to facilitate this. We create a Svelte `store` to hold the data, and add a few custom functions to manage the list: `empty`, `remove`, `add`, `favorite`, and `lookup`. @@ -90,9 +90,9 @@ export const contacts = createContactsStore(); **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/contactsStore.js -### Using the `contacts` store +### Using the `contacts` store {#using-the-contacts-store} -#### On the `/dashboard/contacts` page +#### On the `/dashboard/contacts` page {#on-the-dashboardcontacts-page} We also have a page dedicated to managing contacts. The `/dashboard/contacts` page will allow the user to collect and manage a list of contact entries that stores the contact's name and Stellar address. The contact can also be flagged or unflagged as a "favorite" contact to be displayed on the main `/dashboard` page. @@ -123,7 +123,7 @@ We also have a page dedicated to managing contacts. The `/dashboard/contacts` pa **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/contacts/+page.svelte -#### On the `/dashboard` page +#### On the `/dashboard` page {#on-the-dashboard-page} The `contacts` store is now exported from this file and can be accessed and used inside a Svelte page or component. Here is how we've implemented a "favorite contacts" component for display on the main BasicPay dashboard. diff --git a/docs/build/apps/example-application-tutorial/manage-trust.mdx b/docs/build/apps/example-application-tutorial/manage-trust.mdx index e840fe7e3..a002c945c 100644 --- a/docs/build/apps/example-application-tutorial/manage-trust.mdx +++ b/docs/build/apps/example-application-tutorial/manage-trust.mdx @@ -5,7 +5,7 @@ sidebar_position: 30 For an account to hold and trade assets other than XLM, it must establish a [trustline](../../../learn/fundamentals/stellar-data-structures/accounts.mdx#trustlines) with the issuing account of that particular asset. Each trustline increases the account’s [base reserve](../../../learn/fundamentals/stellar-data-structures/accounts.mdx#base-reserves-and-subentries) by 0.5 XLM, which means the account will have to hold more XLM in its minimum balance. -## User experience +## User experience {#user-experience} First, we’ll have the user create a trustline for an asset by navigating to the Assets page, selecting an asset, and clicking the “Add Asset” button. @@ -33,11 +33,11 @@ Trustlines hold the balances for all of their associated assets (except XLM, whi See it in action here: https://basicpay.pages.dev/dashboard/assets -## Code implementation +## Code implementation {#code-implementation} The trustlines an account holds will be necessary to view in several parts of the BasicPay application. First, we'll discuss how we manage different trustlines for the account. -### The `/dashboard/assets` page +### The `/dashboard/assets` page {#the-dashboardassets-page} The `/dashboard/assets` page allows the user to manage the Stellar assets their account carries trustlines to. On this page, they can select from several pre-suggested or highly ranked assets, or they could specify their own asset to trust using an asset code and issuer public key. They can also remove trustlines that already exist on their account. @@ -136,7 +136,7 @@ The layout of the page is quite similar to our contacts page. It has a table dis **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/assets/+page.svelte -### The `createChangeTrustTransaction` function +### The `createChangeTrustTransaction` function {#the-createchangetrusttransaction-function} In the above page, we've made use of the `createChangeTrustTransaction` function. This function can be used to add, delete, or modify trustlines on a Stellar account. diff --git a/docs/build/apps/example-application-tutorial/overview.mdx b/docs/build/apps/example-application-tutorial/overview.mdx index a5c674e35..348b2b01d 100644 --- a/docs/build/apps/example-application-tutorial/overview.mdx +++ b/docs/build/apps/example-application-tutorial/overview.mdx @@ -19,9 +19,9 @@ Although BasicPay is a full-fledged application on Stellar's Testnet, it has bee ::: -## Project setup +## Project setup {#project-setup} -### Project requirements +### Project requirements {#project-requirements} To build a basic Stellar application, you'll need: @@ -52,14 +52,14 @@ This tutorial is probably best viewed as "_nearly_ comprehensive." We aren't goi ::: -### Dev helpers +### Dev helpers {#dev-helpers} - [Stellar Lab]: an experimental playground to interact with the Stellar network - Friendbot: a bot that funds accounts with 10,000 fake XLM on Stellar's Testnet; you can fund your account by going to `https://friendbot.stellar.org/?addr=G...` - [Testnet toml file]: an example `stellar.toml` file that demonstrates what information an anchor might publish - [BasicPay dev helpers]: if you're _using_ the BasicPay application, we've created a few helpful tools to help you explore its functionality -## Getting started +## Getting started {#getting-started} Here are the steps we've taken to start building BasicPay. Feel free to be inspired and customize these directions as you see fit. The entire [BasicPay codebase] is freely open and available on GitHub for reference. @@ -69,7 +69,7 @@ This part of the tutorial will need a large helping of "your mileage may vary." ::: -### Install frameworks +### Install frameworks {#install-frameworks} The first thing we'll need to do is create a SvelteKit app, using `npm`, we are using v18.x of nodejs. @@ -188,7 +188,7 @@ Your SvelteKit project is now configured and ready to run! npm run dev ``` -### Stellar dependencies +### Stellar dependencies {#stellar-dependencies} To work with the Stellar network, datastructures, and locally stored keypairs, we're going to install and configure a few more dependencies. diff --git a/docs/build/apps/example-application-tutorial/path-payment.mdx b/docs/build/apps/example-application-tutorial/path-payment.mdx index 617f5b219..e1f165687 100644 --- a/docs/build/apps/example-application-tutorial/path-payment.mdx +++ b/docs/build/apps/example-application-tutorial/path-payment.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 A path payment is where the asset sent can be different from the asset received. There are two possible path payment operations: 1) `path_payment_strict_send`, which allows the user to specify the amount of the asset to send, and 2) `path_payment_strict_receive`, which allows the user to specify the amount of the asset received. Read more in the [Path Payments Encyclopedia Entry](../../../learn/encyclopedia/transactions-specialized/path-payments.mdx). -## User experience +## User experience {#user-experience} With BasicPay, the user sends a path payment by navigating to the Payments page, where they can either select a user from their contacts or input the public key of a destination address. They then select the Send and Receive Different Assets toggle and determine whether they want to specify the asset sent or received. Finally they select the asset sent and the asset received and the amounts and select the Preview Transaction button. @@ -13,9 +13,9 @@ With BasicPay, the user sends a path payment by navigating to the Payments page, The user will then preview the transaction, input their pincode, and select the Confirm button to sign and submit the transaction to the network. -## Code implementation +## Code implementation {#code-implementation} -### The `/dashboard/send` page +### The `/dashboard/send` page {#the-dashboardsend-page} Most of this page has been discussed in the [Payment section](./payment.mdx#the-dashboardsend-page). Below, we're highlighting the unique pieces that are added to BasicPay to allow for the path payment feature. @@ -156,7 +156,7 @@ Most of this page has been discussed in the [Payment section](./payment.mdx#the- **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/send/+page.svelte -### The transaction functions +### The transaction functions {#the-transaction-functions} In the above section, we used the `createPathPaymentStrictReceiveTransaction` and `createPathPaymentStrictSendTransaction` functions. These are used to create transactions that contain the actual path payment operation. diff --git a/docs/build/apps/example-application-tutorial/payment.mdx b/docs/build/apps/example-application-tutorial/payment.mdx index 765d4f450..4370e34aa 100644 --- a/docs/build/apps/example-application-tutorial/payment.mdx +++ b/docs/build/apps/example-application-tutorial/payment.mdx @@ -5,7 +5,7 @@ sidebar_position: 40 A payment operation sends an amount in a specific asset (XLM or non-XLM) to a destination account. With a basic payment operation, the asset sent is the same as the asset received. BasicPay also allows for path payments (where the asset sent is different than the asset received), which we’ll talk about in the next section. -## User experience +## User experience {#user-experience} In our BasicPay application, the user will navigate to the Payments page where can either select a user from their contacts or input the public key of a destination address with a specified asset they’d like to send along with the amount of the asset. @@ -21,9 +21,9 @@ In BasicPay, we’ve set it up so that the user always pays a static fee of 100, The user then inputs their pincode and clicks the "Confirm" button, which signs and submits the transaction to the ledger. -## Code implementation +## Code implementation {#code-implementation} -### The `/dashboard/send` page +### The `/dashboard/send` page {#the-dashboardsend-page} The `/dashboard/send` page allows the user to send payments to other Stellar addresses. They can select from a dropdown containing their contact list names, or they can enter their own "Other..." public key. @@ -163,7 +163,7 @@ For now, we'll focus on regular payments, and we'll dig into the path payments i **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/send/+page.svelte -### The transaction functions +### The transaction functions {#the-transaction-functions} In the above section, we used the `createPaymentTransaction` function. This function can be used to send a payment of any asset from one Stellar address to another. diff --git a/docs/build/apps/example-application-tutorial/querying-data.mdx b/docs/build/apps/example-application-tutorial/querying-data.mdx index 69c939239..5da977a7a 100644 --- a/docs/build/apps/example-application-tutorial/querying-data.mdx +++ b/docs/build/apps/example-application-tutorial/querying-data.mdx @@ -13,7 +13,7 @@ In other places in this tutorial, we have omitted the JSDoc descriptions and typ ::: -## Imports and types +## Imports and types {#imports-and-types} ```js title="/src/lib/stellar/horizonQueries.js" import { error } from "@sveltejs/kit"; @@ -49,7 +49,7 @@ const server = new Server(horizonUrl); **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## fetchAccount +## fetchAccount {#fetchaccount} Gives an account's sequence number, asset balances, and trustlines. @@ -87,7 +87,7 @@ export async function fetchAccount(publicKey) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## fetchAccountBalances +## fetchAccountBalances {#fetchaccountbalances} Gets existing balances for a given `publicKey`. @@ -107,7 +107,7 @@ export async function fetchAccountBalances(publicKey) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## fetchRecentPayments +## fetchRecentPayments {#fetchrecentpayments} Finds any payments made to or from the given `publicKey` (includes: payments, path payments, and account merges). @@ -133,7 +133,7 @@ export async function fetchRecentPayments(publicKey, limit = 10) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## submit +## submit {#submit} Submit a signed transaction to the Stellar network. @@ -159,7 +159,7 @@ export async function submit(transaction) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## fetchAssetsWithHomeDomains +## fetchAssetsWithHomeDomains {#fetchassetswithhomedomains} We create a brand new `HomeDomainBalanceLine` type that includes the balance information of a user's trustline, and also adds the `home_domain` of the asset issuer. If you're using something else for type safety (or nothing at all), feel free to adapt or ignore the `@typedef`s we've included here. @@ -205,7 +205,7 @@ export async function fetchAssetsWithHomeDomains(balances) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## findStrictSendPaths +## findStrictSendPaths {#findstrictsendpaths} Find the available strict send paths between a source asset/amount and receiving account. @@ -243,7 +243,7 @@ export async function findStrictSendPaths({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## findStrictReceivePaths +## findStrictReceivePaths {#findstrictreceivepaths} Find the available strict receive paths between a source account and receiving asset/amount. @@ -284,7 +284,7 @@ export async function findStrictReceivePaths({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## Query Stellar Expert +## Query Stellar Expert {#query-stellar-expert} Stellar Expert is a third-party block explorer that is indispensable as a tool for understanding what is happening on the Stellar network. On our `/dashboard/assets` page, we're pre-populating a list of asset trustlines a user might choose to add to their Stellar account. We get this list of assets from the Stellar Expert API. diff --git a/docs/build/apps/ingest-sdk/ingestion-pipeline-code.mdx b/docs/build/apps/ingest-sdk/ingestion-pipeline-code.mdx index baba56d1f..0d082a940 100644 --- a/docs/build/apps/ingest-sdk/ingestion-pipeline-code.mdx +++ b/docs/build/apps/ingest-sdk/ingestion-pipeline-code.mdx @@ -12,7 +12,7 @@ Steps: #2 - compile and run with `go mod tidy;go build -o pipeline ./.; ./pipeline` #3 - in separate terminal, run `python distributed_payment_subsciber.py`, this will perform distributed pipeline topology, as it receives messages with payment info from the pipeline process and does additional processing(printing it to console). -### `go.mod` +### `go.mod` {#gomod} @@ -31,7 +31,7 @@ require ( -### `main.go` +### `main.go` {#maingo} @@ -244,7 +244,7 @@ func main() { -### `config.toml` +### `config.toml` {#configtoml} The CDP configuration settings, this file defines the data storage which contains the pre-generated Ledger Metadata files. Google Cloud storage is used in this example. @@ -264,7 +264,7 @@ files_per_partition = 64000 -### `distributed_payment_subsciber.py` +### `distributed_payment_subsciber.py` {#distributed_payment_subsciberpy} A Python script demonstrating how we now have distributed processing and event driven architecture by leveraging the MQ Broker to push derived application payment data model out to other microservices. Make sure to `pip install pyzmq` diff --git a/docs/build/apps/ingest-sdk/overview.mdx b/docs/build/apps/ingest-sdk/overview.mdx index 714d8f241..f6c369f80 100644 --- a/docs/build/apps/ingest-sdk/overview.mdx +++ b/docs/build/apps/ingest-sdk/overview.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 This tutorial walks through how an application can leverage [CDP architecture](https://stellar.org/blog/developers/composable-data-platform) to create fast, lightweight Stellar Ledger Metada data pipelines using a few select packages from the Stellar Go Repo [github.com/stellar/go](https://github.com/stellar/go/blob/master/) collectively known as the 'Ingestion' SDK: -## The Ingestion SDK packages +## The Ingestion SDK packages {#the-ingestion-sdk-packages} - `github.com/stellar/go/amount` utility package to convert prices from network transaction operations to string - `github.com/stellar/go/historyarchive` `github.com/stellar/go/support/datastore` `github.com/stellar/go/support/storage` utility package with convenient wrappers for accessing history archives, and avoid low-level http aspects @@ -14,9 +14,9 @@ This tutorial walks through how an application can leverage [CDP architecture](h - `github.com/stellar/go/network` provides convenient pre-configured settings for Testnet and Mainnet networks - `github.com/stellar/go/xdr` a complete Golang binding to the Stellar network data model -## Ingestion project setup +## Ingestion project setup {#ingestion-project-setup} -### Project requirements +### Project requirements {#project-requirements} To use this example CDP pipeline for live Stellar network transaction data, you'll need: @@ -49,17 +49,17 @@ The example application will perform both of CDP pipelines. A minimum of two pip ![](/assets/cdp_pipelines.png) -### Ledger Metadata Export Pipeline +### Ledger Metadata Export Pipeline {#ledger-metadata-export-pipeline} This pipeline needs to be initiated first, it is responsible for exporting Stellar Ledger Metadata as files to a [CDP Datastore](https://github.com/stellar/go/blob/master/support/datastore/datastore.go#L17). -#### Determine the Datastore +#### Determine the Datastore {#determine-the-datastore} The Datastore in CDP is an interface, allowing for multiple implementations which represent different physical storage layers that can be 'plugged in' to export and consumer pipelines. Stellar provides the [GCS Datastore] as the first Datastore implementation, and this example chooses to use this existing implementation. There will be open source contributions for implementations on other storage layers to choose from as CDP grows. If you can't find an implementation for a storage layer you would like to use, it is also possible to develop your own [ Datastore](https://github.com/stellar/go/blob/master/support/datastore/datastore.go#L17) implementation, which is beyond scope of this example, as it entails a separate learning exercise of its own, coming soon! -#### Exporting network metadata to Datastore +#### Exporting network metadata to Datastore {#exporting-network-metadata-to-datastore} Use Galexie, a new CDP command line program for exporting network metadata to datastores. @@ -69,24 +69,24 @@ Use Galexie, a new CDP command line program for exporting network metadata to da - For one time export of historical bounded range of ledgers, use `append --start --end ` - For a continuous export of prior ledgers and all new ledgers generated on network, use `append --start `. -### Ledger Metadata Consumer Pipeline +### Ledger Metadata Consumer Pipeline {#ledger-metadata-consumer-pipeline} A consumer pipeline retrieves files from the GCS bucket and uses them as the origin of Ledger Metadata in a data processing pipeline. There can be many separate consumer pipelines all accessing the same Datastore at stame time. Each consumer pipeline will typically perform three distinct stream processor roles: -#### Inbound Adapter +#### Inbound Adapter {#inbound-adapter} The 'source of origin' for the ledger metadata in a pipeline. This processor retrieves [Ledger Metadata](https://github.com/stellar/go/blob/f30d11432e81c7a7cbb739a694520f729bbb31dd/xdr/xdr_generated.go#L18358) files from the GCS Datastore, extracts the `LedgerCloseMeta` for each Ledger and publishes it onto the messaging pipeline. The go sdk provides consumer helper function [ApplyLedgerMetadata](https://github.com/stellar/go/blob/master/ingest/cdp/producer.go#L89) for automated, performant, buffered retrieval of files from the remote datastore, application code can leverage this to acquire pure `LedgerCloseMeta` data from a callback function. -#### Transformer +#### Transformer {#transformer} Subscribes on the pipeline to receive `LedgerCloseMeta`. Uses the Go SDK package [github.com/stellar/go/xdr](https://github.com/stellar/go/tree/master/xdr) to parse the ledger meta data model for payment operations and convert those into a new instance of application data model `AppPayment` instances. Publishes `AppPayment` to the pipeline. -#### Outbound Adapter +#### Outbound Adapter {#outbound-adapter} Acts as the termination of the pipeline, it subscribes to receive `ApplicationPayment` and publishes the data off the pipeline and to an external data store, a ZeroMQ Publisher Socket, which is essentially a message broker. -### Summary +### Summary {#summary} Refer to [Ingestion Pipeline Sample Application](./ingestion-pipeline-code.mdx) for complete consumer code example, demonstrating a live, streaming pipeline against the Stellar network, processing each new ledger's metadata as it is closed on the network. diff --git a/docs/build/apps/moneygram-access-integration-guide.mdx b/docs/build/apps/moneygram-access-integration-guide.mdx index bb84dbdfa..9a6dd4d7b 100644 --- a/docs/build/apps/moneygram-access-integration-guide.mdx +++ b/docs/build/apps/moneygram-access-integration-guide.mdx @@ -9,7 +9,7 @@ This document guides the reader through the technical requirements for integrati MoneyGram requires businesses to go through an onboarding process in order to get access to their testing and production environments. To get started with this process, reach out to partnerships@stellar.org. -## Resources +## Resources {#resources} - [MoneyGram Access Wallet MVP Implementation] - Use this MVP implementation as a reference for building your own integration. Many of the code snippets shared in this document are pulled from this project. @@ -24,18 +24,18 @@ MoneyGram requires businesses to go through an onboarding process in order to ge - [Stellar Ecosystem Proposal 10 (SEP-10)][sep-10] - The standardized API protocol for Stellar authentication, implemented by MoneyGram -## Asset Information +## Asset Information {#asset-information} Before you get access to MoneyGram's test environment, you should test your implementation with the SDF's [Stellar Test Anchor]. It implements the same APIs as MoneyGram's service but uses a different asset. The information for each asset is below. -### Stellar Reference Token +### Stellar Reference Token {#stellar-reference-token} This token is only on testnet. - **Issuing Account**: [GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B] - **Asset Code**: SRT -### USD Coin +### USD Coin {#usd-coin} Testnet: @@ -47,7 +47,7 @@ Pubnet: - **Issuing Account**: [GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN] - **Asset Code**: USDC -## Introduction +## Introduction {#introduction} Applications seeking to integrate MoneyGram Access must implement the client side of [Stellar Ecosystem Proposal 24 (SEP-24)][sep-24], a standardized protocol defined for applications to connect to businesses such as MoneyGram, more generally called anchors, that offer Stellar deposit & withdrawal services utilizing local payment rails. @@ -55,7 +55,7 @@ This document will walk you through the necessary steps to develop a functional The guide will assume your application is first being developed on Stellar’s test network and using MoneyGram’s testing deployment of Access, but there are no functional differences deploying the application to Stellar’s public network and using MoneyGram’s production deployment. -### Installing the Wallet SDK +### Installing the Wallet SDK {#installing-the-wallet-sdk} We highly recommend using the wallet SDK to facilitate building your integration. Find more info on the [Stellar Wallet SDK Docs]. @@ -69,7 +69,7 @@ yarn add @stellar/typescript-wallet-sdk -## Custodial vs. Non-Custodial Applications +## Custodial vs. Non-Custodial Applications {#custodial-vs-non-custodial-applications} Some applications, such as centralized exchanges, are custodial, meaning the application has access to the private keys of the acccounts holding its users’ funds on Stellar. Typically, custodial applications pool user funds into a smaller set of managed Stellar accounts, called pooled, shared, or omnibus accounts. @@ -77,7 +77,7 @@ Other applications are non-custodial, meaning the application does not have acce These two approaches require minor but concrete differences in how applications integrate with MoneyGram Access. The sub-sections below will describe these differences, but the rest of this tutorial will assume the application is custodial. -### Authentication +### Authentication {#authentication} MoneyGram needs to authenticate both the user and the application being used via Stellar's [SEP-10] protocol. @@ -85,15 +85,15 @@ Custodial applications are identified by the Stellar account public key they reg Because each user of a non-custodial application has their own Stellar account, non-custodial applications are identified by the home domain they register with MoneyGram during the onboarding process. When authenticating, the application must pass _the user's_ public key as the `account` query parameter, and pass their home domain as the `client_domain` query parameter. MoneyGram will look up the `SIGNING_KEY` value at `https:///.well-known/stellar.toml`, and return a Stellar transaction that requires signatures from both the user's private key & the private key of the public `SIGNING_KEY` on the application's [SEP-1] stellar.toml file. An example file can be found at https://vibrantapp.com/.well-known/stellar.toml. -### Transaction Initiation +### Transaction Initiation {#transaction-initiation} Because users of custodial applications don't have individual Stellar accounts, only the application knows how much money a user has to withdraw. Because of this, MoneyGram requires custodial applications to always pass the `amount` field in the request to start a new transaction. Non-custodial applications do not need to do this, although they can if they prefer. -### Source & Destination of Funds +### Source & Destination of Funds {#source--destination-of-funds} MoneyGram requires custodial applications to provide the Stellar accounts that may be used as the source or destination of funds during the onboarding process. For non-custodial applications, MoneyGram requires the source and destination of funds for each transaction to be the same account that was authenticated via [SEP-10]. -## Application Flow & Architecture +## Application Flow & Architecture {#application-flow--architecture} This guide will assume the application has a basic client-server architecture. The application’s client will request resources and initiate actions with the application’s server, which will communicate directly with MoneyGram’s server. @@ -107,7 +107,7 @@ After Step 4, the application should open the URL provided by MoneyGram in a mob The provided reference number would then be taken to any MoneyGram cash agent in order to receive cash in the user’s fiat currency. These steps document the cash-out, or withdrawal flow. The deposit flow is similar and detailed in the steps below. -## Generate Stellar Keypairs +## Generate Stellar Keypairs {#generate-stellar-keypairs} In this section, you will generate at least two Stellar keypairs, one that will be used to prove your application’s identity when authenticating with MoneyGram Access, and another that will hold, send & receive USDC on Stellar. You should always use one keypair for authentication, but application could use many keypairs for sending & receiving payments. In this guide, we'll assume the application uses one keypair for each purpose. @@ -119,7 +119,7 @@ The first keypair will be called the “authentication” keypair (or public / s Provide the public keys (starting with a G) of both the authentication and funds keypairs to MoneyGram. They will add these keys to their known lists of keys, granting them access to their deployment. -## Get XLM & USDC +## Get XLM & USDC {#get-xlm--usdc} Many cryptocurrency exchanges support purchasing XLM or USDC on Stellar. The SDF also maintains an [Anchor Directory] that attempts to list all the on & off-ramps for the Stellar Network. @@ -129,7 +129,7 @@ Some exchanges support XLM but do not support USDC on Stellar. This is not a pro To do this, send your XLM to the funds public key from the exchange, add a USDC trustline, and sell XLM for USDC using a [sell offer]. -## Authenticate +## Authenticate {#authenticate} This section encompasses steps 1 & 2 of the diagram displayed in the Architecture section above. The application’s client should request a MoneyGram transaction URL from the application’s server on user initiation. This should trigger an authentication process between the application’s server and MoneyGram’s server. This process is standardized in [SEP-10][sep-10]. @@ -210,7 +210,7 @@ def get_token() -> str: -## Initiate a Transaction +## Initiate a Transaction {#initiate-a-transaction} This section encompasses steps 3 & 4 of the architecture diagram displayed above. The application’s server will make a deposit or withdrawal initiation request to MoneyGram’s server, and MoneyGram will return a transaction ID, which will be used later to poll the transaction’s status, and a transaction URL, which should be returned to the application’s client and opened for the user. @@ -281,7 +281,7 @@ def initiate_withdraw(token: str, amount: str) -> Tuple[str, str]: The logic for initiating a deposit transaction looks very similar. See the [SEP-24][sep-24] standard specification for detailed information. -## Listen for the Close Notification +## Listen for the Close Notification {#listen-for-the-close-notification} The next step is to open the provided URL in the application’s client using a mobile webview, browser tab, or popup. The user will then go through KYC if they have not before in a prior transaction. In the deposit case, the user may also select a MoneyGram agent location to go to when providing cash. @@ -312,13 +312,13 @@ function closeWebView(e) { -## Send or Receive Funds +## Send or Receive Funds {#send-or-receive-funds} In withdrawal (or cash-out) transactions, applications must send USDC to the Stellar account MoneyGram specifies. In deposit (cash-in) transactions, applications must monitor their Stellar account for a payment from MoneyGram. In each case, the transaction submitted to Stellar must have a memo attached to it. This memo is provided by MoneyGram in the withdrawal case, and provided by the application in the deposit case. The memo is an identifier that allows the parties to tie the on-chain payment to the transaction record in the application’s or MoneyGram’s database. -### Poll Until MoneyGram is Ready +### Poll Until MoneyGram is Ready {#poll-until-moneygram-is-ready} Before the application can send funds or instruct the user to provide cash to a MoneyGram agent, the application should confirm with MoneyGram’s server that the transaction is ready to proceed which is signaled by the `pending_user_transfer_start` status. @@ -457,7 +457,7 @@ def poll_transaction_until_status( -### Sending Funds +### Sending Funds {#sending-funds} Once MoneyGram is ready to receive funds, your application should extract the Stellar account, memo and amount to use in the payment transaction, construct a Stellar transaction, and submit it to the Stellar network. You’ll need: @@ -639,7 +639,7 @@ def submit_payment(destination: str, memo: str, amount: str): -### Receiving Funds +### Receiving Funds {#receiving-funds} Once MoneyGram is ready for the user to drop off cash at an MGI agent (in deposit or cash-in cases), the application’s server should begin monitoring its Stellar account for an inbound USDC payment sent by MoneyGram. @@ -729,7 +729,7 @@ def stream_payments(account: str, cursor: str): -## Fetch the Reference Number +## Fetch the Reference Number {#fetch-the-reference-number} For deposit or cash-in transactions, MoneyGram does not provide reference numbers. All the user needs to do is drop off cash at the agent location chosen in the MoneyGram UI earlier in the flow, and the application should complete the transaction when a matching payment is detected on Stellar. diff --git a/docs/build/apps/overview.mdx b/docs/build/apps/overview.mdx index 2d2ca104f..869da82eb 100644 --- a/docs/build/apps/overview.mdx +++ b/docs/build/apps/overview.mdx @@ -9,7 +9,7 @@ Stellar has built-in logic for key storage, creating accounts, signing transacti This documentation includes sections on how to build applications without smart contracts with the [Wallet SDK](./wallet/overview.mdx) or the [JS SDK](./example-application-tutorial/overview.mdx), building with smart contracts with the [dapp frontend tutorial](./dapp-frontend.mdx), and all information regarding experimentation with [smart wallets](./smart-wallets.mdx). -## Anchors +## Anchors {#anchors} Many Stellar assets connect to real-world currencies, and Stellar has open protocols for integrating deposits and withdrawals of these assets via the [anchor network](https://stellar.org/learn/anchor-basics). Because of this, a Stellar-based application can take advantage of real banking rails and connect to real money. @@ -19,7 +19,7 @@ Set up an anchor using the [Anchor Platform](/platforms/anchor-platform). Integrate MoneyGram Access into an existing application with the [Integrate with MoneyGram Access tutorial](./moneygram-access-integration-guide.mdx). -## Stellar Ecosystem Proposals (SEPs) +## Stellar Ecosystem Proposals (SEPs) {#stellar-ecosystem-proposals-seps} Stellar-based products and services interoperate by implementing various Stellar Ecosystem Proposals (SEPs), which are publicly created, open-source documents that live in a [GitHub repository](https://github.com/stellar/stellar-protocol/tree/master/ecosystem#stellar-ecosystem-proposals-seps) and define how asset issuers, anchors, wallets, and other service providers interact with each other. diff --git a/docs/build/apps/smart-wallets.mdx b/docs/build/apps/smart-wallets.mdx index 690c367d1..d8cb77633 100644 --- a/docs/build/apps/smart-wallets.mdx +++ b/docs/build/apps/smart-wallets.mdx @@ -27,7 +27,7 @@ See the work being done on creating a standard for a smart wallet interface in t Join the SEP discussion on the WebAuthn contract interface in [GitHub](https://github.com/stellar/stellar-protocol/discussions/1499). -## Experiment with passkeys on Stellar +## Experiment with passkeys on Stellar {#experiment-with-passkeys-on-stellar} Check out some of the current work being done with passkeys on Stellar! This page will be updated frequently as more projects and standards are created. @@ -39,7 +39,7 @@ These examples are not created or maintained officially by the SDF but by dedica Play around with the various examples linked below, build your own passkey-powered projects, and share your findings in the `#passkeys` channel on [Discord](https://discord.gg/stellardev). -### Soroban by example 🐔 +### Soroban by example 🐔 {#soroban-by-example-} An app that uses passkeys to sign Stellar smart contract transactions. @@ -49,7 +49,7 @@ An app that uses passkeys to sign Stellar smart contract transactions. - Watch the [discussion](https://developers.stellar.org/meetings/2024/05/09) - Read the [blog](https://kalepail.com/blockchain/the-passkey-powered-future-of-web3) -### Super Peach 🍑 +### Super Peach 🍑 {#super-peach-} A passkey-powered multi-signer abstract account contract example. @@ -57,7 +57,7 @@ A passkey-powered multi-signer abstract account contract example. - View the [code](https://github.com/kalepail/superpeach) - Watch the [demo](https://youtu.be/0Agiwso2OMc?si=CHD9U8s-YLyqbXUJ) -### Passkey Kit 📦 +### Passkey Kit 📦 {#passkey-kit-} A client-side SDK tool for managing and using passkeys. @@ -65,16 +65,16 @@ A client-side SDK tool for managing and using passkeys. - View the [code](https://github.com/kalepail/passkey-kit) - Watch the [discussion](https://developers.stellar.org/meetings/2024/06/13) -### Launchtube transaction submission 🧪 +### Launchtube transaction submission 🧪 {#launchtube-transaction-submission-} An API service where developers can send their smart contract transactions to get them funded and submitted to the Stellar Testnet. No classic Stellar G addresses needed! - View the [code](https://github.com/kalepail/launchtube) - Ask in the `#passkeys` channel on [Discord](https://discord.gg/stellardev) for an access token -## What does it all mean? +## What does it all mean? {#what-does-it-all-mean} -### Secp256r1 +### Secp256r1 {#secp256r1} The [secp256r1 signature scheme](https://wiki.hyperledger.org/display/BESU/SECP256R1+Support) is an elliptic curve that is often used with the Elliptic Curve Digital Signature Algorithm (ECDSA), which is a widely used public key signature scheme. @@ -82,19 +82,19 @@ Secp256r1 is a common signature algorithm used in WebAuthn, which is the standar The Stellar blockchain natively uses the Ed25519 elliptic curve, which is extremely fast and secure but is not as widely supported in WebAuthn implementations as secp256r1. -### WebAuthn +### WebAuthn {#webauthn} [WebAuthn (web authentication)](https://www.okta.com/blog/2019/03/what-is-webauthn/) is a web standard for secure, passwordless authentication. It uses public-key cryptography to eliminate the reliance on secret keys and enhances security and usability for dapps. WebAuthn provides decentralized authentication (no central authority manages passwords), enhanced security (secret keys remain on the user’s device), improved user experience (users don’t have to worry about remembering their secret keys), and broader interoperability (WebAuthn is already supported by major browsers and platforms). -### Passkeys +### Passkeys {#passkeys} Passkeys are an implementation of the WebAuthn standard. The ability to use passkeys to sign transactions and access accounts removes the need for users to remember their secret keys or 12- to 24-word seed phrases, something that has been a massive barrier to entry for end-users entering the blockchain space. Secret keys and seed phrases can be overwhelming, hard to remember, entered incorrectly, and prone to security breaches. Passkeys offer a faster, more secure method of identity authentication by using encrypted data stored on a device and performing user verification with hardware tokens (like YubiKeys), biometric data (like fingerprints or facial recognition), or other cryptographic methods. -### Smart wallets +### Smart wallets {#smart-wallets} Smart wallets are digital wallets that leverage smart contract composability to offer enhanced functionality and security for managing digital assets. Unlike traditional cryptocurrency wallets, smart wallets integrate features such as multi-signature support, programmable transactions, and enhanced user experience compatibilities with decentralized applications (dApps). @@ -102,7 +102,7 @@ Smart wallets enable users to interact seamlessly with blockchain ecosystems, pr By utilizing smart contracts, smart wallets can automate transactions and implement advanced security protocols, such as time-locked transfers, spending limits, and fraud detection. These features make smart wallets an ideal choice for users seeking a secure, convenient, and versatile solution for managing their digital assets in the evolving landscape of blockchain technology. -### How they work together +### How they work together {#how-they-work-together} Secp256r1 provides the cryptographic foundation for key generation and digital signatures, WebAuthn offers a standardized framework for passwordless authentication using public-key cryptography, and passkeys implement these technologies to provide a seamless and secure user experience. Bundle all of that together into a Stellar smart contract and you have the foundation for the planet's best smart wallet impelementation! diff --git a/docs/build/apps/wallet/README.md b/docs/build/apps/wallet/README.md index 59ecdf3fc..b1add8054 100644 --- a/docs/build/apps/wallet/README.md +++ b/docs/build/apps/wallet/README.md @@ -1,4 +1,4 @@ -## Contributing guide +## Contributing guide {#contributing-guide} Thank you for contributing to the Stellar Wallet documentation! To get started, please first read [main README](../../../README.md) guide. @@ -13,9 +13,9 @@ Generally, text should be applicable to all of supported programming languages, but for differences special `` component can be used (read more below) -### Wallet guide components +### Wallet guide components {#wallet-guide-components} -#### Header +#### Header {#header} Header is a special .mdx file that should be included on all pages. It contains: @@ -30,17 +30,17 @@ of languages that are work in progress:
``` -#### LanguageButtons +#### LanguageButtons {#languagebuttons} This component is a part of the header. It allows to switch between programming languages. Current language is stored as a cookie. -#### WalletGuideWarn +#### WalletGuideWarn {#walletguidewarn} This component puts a warning if language is in progress for this section. Please use `WIPLangs` property to enable it for a language for the page. -#### WalletCodeExample +#### WalletCodeExample {#walletcodeexample} This is improved `CodeExample` component. It currently supports dynamic switching between TypeScript, Kotlin and Flutter code snippets (depending on the @@ -67,7 +67,7 @@ missing. Here's an example on how to use it: For a regular code examples (non Wallet SDK) please use vanilla `CodeExample` component. -#### LanguageSpecific +#### LanguageSpecific {#languagespecific} This component allows to render parts of documentation based on selected code. To get started, crete 2 files in `component` directory: diff --git a/docs/build/apps/wallet/component/dart/configClient.mdx b/docs/build/apps/wallet/component/dart/configClient.mdx index 17963fc43..12884f47b 100644 --- a/docs/build/apps/wallet/component/dart/configClient.mdx +++ b/docs/build/apps/wallet/component/dart/configClient.mdx @@ -1,6 +1,6 @@ import { CodeExample } from "@site/src/components/CodeExample"; -### Configuring the Client +### Configuring the Client {#configuring-the-client} The Flutter Wallet SDK uses the standard Client from the [http package](https://pub.dev/packages/http) for all network requests (excluding Horizon, where the Flutter Stellar SDK's HTTP client is used). diff --git a/docs/build/apps/wallet/component/kt/configClient.mdx b/docs/build/apps/wallet/component/kt/configClient.mdx index c344030ac..8f8fe0682 100644 --- a/docs/build/apps/wallet/component/kt/configClient.mdx +++ b/docs/build/apps/wallet/component/kt/configClient.mdx @@ -1,6 +1,6 @@ import { CodeExample } from "@site/src/components/CodeExample"; -### Configuring the Client +### Configuring the Client {#configuring-the-client} The Kotlin wallet SDK uses the [ktor client](https://ktor.io/docs/getting-started-ktor-client.html) for all network requests (excluding Horizon, where the Stellar SDK's HTTP client is used). Currently, the okhttp engine is configured to be used with the client. You can read more about how to configure the ktor client [here](https://ktor.io/docs/create-client.html#configure-client). @@ -41,7 +41,7 @@ val anchorCustomClient = -### Closing Resources +### Closing Resources {#closing-resources} After the wallet class is no longer used, it's necessary to close all clients used by it. While in some applications it may not be required (e.g. the wallet lives for the whole lifetime of the application), in other cases it can be required. If your wallet class is short-lived, it's recommended to close client resources using a close function: diff --git a/docs/build/apps/wallet/component/ts/configClient.mdx b/docs/build/apps/wallet/component/ts/configClient.mdx index d1c980d19..fa4e67d2c 100644 --- a/docs/build/apps/wallet/component/ts/configClient.mdx +++ b/docs/build/apps/wallet/component/ts/configClient.mdx @@ -1,6 +1,6 @@ import { CodeExample } from "@site/src/components/CodeExample"; -### Configuring the Client +### Configuring the Client {#configuring-the-client} The Typescript wallet SDK uses the [axios client](https://axios-http.com/docs/intro) for all network requests. You can read more about how to configure the axios client [here](https://axios-http.com/docs/instance). diff --git a/docs/build/apps/wallet/intro.mdx b/docs/build/apps/wallet/intro.mdx index 94556d89a..a03417926 100644 --- a/docs/build/apps/wallet/intro.mdx +++ b/docs/build/apps/wallet/intro.mdx @@ -17,7 +17,7 @@ import AllowHttpInfo from "./component/ts/allowHttpInfo.mdx";
-## Installation +## Installation {#installation} First, you need to add the SDK dependency to your project. @@ -27,7 +27,7 @@ First, you need to add the SDK dependency to your project. dart={} /> -## Working with the SDK +## Working with the SDK {#working-with-the-sdk} Let's start with the main class that provides all SDK functionality. It's advised to have a singleton wallet object shared across the application. Creating a wallet with a default configuration connected to Stellar's Testnet is simple: @@ -75,7 +75,7 @@ var wallet = Wallet(StellarConfiguration.publicNet); dart={} /> -## Stellar Basics +## Stellar Basics {#stellar-basics} The wallet SDK provides some extra functionality on top of the existing [Horizon SDK]. For interaction with the Stellar network, the wallet SDK covers only the basics used in a typical wallet flow. For more advanced use cases, the underlying [Horizon SDK] should be used instead. @@ -107,7 +107,7 @@ Default configuration connects to the public Stellar Horizon instance. You can c You can read more about working with the Stellar network in the [respective section](./stellar.mdx). -## Anchor Basics +## Anchor Basics {#anchor-basics} Primary use of the SDK is to provide an easy way to connect to anchors via sets of protocols known as SEPs. Let's look into connecting to the Stellar test anchor: diff --git a/docs/build/apps/wallet/sep10.mdx b/docs/build/apps/wallet/sep10.mdx index 1543f0279..b239e5f25 100644 --- a/docs/build/apps/wallet/sep10.mdx +++ b/docs/build/apps/wallet/sep10.mdx @@ -16,7 +16,7 @@ Wallets connect to anchors using a standard way of authentication via the Stella This guide will cover all ways to use SEP-10 to authenticate with an anchor. -## Creating Authentication Key +## Creating Authentication Key {#creating-authentication-key} :::info Custodial wallets only @@ -28,7 +28,7 @@ The authentication key is only used for authentication purposes and doesn't need Go to the [Stellar Lab] and generate a keypair. The secret key must be handled securely, because it will be used for authentication. -## Basic Authentication +## Basic Authentication {#basic-authentication} Let's do a basic authentication. In this example, we will use wallet SDK to create an authentication token. @@ -80,11 +80,11 @@ final authToken = await sep10.authenticate(authKey); For non-custodial wallets, you want to use the user's private key as an `authKey`. -## Home Domain (Optional) +## Home Domain (Optional) {#home-domain-optional} The home domain is the optional parameter for SEP-10 authentication, when a single auth server is shared between multiple domains. Some anchors may require you to provide this argument. The SDK automatically sets the `home_domain` parameter in all SEP-10 requests. -## Client Domain (Optional) +## Client Domain (Optional) {#client-domain-optional} :::info Non-custodial wallets only @@ -100,7 +100,7 @@ Client domain is used by anchors to verify the origin of user's request (which w Supporting `client_domain` comes in two parts, the wallet's client and the wallet's server implementations. In this setup, we will have an extra authentication key. This key will be stored remotely on the server. Using the SEP-1 info file, the anchor will be able to query this key and verify the signature. As such, the anchor would be able to confirm that the request is coming from your wallet, belonging to wallet's `client_domain`. -### Client Side +### Client Side {#client-side} First, let's implement the client side. In this example we will connect to a remote signer that signs transactions on the endpoint `https://demo-wallet-server.stellar.org/sign` for the client domain `demo-wallet-server.stellar.org`. @@ -175,7 +175,7 @@ var signer = DomainSigner("https://demo-wallet-server.stellar.org/sign", } ts={} /> -### Server Side +### Server Side {#server-side} Next, let's implement the server side. diff --git a/docs/build/apps/wallet/sep24.mdx b/docs/build/apps/wallet/sep24.mdx index ea263c883..675deaf0f 100644 --- a/docs/build/apps/wallet/sep24.mdx +++ b/docs/build/apps/wallet/sep24.mdx @@ -15,7 +15,7 @@ The [SEP-24] standard defines the standard way for anchors and wallets to intera During the flow, a wallet makes several requests to the anchor, and finally receives an interactive URL to open in iframe. This URL is used by the user to provide an input (such as KYC) directly to the anchor. Finally, the wallet can fetch transaction information using query endpoints. -## Get Anchor Information +## Get Anchor Information {#get-anchor-information} Let's start with getting an instance of `Sep24` class, responsible for all SEP-24 interactions: @@ -57,7 +57,7 @@ final servicesInfo = await sep24.getServiceInfo(); -## Interactive Flows +## Interactive Flows {#interactive-flows} Before getting started, make sure you have connected to the anchor and received an authentication token, as described in the [Stellar Authentication] wallet guide. We will use the `authToken` object in the examples below as the [SEP-10] authentication token, obtained earlier. @@ -99,7 +99,7 @@ Before starting with the deposit flow, make sure that the user account has [esta ::: -### Basic Flow +### Basic Flow {#basic-flow} Let's start with a basic deposit: @@ -172,7 +172,7 @@ final id = withdrawal.id; -### Providing KYC Info +### Providing KYC Info {#providing-kyc-info} To improve the user experience, the [SEP-24] standard supports passing user KYC to the anchor via [SEP-9]. In turn, the anchor will pre-fill this information in the interactive popup. @@ -211,7 +211,7 @@ final deposit = await sep24.deposit(asset, authToken, -### Changing Stellar Transfer Account +### Changing Stellar Transfer Account {#changing-stellar-transfer-account} By default, the Stellar transfer will be sent to the authenticated account (with a memo) that initiated the deposit. @@ -274,13 +274,13 @@ final withdrawal = await sep24.withdraw(asset, authToken, withdrawalAccount: ori -## Getting Transaction Info +## Getting Transaction Info {#getting-transaction-info} On the typical flow, the wallet would get transaction data to notify users about status updates. This is done via the [SEP-24] `GET /transaction` and `GET /transactions` endpoint. Alternatively, some anchors support webhooks for notifications. Note that this feature is not widely adopted yet. -### Tracking Transaction +### Tracking Transaction {#tracking-transaction} Let's look into how to use the wallet SDK to track transaction status changes. We will use `Watcher` class for this purpose. First, let's initialize watcher and start tracking a transaction. @@ -340,7 +340,7 @@ final result = watcher.watchAsset(authToken, asset); } /> -### Fetching Transaction +### Fetching Transaction {#fetching-transaction} While `Watcher` class offers powerful tracking capabilities, sometimes it's required to just fetch a transaction (or transactions) once. The `Anchor` class allows you to fetch a transaction by ID, Stellar transaction ID, or external transaction ID: @@ -431,7 +431,7 @@ final transactions = await sep24.getTransactionsForAsset(asset, authToken); -## Submitting Withdrawal Transfer +## Submitting Withdrawal Transfer {#submitting-withdrawal-transfer} Previously, we took a look at starting the withdrawal flow. Now, let's take a look at a full example. diff --git a/docs/build/apps/wallet/sep30.mdx b/docs/build/apps/wallet/sep30.mdx index 029d8ada7..d6f1a39cd 100644 --- a/docs/build/apps/wallet/sep30.mdx +++ b/docs/build/apps/wallet/sep30.mdx @@ -10,7 +10,7 @@ import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCod The [Sep-30] standard defines the standard way for an individual (e.g., a user or wallet) to regain access to their Stellar account after losing its private key without providing any third party control of the account. During this flow the wallet communicates with one or more recovery signer servers to register the wallet for a later recovery if it's needed. -## Create Recoverable Account +## Create Recoverable Account {#create-recoverable-account} First, let's create an account key, a device key, and a recovery key that will be attached to the account. @@ -214,7 +214,7 @@ await wallet.stellar().submitTransaction(transaction); -## Get Account Info +## Get Account Info {#get-account-info} You can fetch account info from one or more servers. To do so, first we need to authenticate with a recovery server using the SEP-10 authentication method: @@ -289,7 +289,7 @@ var accountInfo = await recovery.getAccountInfo(accountKp, {second: -## Recover Wallet +## Recover Wallet {#recover-wallet} Let's say we've lost our device key and need to recover our wallet. diff --git a/docs/build/apps/wallet/sep38.mdx b/docs/build/apps/wallet/sep38.mdx index ef05a8c49..83a935b21 100644 --- a/docs/build/apps/wallet/sep38.mdx +++ b/docs/build/apps/wallet/sep38.mdx @@ -12,7 +12,7 @@ import Header from "./component/header.mdx"; The [SEP-38] standard defines a way for anchors to provide quotes for the exchange of an off-chain asset and a different on-chain asset, and vice versa. Quotes may be [indicative](https://www.investopedia.com/terms/i/indicativequote.asp) or [firm](https://www.investopedia.com/terms/f/firmquote.asp) ones. When either is used is explained in the sections below. -## Creating Sep-38 Object +## Creating Sep-38 Object {#creating-sep-38-object} Let's start with creating a sep38 object, which we'll use for all SEP-38 interactions. Authentication is optional for these requests, and depends on the anchor implementation. For our example we will include it. @@ -38,7 +38,7 @@ var sep38 = anchor.sep38(authToken: authToken); -## Get Anchor Information +## Get Anchor Information {#get-anchor-information} First, let's get information about the anchor's support for [SEP-38]. The response gives what stellar on-chain assets and off-chain assets are available for trading. @@ -72,7 +72,7 @@ For example a response will look like this. The asset identifiers are described } ``` -## Asset Identification Format +## Asset Identification Format {#asset-identification-format} Before calling other endpoints we should understand the scheme used to identify assets in this protocol. The following format is used: @@ -96,7 +96,7 @@ iso4217:USD Further explanation can be found in [SEP-38 specification](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0038.md#asset-identification-format). -## Get Prices +## Get Prices {#get-prices} Now let's get [indicative](https://www.investopedia.com/terms/i/indicativequote.asp) prices from the anchor in exchange for a given asset. This is an indicative price. The actual price will be calculated at conversion time once the Anchor receives the funds from a user. @@ -134,7 +134,7 @@ The response gives the asset prices for exchanging the requested sell asset. For } ``` -## Get Price +## Get Price {#get-price} Next, let's get an [indicative](https://www.investopedia.com/terms/i/indicativequote.asp) price for a certain pair. @@ -172,7 +172,7 @@ The response gives information for exchanging these assets. For example, a respo { price: '1.18', sell_amount: '5.00', buy_amount: '4.24' } ``` -## Post Quote +## Post Quote {#post-quote} Now let's get a [firm](https://www.investopedia.com/terms/f/firmquote.asp) quote from the anchor. As opposed to the earlier endpoints, this quote is stored by the anchor for a certain period of time. We will show how we can grab the quote again later. @@ -218,7 +218,7 @@ An example response looks like this: } ``` -## Get Quote +## Get Quote {#get-quote} Now let's get the previously requested quote. To do that we use the `id` from the `.requestQuote()` response. diff --git a/docs/build/apps/wallet/sep6.mdx b/docs/build/apps/wallet/sep6.mdx index b57404197..9eaae23e9 100644 --- a/docs/build/apps/wallet/sep6.mdx +++ b/docs/build/apps/wallet/sep6.mdx @@ -14,7 +14,7 @@ The [SEP-6] standard defines a way for anchors and wallets to interact on behalf Please note, this is for _programmatic_ deposits and withdrawals. For hosted deposits and withdrawals, where the anchor interacts with wallets interactively using a popup, please see [Hosted Deposit and Withdrawal](./sep24.mdx). -## Get Anchor Information +## Get Anchor Information {#get-anchor-information} Let's start with creating a sep6 object, which we'll use for all SEP-6 interactions: @@ -44,7 +44,7 @@ var info = await sep6.info(); -## Start a deposit +## Start a deposit {#start-a-deposit} Before getting started, make sure you have connected to the anchor and received an authentication token, as described in the [Stellar Authentication] wallet guide. We will use `authToken` in the examples below as the [SEP-10] authentication token, obtained earlier. @@ -81,11 +81,11 @@ var deposit = await anchor.sep6().deposit( There are several kinds of responses, depending on if the anchor needs more information. All deposits and withdrawals will have these same response types: -### 1. Success response +### 1. Success response {#1-success-response} If the response is successful (HTTP 200), then the anchor is processing the deposit. If it needs additional information, it will communicate it when providing the [transaction info](#getting-transaction-info). -### 2. Still processing, or denied +### 2. Still processing, or denied {#2-still-processing-or-denied} If an HTTP 403 with data: `customer_info_status` is returned, it means the action is still processing, or not accepted. In this case the `more_info_url` field should have a link describing next steps. @@ -99,7 +99,7 @@ An example response: } ``` -### 3. Needs more KYC info +### 3. Needs more KYC info {#3-needs-more-kyc-info} Another common response is an HTTP 403, with the response: `non_interactive_customer_info_needed`. In this case the anchor needs more KYC information via [SEP-12]. @@ -169,7 +169,7 @@ Then, we can re-call the deposit method like before and it should be successful. More information about sending KYC info using [SEP-12] can be found in [Providing KYC info](#providing-kyc-info). -## Providing KYC info +## Providing KYC info {#providing-kyc-info} An anchor may respond to a deposit or withdrawal request saying they need additional KYC info. To faciliate this, [SEP-6] supports adding a customer's KYC info via [SEP-12]. The user can send in the required info using the sep12 object like below. @@ -219,7 +219,7 @@ await sep12.add(sep9Info, sep9Files: sep9Files); -## Start a withdrawal +## Start a withdrawal {#start-a-withdrawal} Starting a withdrawal is similar to deposit, and has the same response types as described earlier. @@ -252,7 +252,7 @@ var resp = await anchor.sep6().withdraw(params, authToken); -## Get exchange info +## Get exchange info {#get-exchange-info} If the anchor supports [SEP-38] quotes, it can support deposits that make a bridge between non-equivalent assets. For example, an anchor recieves BRL via bank transfer and in return sends USDC (of equivalent value minus fees) to the user on Stellar. @@ -320,11 +320,11 @@ var resp = await anchor.sep6().withdrawExchange(params, authToken); The response follows the same types as all the deposits and withdrawals for SEP-6. -## Getting Transaction Info +## Getting Transaction Info {#getting-transaction-info} On the typical flow, the wallet would get transaction data to notify users about status updates. This is done via the [SEP-6] `GET /transaction` and `GET /transactions` endpoint. -### Tracking Transaction +### Tracking Transaction {#tracking-transaction} Let's look into how to use the sdk to track transaction status changes. We will use the `Watcher` class for this purpose. First, let's initialize it and start tracking a transaction. @@ -396,7 +396,7 @@ result.controller.stream.listen( -### Fetching Transaction +### Fetching Transaction {#fetching-transaction} While `Watcher` class offers powerful tracking capabilities, sometimes it's required to just fetch a transaction (or transactions) once. The `Anchor` class allows you to fetch a transaction by ID, Stellar transaction ID, or external transaction ID: diff --git a/docs/build/apps/wallet/sep7.mdx b/docs/build/apps/wallet/sep7.mdx index 8199c50ca..9a6048c8b 100644 --- a/docs/build/apps/wallet/sep7.mdx +++ b/docs/build/apps/wallet/sep7.mdx @@ -10,7 +10,7 @@ import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCod The [Sep-7] standard defines a way for a non-wallet application to construct a URI scheme that represents a specific transaction for an account to sign. The scheme used is `web+stellar`, followed by a colon. Example: `web+stellar:?=&=` -## Tx Operation +## Tx Operation {#tx-operation} The tx operation represents a request to sign a specific transaction envelope, with [some configurable parameters]. @@ -101,7 +101,7 @@ uri.toString(); // encodes everything and converts to a uri string -## Pay Operation +## Pay Operation {#pay-operation} The pay operation represents a request to pay a specific address with a specific asset, regardless of the source asset used by the payer. You can [configure parameters] to build the payment operation. diff --git a/docs/build/apps/wallet/stellar.mdx b/docs/build/apps/wallet/stellar.mdx index c1a737042..2963b4339 100644 --- a/docs/build/apps/wallet/stellar.mdx +++ b/docs/build/apps/wallet/stellar.mdx @@ -12,7 +12,7 @@ import CreateKeyPairInfo from "./component/ts/createKeypairInfo.mdx"; In the previous section we learned how to create a wallet and a `Stellar` object that provides a connection to Horizon. In this section, we will look at the usages of this class. -## Accounts +## Accounts {#accounts} The most basic entity on the Stellar network is an account. Let's look into AccountService that provides the capability to work with accounts: @@ -52,15 +52,15 @@ var accountKeyPair = account.createKeyPair(); } /> -## Build Transaction +## Build Transaction {#build-transaction} The transaction builder allows you to create various transactions that can be signed and submitted to the Stellar network. Some transactions can be sponsored. -### Building Basic Transactions +### Building Basic Transactions {#building-basic-transactions} First, let's look into building basic transactions. -#### Create Account +#### Create Account {#create-account} The create account transaction activates/creates an account with a starting balance of XLM (1 XLM by default). @@ -86,7 +86,7 @@ var tx = txBuilder.createAccount(destinationAccountKeyPair).build(); -#### Modify Account +#### Modify Account {#modify-account} You can lock the master key of the account by setting its weight to 0. Use caution when locking the account's master key. Make sure you have set the correct signers and weights. Otherwise, you will lock the account irreversibly. @@ -182,7 +182,7 @@ var tx = txBuilder.setThreshold(low: 1, medium: 10, high: 20).build(); -#### Modify Assets (Trustlines) +#### Modify Assets (Trustlines) {#modify-assets-trustlines} Add an asset (trustline) to the account. This allows the account to receive transfers of the asset. @@ -237,7 +237,7 @@ var tx = txBuilder.removeAssetSupport(asset).build(); -#### Swap +#### Swap {#swap} Exchange an account's asset for a different asset. The account must have a trustline for the destination asset. @@ -271,7 +271,7 @@ var txn = txBuilder.swap( -#### Path Pay +#### Path Pay {#path-pay} Send one asset from the source account and receive a different asset in the destination account. @@ -313,7 +313,7 @@ var txn = txBuilder.pathPay( -#### Set Memo +#### Set Memo {#set-memo} Set a memo on the transaction. The memo object can be imported from ["@stellar/stellar-sdk"](https://www.npmjs.com/package/@stellar/stellar-sdk). @@ -334,7 +334,7 @@ var tx = txBuilder.setMemo(memo).build(); -#### Account Merge +#### Account Merge {#account-merge} Merges account into a destination account. @@ -361,7 +361,7 @@ var mergeTxn = txBuilder.accountMerge( -#### Fund Testnet Account +#### Fund Testnet Account {#fund-testnet-account} Fund an account on the Stellar test network @@ -377,7 +377,7 @@ await wallet.stellar().fundTestNetAccount(accountKp.address); -### Building Advanced Transactions +### Building Advanced Transactions {#building-advanced-transactions} In some cases a private key may not be known prior to forming a transaction. For example, a new account must be funded to exist and the wallet may not have the key for the account so may request the create account transaction to be sponsored by a third party. @@ -539,7 +539,7 @@ bool success = await stellar.submitTransaction(modifyAccountTransaction); -#### Adding an Operation +#### Adding an Operation {#adding-an-operation} Add a custom Operation to a transaction. This can be any [Operation](../../../learn/fundamentals/transactions/list-of-operations) supported by the Stellar network. The Operation object can be imported from ["@stellar/stellar-sdk"](https://www.npmjs.com/package/@stellar/stellar-sdk). @@ -581,9 +581,9 @@ var tx = txBuilder.addOperation( -### Sponsoring Transactions +### Sponsoring Transactions {#sponsoring-transactions} -#### Sponsor Operations +#### Sponsor Operations {#sponsor-operations} Some operations, that modify account reserves can be [sponsored](../../../learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx#sponsored-reserves-operations). For sponsored operations, the sponsoring account will be paying for the reserves instead of the account that being sponsored. This allows you to do some operations, even if account doesn't have enough funds to perform such operations. To sponsor a transaction, simply start a sponsoring block:} ts={simply create a building function (describing which operations are to be sponsored) and pass it to the sponsoring method:}/> @@ -633,7 +633,7 @@ Only some operations can be sponsored, and a sponsoring sponsored block} ts={sponsoring method} /> (`newKeyPair` below). If this argument is present, all operations inside the sponsored block will be sourced by this `sponsoredAccount`. (Except account creation, which is always sourced by the sponsor). @@ -754,7 +754,7 @@ stellar.sign(transaction, newKeyPair); -### Fee-Bump Transaction +### Fee-Bump Transaction {#fee-bump-transaction} If you wish to modify a newly created account with a 0 balance, it's also possible to do so via `FeeBump`. It can be combined with a sponsoring block} ts={method} /> to achieve the same result as in the example above. However, with `FeeBump` it's also possible to add more operations (that don't require sponsoring), such as a transfer. @@ -864,7 +864,7 @@ bool success = await stellar.submitTransaction(feeBump); -### Using XDR to Send Transaction Data +### Using XDR to Send Transaction Data {#using-xdr-to-send-transaction-data} Note, that a wallet may not have a signing key for `sponsorKeyPair`. In that case, it's necessary to convert the transaction to XDR, send it to the server, containing `sponsorKey` and return the signed transaction back to the wallet. Let's use the previous example of sponsoring account creation, but this time with the sponsor key being unknown to the wallet. The first step is to define the public key of the sponsor keypair: @@ -996,7 +996,7 @@ bool success = await stellar.submitTransaction(signedTransaction); -## Submit Transaction +## Submit Transaction {#submit-transaction} :::info @@ -1069,7 +1069,7 @@ bool success = await stellar.submitWithFeeIncrease( This will create and sign the transaction that originated from the `sourceAccountKeyPair`. Every 30 seconds this function will re-construct this transaction with a new fee (increased by 100 stroops), repeating signing and submitting. Once the transaction is successful, the function will return the transaction body. Note, that any other error will terminate the retry cycle and an exception will be thrown. -## Accessing Horizon SDK +## Accessing Horizon SDK {#accessing-horizon-sdk} It's very simple to use the Horizon SDK connecting to the same Horizon instance as a `Wallet` class. To do so, simply call: diff --git a/docs/build/guides/archival/create-restoration-footprint-js.mdx b/docs/build/guides/archival/create-restoration-footprint-js.mdx index 9703ace49..e112ce266 100644 --- a/docs/build/guides/archival/create-restoration-footprint-js.mdx +++ b/docs/build/guides/archival/create-restoration-footprint-js.mdx @@ -79,7 +79,7 @@ async function createRestorationFootprint( } ``` -## Code walkthrough +## Code walkthrough {#code-walkthrough} As we're making use of [Stellar SDK for JavaScript](https://stellar.github.io/js-stellar-sdk/) `js-stellar-sdk`, first we import the module. diff --git a/docs/build/guides/archival/test-ttl-extension.mdx b/docs/build/guides/archival/test-ttl-extension.mdx index 8632c108d..85e79af2a 100644 --- a/docs/build/guides/archival/test-ttl-extension.mdx +++ b/docs/build/guides/archival/test-ttl-extension.mdx @@ -6,7 +6,7 @@ description: Test contracts that extend contract data time to live (TTL) In order to test contracts that extend the contract data [TTL](../../../learn/encyclopedia/storage/state-archival.mdx#ttl) via `extend_ttl` storage operations, you can use the TTL getter operation (`get_ttl`) in combination with manipulating the ledger sequence number. Note, that `get_ttl` function is only available for tests and only in Soroban SDK v21+. -## Example +## Example {#example} Follow along the [example](https://github.com/stellar/soroban-examples/blob/main/ttl/src/lib.rs) that tests TTL extensions. The example has extensive comments, this document just highlights the most important parts. @@ -167,6 +167,6 @@ fn test_persistent_entry_archival() { } ``` -## Testing TTL extension for other contract instances +## Testing TTL extension for other contract instances {#testing-ttl-extension-for-other-contract-instances} Sometimes a contract may want to extend TTL of another contracts and/or their Wasm entries (usually that would happen in factory contracts). This logic may be covered in a similar fashion to the example above using `env.deployer().get_contract_instance_ttl(&contract)` to get TTL of any contract's instance, and `env.deployer().get_contract_code_ttl(&contract)` to get TTL of any contract's Wasm entry. You can find an example of using these function in the SDK [test suite](https://github.com/stellar/rs-soroban-sdk/blob/ff05c3d4cbed97db50142372e9d7a4fa4a8d1d5d/soroban-sdk/src/tests/storage_testutils.rs#L76). diff --git a/docs/build/guides/basics/automate-reset-data.mdx b/docs/build/guides/basics/automate-reset-data.mdx index fbe13b563..586f1a3db 100644 --- a/docs/build/guides/basics/automate-reset-data.mdx +++ b/docs/build/guides/basics/automate-reset-data.mdx @@ -16,36 +16,36 @@ description: Learn how to automate Testnet and Futurenet reset data on Stellar /> -## Overview +## Overview {#overview} Stellar operates two primary testing environments: the [Testnet and the Futurenet](../../../learn/fundamentals/networks.mdx). These networks allow developers to experiment with Stellar features without risking real assets. Periodically, these networks are reset to ensure they remain clean and manageable. -## What is the Testnet and Futurenet reset? +## What is the Testnet and Futurenet reset? {#what-is-the-testnet-and-futurenet-reset} Testnet and Futurenet are reset periodically to the genesis ledger to declutter the network, remove spam, reduce the time needed to catch up on the latest ledger, and help maintain the system. These resets take place approximately quarterly. Resets clear all ledger entries (accounts, trustlines, offers, smart contract data, etc.), transactions, and historical data from Stellar Core, Horizon, and the Stellar RPC, which is why developers should not rely on the persistence of accounts or the state of any balances when using Testnet or Futurenet. You can check current reset dates [here](../../../learn/fundamentals/networks.mdx#testnet-and-futurenet-data-reset). -## Why resets are important +## Why resets are important {#why-resets-are-important} 1. **Clean Slate:** Regular resets ensure that both Testnet and Futurenet provide a clean environment for testing. This helps in avoiding complications arising from old data or configurations. 2. **Performance:** Over time, test environments can accumulate a lot of data, which can slow down performance. Resets help in maintaining optimal performance. 3. **Protocol Updates:** Introducing new features or protocol changes often requires a reset to ensure compatibility and stability. 4. **Development Cycles:** Aligning with development cycles allows developers to plan their testing phases and ensures they have a reliable environment for their work. -## Data automation on Testnet and Futurenet +## Data automation on Testnet and Futurenet {#data-automation-on-testnet-and-futurenet} Automating blockchain state on Stellar's Testnet and Futurenet can streamline development workflows, ensuring that you can consistently test and validate your applications in these environments. -### Code walkthrough +### Code walkthrough {#code-walkthrough} -### Prerequisites: +### Prerequisites: {#prerequisites} - [Node.js](https://nodejs.org/en) and `npm` installed. - Stellar SDK for [JavaScript](https://www.npmjs.com/package/@stellar/stellar-sdk) and `fs` installed - An understanding of the rudimentary, retry-enabled transaction polling function `yeetTx` which we outlined in [another guide](../transactions/submit-transaction-wait-js.mdx) -### Code +### Code {#code} ```javascript import { @@ -357,6 +357,6 @@ Initializes the Stellar server connection, Creates two accounts, Issues a custom `yeetTx(feedback, message)`: provides more detailed logging of transaction results. -### Conclusion +### Conclusion {#conclusion} Automating the setup of data on the Stellar Testnet and Futurenet can significantly enhance your development workflow, ensuring that you can quickly return to testing after a network reset. By following the above steps and using the provided code samples, you can streamline your processes and maintain consistency across resets. diff --git a/docs/build/guides/basics/create-account.mdx b/docs/build/guides/basics/create-account.mdx index 975e0e56c..6f7e7a579 100644 --- a/docs/build/guides/basics/create-account.mdx +++ b/docs/build/guides/basics/create-account.mdx @@ -11,7 +11,7 @@ _Before we get started with working with Stellar in code, consider going through [Accounts](../../../learn/fundamentals/stellar-data-structures/accounts.mdx) are a fundamental building block of Stellar: they hold all your balances, allow you to send and receive payments, and let you place offers to buy and sell assets. Since pretty much everything on Stellar is in some way tied to an account, the first thing you generally need to do when you start developing is create one. This beginner-level tutorial will show you how to do that. -## Create a Keypair +## Create a Keypair {#create-a-keypair} Stellar uses public key cryptography to ensure that every transaction is secure: every Stellar account has a keypair consisting of a **public key** and a **secret key**. The public key is always safe to share — other people need it to identify your account and verify that you authorized a transaction. It's like an email address. The secret key, however, is private information that proves you own — and gives you access to — your account. It's like a password, and you should never share it with anyone. @@ -79,7 +79,7 @@ print(f"Public Key: {pair.public_key}") -## Create Account +## Create Account {#create-account} A valid keypair, however, does not make an account: in order to prevent unused accounts from bloating the ledger, Stellar requires accounts to hold a [minimum balance](../../../learn/fundamentals/lumens.mdx#minimum-balance) of 1 XLM before they actually exist. Until it gets a bit of funding, your keypair doesn't warrant space on the ledger. diff --git a/docs/build/guides/basics/follow-received-payments.mdx b/docs/build/guides/basics/follow-received-payments.mdx index 61839947d..9d739988e 100644 --- a/docs/build/guides/basics/follow-received-payments.mdx +++ b/docs/build/guides/basics/follow-received-payments.mdx @@ -21,7 +21,7 @@ In this tutorial we will learn: - How to fund your account using friendbot. - How to follow payments to your account using curl and EventSource. -## Project Skeleton +## Project Skeleton {#project-skeleton} Let's get started by building our project skeleton: @@ -48,7 +48,7 @@ $ node -e "require('stellar-base')" Everything was successful if no output was generated from the above command. Now let's write a script to create a new account. -## Creating an account +## Creating an account {#creating-an-account} Create a new file named `make_account.js` and paste the following text into it: @@ -82,7 +82,7 @@ $ Before our account can do anything it must be funded. Indeed, before an account is funded it does not truly exist! -## Funding your account +## Funding your account {#funding-your-account} The Stellar test network provides the Friendbot, a tool that developers can use to get testnet lumens for testing purposes. To fund your account, simply execute the following curl command: @@ -110,7 +110,7 @@ Don't forget to replace the account id above with your own. If the request succe After a few seconds, the Stellar network will perform consensus, close the ledger, and your account will have been created. Next up we will write a command that watches for new payments to your account and outputs a message to the terminal. -## Following payments using `curl` +## Following payments using `curl` {#following-payments-using-curl} To follow new payments connected to your account you simply need to send the `Accept: text/event-stream` header to the [/payments](../../../data/horizon/api-reference/resources/operations/README.mdx) endpoint. @@ -150,7 +150,7 @@ data: {"_links":{"effects":{"href":"/operations/713226564145153/effects/{?cursor Every time you receive a new payment you will get a new row of data. Payments is not the only endpoint that supports streaming. You can also stream transactions [/transactions](../../../data/horizon/api-reference/resources/transactions/README.mdx) and operations [/operations](../../../data/horizon/api-reference/resources/operations/README.mdx). -## Following payments using `EventStream` +## Following payments using `EventStream` {#following-payments-using-eventstream} > **Warning!** `EventSource` object does not reconnect for certain error types so it can stop working. If you need a reliable streaming connection please use our [SDK](https://github.com/stellar/js-stellar-sdk). @@ -200,7 +200,7 @@ New payment: -## Testing it out +## Testing it out {#testing-it-out} We now know how to get a stream of transactions to an account. Let's check if our solution actually works and if new payments appear. Let's watch as we send a payment ([`create_account` operation](../../../learn/fundamentals/transactions/list-of-operations.mdx#create-account)) from our account to another account. diff --git a/docs/build/guides/basics/send-and-receive-payments.mdx b/docs/build/guides/basics/send-and-receive-payments.mdx index 42be6c52a..6607c2261 100644 --- a/docs/build/guides/basics/send-and-receive-payments.mdx +++ b/docs/build/guides/basics/send-and-receive-payments.mdx @@ -9,7 +9,7 @@ import { Alert } from "@site/src/components/Alert"; Most of the time, you’ll be sending money to someone else who has their own account. For this tutorial, however, you'll need a second account to transact with. So before proceeding, follow the steps outlined in [Create an Account](./create-account.mdx) to make _two_ accounts: one for sending and one for receiving. -## About Operations and Transactions +## About Operations and Transactions {#about-operations-and-transactions} Actions that do things on Stellar — like sending payments or making buy or sell offers — are called [operations](../../../learn/fundamentals/transactions/operations-and-transactions.mdx#operations). To submit an operation to the network, you bundle it into a [transaction](../../../learn/fundamentals/transactions/operations-and-transactions.mdx#transactions), which is a group of anywhere from 1 to 100 operations accompanied by some extra information, like which account is making the transaction and a cryptographic signature to verify that the transaction is authentic. @@ -23,7 +23,7 @@ In the following code samples, proper error checking is omitted for brevity. How -## Send a Payment +## Send a Payment {#send-a-payment} Stellar stores and communicates transaction data in a binary format called [XDR](../../../learn/encyclopedia/data-format/xdr.mdx), which is optimized for network performance but unreadable to the human eye. Luckily, [Horizon](../../../data/horizon/README.mdx), the Stellar API, and the [Stellar SDKs](../../../tools/sdks/library.mdx) convert XDRs into friendlier formats. Here’s how you might send 10 lumens to an account: @@ -474,7 +474,7 @@ server.submit_transaction(transaction) In this example, we're submitting the transaction to the SDF-maintained public testnet instance of Horizon, the Stellar API. When submitting transactions to a Horizon server — which is what most people do — it's possible that you will not receive a response from the server due to a bug, network conditions, etc. In such a situation it's impossible to determine the status of your transaction. That's why you should always save a built transaction (or transaction encoded in XDR format) in a variable or a database and resubmit it if you don't know its status. If the transaction has already been successfully applied to the ledger, Horizon will simply return the saved result and not attempt to submit the transaction again. Only in cases where a transaction’s status is unknown (and thus will have a chance of being included into a ledger) will a resubmission to the network occur. -## Receive a Payment +## Receive a Payment {#receive-a-payment} You don’t actually need to do anything to receive payments into a Stellar account: if a payer makes a successful transaction to send assets to you, those assets will automatically be added to your account. @@ -795,7 +795,7 @@ payments_next = payments.next() -## Transacting in Other Currencies +## Transacting in Other Currencies {#transacting-in-other-currencies} One of the amazing things about the Stellar network is that you can create, hold, send, receive, and trade any type of asset. Many organizations issue assets on Stellar that represent real-world currencies such as US dollars or Nigerian naira or other cryptocurrencies such as bitcoin or ether. diff --git a/docs/build/guides/conventions/check-auth-tutorials.mdx b/docs/build/guides/conventions/check-auth-tutorials.mdx index f7d9cf6b7..a709b2eed 100644 --- a/docs/build/guides/conventions/check-auth-tutorials.mdx +++ b/docs/build/guides/conventions/check-auth-tutorials.mdx @@ -13,23 +13,23 @@ description: Two guides that walk through using __check_auth /> -## Tutorial 1: time based restriction on token transfers +## Tutorial 1: time based restriction on token transfers {#tutorial-1-time-based-restriction-on-token-transfers} Imagine a multi-sig account contract where certain actions, like transferring tokens, need to be controlled by the time elapsed between consecutive transfers. For example, a token transfer should only be allowed if a certain period of time has passed since the last transfer. This can be useful in scenarios where you want to limit the frequency of transactions to prevent misuse or to implement rate limiting. -### Base concepts +### Base concepts {#base-concepts} -#### Time-based restrictions +#### Time-based restrictions {#time-based-restrictions} The idea is to enforce a minimum time interval between consecutive token transfers. Each token can have its own time limit, and the contract will track the last transfer time for each token. -#### Data storage +#### Data storage {#data-storage} The contract will store the time limit and last transfer time for each token in its storage to keep track of these values across transactions. -### Code walkthrough +### Code walkthrough {#code-walkthrough} -#### Contract structure and imports +#### Contract structure and imports {#contract-structure-and-imports} ```rust #![no_std] @@ -73,7 +73,7 @@ const TRANSFER_FN: Symbol = symbol_short!("transfer"); ``` -#### Contract initialization +#### Contract initialization {#contract-initialization} 1. Initializes the contract with a list of signers' public keys 2. Stores the count of signers in the contract's storage @@ -93,7 +93,7 @@ impl AccountContract { } ``` -#### Setting time limits +#### Setting time limits {#setting-time-limits} 1. Allows setting a time limit for a specific token 2. Ensures that only the contract itself can set these limits by requiring the contract's authorization @@ -111,7 +111,7 @@ impl AccountContract { } ``` -#### Custom authentication and authorization +#### Custom authentication and authorization {#custom-authentication-and-authorization} 1. Authenticates the signatures 2. Checks if all required signers have signed @@ -157,7 +157,7 @@ impl CustomAccountInterface for AccountContract { } ``` -#### Authentication logic +#### Authentication logic {#authentication-logic} 1. Verifies that the signatures are in the correct order and that each signer is authorized 2. Uses [ed25519_verify](https://docs.rs/soroban-sdk/latest/soroban_sdk/crypto/struct.Crypto.html#method.ed25519_verify) function to verify each signature @@ -193,7 +193,7 @@ impl CustomAccountInterface for AccountContract { } ``` -#### Authorization policy verification +#### Authorization policy verification {#authorization-policy-verification} 1. Checks if the function being called is a transfer or approve function 2. Enforces the time-based restriction by comparing the current time with the last transfer time @@ -248,11 +248,11 @@ fn verify_authorization_policy( } ``` -#### Summary +#### Summary {#summary} The contract begins by initializing with a set of authorized signers. It allows setting a time limit for token transfers, which controls how frequently a token can be transferred. The \_\_check_auth function is the core of the authorization process, ensuring that all necessary signatures are valid and checking the time-based restriction for token transfers. If the required time has not passed since the last transfer, the contract will deny the operation, enforcing the desired rate limiting. By tracking the last transfer time and enforcing a minimum time interval between transfers, the contract effectively limits the frequency of token transfers, resolving the issue of potential abuse through rapid consecutive transactions. -#### Complete code +#### Complete code {#complete-code} Here are all the snippets stacked together in a single file for convenience: @@ -594,11 +594,11 @@ fn test_token_auth() { } ``` -## Tutorial 2: implementing a smart wallet (WebAuthn) +## Tutorial 2: implementing a smart wallet (WebAuthn) {#tutorial-2-implementing-a-smart-wallet-webauthn} Imagine a world where traditional passwords are obsolete. In this world, WebAuthn (Web Authentication) has become the standard for secure online interactions. Alice, a blockchain enthusiast, wants to create a wallet that leverages WebAuthn technology for enhanced security. She decides to implement a WebAuthn wallet on Stellar, allowing users to manage their digital assets using their device's biometric features or security keys (e.g., YubiKey, Google Titan Security Key, etc.). -### Base concepts +### Base concepts {#base-concepts-1} WebAuthn is a web standard for passwordless authentication. It allows users to authenticate using biometrics (like fingerprints or facial recognition). @@ -615,9 +615,9 @@ This tutorial's code credit goes to [@kalepail's](https://github.com/kalepail) w ::: -### Code walkthrough +### Code walkthrough {#code-walkthrough-1} -#### Contract structure and imports +#### Contract structure and imports {#contract-structure-and-imports-1} This section sets up the contract structure and imports necessary components from the Soroban SDK. @@ -635,7 +635,7 @@ use soroban_sdk::{ pub struct Contract; ``` -#### Error definitions +#### Error definitions {#error-definitions} This enum defines possible errors that can occur during contract execution. @@ -653,7 +653,7 @@ pub enum Error { } ``` -#### Core contract functions +#### Core contract functions {#core-contract-functions} These functions handle adding and removing signers, updating the contract, and managing admin counts. @@ -803,7 +803,7 @@ impl Contract { ``` -#### Signature structure +#### Signature structure {#signature-structure} This structure represents a WebAuthn signature. @@ -817,7 +817,7 @@ pub struct Signature { } ``` -#### CustomAccountInterface implementation +#### CustomAccountInterface implementation {#customaccountinterface-implementation} This implements the core authentication logic for the WebAuthn wallet. @@ -916,7 +916,7 @@ impl CustomAccountInterface for Contract { } ``` -#### Base64 url encoding +#### Base64 url encoding {#base64-url-encoding} This function provides Base64 URL encoding functionality used in the WebAuthn process. @@ -974,11 +974,11 @@ pub fn encode(dst: &mut [u8], src: &[u8]) { ``` -#### Written explanation of code +#### Written explanation of code {#written-explanation-of-code} The WebAuthn wallet contract manages user credentials and authentication. It allows adding and removing signers, distinguishing between admin and regular users. The add function registers new signers, storing admin keys persistently and regular keys temporarily. The remove function deletes signers, and update allows contract upgrades. The core of the wallet's security is the `__check_auth` function, which verifies WebAuthn signatures. It checks the signature against the stored public key, verifies the client data JSON, and ensures the challenge matches the expected value. The contract uses Soroban's storage capabilities to manage keys and admin counts, with different TTLs (Time To Live) for persistent and temporary storage. -#### Test cases +#### Test cases {#test-cases} These are test cases to ensure our WebAuthn wallet is functioning correctly. We'll use the Soroban SDK's testing utilities to create and run these tests. @@ -1067,11 +1067,11 @@ mod test { } ``` -#### Summary +#### Summary {#summary-1} This WebAuthn wallet implementation provides a secure and user-friendly way to manage digital assets on Stellar. It leverages the security benefits of WebAuthn while maintaining the flexibility needed for blockchain interactions. -#### Complete code +#### Complete code {#complete-code-1} Here are all the snippets stacked together in a single file for convenience: diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index 4d69293ef..35fc2fc41 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -12,7 +12,7 @@ There are two kinds of dependencies that can be introduced in a Stellar smart co In the following, we will see how contracts can be leveraged from within another contract. -## Contract as a dependency +## Contract as a dependency {#contract-as-a-dependency} While finding a contract is out of scope for this guide, there are a few place to be on the lookout. Most projects and dApps publicly disclose the address of their Stellar smart contract on their website. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorers also allow you to download the compiled contract as a Wasm file. There are also projects that provide a link to access the code itself. @@ -22,7 +22,7 @@ To depend on a project, we need to know the contract address of the contract to ::: -## Public API +## Public API {#public-api} All public functions of a contract can be called. Using a network explorer can be helpful as some propose to see the Rust interface of a contract. Bindings can also be generated using the CLI: @@ -30,7 +30,7 @@ All public functions of a contract can be called. Using a network explorer can b stellar contract bindings rust --network --contract-id ... --output-dir ... ``` -## Making a cross-contract call +## Making a cross-contract call {#making-a-cross-contract-call} Once we know which function to call and which arguments to use, there are two main ways to make a cross-contract call: we can either load the Wasm or call the contract. @@ -81,7 +81,7 @@ client::ContractAEnum::SomeField ::: -## Handling responses +## Handling responses {#handling-responses} In the examples above, we have used `env.invoke_contract` and `client.some_function`. In both cases, if there is an issue with the underlying contract call, the contract will panic. This might be a valid approach, but in some cases we want to catch errors and handle them depending on the outcome. This is to forward a custom error message, or even triggers an alternative code path. @@ -105,7 +105,7 @@ match client.try_add(&x, &y) { } ``` -## Depending on another contract +## Depending on another contract {#depending-on-another-contract} Congratulations, now you can effectively leverage the whole Soroban ecosystem and its myriad of smart contracts. There is one last point to discuss before closing up: **dependability**. @@ -123,7 +123,7 @@ stellar contract fetch --id C... --network ... > contract.wasm Besides this security consideration, upgrading a contract is an integral part of a contract's lifecycle. New features are added, bugs are fixed, and public API changes are made. Here as well, it is important to observe any development on these contracts to ensure the continuous operation of your own contract. -## Examples +## Examples {#examples} See the following full example with tests: diff --git a/docs/build/guides/conventions/deploy-contract.mdx b/docs/build/guides/conventions/deploy-contract.mdx index 1881143b0..6e355603d 100644 --- a/docs/build/guides/conventions/deploy-contract.mdx +++ b/docs/build/guides/conventions/deploy-contract.mdx @@ -18,17 +18,17 @@ description: Deploy a contract from installed Wasm bytecode using a deployer con /> -## Overview +## Overview {#overview} This guide walks through the process of deploying a smart contract from installed Wasm bytecode using a deployer contract. We will cover setting up your environment, uploading Wasm bytecode, and deploying and initializing a contract atomically. -### Prerequisites: +### Prerequisites: {#prerequisites} - Basic understanding of [Rust programming language](https://www.rust-lang.org/). To brush up on Rust, check out [Rustlings](https://github.com/rust-lang/rustlings) or [The Rust book](https://doc.rust-lang.org/book/). - Familiarity with [Stellar smart contracts](../../smart-contracts/getting-started/hello-world.mdx) - Installed Cargo, [Stellar CLI](../../smart-contracts/getting-started/setup.mdx#install-the-stellar-cli) and Soroban SDK -### Setup environment +### Setup environment {#setup-environment} The [deployer example](https://github.com/stellar/soroban-examples/tree/v21.6.0/deployer) demonstrates how to deploy contracts using a contract. @@ -66,7 +66,7 @@ test test::test_deploy_from_contract ... ok test test::test_deploy_from_address ... ok ``` -### Code overview +### Code overview {#code-overview} ```rust title="deployer/deployer/src/lib.rs" #[contract] @@ -110,11 +110,11 @@ impl Deployer { } ``` -## How it works +## How it works {#how-it-works} The deployer contract provides a mechanism to deploy other contracts in a secure and deterministic manner. It ensures that the deployment is authorized by the specified deployer address and supports atomic initialization of the newly deployed contract. This guarantees that the contract is properly initialized immediately after deployment, preventing any potential issues with uninitialized contracts. -### Function breakdown +### Function breakdown {#function-breakdown} - `env: Env`: The Env object represents the current contract execution environment. It provides methods to interact with the blockchain and other contracts, as well as perform various operations. - `deployer: Address`: The Address of the entity that is requesting the contract deployment. This address will be used to authorize the deployment. @@ -123,7 +123,7 @@ The deployer contract provides a mechanism to deploy other contracts in a secure - `init_fn: Symbol`: The name of the initialization function to be called on the newly deployed contract. - `init_args: Vec`: A vector of arguments, specified as `{type: value}` objects, to be passed to the initialization function of the deployed contract. -### Function steps +### Function steps {#function-steps} ```rust if deployer != env.current_contract_address() { @@ -157,7 +157,7 @@ let res: Val = env.invoke_contract(&deployed_address, &init_fn, init_args); Returns a tuple containing the address of the newly deployed contract and the result of the initialization function. -### Build the contracts +### Build the contracts {#build-the-contracts} To build the contract into a `.wasm` file, use the `stellar contract build` command. This command builds both the deployer contract and the test contract. @@ -175,7 +175,7 @@ target/wasm32-unknown-unknown/release/soroban_deployer_contract.wasm target/wasm32-unknown-unknown/release/soroban_deployer_test_contract.wasm ``` -## Run the contract +## Run the contract {#run-the-contract} Before deploying the test contract with the deployer, install the test contract Wasm using the `install` command. The `install` command will print out the hash derived from the Wasm file which should be used by the deployer. diff --git a/docs/build/guides/conventions/deploy-sac-with-code.mdx b/docs/build/guides/conventions/deploy-sac-with-code.mdx index 814e465f0..058b91e72 100644 --- a/docs/build/guides/conventions/deploy-sac-with-code.mdx +++ b/docs/build/guides/conventions/deploy-sac-with-code.mdx @@ -18,18 +18,18 @@ description: Deploy a SAC for a Stellar asset using Javascript SDK /> -## Overview +## Overview {#overview} In this guide, you'll learn how to deploy a [Stellar Asset Contract (SAC)](../../../tokens/stellar-asset-contract.mdx) for a Stellar asset using the [Stellar SDK](../../../tools/sdks/library.mdx#javascript-sdk). The Stellar SDK is a set of tools and library designed to help developers build applications that interact with the Stellar blockchain network. -### Prerequisites: +### Prerequisites: {#prerequisites} - [Node.js ](https://nodejs.org/en) and npm installed. - Stellar SDK for [JavaScript](https://www.npmjs.com/package/@stellar/stellar-sdk) installed - [Knowledge about Issuing an Asset on Stellar](https://developers.stellar.org/docs/tokens/how-to-issue-an-asset) - An understanding of the rudimentary, retry-enabled transaction polling function `yeetTx` which we outlined in [another guide](../transactions/submit-transaction-wait-js.mdx) -## Code overview +## Code overview {#code-overview} ```javascript title="deployassetcontract.js" import * as StellarSdk from "@stellar/stellar-sdk"; @@ -78,7 +78,7 @@ const deployStellarAssetContract = async () => { await deployStellarAssetContract(); ``` -## Code explanation +## Code explanation {#code-explanation} **Server Setup** diff --git a/docs/build/guides/conventions/extending-wasm-ttl.mdx b/docs/build/guides/conventions/extending-wasm-ttl.mdx index 332048cf0..6aed1fa85 100644 --- a/docs/build/guides/conventions/extending-wasm-ttl.mdx +++ b/docs/build/guides/conventions/extending-wasm-ttl.mdx @@ -11,13 +11,13 @@ The TTL is the number of ledgers between the current ledger and the final ledger This guide will show you how to extend the TTL of a deployed contract's Wasm code using JavaScript. -## Prerequisites +## Prerequisites {#prerequisites} - Stellar SDK: `npm install @stellar/stellar-sdk` - A Stellar RPC endpoint (e.g., `https://soroban-testnet.stellar.org`) - Basic knowledge of Stellar SDK -## Process overview +## Process overview {#process-overview} - Get the contract's footprint, - Set a reasonable resource fee (perhaps start at 10,000 stroops as this is a costly operation), @@ -26,7 +26,7 @@ This guide will show you how to extend the TTL of a deployed contract's Wasm cod - Create an operation `StellarSdk.Operation.extendFootprintTtl`, - Note that a resource fee and base fee are both charged in this operation. -## JavaScript code +## JavaScript code {#javascript-code} The code below uses Nodejs environment but same concept can also be applied in the browser using Freighter wallet or using any other [Stellar SDK](../../../tools/sdks/library.mdx). @@ -86,7 +86,7 @@ extendContractWasmTTL(contractId, sourceKeypair) .catch(console.error); ``` -### Breaking Down the Code +### Breaking Down the Code {#breaking-down-the-code} Let's walk through the key parts of this function: diff --git a/docs/build/guides/conventions/upgrading-contracts.mdx b/docs/build/guides/conventions/upgrading-contracts.mdx index baa8a770e..011efbc1f 100644 --- a/docs/build/guides/conventions/upgrading-contracts.mdx +++ b/docs/build/guides/conventions/upgrading-contracts.mdx @@ -16,17 +16,17 @@ description: Upgrade Wasm bytecode for a deployed contract /> -## Introduction +## Introduction {#introduction} Upgrading a smart contract allows you to improve or modify your contract without changing its address. This guide will walk you through the process of upgrading a WebAssembly (Wasm) bytecode contract using the Soroban SDK. -### Prerequisites: +### Prerequisites: {#prerequisites} - Basic understanding of [Rust programming language]. To brush up on Rust, check out [Rustlings](https://github.com/rust-lang/rustlings) or [The Rust book](https://doc.rust-lang.org/book/). - Familiarity with [Stellar smart contracts](../../smart-contracts/getting-started/hello-world.mdx) - Installed [Stellar CLI](../../smart-contracts/getting-started/setup.mdx#install-the-stellar-cli) and Soroban SDK -### Download the upgradeable contract example +### Download the upgradeable contract example {#download-the-upgradeable-contract-example} The [upgradeable contract example] demonstrates how to upgrade a Wasm contract. @@ -36,7 +36,7 @@ The [upgradeable contract example] demonstrates how to upgrade a Wasm contract. [upgradeable contract example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/upgradeable_contract [Rust programming language]: https://www.rust-lang.org/ -### Code +### Code {#code} The example contains both an "old" and "new" contract, where we upgrade from "old" to "new". The code below is for the "old" contract. @@ -85,7 +85,7 @@ impl UpgradeableContract { ``` -## How it works +## How it works {#how-it-works} When upgrading a contract, the key function used is `e.deployer().update_current_contract_wasm`, which takes the Wasm hash of the new contract as a parameter. Here’s a step-by-step breakdown of how this process works: @@ -113,7 +113,7 @@ pub fn upgrade(e: Env, new_wasm_hash: BytesN<32>) { [here]: https://docs.rs/soroban-sdk/20.0.2/soroban_sdk/struct.Env.html#method.update_current_contract_wasm [event]: ../../../learn/encyclopedia/contract-development/events.mdx#event-types -## Tests +## Tests {#tests} Open the `upgradeable_contract/old_contract/src/test.rs` file to follow along. @@ -234,7 +234,7 @@ client.upgrade(&new_wasm_hash); assert_eq!(2, client.version()); ``` -## Build the contract +## Build the contract {#build-the-contract} To build the contract `.wasm` files, run `stellar contract build` in both `upgradeable_contract/old_contract` and `upgradeable_contract/new_contract` in that order. @@ -248,7 +248,7 @@ target/wasm32-unknown-unknown/release/soroban_upgradeable_contract_old_contract. target/wasm32-unknown-unknown/release/soroban_upgradeable_contract_new_contract.wasm ``` -## Run the contract +## Run the contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract functions. Deploy the old contract and install the Wasm for the new contract. diff --git a/docs/build/guides/conversions/address-conversions.mdx b/docs/build/guides/conversions/address-conversions.mdx index 82ef7b281..75689aefc 100644 --- a/docs/build/guides/conversions/address-conversions.mdx +++ b/docs/build/guides/conversions/address-conversions.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; The `Address` is an opaque type that could represent an "account" on the Stellar network (i.e., a keypair), or a "contract." From Soroban's point of view, it doesn't really matter which it is. The "account" variety of these addresses are typically displayed as a `G...` public address, and the "contract" variety is typically displayed as a `C...` address. An address may also be displayed in other formats such as a 32 byte array, a string, or an ScVal type. The Soroban SDKs provide methods that easily convert an address to any of these types. -## Address to bytesN +## Address to bytesN {#address-to-bytesn} Bytes are a more compact and efficient way to store data in terms of storage optimization and data transmission. In situations where you need to store or transmit an address in a fixed-size, such as for cryptographic operations or data serialization, you need to convert the address to a bytesN format @@ -47,7 +47,7 @@ StrKey.decode_ed25519_public_key(stellar_address) -## Address to String +## Address to String {#address-to-string} When transferring data between different systems or over a network, using text-based formats like JSON and XML string formats are often required. Storing addresses as strings in databases can simplify database schema design and queries. Strings are easier to manipulate and are more compatible with user interfaces and APIs. diff --git a/docs/build/guides/conversions/bytes-conversions.mdx b/docs/build/guides/conversions/bytes-conversions.mdx index f04548b7e..7f9c25a41 100644 --- a/docs/build/guides/conversions/bytes-conversions.mdx +++ b/docs/build/guides/conversions/bytes-conversions.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Bytes is a contiguous growable array type containing u8s. They may represent various types of data including strings, addresses, or other information. Converting any data type to bytes ensures that the data be consistently handled by the Soroban runtime and interacting systems. -## Bytes to Address +## Bytes to Address {#bytes-to-address} When retrieving data stored on the blockchain, addresses might be stored in byte representation for compactness and efficiency. Off-chain systems, such as APIs, databases, or user interfaces, usually expect addresses in a human-readable format. In such cases, you need to convert the bytes to an address format to ensure compatibility. @@ -48,7 +48,7 @@ bytes_to_address = Address.from_raw_account(raw_bytes) -## Bytes to String +## Bytes to String {#bytes-to-string} When dealing with binary data, you may need to convert certain portions of the data to a human-readable format like strings for logging, debugging, processing or display. @@ -85,7 +85,7 @@ bytes_to_string = raw_bytes.decode('utf-8') -## Bytes to ScVal +## Bytes to ScVal {#bytes-to-scval} In a Soroban smart contract that interacts with an external oracle service to provide price data in raw byte format, you would need to convert the bytes to ScVal to process and manipulate the data within your contract. diff --git a/docs/build/guides/conversions/scval-conversions.mdx b/docs/build/guides/conversions/scval-conversions.mdx index 455945503..f131a0b98 100644 --- a/docs/build/guides/conversions/scval-conversions.mdx +++ b/docs/build/guides/conversions/scval-conversions.mdx @@ -9,7 +9,7 @@ import TabItem from "@theme/TabItem"; Soroban Contract Value (`ScVal`) is a custom type defined within the Soroban runtime environment that represents other data types such as strings, bytes, and more complex structures used within smart contracts in a format that that the soroban runtime can process, store and retrieve efficiently. -## ScVal to bytesN +## ScVal to bytesN {#scval-to-bytesn} @@ -40,7 +40,7 @@ sc_val_to_bytes = stellar_sdk.scval.from_bytes(sc_val) -## ScVal to address +## ScVal to address {#scval-to-address} @@ -70,7 +70,7 @@ sc_to_address = Address.from_xdr_sc_address(sc_val) -## ScVal to String +## ScVal to String {#scval-to-string} diff --git a/docs/build/guides/conversions/string-conversions.mdx b/docs/build/guides/conversions/string-conversions.mdx index bbe4f9508..384a58752 100644 --- a/docs/build/guides/conversions/string-conversions.mdx +++ b/docs/build/guides/conversions/string-conversions.mdx @@ -9,7 +9,7 @@ import TabItem from "@theme/TabItem"; Strings are a sequence of characters used to represent readable text. They are used to store and manipulate text-based information such as function names, arguments, key-value data and interfacing with external systems. Strings may often need to be converted to other data types for efficient processing and storage. -## String to bytesN +## String to bytesN {#string-to-bytesn} Some systems use binary formats where data needs to be represented as a fixed-length byte array for storage or processing. For example, fixed-length hashes or identifiers. Converting strings to a fixed byte size ensures that the data fits the required size constraints. @@ -51,7 +51,7 @@ string_value.encode() -## String to address +## String to address {#string-to-address} An address received in a user input may be of string type and you would need to convert it to an address type to perform validations, transactions, or other operations within your smart contract. @@ -81,7 +81,7 @@ const stringToAddress = StellarSdk.Address.fromString(stellarAddress); -## String to ScVal +## String to ScVal {#string-to-scval} When calling functions or methods that expect ScVal types, you need to convert your string data to ScVal to make the call successful. For example, if your smart contract needs to store or manipulate a user input string within its state or use it as part of its logic, you would convert the string to an ScVal type to integrate it with the contract's operations. diff --git a/docs/build/guides/dapps/docker.mdx b/docs/build/guides/dapps/docker.mdx index 1002ef49e..c91093b39 100644 --- a/docs/build/guides/dapps/docker.mdx +++ b/docs/build/guides/dapps/docker.mdx @@ -3,7 +3,7 @@ title: Use Docker to build and run dapps description: Understand Docker and use it to build applications --- -## What is Docker? +## What is Docker? {#what-is-docker} Welcome to the world of [Docker](https://www.docker.com/), an essential tool for software development. Docker packages software into units known as containers, ensuring consistency, isolation, portability, and scalability. @@ -11,7 +11,7 @@ Docker is particularly useful in dapp development. It helps manage microservices Understanding Docker begins with understanding Docker images and containers. A Docker image, created from a Dockerfile, is a package that contains everything needed to run the software. A Docker container is a running instance of this image. -## Building and Running a Docker Image +## Building and Running a Docker Image {#building-and-running-a-docker-image} You can create a Docker image using the docker build command with a Dockerfile. Once the image is created, you can run a Docker container using the docker run command. @@ -34,7 +34,7 @@ docker build . \ --rm ``` -### Makefile Overview +### Makefile Overview {#makefile-overview} ```bash docker build . @@ -60,7 +60,7 @@ Ensures Docker removes any intermediate containers after the build process compl Guarantees the removal of the intermediate container, even if the build fails. By using `make build-docker`, you're harnessing the power of Docker to create a consistent, reliable environment for our dapp. -## Container Deployment +## Container Deployment {#container-deployment} You can streamline the deployment process by using a script to run the Docker container. The following script is a wrapper for the [`stellar/quickstart` Docker image], which provides a quick way to run a Stellar network. You can find an example of the `quickstart.sh` script located in the root directory of the [example crowdfund dapp]. diff --git a/docs/build/guides/dapps/frontend-guide.mdx b/docs/build/guides/dapps/frontend-guide.mdx index 5e6685c83..e1db91554 100644 --- a/docs/build/guides/dapps/frontend-guide.mdx +++ b/docs/build/guides/dapps/frontend-guide.mdx @@ -3,16 +3,16 @@ title: Comprehensive frontend guide for Stellar dapps description: Learn how to build functional frontend interfaces for Stellar dapps using React, Tailwind CSS, and the Stellar SDK. --- -## Pre-requisites: +## Pre-requisites: {#pre-requisites} - Basic knowledge of React, Tailwind CSS, and related web technologies - Basic understanding of the Stellar blockchain - Node.js and npm installed - Web browser with [Freighter Wallet](https://www.freighter.app) extension installed -## 1. Introduction +## 1. Introduction {#1-introduction} -### The role of frontend in Stellar dapps +### The role of frontend in Stellar dapps {#the-role-of-frontend-in-stellar-dapps} Frontend development plays a crucial role in decentralized applications (dapps) built on the Stellar network. It serves as the primary interface between users and the underlying blockchain technology. A well-designed frontend not only makes your dapp accessible and user-friendly but also helps users interact seamlessly with complex blockchain operations. @@ -24,7 +24,7 @@ In Stellar dapps, the frontend is responsible for: 4. Providing real-time updates on transaction status and account balances 5. Guiding users through complex processes like multi-signature transactions or claimable balance operations -### Importance of user interface and user experience +### Importance of user interface and user experience {#importance-of-user-interface-and-user-experience} The importance of a good user interface (UI) and user experience (UX) in Stellar dapps cannot be overstated. Blockchain technology can be intimidating for many users, and a well-designed UI/UX can make the difference between a successful dapp and one that users find frustrating or confusing. @@ -38,11 +38,11 @@ Key aspects of UI/UX in Stellar dapps include: By focusing on these aspects, you can create Stellar dapps that are not only functional but also enjoyable to use, encouraging wider adoption of your application and the Stellar network as a whole. -## 2. Setting up the development environment +## 2. Setting up the development environment {#2-setting-up-the-development-environment} Before we start building our Stellar dapp, we need to set up our development environment. We'll be using React with Next.js for our frontend framework, Tailwind CSS for styling, and the Stellar SDK for interacting with the Stellar network. -### Installing Node.js and npm +### Installing Node.js and npm {#installing-nodejs-and-npm} First, make sure you have Node.js and npm (Node Package Manager) installed on your system. You can download and install them from the official Node.js website: https://nodejs.org/ @@ -55,7 +55,7 @@ npm --version Both commands should return version numbers if the installation was successful. -### Setting up a Next.js project +### Setting up a Next.js project {#setting-up-a-nextjs-project} Next.js is a React framework that provides features such as server-side rendering and routing out of the box. To create a new Next.js project, run the following commands in your terminal: @@ -73,7 +73,7 @@ When prompted, choose the following options: - Would you like to use App Router? Yes - Would you like to customize the default import alias? No -### Setup HTTPS on Localhost +### Setup HTTPS on Localhost {#setup-https-on-localhost} Freighter wallet requires a secure connection (HTTPS) to interact with your dapp. To enable HTTPS on localhost, you can use a tool like `mkcert`. Fortunately, Next.js provides built-in support for HTTPS. @@ -85,7 +85,7 @@ To enable HTTPS in your Next.js project, open the `package.json` file and edit t } ``` -### Installing Stellar SDK and other dependencies +### Installing Stellar SDK and other dependencies {#installing-stellar-sdk-and-other-dependencies} To interact with the Stellar network, we'll need to install the Stellar SDK and some additional dependencies: @@ -99,11 +99,11 @@ npm install stellar-sdk @stellar/freighter-api bignumber.js Now that we have our development environment set up, we're ready to start building our Stellar dapp! -## 3. Building basic interface elements +## 3. Building basic interface elements {#3-building-basic-interface-elements} In this section, we'll create reusable components for our Stellar dapp and implement forms and inputs using React and Tailwind CSS. -### Creating reusable components +### Creating reusable components {#creating-reusable-components} Let's start by creating a button component that we'll use throughout our application. Create a new file `components/Button.tsx`: @@ -167,7 +167,7 @@ export function ConnectButton({ label }: ConnectButtonProps) { This button component uses the `setAllowed` function from the `@stellar/freighter-api` library to connect the Freighter wallet when clicked. -### Implementing forms and inputs +### Implementing forms and inputs {#implementing-forms-and-inputs} Next, let's create a reusable input component. Create a new file `components/Input.tsx`: @@ -268,7 +268,7 @@ const SendPaymentForm: React.FC = ({ onSubmit }) => { export default SendPaymentForm; ``` -### Designing responsive layouts with Tailwind CSS +### Designing responsive layouts with Tailwind CSS {#designing-responsive-layouts-with-tailwind-css} To create a responsive layout for our dapp, we'll use Tailwind CSS utility classes. Let's create a layout component that we can use across our pages. Edit the file `app/layout.tsx`: @@ -341,27 +341,27 @@ export default function Home() { This setup provides a solid foundation for building the user interface of our Stellar dapp. In the next section, we'll integrate these components with the Stellar SDK to perform actual blockchain operations. -## 4. Basic Concepts of Soroban Contracts +## 4. Basic Concepts of Soroban Contracts {#4-basic-concepts-of-soroban-contracts} Before we start integrating smart contract functionality into our Stellar dapp, let's understand the basic concepts of Soroban contracts. Soroban is a smart contract platform built on the Stellar network. It allows developers to write and deploy smart contracts that run on the Stellar blockchain. Soroban contracts are written in Rust and compiled to [XDR (External Data Representation)](/docs/learn/encyclopedia/data-format/xdr) for execution on the Stellar network. -### Data Types +### Data Types {#data-types} Stellar supports a few data types that can be used in Soroban contracts and we need to do conversions from time to time between those types and the types we have in Javascript. The full list of primitive data types are explained [here](/docs/learn/encyclopedia/contract-development/types/built-in-types). -### XDR +### XDR {#xdr} Values that are passed to contracts and returned from contracts are serialized using XDR. XDR is a standard data serialization format used in Stellar to represent complex data structures. It is used to encode and decode data for transmission over the Stellar network. XDR is mostly represented in Javascript as string and can be converted to other types using the Stellar SDK. -### Fees +### Fees {#fees} Gas fees like they are called in the ethereum network are charged differently here. When submitting different types of transactions, the type of fees paid are different. When submitting a transaction to the network that interacts with the network, a Base fee is paid together with the resource fee for the operation. The base fee is a fixed fee that is paid for every transaction on the network. The resource fee is a fee that is paid for the resources used by the operation and is calculated based on the resources used by the operation and the network's current resource price. Calculating these fees can be cumbersome but the Stellar SDK provides a way to calculate these fees using the `server.prepareTransaction` method which simulates the transaction, gets the appropriate fees and appends the correct fee settings to the transaction. -### ABI or Spec +### ABI or Spec {#abi-or-spec} The ABI or spec is a json file that contains the contract's interface. It defines the functions that can be called on the contract, their parameters, and return types. The ABI is used by clients to interact with the contract and execute its functions. The ABI is generated from the contract's source code and is used to compile the contract into XDR for execution on the Stellar network. @@ -369,7 +369,7 @@ ABI can be genrated for a contract using the [`stellar contract bindings`](/docs This ABI can also be generated as a typescript library to ease development in your DApp and we'll be looking it later in this guide -## 5. Integrating with Stellar blockchain +## 5. Integrating with Stellar blockchain {#5-integrating-with-stellar-blockchain} Now that we have our basic UI components in place, let's integrate them with the Stellar blockchain using the Stellar SDK. It is imperative to know that the Stellar blockchain has three major networks: @@ -379,7 +379,7 @@ Now that we have our basic UI components in place, let's integrate them with the For this guide, we'll be using the Test network to avoid using real lumens during development. Read more about the Stellar networks [here](https://developers.stellar.org/docs/learn/fundamentals/networks). -### Setting up the Stellar SDK +### Setting up the Stellar SDK {#setting-up-the-stellar-sdk} Below is a snippet that shows how to set up the Stellar SDK in your project. We will be using parts of it a lot in this guide so lets try to understand it. @@ -400,7 +400,7 @@ In the above snippet, we import the Stellar SDK and create a server instance for We also create a transaction builder instance with the appropriate network passphrase. The `BASE_FEE` is the minimum fee required for a transaction on the Stellar network. while the `Networks.TESTNET` is the network passphrase for the Stellar Testnet. When using the public network, you can replace `TESTNET` with `PUBLIC` or `FUTURENET` for the Futurenet network. -### Interacting with the Stellar network +### Interacting with the Stellar network {#interacting-with-the-stellar-network} If you are coding along this guide at this point, you should have a minimal web application with a form to send payments. Now, let's integrate this form with the Stellar SDK to send actual payments on the Stellar network. @@ -528,7 +528,7 @@ Hurray! You have successfully integrated your Stellar dapp with the Stellar netw ::: -### Interacting with smart contracts +### Interacting with smart contracts {#interacting-with-smart-contracts} In the above example, we sent a simple payment transaction using the `StellarSdk.Operation.payment` operation. However, Stellar also supports many other operations, one of which is `invokeHostFunction` operation which is used to interact with smart contracts on the Stellar network. @@ -733,7 +733,7 @@ Congratulations! You have successfully interacted with a smart contract on the S ::: -### Reading events from the Stellar network +### Reading events from the Stellar network {#reading-events-from-the-stellar-network} Events on Stellar are values emitted from contracts grouped by topics. These events are emitted when a contract is called and can be read by any client that is interested in the contract. Events are stored in the Stellar ledger and can be read by any client that is interested in the contract. @@ -791,13 +791,13 @@ Source code for this program is available [here](https://github.com/myestery/ste Now, when the page loads, it will query the events from the Stellar network and update the counter value accordingly. -## 6. Using Typescript Bindings +## 6. Using Typescript Bindings {#6-using-typescript-bindings} The Stellar CLI comes with support for exporting a contract spec to a typescript library. This library is optimized for importing as an npm based module to your application. The library generated contains helper methods for calling each contract and also does automatic type conversion of the types for any contract method. -### How to create the bindings library +### How to create the bindings library {#how-to-create-the-bindings-library} To achieve this, you need to @@ -805,39 +805,39 @@ To achieve this, you need to - Have either source code or deployed contract ID of the contract. - Know the network it was deployed to. -#### Scenario 1: I have the Contract ID but no code +#### Scenario 1: I have the Contract ID but no code {#scenario-1-i-have-the-contract-id-but-no-code} In this scenario, we need to use the command [`stellar contract fetch`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-fetch) to fetch the wasm code of the contract -#### Scenario 2: I have the code +#### Scenario 2: I have the code {#scenario-2-i-have-the-code} The next step here is to build it to a wasm file using the [`stellar contract build`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-build) command. -### Generating the Library +### Generating the Library {#generating-the-library} After getting the wasm, we can now run [`stellar contract bindings typescript`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-bindings-typescript) to generate the library which is ready to be published to NPM. The library generated is suited for working with complex contracts. -## 7. Common Pitfalls +## 7. Common Pitfalls {#7-common-pitfalls} Below are a few common pitfalls that soroban DApp developers might run into -### Data Type Conversions +### Data Type Conversions {#data-type-conversions} The data types in Javascript are different from the data types in soroban. When working with soroban contracts, you need to be aware of the data types and how to convert them to the types you are familiar with in Javascript. The Stellar SDK provides helper methods for converting between XDR and Javascript types in the `xdr` namespace. -### Fees +### Fees {#fees-1} Calculating fees for transactions can be tricky. The Stellar SDK provides a way to calculate fees using the `server.prepareTransaction` method, which simulates the transaction and returns the appropriate fees. Fees are calculated in [stroops](/docs/learn/glossary#stroop) -### SendTransaction and GetTransaction +### SendTransaction and GetTransaction {#sendtransaction-and-gettransaction} Results from a smart contract execution or any of the [valid transactions](/docs/learn/fundamentals/transactions/list-of-operations#extend-footprint-ttl) on soroban are not immediate. They are kept in a `PENDING` state until they are confirmed. You need to poll the `getTransaction` method to get the final result of the transaction. -### State Archival +### State Archival {#state-archival} State Archival is a characteristic of soroban contracts where some data stored on the ledger about the contract might be archived. This [guide](/docs/build/guides/archival) helps to understand how to work with state archival in DApps. -### Data Retention +### Data Retention {#data-retention} A few things to note about data retention in soroban contracts: diff --git a/docs/build/guides/dapps/initialization.mdx b/docs/build/guides/dapps/initialization.mdx index f72bb9c0b..054f44b6a 100644 --- a/docs/build/guides/dapps/initialization.mdx +++ b/docs/build/guides/dapps/initialization.mdx @@ -5,7 +5,7 @@ description: Set up initialization correctly to ensure seamless setup for your d When setting up an example Soroban Dapp, correct initialization is crucial. This process entails several steps, including deploying Docker, cloning and deploying smart contracts, and invoking functions to configure them. In this comprehensive guide, you will walk you through the necessary steps to successfully build and deploy these smart contracts, ensuring a seamless setup for your Soroban Dapp. -## Building and Deploying the Soroban Token Smart Contract +## Building and Deploying the Soroban Token Smart Contract {#building-and-deploying-the-soroban-token-smart-contract} In dapps like the [Example Payment Dapp](https://github.com/stellar/soroban-react-payment/), the [Soroban Token smart contracts](https://github.com/stellar/soroban-examples/tree/main/token) are used to represent the tokenized asset that users can send and receive. Here is an example of how to build and deploy the Soroban Token smart contracts: @@ -41,7 +41,7 @@ stellar contract deploy \ This command deploys the smart contracts to Futurenet using the `stellar contract deploy` function. -## Initializing a Token Contract +## Initializing a Token Contract {#initializing-a-token-contract} With the contracts deployed, it's time to initialize the token contract: @@ -68,7 +68,7 @@ This command requires certain inputs: - Token Symbol: This is the token's symbol, also represented as a hex string. '4454' translates to the symbol "DT". -## Minting Tokens +## Minting Tokens {#minting-tokens} Lastly, you need to mint some tokens to the sender's account: @@ -89,7 +89,7 @@ By following these steps, you ensure that the Soroban token smart contracts are For a deeper dive into Stellar CLI commands, check out the [Stellar CLI repo](https://github.com/stellar/stellar-cli/blob/main/FULL_HELP_DOCS.md). -## Automating Initialization with Scripts +## Automating Initialization with Scripts {#automating-initialization-with-scripts} To streamline the initialization process, you can use a script. This script should automate various tasks such as setting up the network, wrapping Stellar assets, generating token-admin identities, funding the token-admin account, building and deploying the contracts, and initializing them with necessary parameters. diff --git a/docs/build/guides/dapps/react.mdx b/docs/build/guides/dapps/react.mdx index a905a085a..5490ef23a 100644 --- a/docs/build/guides/dapps/react.mdx +++ b/docs/build/guides/dapps/react.mdx @@ -30,7 +30,7 @@ import { useSorobanReact } from "@soroban-react/core"; These imports include `SorobanReactProvider` from `@soroban-react/core`, which is a context provider used to pass the SorobanReact instance to other components. You also import several types such as `WalletChain`, `ChainMetadata`, and `ChainName`, which help to maintain type safety within our application. -## React Components and Prop Passing +## React Components and Prop Passing {#react-components-and-prop-passing} React thrives on its component-based architecture. Components are reusable pieces of code that return a React element to be rendered on the page. A typical React application consists of multiple components working harmoniously to create a dynamic user interface. @@ -58,7 +58,7 @@ function MintButton({ This functional component takes three properties as arguments: `account`, `decimals`, and `symbol`. It demonstrates the concept of prop passing, a way to pass data from parent to child components in React. The `onComplete` prop even allows you to pass functions to your copmonents as props. We also see React's `useState` hook for local state management, a method to preserve values between function calls. -## State Management and Hooks +## State Management and Hooks {#state-management-and-hooks} State management is another core concept of React, allowing components to create and manage their own data. The `useState` hook is a feature introduced in React 16.8 that allows functional components to have their own state. @@ -70,7 +70,7 @@ const [isSubmitting, setSubmitting] = useState(false); The `useState` hook returns a pair of values: the current state and a function that updates it. In this case, the `isSubmitting` state is initialized to `false` and the `setSubmitting` function is used to update it. React also allows for the creation of custom hooks, like `useNetwork` and `useSendTransaction`, for encapsulating and reusing stateful logic across multiple components. -## Custom Hooks +## Custom Hooks {#custom-hooks} React hooks are functions that let you “hook into” React state and lifecycle features from functional components. Custom hooks allow you to encapsulate complex logic and make it reusable across components. Let's take a look at `useNetwork` and `useSendTransaction`, two custom hooks used in the [example crowdfund dapp]. @@ -86,7 +86,7 @@ const { sendTransaction } = useSendTransaction(); `useNetwork` provides the active chain and the server, and `useSendTransaction` gives us the `sendTransaction` method, which you'll later use to mint tokens. This way, you can keep the component focused on rendering and event handling logic, making it easier to test and maintain. -## Asynchronous Processing and Robust Error Handling +## Asynchronous Processing and Robust Error Handling {#asynchronous-processing-and-robust-error-handling} When dealing with operations that might take an unpredictable amount of time, like network requests or, in our case, minting tokens on the blockchain, React's support for asynchronous operations is crucial. This allows the execution of the rest of the code without being blocked by these operations. @@ -132,7 +132,7 @@ The `sendTransaction` method accepts two arguments: a `TransactionBuilder` insta If the transaction is successful, `paymentResult` contains the result, which you log for debugging purposes. If an error occurs during the transaction, the function throws an error, which you catch and log. -## Conclusion +## Conclusion {#conclusion} React offers a host of high-level concepts that can drastically improve your web development process. By understanding and utilizing these concepts—such as components, prop passing, state management, asynchronous operations, and error handling—you can create scalable, maintainable, and efficient applications. diff --git a/docs/build/guides/dapps/soroban-contract-init-template.mdx b/docs/build/guides/dapps/soroban-contract-init-template.mdx index 8b54a100c..bac879b21 100644 --- a/docs/build/guides/dapps/soroban-contract-init-template.mdx +++ b/docs/build/guides/dapps/soroban-contract-init-template.mdx @@ -23,7 +23,7 @@ This guide picks up where [Build a Dapp Frontend](../../apps/dapp-frontend.mdx) Building our own template will be a great way to learn how they work. They're not that complicated! -## Search GitHub for other Soroban templates +## Search GitHub for other Soroban templates {#search-github-for-other-soroban-templates} The official template maintained by Stellar Development Foundation (SDF), as used in [Build a Dapp Frontend](../../apps/dapp-frontend.mdx), lives on GitHub at [stellar/soroban-template-astro](https://github.com/stellar/soroban-astro-template). It uses the [Astro](https://astro.build/) web framework. While Astro works with React, Vue, Svelte, and any other UI library, the template opts not to use them, preferring Astro's own templating language, which uses vanilla JavaScript with no UI library. @@ -48,11 +48,11 @@ How do you know if any of these are any good? Try them. Look at their source cod If none of them suit, then it might be time to... -## Make your own template +## Make your own template {#make-your-own-template} This will be easier than you might imagine. There are a few gotchas, but overall these templates are fairly standard Node projects. -### But first, how are these projects organized? +### But first, how are these projects organized? {#but-first-how-are-these-projects-organized} When you run `stellar contract init`, it _always_ includes a Rust/Cargo project, with a `Cargo.toml` that defines a workspace, and workspace members located in a `contracts` folder. At a minimum, there's one contract, `contracts/hello_world`, but you can get more by using `--with-example`. @@ -60,7 +60,7 @@ Separately, you _may_ include a `--frontend-template`. Frontend templates so far So keep that in mind. We're making a fairly simple Node project, and telling it about our Soroban stuff, like the `contracts` folder. -### 1. Initialize an NPM project +### 1. Initialize an NPM project {#1-initialize-an-npm-project} So let's make a simple Node project! Rather than initializing an Astro project, like the official frontend template, let's try something new. The [State of JS survey](https://2022.stateofjs.com/en-US/libraries/front-end-frameworks/#front_end_frameworks_experience_linechart) tells me that something called "Solid" is fairly new and well-loved. [What does it say to do?](https://www.solidjs.com/) @@ -73,7 +73,7 @@ npm run dev Ok, we have a running Solid template! Now let's turn it into a Soroban template! -### 2. git init +### 2. git init {#2-git-init} Commit early, commit often! You can stop running the dev server (the one you started with `npm run dev` above; stop it with ctrlc, even on a Mac) if you want, or open a new terminal and: @@ -83,7 +83,7 @@ git add . git commit -m "init from solid ts template" ``` -### 3. Copy in the `initialize.js` script +### 3. Copy in the `initialize.js` script {#3-copy-in-the-initializejs-script} The SDF-maintained `soroban-template-astro` has [an `initialize.js` script](https://github.com/stellar/soroban-astro-template/blob/main/initialize.js) in its project root. Copy-paste it into your project. @@ -105,7 +105,7 @@ So this script does that. But it needs a few other things. -#### A. `devDependencies` +#### A. `devDependencies` {#a-devdependencies} The script uses a couple NPM packages. Install them: @@ -113,7 +113,7 @@ The script uses a couple NPM packages. Install them: npm install --save-dev dotenv glob ``` -#### B. `.env` +#### B. `.env` {#b-env} The [`dotenv` package](https://www.npmjs.com/package/dotenv) installed above parses environment variables from a `.env` file. The official template includes [a `.env.example`](https://github.com/stellar/soroban-astro-template/blob/main/.env.example). Go ahead and copy it into your own project. To set you up for testing it all out, you can also copy it to a local `.env`. @@ -121,7 +121,7 @@ The [`dotenv` package](https://www.npmjs.com/package/dotenv) installed above par cp .env.example .env ``` -#### C. `.gitignore` +#### C. `.gitignore` {#c-gitignore} You'll want to ignore the `.env` file you created above, as well as some other build artifacts created by the `initialize.js` script. Paste the bottom of [the official template's `.gitignore`](https://github.com/stellar/soroban-astro-template/blob/main/.gitignore) into your template's `.gitignore`: @@ -140,7 +140,7 @@ src/contracts/* !src/contracts/util.ts ``` -#### C. `package.json` +#### C. `package.json` {#c-packagejson} Make sure users of your template don't forget to run the `initialize.js` script. Modify the `scripts` section as follows: @@ -181,17 +181,17 @@ Also make sure that this project is set up to allow the `import` statements in t While you're here, you can also update the `name` (maybe `"soroban-template-solid"`) and `description`. -#### E. `src/contracts/util.ts` +#### E. `src/contracts/util.ts` {#e-srccontractsutilts} In the `.gitignore` above, you may have noticed that this file is explicitly included. Copy it in from [the official template](https://github.com/stellar/soroban-astro-template/blob/main/src/contracts/util.ts). You'll need to create the `src/contracts` folder. As you can see, it just makes it easy to `import { rpcUrl, networkPassphrase } from 'util'` in the files generated in the `importAll` step. -#### F. README +#### F. README {#f-readme} You might want to start by copying [the official template's README](https://github.com/stellar/soroban-astro-template/blob/main/README.md) to explain how to `cp .env.example .env`. From there, this might also be a good time to explain anything else that makes your template unique! Why might people want to use it? -### 4. `git commit` +### 4. `git commit` {#4-git-commit} Commit changes! @@ -200,7 +200,7 @@ git add . git commit -m "add initialize.js script and supporting changes" ``` -### 5. Try it! +### 5. Try it! {#5-try-it} That's it! You have an NPM project with an `initialize.js` script (and its supporting cast). That's all you really need! @@ -241,7 +241,7 @@ And projects that use yours will want to commit the `Cargo.*` files and `contrac Alright. Go ahead and open the app in your browser. Solid runs its dev server on `http://localhost:3000`. Does it load? It should! We didn't actually use the new `src/contracts/*` stuff in the app itself! -### 6. Wait. Should the template actually use the contracts? +### 6. Wait. Should the template actually use the contracts? {#6-wait-should-the-template-actually-use-the-contracts} Good question! @@ -273,7 +273,7 @@ Here's a way you could demonstrate how to import and use the `hello_world` contr + ``` -### 7. Make it as complex as you want! +### 7. Make it as complex as you want! {#7-make-it-as-complex-as-you-want} This is _your_ template. Go ahead and add helpful dependencies and utility files that you always want, like wallet management or whatever. If you want to add a whole complex stack of UI components, styles, and state-management libraries, go ahead! @@ -281,7 +281,7 @@ The official template strives for simplicity. For shallowness, even. It's meant And templates are cheap to make! If you want to have one `soroban-template-framework-x-basic` for a broader audience, and another `soroban-template-framework-x-opinionated` for your own projects, you can do that! -## Wrapping up +## Wrapping up {#wrapping-up} Some things we did in this section: diff --git a/docs/build/guides/dapps/state-archival.mdx b/docs/build/guides/dapps/state-archival.mdx index 86b012b96..ff96db1a0 100644 --- a/docs/build/guides/dapps/state-archival.mdx +++ b/docs/build/guides/dapps/state-archival.mdx @@ -7,7 +7,7 @@ When developing decentralized applications on Stellar, state archival is part of Some state archival terminology we will be using in this guide are described in the [state archival section](/docs/learn/encyclopedia/storage/state-archival#terms-and-semantics). -## Why managing state archival is important for applications +## Why managing state archival is important for applications {#why-managing-state-archival-is-important-for-applications} Managing state archival is crucial for Stellar dapps for several reasons: @@ -16,9 +16,9 @@ Managing state archival is crucial for Stellar dapps for several reasons: - Data lifecycle management: Proper management ensures that important data remains accessible while allowing temporary data to expire. - Application continuity: Ensuring contract instances and Wasm code remain live is essential for uninterrupted dapp operation. It is essential to check for contract availability before attempting to interact with the contract after a long period of inactivity. -## Methods of implementing state archival on the client side +## Methods of implementing state archival on the client side {#methods-of-implementing-state-archival-on-the-client-side} -### 1. Extending TTL from the smart contract +### 1. Extending TTL from the smart contract {#1-extending-ttl-from-the-smart-contract} This method involves invoking the [`extend_ttl()` method](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Instance.html#method.extend_ttl) from your smart contract to extend the TTL of the contract instance and its associated data. This method is useful when you want to keep the data accessible for a longer period. To use this method, your contract must not be archived at the time of calling. @@ -87,7 +87,7 @@ The above contract shows how to extend the TTL of a `Persistent`, `Instance`, an ::: -#### Using the Extend TTL method in your Contract +#### Using the Extend TTL method in your Contract {#using-the-extend-ttl-method-in-your-contract} When we create DApps, we do not typically create buttons to extend the TTL of data entries. Instead, we can create a function that extends the TTL of the data entries when the DApp is used. @@ -123,17 +123,17 @@ impl BiddingContract { } ``` -### 2. Restoring archived data +### 2. Restoring archived data {#2-restoring-archived-data} When developing a dapp on Stellar, you may encounter situations where contract data or the contract instance has been archived due to inactivity. Let's walk through the process of restoring archived data using the JavaScript SDK and Freighter wallet. -#### Prerequisites +#### Prerequisites {#prerequisites} - Stellar SDK: `npm install @stellar/stellar-sdk` - Freighter API: `npm install @stellar/freighter-api` - A Stellar RPC endpoint (e.g., `https://soroban-testnet.stellar.org`) -#### Step 1: Set up the SDK and Freighter +#### Step 1: Set up the SDK and Freighter {#step-1-set-up-the-sdk-and-freighter} First, import the necessary components: @@ -154,7 +154,7 @@ const networkPassphrase = StellarSdk.Networks.TESTNET; // Use PUBLIC for product This setup provides the foundation for interacting with the Stellar network and Freighter wallet. -#### Step 2: Create a helper function for restoration +#### Step 2: Create a helper function for restoration {#step-2-create-a-helper-function-for-restoration} Let's create a helper function that attempts to submit a transaction, and if it fails due to archived data, it will restore the data and retry: @@ -237,7 +237,7 @@ async function submitOrRestoreAndRetry(contractId, method, ...args) { This function now uses Freighter for signing transactions. It first checks if Freighter is connected and authorized, then proceeds with the transaction. If restoration is needed (indicated by a `HostStorageError`), it creates a separate restoration transaction, signs it with Freighter, and submits it before retrying the original transaction. -#### Step 3: Use the helper function in your dapp +#### Step 3: Use the helper function in your dapp {#step-3-use-the-helper-function-in-your-dapp} You can now use this function to make contract calls that automatically handle restoration: @@ -254,7 +254,7 @@ async function performContractAction(contractId, method, ...args) { } ``` -#### Step 4: Handling contract instance restoration +#### Step 4: Handling contract instance restoration {#step-4-handling-contract-instance-restoration} For restoring an entire contract instance, you might need a separate function: @@ -336,12 +336,12 @@ This function specifically restores a contract instance and its associated Wasm ::: -## When to use these functions +## When to use these functions {#when-to-use-these-functions} 1. [`performContractAction`](#step-3-use-the-helper-function-in-your-dapp) helper can be used when trying to invoke a smart contract function. It can help to restore persistent data associated with the call. 2. [`restoreContractInstance`](#step-4-handling-contract-instance-restoration) helper can be used during app initialization after the app has not been used for a long time. Using an indexer to get this info (when last app was used) is a great approach. -## Conclusion +## Conclusion {#conclusion} By implementing these state archival and restoration techniques, your dapp will be able to handle situations where contract data or instances have been archived, ensuring a smoother user experience even after periods of inactivity. The use of wallets like Freighter for transaction signing provides a secure and user-friendly way for users to interact with your dapp. diff --git a/docs/build/guides/dapps/working-with-contract-specs.mdx b/docs/build/guides/dapps/working-with-contract-specs.mdx index c285613c1..ee764476e 100644 --- a/docs/build/guides/dapps/working-with-contract-specs.mdx +++ b/docs/build/guides/dapps/working-with-contract-specs.mdx @@ -5,7 +5,7 @@ description: A guide to understanding and interacting with Soroban smart contrac import { CodeExample } from "@site/src/components/CodeExample"; -## Introduction +## Introduction {#introduction} Soroban smart contracts are powerful tools for building decentralized applications on the Stellar network. To interact with these contracts effectively, it's crucial to understand their specifications and how to use them in your programming language of choice. @@ -17,7 +17,7 @@ A typical contract specification (spec) includes: These details guide how you interact with the contract, regardless of the programming language you're using. -## Prerequisites +## Prerequisites {#prerequisites} Before diving into contract interactions, ensure you have the following: @@ -27,13 +27,13 @@ Before diving into contract interactions, ensure you have the following: For this guide, we will focus on the [Java](/docs/tools/sdks/library#java-sdk), [Python](/docs/tools/sdks/library#python-sdk), and [PHP](/docs/tools/sdks/library#php-sdk) SDKs for reference, but the concepts can also be applied to other languages. -## What are contract specs? +## What are contract specs? {#what-are-contract-specs} A contract spec is just like an ABI (Application Binary Interface) in Ethereum. It is a standardized description of a smart contract's interface, typically in JSON format. It defines the contract's functions, data structures, events, and errors in a way that external applications can understand and use. This specification serves as a crucial bridge between the smart contract and client applications, enabling them to interact without needing to know the contract's internal implementation details. -## Generating contract specs +## Generating contract specs {#generating-contract-specs} The Stellar CLI provides a command to generate a contract spec from a contract's source code. This process is easy but requires you to have the Wasm binary of the contract. @@ -41,19 +41,19 @@ Sometimes, you may not have access to the contract's source code or the ability Finally, we use the [`stellar bindings`](../../../tools/developer-tools/cli/stellar-cli.mdx#stellar-contract-bindings-json) command to generate the contract spec from the Wasm binary. -### Fetching the contract binary +### Fetching the contract binary {#fetching-the-contract-binary} ```bash stellar contract fetch --network-passphrase 'Test SDF Network ; September 2015' --rpc-url https://soroban-testnet.stellar.org --id CONTRACT_ID --out-file contract.wasm ``` -### Generating the contract spec from Wasm +### Generating the contract spec from Wasm {#generating-the-contract-spec-from-wasm} ```bash stellar contract bindings json --wasm contract.wasm > abi.json ``` -## Understanding the contract specification +## Understanding the contract specification {#understanding-the-contract-specification} The ABI (Application Binary Interface) specification for Stellar smart contracts includes several key components that define how to interact with the contract. Let's examine these in detail with examples: @@ -204,7 +204,7 @@ These specifications are crucial for encoding and decoding data when interacting - If a function returns a `ClaimableBalance`, you would expect to receive a struct with an amount (i128), a vector of addresses (claimants), a TimeBound object, and an address (token). - If a function could return an `Error`, it will most likely fail at simulation and you won't need to decode the result. -## Soroban types +## Soroban types {#soroban-types} Before we dive into interacting with Stellar smart contracts, it is important to note that Soroban has its own set of types that are used to interact with the contracts as described in [this guide](../../../learn/encyclopedia/contract-development/types/built-in-types.mdx). Here are some of the common types: @@ -225,7 +225,7 @@ In this guide and the SDKs, these types are represented as `ScU32`, `ScU64`, `Sc Every other complex type can be derived using these basic types but these types do not really map to values in the programming languages. The Stellar SDKs provide helper classes to work with these types. -## Working with native Soroban types +## Working with native Soroban types {#working-with-native-soroban-types} One of the most common tasks when working with Stellar smart contracts is converting between Stellar smart contract types and native types in your programming language. In this guide, we will go over some common conversions and show how they can be used to invoke contracts with the help of the contract spec. @@ -237,7 +237,7 @@ The JSON code block shows the contract spec, while RUST code blocks show the con ::: -### 1. Invoking a contract function with no parameters +### 1. Invoking a contract function with no parameters {#1-invoking-a-contract-function-with-no-parameters} We will be using the `increment` function of the sample [increment contract](https://github.com/stellar/soroban-examples/tree/main/increment) to exemplify this. The `increment` function takes no parameters and increments the counter by 1. @@ -414,7 +414,7 @@ Subsequent examples will show code blocks for using the contract spec only to re ::: -### 2. Invoking a contract function with one or more parameters +### 2. Invoking a contract function with one or more parameters {#2-invoking-a-contract-function-with-one-or-more-parameters} Generally, this involves passing in a native `array` (not a `ScVec`) of parameters to the contract function. @@ -504,7 +504,7 @@ $transaction = (new TransactionBuilder($accountA)) -### 3. Getting responses from contracts +### 3. Getting responses from contracts {#3-getting-responses-from-contracts} Data returned from contracts is also in `ScVal` format and need to be converted to native types in your programming language. @@ -651,7 +651,7 @@ class Test { -## Working with complex data types +## Working with complex data types {#working-with-complex-data-types} As described in [this guide](../../../learn/encyclopedia/contract-development/types/custom-types.mdx), there are some other variants of data structure supported by Soroban. They are @@ -662,7 +662,7 @@ As described in [this guide](../../../learn/encyclopedia/contract-development/ty We would be looking at how these variants translate to the spec and how to construct them in the different SDKs. -### Struct with named fields +### Struct with named fields {#struct-with-named-fields} Structs with named values when converted to ABI or spec are represented as a `ScMap` where each value has the key in `ScSymbol` and the value in the underlying type. @@ -738,7 +738,7 @@ XdrSCVal::forMap( -### Struct with unnamed fields +### Struct with unnamed fields {#struct-with-unnamed-fields} Structs with unnamed values when converted to ABI or spec are represented as a `ScVal` where each value has the underlying type. @@ -809,7 +809,7 @@ XdrSCVal::forVec( -### Enum (unit and tuple variants) +### Enum (unit and tuple variants) {#enum-unit-and-tuple-variants} Enums are generally represented with `ScVec`, their unit types are represented as `ScSymbol` and their tuple variants are represented as the underlying types. @@ -895,7 +895,7 @@ XdrSCVal::forVec( -### Enum (integer variants) +### Enum (integer variants) {#enum-integer-variants} Enums are generally represented with `ScVec`, the integer variant has no keys so it's just a `ScVec` of the underlying type. @@ -968,7 +968,7 @@ XdrSCVal::forVec( -### A complex example +### A complex example {#a-complex-example} Let's use the [timelock contract](https://github.com/stellar/soroban-examples/blob/main/timelock/src/lib.rs) example to show how to interact with a contract that has complex data types. @@ -1142,7 +1142,7 @@ tx = ( -## Reading contract events +## Reading contract events {#reading-contract-events} Reading contract events is similar to reading transaction results. You can use the [`getEvents`](../../../data/rpc/api-reference/methods/getEvents.mdx) RPC method to get the list of events associated with a contract. @@ -1251,7 +1251,7 @@ curl -X POST \ -## Wrapping Up +## Wrapping Up {#wrapping-up} As we've seen, working with Soroban smart contracts across different programming languages isn't rocket science, but it does require some careful attention to detail. The key takeaways: diff --git a/docs/build/guides/events/consume.mdx b/docs/build/guides/events/consume.mdx index d011b3c51..d214fe65b 100644 --- a/docs/build/guides/events/consume.mdx +++ b/docs/build/guides/events/consume.mdx @@ -7,7 +7,7 @@ Once events have been ingested into a database, for instance as done in the [ing Let's get started! -## First, get some events in a DB +## First, get some events in a DB {#first-get-some-events-in-a-db} Continuing right where we left in the [ingest guide], we will use the ORM models to add a few more events. @@ -85,7 +85,7 @@ Here, we are storing XDR encoded values. We could have instead decided to store ::: -## Consuming events +## Consuming events {#consuming-events} Using the same model we used to ingest events into the database, we can query the database to iterate over all events present in the table. @@ -138,7 +138,7 @@ INFO sqlalchemy.engine.Engine [...] (1,) INFO sqlalchemy.engine.Engine ROLLBACK ``` -## Streaming events +## Streaming events {#streaming-events} Depending on our application, we might want to consume events periodically by calling the database to see if there is anything new. Or fetch data as needed by our application. There is another possibility: event listeners! @@ -184,11 +184,11 @@ INFO sqlalchemy.engine.Engine COMMIT Congratulations, you are ready to consume events from Stellar RPC! -## Going further +## Going further {#going-further} Using the techniques we just presented would probably be enough for a lot of use cases. Still, for the readers wanting to go further there are a few things to look into. -### Asynchronous programming +### Asynchronous programming {#asynchronous-programming} So far, we have used SQLAlchemy in a synchronous way. If we were to have an endpoint in the backend calling the database, this endpoint would block during the database call. SQLAlchemy supports asynchronous programming with `async` and `await` keywords. @@ -196,7 +196,7 @@ As a general thought, it's simpler to start with a synchronous logic and then mo SQLAlchemy allows you to simply change from a synchronous session to an asynchronous one without having to change your models nor queries making it a very easy task to use one or the other. -### Idempotency considerations +### Idempotency considerations {#idempotency-considerations} Depending on your application, you might want to look into the concept of idempotency. Or simply put: guarantee that an event is consumed only once. diff --git a/docs/build/guides/events/ingest.mdx b/docs/build/guides/events/ingest.mdx index f112a4072..2ee85d1d5 100644 --- a/docs/build/guides/events/ingest.mdx +++ b/docs/build/guides/events/ingest.mdx @@ -12,7 +12,7 @@ There are many strategies you can use to ingest and keep the events published by Another approach we'll explore here is using a cron job to query Stellar RPC periodically and store the relevant events in a locally stored SQLite database. We are going to use an Object Relational Mapper (ORM), allowing us to write database query directly in Python or JavaScript. -## Setup +## Setup {#setup} @@ -28,7 +28,7 @@ pip install sqlalchemy stellar-sdk -## Setup the Database Client +## Setup the Database Client {#setup-the-database-client} @@ -125,7 +125,7 @@ Using a database model is very convenient as it allows us to control the databas We'll use this model to create and query for the events stored in our database. -## Query Events from Stellar RPC +## Query Events from Stellar RPC {#query-events-from-stellar-rpc} First, we'll need to query the events from Stellar RPC. This simple example makes an RPC request using the `getEvents` method, filtering for all `transfer` events that are emitted by the native XLM contract. @@ -215,7 +215,7 @@ let events = await server.getEvents({ -## Store Events in the Database +## Store Events in the Database {#store-events-in-the-database} Now, we'll check if the `events` object contains any new events we should store, and we do exactly that. We're storing the event's topics and values as base64-encoded strings here, but you could decode the necessary topics and values into the appropriate data types for your use-case. @@ -283,7 +283,7 @@ if (events.events?.length) { -## Run the Script with Cron +## Run the Script with Cron {#run-the-script-with-cron} A cron entry is an excellent way to automate this script to gather and ingest events every so often. You could configure this script to run as (in)frequently as you want or need. This example would run the script every 24 hours at 1:14 pm: diff --git a/docs/build/guides/fees/analyzing-smart-contract-cost.mdx b/docs/build/guides/fees/analyzing-smart-contract-cost.mdx index cd88515af..dc20a7157 100644 --- a/docs/build/guides/fees/analyzing-smart-contract-cost.mdx +++ b/docs/build/guides/fees/analyzing-smart-contract-cost.mdx @@ -6,15 +6,15 @@ description: Create efficient and cost-effective contracts Several factors influence how quickly and efficiently your smart contracts execute on the Stellar network. This guide will help you understand these factors and provide tips on how to write cost-effective contracts. -## How to optimize smart contract cost: +## How to optimize smart contract cost: {#how-to-optimize-smart-contract-cost} Complex contracts with numerous conditions, loops, and computations require more processing power on Stellar. This can lead to higher gas costs (transaction fees) and slower execution times. -### 1. Efficient loop and storage calls usage +### 1. Efficient loop and storage calls usage {#1-efficient-loop-and-storage-calls-usage} A contract that requires multiple loops and conditions to execute will cost more than a simple contract that executes a single operation. -#### Not Optimal Contract ❎ +#### Not Optimal Contract ❎ {#not-optimal-contract-} ```rust #![no_std] @@ -44,7 +44,7 @@ impl ExampleContract { ::: -#### Optimal Contract ✅ +#### Optimal Contract ✅ {#optimal-contract-} ```rust #![no_std] @@ -75,11 +75,11 @@ In this optimized approach, we'll accumulate the changes outside the loop and pe ::: -### 2. Proper use of batch operations +### 2. Proper use of batch operations {#2-proper-use-of-batch-operations} From the first example, we can see that batch operations are more efficient than individual operations. This is because batch operations reduce the number of external calls to the blockchain, which can be costly. However, there are some scenarios where the use of batch operations can be further optimized. Examples are shown below. -#### Not Optimal Contract ❎ +#### Not Optimal Contract ❎ {#not-optimal-contract--1} ```rust #![no_std] @@ -114,7 +114,7 @@ This function performs individual transfers for each recipient. While straightfo ::: -#### Optimal Contract ✅ +#### Optimal Contract ✅ {#optimal-contract--1} ```rust #![no_std] @@ -159,11 +159,11 @@ Internal distributions are cheaper due to the reduction in the number of costly ::: -### 3. Use of events over storage +### 3. Use of events over storage {#3-use-of-events-over-storage} Events are a cost-effective way to store data that doesn't need to be accessed frequently. Events are cheaper than storage operations and can be used to store data that doesn't need to be accessed frequently. -#### Default Contract +#### Default Contract {#default-contract} ```rust #![no_std] @@ -203,7 +203,7 @@ We cannot store everything in storage like we would do in a traditional database ::: -#### Optimized Using Events +#### Optimized Using Events {#optimized-using-events} ```rust #![no_std] @@ -236,7 +236,7 @@ In this optimized approach, we use events to store data that doesn't need to be ::: -#### Trade-offs: +#### Trade-offs: {#trade-offs} The current approach using events is indeed optimized for gas efficiency, but it comes with its own set of trade-offs. Let's see different approaches and their implications: @@ -269,17 +269,17 @@ This approach offers a balance between accessibility and efficiency. - Slightly higher gas cost than using only events - Temporary storage is cleared after each transaction, so historical data is not permanently accessible on-chain -### 4. Use of efficient data structures +### 4. Use of efficient data structures {#4-use-of-efficient-data-structures} Heap allocated arrays are slow and costly. Prefer fixed-sized arrays or `soroban_sdk::vec!`. This is crucial for large arrays, as exceeding the current linear memory size (a multiple of 64KB) triggers `wasm32::memory_grow`, which is highly computationally intensive. -##### Example (Heap Allocated Array) ❎ +##### Example (Heap Allocated Array) ❎ {#example-heap-allocated-array-} ```rust let mut v1 = alloc::vec![]; ``` -##### Example (Fixed-Sized Array) ✅ +##### Example (Fixed-Sized Array) ✅ {#example-fixed-sized-array-} ```rust let mut v2 = [0; 100]; @@ -287,7 +287,7 @@ let mut v2 = [0; 100]; Storing many items in a `Vec` can be inefficient due to the linear time complexity of membership checks. However, there are some alternatives to having a cumbersome `Vec`: -##### Example (Inefficient Data Storage) ❎ +##### Example (Inefficient Data Storage) ❎ {#example-inefficient-data-storage-} ```rust #![no_std] @@ -380,7 +380,7 @@ impl NonOptimalGameContract { ::: -##### Alternative: using keyed vecs ✅ +##### Alternative: using keyed vecs ✅ {#alternative-using-keyed-vecs-} ```rust #![no_std] @@ -459,64 +459,64 @@ Here's a breakdown of the optimizations and benefits: ::: -### 5. Use of appropriate `env.storage` mechanisms +### 5. Use of appropriate `env.storage` mechanisms {#5-use-of-appropriate-envstorage-mechanisms} There are three types of storage mechanisms in Stellar: -#### [`env.storage().persistent()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.persistent) +#### [`env.storage().persistent()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.persistent) {#envstoragepersistent} Persistent storage is used to store data that needs to be retained across contract invocations. Data stored in persistent storage is maintained between contract invocations and is accessible to all contract functions. Storage for data here is intended to stay in the ledger indefinitely until explicitly deleted. Expired entries can be restored but cannot be recreated. -#### Use cases +#### Use cases {#use-cases} - Data requiring long-term persistence, such as token balances and user properties. - When data needs to be stored indefinitely and must survive even if it expires and needs restoration. - Examples: Token balances, user properties. -#### Cost +#### Cost {#cost} - Highest cost compared to others due to long-term persistence. -#### Lifetime +#### Lifetime {#lifetime} - Data behaves as if it were stored forever but can expire and be restored. -### [`env.storage().temporary()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.temporary) +### [`env.storage().temporary()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.temporary) {#envstoragetemporary} Temporary storage is used to store data that is only needed during the current contract invocation. Data stored in temporary storage is cleared at the end of the contract invocation and is not accessible to other contract functions. Storage for data here is done with a limited lifespan in the ledger. Entries will be removed after their lifetime ends and can be recreated with different values. -#### Use cases +#### Use cases {#use-cases-1} - Data that only needs to exist temporarily, such as oracle data, claimable balances, and offers. - When data only needs to exist for a limited time and can be recreated if needed. - Examples: Oracle data, claimable balances, offers. -#### Cost +#### Cost {#cost-1} - Cheaper than persistent storage due to the limited lifespan of data. (Cheapest cost). -#### Lifetime +#### Lifetime {#lifetime-1} - Data exists for a predefined period and is then removed. -### [`env.storage().instance()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.instance) +### [`env.storage().instance()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.instance) {#envstorageinstance} Storage here is done for a small amount of persistent data tightly coupled with the contract instance. Data is loaded from the ledger every time the contract instance is loaded and it is limited by the ledger entry size, typically in the order of 100 KB serialized. -#### Use cases +#### Use cases {#use-cases-2} - Small data directly associated with the contract, such as admin details, configuration settings, and tokens. For small, frequently used data that is integral to the contract instance and benefits from being loaded every time the contract is used. - Examples: Contract admin details, configuration settings, tokens operated by the contract. -#### Cost +#### Cost {#cost-2} - Likely cheaper than storing data separately in persistent storage. -#### Lifetime +#### Lifetime {#lifetime-2} - Similar lifetime properties to persistent storage but does not appear in the ledger footprint. -### 5. Contract size +### 5. Contract size {#5-contract-size} The size of your smart contract's `wasm` binary influences the cost of running your smart contract on the Stellar network. Larger `wasm` binaries require more processing power and memory to execute, leading to higher gas costs. Larger binaries also cost more gas to deploy and invoke. @@ -526,9 +526,9 @@ To optimize the size of your `wasm` binary, you can: - Minimize the use of external dependencies - Use built-in tools to optimize the size of your `wasm` binary -## Other tips to optimize smart contract cost: +## Other tips to optimize smart contract cost: {#other-tips-to-optimize-smart-contract-cost} -### 1. Use of built-in tools +### 1. Use of built-in tools {#1-use-of-built-in-tools} One way to optimize the size of your `wasm` binary is to use the `soroban optimize` command. This command comes from the [Soroban CLI](https://www.google.com) will optimize the size of your `wasm` binary by removing unnecessary code and reducing the size of the binary. @@ -552,24 +552,24 @@ stellar contract invoke \ Reference: https://sorobandev.com/guides/soroban-cli -### 2. Manual code review +### 2. Manual code review {#2-manual-code-review} Perform a manual code review of your smart contract to identify areas where you can optimize the code. Look for redundant loops, conditions, and storage operations that can be minimized or removed. -### 3. Unit testing with gas measurements +### 3. Unit testing with gas measurements {#3-unit-testing-with-gas-measurements} Use unit tests to measure the gas cost of your smart contract functions. This will help you identify functions that are consuming a lot of gas and optimize them accordingly. Also, using [simulateTransaction](/docs/data/rpc/api-reference/methods/simulateTransaction) rpc helper method can give you an insight of the gas cost of your contract functions. -### 4. Static analysis tools +### 4. Static analysis tools {#4-static-analysis-tools} Tools like [Clippy](https://doc.rust-lang.org/clippy/) (part of the Rust compiler) can identify potential performance issues during the compilation stage. These tools can warn about: - Unnecessary allocations - Redundant code -### 5. Reconsidering storage locations +### 5. Reconsidering storage locations {#5-reconsidering-storage-locations} - #### State Variables: diff --git a/docs/build/guides/freighter/integrate-freighter-react.mdx b/docs/build/guides/freighter/integrate-freighter-react.mdx index 5d0c1cd09..ce6ab0879 100644 --- a/docs/build/guides/freighter/integrate-freighter-react.mdx +++ b/docs/build/guides/freighter/integrate-freighter-react.mdx @@ -5,7 +5,7 @@ description: Integrate the Freighter wallet into your React dapps Wallets are an essential part of any dapp. They allow users to interact with the blockchain and sign transactions. In this section, you'll learn how to integrate the Freighter wallet into your React dapps. -### WalletData Component +### WalletData Component {#walletdata-component} In the [example crowdfund dapp](https://github.com/stellar/soroban-example-dapp), the `WalletData` component plays a key role in wallet integration. Let's break down the code and understand its functionality: diff --git a/docs/build/guides/storage/choosing-the-right-storage.mdx b/docs/build/guides/storage/choosing-the-right-storage.mdx index 9ffcac1b3..3b90fac6c 100644 --- a/docs/build/guides/storage/choosing-the-right-storage.mdx +++ b/docs/build/guides/storage/choosing-the-right-storage.mdx @@ -4,7 +4,7 @@ hide_table_of_contents: true description: This guide walks you through choosing the most suitable storage type for your use case and how to implement it --- -## Storage types +## Storage types {#storage-types} Smart contracts can persist data in the Stellar ledger using the storage interface (`env.storage()` in Soroban SDK). There are three types of storage available on the Stellar network: @@ -20,7 +20,7 @@ Every storage 'map' is completely independent from every other storage 'map'. It All the storage types have almost exactly the same functionality, besides the differences highlighted in the table above, specifically cost, behavior when TTL expires, and limit for the number of keys stored per contract. -### A note on TTL +### A note on TTL {#a-note-on-ttl} If you're wondering what 'TTL' means, here is a quick intro on TTLs and state archival in Stellar. @@ -30,7 +30,7 @@ TTL also may be extended however many times is necessary, for a fee. Read more about state archival [here](../../../learn/encyclopedia/storage/state-archival.mdx). -## Persistent storage +## Persistent storage {#persistent-storage} This storage type is used for storing data on the network over an indefinitely long time period. @@ -82,7 +82,7 @@ impl LoyaltyPointsContract { } ``` -## Instance storage +## Instance storage {#instance-storage} Instance storage is a small, limited-size map attached to the contract instance. It is physically stored in the same ledger entry as the contract itself and shares TTL with it. @@ -127,7 +127,7 @@ impl LoyaltyPointsContract { } ``` -## Temporary storage +## Temporary storage {#temporary-storage} As the name implies, temporary storage stores data only for a certain time period, and then discards it automatically when TTL expires. **Temporary entries are gone forever when their TTL expires**. diff --git a/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx b/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx index f595ae9dd..a8aa6c2e0 100644 --- a/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx +++ b/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx @@ -8,13 +8,13 @@ Tests are written to ensure that contracts behave today as expected, and in the However tests are limited, as they only show changes to values that the tests assert on. -## Test Snapshots +## Test Snapshots {#test-snapshots} The Soroban Rust SDK generates test snapshots on every test involving an `Env`. Test snapshots are enabled by default. At the end of the test the `Env` writes a JSON file to the `test_snapshots` directory with a full snapshot of all the events published, logged, and the final ledger storage state. Most tests have a single `Env` and will result in a single test snapshot. Tests that have multiple `Env`s will write multiple test snapshots, one for each `Env`. Test snapshot files are named with a incrementing number on the end to separate the test snapshots for each `Env`. -### How to Use Test Snapshots +### How to Use Test Snapshots {#how-to-use-test-snapshots} 1. Write tests using the default `Env`. For example: diff --git a/docs/build/guides/tokens/deploying-a-sac.mdx b/docs/build/guides/tokens/deploying-a-sac.mdx index feb15e9e2..b8adb7cb2 100644 --- a/docs/build/guides/tokens/deploying-a-sac.mdx +++ b/docs/build/guides/tokens/deploying-a-sac.mdx @@ -19,11 +19,11 @@ description: Deploy a SAC from another smart contract using the Rust SDK /> -## Overview +## Overview {#overview} In this guide, you'll learn how to deploy a [Stellar Asset Contract (SAC)](../../../tokens/stellar-asset-contract.mdx) from within another smart contract using the Soroban Rust SDK. The Soroban Rust SDK provides tools and utilities for working with Stellar smart contracts, allowing you to deploy and interact with SACs directly from your contract logic. -## Prerequisites: +## Prerequisites: {#prerequisites} Before you begin, make sure you have the following: @@ -31,7 +31,7 @@ Before you begin, make sure you have the following: - [Soroban Rust SDK](../../../tools/sdks/library.mdx#soroban-rust-sdk) installed and configured in your development environment. - Basic understanding of the Soroban Rust SDK and familiarity with Soroban's core concepts and Rust programming. -## 1. Define the SacDeployer contract +## 1. Define the SacDeployer contract {#1-define-the-sacdeployer-contract} The SacDeployer contract will be responsible for deploying the Stellar Asset Contract. Here is the code for the SacDeployer contract: @@ -55,14 +55,14 @@ impl SacDeployer { } ``` -### Explanation +### Explanation {#explanation} - `SacDeployer` contract: this contract defines the `deploy_sac` function to handle the deployment of the SAC. - `deploy_sac` function: - `env.deployer().with_stellar_asset(serialized_asset)`: creates a deployer configured to deploy a Stellar Asset Contract using the provided serialized asset. - `deployer.deploy()`: Deploys the SAC and returns the address of the deployed contract. -## 2. Testing the deployment +## 2. Testing the deployment {#2-testing-the-deployment} You need to test the deployment to ensure everything works as expected. The following code demonstrates how to test the SacDeployer contract using the Soroban Rust SDK's test utilities. @@ -77,7 +77,7 @@ fn main() { } ``` -### Explanation +### Explanation {#explanation-1} - `TestEnv::default()`: creates a default testing environment for the deployment. - `SacDeployer::default()`: initializes the SacDeployer contract. @@ -86,7 +86,7 @@ fn main() { - `assert!(sac_address.to_string().len() > 0, "SAC address should be non-empty")`: asserts that the SAC address is non-empty, ensuring a successful deployment. - `serialized_asset`is the Stellar `Asset` XDR serialized to bytes. Refer to `[soroban_sdk::xdr::Asset]` [XDR](https://docs.rs/stellar-xdr/latest/stellar_xdr/curr/enum.Asset.html) -### Conclusion +### Conclusion {#conclusion} By following this guide, you’ve successfully deployed a Stellar Asset Contract from within another contract using the Soroban Rust SDK. This approach enables smart contracts to handle SAC deployments dynamically, providing flexibility for various use cases in the Stellar ecosystem. diff --git a/docs/build/guides/tokens/stellar-asset-contract.mdx b/docs/build/guides/tokens/stellar-asset-contract.mdx index 65b5a07e2..a05956d2c 100644 --- a/docs/build/guides/tokens/stellar-asset-contract.mdx +++ b/docs/build/guides/tokens/stellar-asset-contract.mdx @@ -6,7 +6,7 @@ description: Test and use Stellar assets in a Stellar smart contract When interacting with assets in a smart contract, the [Stellar Asset Contract](../../../tokens/stellar-asset-contract.mdx) is not different from any other token that implements the Stellar [SEP-41 Token Interface]. -## Contract Code +## Contract Code {#contract-code} The Rust SDK contains a pre-generated client for any contract that implements the token interface: @@ -55,7 +55,7 @@ client.mint(...); ::: -## Testing +## Testing {#testing} Soroban Rust SDK provides an easy way to instantiate a Stellar Asset Contract tokens using `register_stellar_asset_contract_v2`. This function can be seen as the deployment of a generic token. It also allows you to manipulate flags on the issuer account like `AUTH_REVOCABLE` and `AUTH_REQUIRED`. In the following example, we are following the best practices outlined in the [Issuing and Distribution Accounts section](../../../tokens/control-asset-access.mdx#issuing-and-distribution-accounts): @@ -97,7 +97,7 @@ fn test() { } ``` -## Examples +## Examples {#examples} See the full examples that utilize the token contract in various ways for more details: diff --git a/docs/build/guides/transactions/install-deploy-contract-with-code.mdx b/docs/build/guides/transactions/install-deploy-contract-with-code.mdx index 06847aed6..8a452d645 100644 --- a/docs/build/guides/transactions/install-deploy-contract-with-code.mdx +++ b/docs/build/guides/transactions/install-deploy-contract-with-code.mdx @@ -18,7 +18,7 @@ description: Install and deploy a smart contract with code This guide will walk you through the process of installing and deploying a smart contract using [js-stellar-sdk](https://github.com/stellar/js-stellar-sdk). We will cover the setup of a sample Rust contract, creating a Node.js project to manage the deployment, and finally, installing the Wasm of the contract and deploying it to the network -## Prerequisites +## Prerequisites {#prerequisites} Before you begin, ensure you have the following installed: @@ -26,7 +26,7 @@ Before you begin, ensure you have the following installed: 2. [Node.js](https://nodejs.org/en) and npm (for running JavaScript deployment scripts) 3. [Soroban CLI](../../smart-contracts/getting-started/setup.mdx#install-the-stellar-cli) -## Initialize a sample Rust Contract +## Initialize a sample Rust Contract {#initialize-a-sample-rust-contract} ```bash soroban contract init hello-world @@ -36,7 +36,7 @@ soroban contract build This sequence of commands creates a new directory for your project, initializes a new Soroban smart contract within that directory, and builds the contract. The build generates .wasm file in the path `hello-word/target/wasm32-unknown-unknown/release/hello_world.wasm` -## Create a Node Project +## Create a Node Project {#create-a-node-project} 1. Create a new directory for your Node.js project and navigate into it: @@ -52,9 +52,9 @@ npm init -y npm install @stellar/stellar-sdk fs ``` -## Set Up Deployment Scripts +## Set Up Deployment Scripts {#set-up-deployment-scripts} -### Imports +### Imports {#imports} Import necessary modules in your JavaScript file: @@ -63,7 +63,7 @@ import * as StellarSDK from "@stellar/stellar-sdk"; import fs from "fs"; ``` -### Installing the Wasm on the network +### Installing the Wasm on the network {#installing-the-wasm-on-the-network} Create a function to upload the compiled Wasm file: @@ -78,7 +78,7 @@ async function uploadWasm(filePath) { This function reads the compiled Wasm file, retrieves account details from the network, and installs the bytecode using `uploadContractWasm` Stellar operation, which when wrapped in a transaction is sent to the network. -### Deploy contract +### Deploy contract {#deploy-contract} Deploy the contract by referencing the Wasm hash: @@ -102,7 +102,7 @@ async function deployContract(response) { This function uses the Wasm hash to deploy the contract using the `createCustomContract` stellar operation, which when wrapped in a transaction is sent to the network, generating a contract address. -### Building, Signing and Sending the Transaction +### Building, Signing and Sending the Transaction {#building-signing-and-sending-the-transaction} Handle the building, signing, and sending of transactions: @@ -145,7 +145,7 @@ async function buildAndSendTransaction(account, operations) { This function constructs a transaction, signs it, and submits it to the network, handling any necessary retries for transaction confirmation. -## Running the Script +## Running the Script {#running-the-script} Execute the deployment script: @@ -169,7 +169,7 @@ Replace "Your_Secret_Key" with your actual secret key. This script initiates the This is just demo code, so ensure that you handle secrets and private keys securely in production environments and never expose them in your code repositories. This guide should provide you with a clear path to installing and deploying your smart contracts using Javascript code. -## Complete Script +## Complete Script {#complete-script} Here are all the snippets stacked together in a single file for convenience: diff --git a/docs/build/guides/transactions/install-wasm-bytecode.mdx b/docs/build/guides/transactions/install-wasm-bytecode.mdx index 35f8d372a..4a33d4a71 100644 --- a/docs/build/guides/transactions/install-wasm-bytecode.mdx +++ b/docs/build/guides/transactions/install-wasm-bytecode.mdx @@ -23,14 +23,14 @@ import TabItem from "@theme/TabItem"; This process uploads the contract code to the Stellar Testnet in a transaction, the uploaded Wasm blob is a [contract source](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-02.md#contract-source), which can be thought of as a 'class' of a contract. Multiple [instances of a contract can be deployed](../conventions/deploy-contract.mdx) which share the same source, but have their own state. -## Prerequisites +## Prerequisites {#prerequisites} Before you begin, ensure you have the following installed to compile a smart contract: 1. [Rust](https://www.rust-lang.org/) and Cargo (for compiling smart contracts) 2. The [Stellar CLI](https://github.com/stellar/stellar-cli) -## Initialize and build a sample Rust contract +## Initialize and build a sample Rust contract {#initialize-and-build-a-sample-rust-contract} ```bash soroban contract init hello-world @@ -45,7 +45,7 @@ We are initializing the default `hello_world` contract in [soroban_examples](htt After building the contract for release, the generated .wasm file is at the path `hello-word/target/wasm32-unknown-unknown/release/hello_world.wasm` -## Upload Wasm to the Stellar blockchain +## Upload Wasm to the Stellar blockchain {#upload-wasm-to-the-stellar-blockchain} We can use one of the [SDKs](https://developers.stellar.org/docs/tools/sdks/library), install necessary dependencies for your chosen programming language: @@ -59,7 +59,7 @@ mkdir install-wasm cd install-wasm ``` -### Running the install script +### Running the install script {#running-the-install-script} Different programming languages can be used to upload the `.wasm` file, its SHA256 hash is used for deploying the contract. diff --git a/docs/build/guides/transactions/simulateTransaction-Deep-Dive.mdx b/docs/build/guides/transactions/simulateTransaction-Deep-Dive.mdx index 1a9972528..4906e78b6 100644 --- a/docs/build/guides/transactions/simulateTransaction-Deep-Dive.mdx +++ b/docs/build/guides/transactions/simulateTransaction-Deep-Dive.mdx @@ -3,7 +3,7 @@ title: simulateTransaction RPC method guide description: simulateTransaction examples and tutorials guide --- -## Overview +## Overview {#overview} The `simulateTransaction` endpoint in Stellar RPC allows you to submit a trial contract invocation to simulate how it would be executed by the Stellar network. This simulation calculates the effective transaction data, required authorizations, and minimal resource fee. It provides a way to test and analyze the potential outcomes of a transaction without actually submitting it to the network. It can be a nice way to get contract data as well sometimes. @@ -11,11 +11,11 @@ While calling the method on the rpc server is not the ONLY way to simulate a tra Here we will look at the objects involved and their definitions. -## RPC Services +## RPC Services {#rpc-services} Stellar Development Foundation provides a testnet RPC service at `http://soroban-testnet.stellar.org`. For public network providers please refer to the [Ecosystem RPC Providers](../../../data/rpc/rpc-providers.mdx) list. -### Testnet Endpoint: +### Testnet Endpoint: {#testnet-endpoint} https://soroban-testnet.stellar.org:443 @@ -32,7 +32,7 @@ interface SimulateTransactionParams { **SimulateTransactionResult** is the return result from the call. It includes [many useful things](https://developers.stellar.org/docs/data/rpc/api-reference/methods/simulateTransaction)! -## Things `simulateTransaction` is used for: +## Things `simulateTransaction` is used for: {#things-simulatetransaction-is-used-for} 1. **Preparing `invokeHostFunctionOp` Transactions**: Anytime you need to submit an `invokeHostFunctionOp` transaction to the network. 2. **Footprint Determination**: To determine the ledger footprint, which includes all the data entries the transaction will read or write. @@ -42,9 +42,9 @@ interface SimulateTransactionParams { 6. **Simulating Contract Getter Calls**: To retrieve certain data from the contract without affecting the ledger state. (It's worth noting you could also retrieve certain contract data direct from the ledgerkeys without simulation if it doesn't require any manipulation within the contract logic.) 7. **Resource Calculation**: To calculate the necessary resources (CPU instructions, memory, etc.) that a transaction will consume. -## How to Call `simulateTransaction` +## How to Call `simulateTransaction` {#how-to-call-simulatetransaction} -### Using Fetch +### Using Fetch {#using-fetch} Here's an example of how to call the `simulateTransaction` endpoint directly using `fetch` in JavaScript: @@ -82,7 +82,7 @@ const transactionXDR = simulateTransaction(transactionXDR); ``` -### Using the JavaScript SDK +### Using the JavaScript SDK {#using-the-javascript-sdk} The Stellar SDK provides a convenient method to simulate a transaction: @@ -146,7 +146,7 @@ RpcServer.simulateTransaction(transaction).then((sim) => { }); ``` -#### Running the example +#### Running the example {#running-the-example} To run the above code, you will need to install the Stellar SDK into your project. You can do this by running the following command in your project directory: @@ -156,7 +156,7 @@ Once your project is set up, you can create a new mjs file and paste the code ab `node .mjs` -## Understanding the Footprint +## Understanding the Footprint {#understanding-the-footprint} A footprint is a set of ledger keys that the transaction will read or write. These keys are marked as either read-only or read-write: @@ -165,11 +165,11 @@ A footprint is a set of ledger keys that the transaction will read or write. The The footprint ensures that a transaction is aware of all the ledger entries it will interact with, preventing unexpected errors during execution. -## Assembling a Transaction +## Assembling a Transaction {#assembling-a-transaction} Once you have simulated the transaction and obtained the necessary data, you can assemble the transaction for actual submission. The `assembleTransaction` function in the SDK helps with this process, but you can also call `prepareTransaction` to have it both simulate and assemble the transaction for you in one step. Using the javascript SDK we can call [`assembleTransaction`](https://stellar.github.io/js-stellar-sdk/global.html#assembleTransaction) to easily assemble a transaction. -## Handling Archived Ledger Entries +## Handling Archived Ledger Entries {#handling-archived-ledger-entries} When a ledger entry is archived, it needs to be restored before the transaction can be submitted. This is indicated in the `restorePreamble` field of the result. @@ -362,7 +362,7 @@ export async function handleRestoration( } ``` -## Fees and Resource Usage +## Fees and Resource Usage {#fees-and-resource-usage} Soroban smart contracts on Stellar use a multidimensional resource fee model, charging fees for several resource types: @@ -375,13 +375,13 @@ Soroban smart contracts on Stellar use a multidimensional resource fee model, ch Fees are calculated based on the resource consumption declared in the transaction. Refundable fees are charged before execution and refunded based on actual usage, while non-refundable fees are calculated from CPU instructions, read bytes, write bytes, and transaction size. [Check out this document for a more in depth understanding of fees and metering.](https://developers.stellar.org/docs/learn/fundamentals/fees-resource-limits-metering) -## Preflight Error Handling +## Preflight Error Handling {#preflight-error-handling} The preflight mechanism provides an estimation of CPU and memory consumption in a transaction. It helps identify potential errors and resource limitations before actual submission. Errors returned by the host are propagated through RPC and do not cover network errors or errors in RPC itself. [Common Preflight Errors, and more information can be found here.](https://developers.stellar.org/docs/learn/encyclopedia/errors-and-debugging/debugging-errors#1-preflight) -## Backend Code and Workflow +## Backend Code and Workflow {#backend-code-and-workflow} The `simulateTransaction` endpoint leverages various backend components to simulate the execution of a transaction. Here is a brief explanation of how it works: @@ -407,7 +407,7 @@ The `simulateTransaction` endpoint leverages various backend components to simul These functions are defined in the [`rs-soroban-env`](https://github.com/stellar/rs-soroban-env) and also in a [`soroban-simulation`](https://github.com/stellar/rs-soroban-env/tree/main/soroban-simulation) [crate](https://crates.io/crates/soroban-simulation) and handle the core logic for simulating transactions. -## Further Reading +## Further Reading {#further-reading} For more information and examples, check out the code and other documentation: diff --git a/docs/build/smart-contracts/example-contracts/TEMPLATE.mdx b/docs/build/smart-contracts/example-contracts/TEMPLATE.mdx index 55cda0312..7d561ff15 100644 --- a/docs/build/smart-contracts/example-contracts/TEMPLATE.mdx +++ b/docs/build/smart-contracts/example-contracts/TEMPLATE.mdx @@ -23,7 +23,7 @@ Place each link definition at the bottom of the section it first is used in. [example demonstrates]: https://github.com/stellar/soroban-examples/tree/v21.6.0/hello_world [other example]: ../getting-started/setup.mdx -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -49,7 +49,7 @@ test test::test ... ok [setup]: ../getting-started/setup.mdx -## Code +## Code {#code} ```rust title="hello_world/src/lib.rs" #![no_std] @@ -69,11 +69,11 @@ mod test; Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/hello_world -## How it Works +## How it Works {#how-it-works} This is the written part of each guide. You can call out each thing unique to this contract, sometimes referencing other important concepts from other example contracts, too. -### Major Concepts +### Major Concepts {#major-concepts} You could add sub-headings for highlighting even further important bits or concepts to know. The `events` example guide has the following `h3` headings: @@ -83,7 +83,7 @@ You could add sub-headings for highlighting even further important bits or conce Underneath each of those headings is a brief discussion of how that concept ties into the example contract code. -## Tests +## Tests {#tests} Open the `/hello_world/src/test.rs` file to follow along. @@ -129,7 +129,7 @@ All public functions within an `impl` block that is annotated with the `#[contra Then you can describe the intricacies of what your contract test does uniquely. -## Build the Contract +## Build the Contract {#build-the-contract} To build the contract, use the `cargo build` command. @@ -143,7 +143,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_hello_world_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract functions using it. @@ -179,6 +179,6 @@ stellar contract invoke ` [`stellar-cli`]: ../getting-started/setup.mdx#install-the-stellar-cli -## Further Reading +## Further Reading {#further-reading} If you have some further links to share or background knowledge you can link to, this is the place to share it. Or, maybe you want to point out how this example is similar or not when compared with other examples. diff --git a/docs/build/smart-contracts/example-contracts/alloc.mdx b/docs/build/smart-contracts/example-contracts/alloc.mdx index 3784a237e..d05d9527b 100644 --- a/docs/build/smart-contracts/example-contracts/alloc.mdx +++ b/docs/build/smart-contracts/example-contracts/alloc.mdx @@ -28,7 +28,7 @@ The [allocator example] demonstrates how to utilize the allocator feature when w The `soroban-sdk` crate provides a lightweight bump-pointer allocator which can be used to emulate heap memory allocation in a Wasm smart contract. -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -54,7 +54,7 @@ running 1 test test test::test ... ok ``` -## Dependencies +## Dependencies {#dependencies} This example depends on the `alloc` feature in `soroban-sdk`. To include it, add "alloc" to the "features" list of `soroban-sdk` in the `Cargo.toml` file: @@ -66,7 +66,7 @@ soroban-sdk = { version = "20.0.0", features = ["alloc"] } soroban-sdk = { version = "20.0.0", features = ["testutils", "alloc"] } ``` -## Code +## Code {#code} ```rust title="alloc/src/lib.rs" #![no_std] @@ -96,7 +96,7 @@ impl AllocContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/alloc -## How it Works +## How it Works {#how-it-works} ```rust extern crate alloc; diff --git a/docs/build/smart-contracts/example-contracts/atomic-swap.mdx b/docs/build/smart-contracts/example-contracts/atomic-swap.mdx index 78adef05a..462975e33 100644 --- a/docs/build/smart-contracts/example-contracts/atomic-swap.mdx +++ b/docs/build/smart-contracts/example-contracts/atomic-swap.mdx @@ -26,7 +26,7 @@ This is example demonstrates advanced usage of Soroban auth framework and assume [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v21.6.0 [atomic swap example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/atomic_swap -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -51,7 +51,7 @@ running 1 test test test::test_atomic_swap ... ok ``` -## Code +## Code {#code} ```rust title="atomic_swap/src/lib.rs" #[contract] @@ -125,13 +125,13 @@ fn move_token( Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/atomic_swap -## How it Works +## How it Works {#how-it-works} The example contract requires two `Address`-es to authorize their parts of the swap operation: one `Address` wants to sell a given amount of token A for token B at a given price and another `Address` wants to sell token B for token A at a given price. The contract swaps the tokens atomically, but only if the requested minimum price is respected for both parties. Open the `atomic_swap/src/lib.rs` file or see the code above to follow along. -### Swap authorization +### Swap authorization {#swap-authorization} ```rust ... @@ -146,7 +146,7 @@ b.require_auth_for_args( Authorization of `swap` function leverages `require_auth_for_args` Soroban host function. Both `a` and `b` need to authorize symmetric arguments: token they sell, token they buy, amount of token they sell, minimum amount of token they want to receive. This means that `a` and `b` can be freely exchanged in the invocation arguments (as long as the respective arguments are changed too). -### Moving the tokens +### Moving the tokens {#moving-the-tokens} ```rust ... @@ -182,7 +182,7 @@ fn move_token( The swap itself is implemented via two token moves: from `a` to `b` and from `b` to `a`. The token move is implemented via allowance: the users don't need to know each other in order to perform the swap, and instead they authorize the swap contract to spend the necessary amount of token on their behalf via `transfer`. Soroban auth framework makes sure that the `transfer` signatures would have the proper context, and they won't be usable outside the `swap` contract invocation. -### Tests +### Tests {#tests} Open the [`atomic_swap/src/test.rs`] file to follow along. diff --git a/docs/build/smart-contracts/example-contracts/auth.mdx b/docs/build/smart-contracts/example-contracts/auth.mdx index 4042b5e7a..082ed0834 100644 --- a/docs/build/smart-contracts/example-contracts/auth.mdx +++ b/docs/build/smart-contracts/example-contracts/auth.mdx @@ -31,7 +31,7 @@ This example is an extension of the [storing data example]. [storing data example]: ../getting-started/storing-data.mdx [auth example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/auth -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -57,7 +57,7 @@ running 1 test test test::test ... ok ``` -## Code +## Code {#code} ```rust title="auth/src/lib.rs" #[contracttype] @@ -112,13 +112,13 @@ impl IncrementContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/auth -## How it Works +## How it Works {#how-it-works} The example contract stores a per-`Address` counter that can only be incremented by the owner of that `Address`. Open the `auth/src/lib.rs` file or see the code above to follow along. -### `Address` +### `Address` {#address} ```rust #[contracttype] @@ -137,7 +137,7 @@ In the example the counter for each address is stored against `DataKey::Counter( ::: -### `require_auth` +### `require_auth` {#require_auth} ```rust impl IncrementContract { @@ -162,7 +162,7 @@ user.require_auth_for_args((&user, value).into_val(&env)); user.require_auth_for_args((value,).into_val(&env)); ``` -### Tests +### Tests {#tests} Open the [`auth/src/test.rs`] file to follow along. @@ -271,7 +271,7 @@ assert_eq!(client.increment(&user_1, &3), 10); assert_eq!(client.increment(&user_2, &4), 5); ``` -## Build the Contract +## Build the Contract {#build-the-contract} To build the contract into a `.wasm` file, use the `stellar contract build` command. @@ -285,7 +285,7 @@ The `.wasm` file should be found in the `target` directory after building: target/wasm32-unknown-unknown/release/soroban_auth_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke functions on the contract. @@ -476,7 +476,7 @@ Contract auth: [{"address_with_nonce":null,"root_invocation":{"contract_id":"000 [`stellar-cli`]: ../getting-started/setup.mdx#install-the-stellar-cli -## Further reading +## Further reading {#further-reading} [Authorization documentation](../../../learn/encyclopedia/security/authorization.mdx) provides more details on how Soroban auth framework works. diff --git a/docs/build/smart-contracts/example-contracts/cross-contract-call.mdx b/docs/build/smart-contracts/example-contracts/cross-contract-call.mdx index 81f274274..d2ad0d88c 100644 --- a/docs/build/smart-contracts/example-contracts/cross-contract-call.mdx +++ b/docs/build/smart-contracts/example-contracts/cross-contract-call.mdx @@ -34,7 +34,7 @@ In this example there are two contracts that are compiled separately, deployed s [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v21.6.0 [cross contract call example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/cross_contract -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -60,7 +60,7 @@ running 1 test test test::test ... ok ``` -## Code +## Code {#code} ```rust title="cross_contract/contract_a/src/lib.rs" #[contract] @@ -95,7 +95,7 @@ impl ContractB { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/cross_contract -## How it Works +## How it Works {#how-it-works} Cross contract calls are made by invoking another contract by its contract ID. @@ -112,7 +112,7 @@ The `contractimport!` macro will generate the types in the module it is used, so Open the files above to follow along. -### Contract A: The Contract to be Called +### Contract A: The Contract to be Called {#contract-a-the-contract-to-be-called} The contract to be called is Contract A. It is a simple contract that accepts `x` and `y` parameters, adds them together and returns the result. @@ -134,7 +134,7 @@ The contract uses the `checked_add` method to ensure that there is no overflow, ::: -### Contract B: The Contract doing the Calling +### Contract B: The Contract doing the Calling {#contract-b-the-contract-doing-the-calling} The contract that does the calling is Contract B. It accepts a contract ID that it will call, as well as the same parameters to pass through. In many contracts the contract to call might have been stored as contract data and be retrieved, but in this simple example it is being passed in as a parameter each time. @@ -163,7 +163,7 @@ impl ContractB { } ``` -### Tests +### Tests {#tests} Open the `cross_contract/contract_b/src/test.rs` file to follow along. @@ -223,7 +223,7 @@ The test asserts that the result that is returned is as we expect. assert_eq!(sum, 12); ``` -## Build the Contracts +## Build the Contracts {#build-the-contracts} To build the contract into a `.wasm` file, use the `stellar contract build` command. Both `contract_call/contract_a` and `contract_call/contract_b` must be built, with `contract_a` being built first. @@ -241,7 +241,7 @@ target/wasm32-unknown-unknown/release/soroban_cross_contract_a_contract.wasm target/wasm32-unknown-unknown/release/soroban_cross_contract_b_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract functions. Both contracts must be deployed. diff --git a/docs/build/smart-contracts/example-contracts/custom-account.mdx b/docs/build/smart-contracts/example-contracts/custom-account.mdx index a4aa2b7e5..e4a08d4bf 100644 --- a/docs/build/smart-contracts/example-contracts/custom-account.mdx +++ b/docs/build/smart-contracts/example-contracts/custom-account.mdx @@ -41,7 +41,7 @@ While custom accounts are supported by the Stellar protocol and Soroban SDK, the [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v21.6.0 [custom account example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/account -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -66,7 +66,7 @@ running 1 test test test::test_token_auth ... ok ``` -## How it Works +## How it Works {#how-it-works} Open the `account/src/lib.rs` file to follow along. @@ -76,7 +76,7 @@ This example contract uses ed25519 keys for signature verification and supports For example, the user may initialize this contract with 2 keys and introduce 100 USDC spend limit. This way they can use a single key to sign their contract invocations and be sure that even if they sign a malicious transaction they won't spend more than 100 USDC. -### Initialization +### Initialization {#initialization} ```rust #[contracttype] @@ -102,7 +102,7 @@ pub fn init(env: Env, signers: Vec>) { This account contract needs to work with the public keys explicitly. Here we initialize the contract with ed25519 keys. -### Policy modification +### Policy modification {#policy-modification} ```rust // Adds a limit on any token transfers that aren't signed by every signer. @@ -122,7 +122,7 @@ pub fn add_limit(env: Env, token: BytesN<32>, limit: i128) { This function allows users to set and modify the per-token spend limit described above. The neat trick here is that `require_auth` can be used for the `current_contract_address()`, i.e. the account contract may be used to verify authorization for its own administrative functions. This way there is no need to write duplicate authorization and authentication logic. -### `__check_auth` +### `__check_auth` {#\_\_check_auth} ```rust pub fn __check_auth( @@ -168,7 +168,7 @@ Here it is implemented in two steps. First, authentication is performed using th `__check_auth` is a reserved function and can only be called by the Soroban environment in response to a call to `require_auth`. Any direct call to `__check_auth` will fail. This makes it safe to write to the account contract storage from `__check_auth`, as it's guaranteed to not be called in unexpected context. In this example it's possible to persist the spend limits without worrying that they'll be exhausted via a bad actor calling `__check_auth` directly. -### Authentication +### Authentication {#authentication} ```rust fn authenticate( @@ -203,7 +203,7 @@ fn authenticate( Authentication here simply checks that the provided signatures are valid given the payload and also that they belong to the signers of this account contract. -### Authorization policy +### Authorization policy {#authorization-policy} ```rust fn verify_authorization_policy( @@ -274,7 +274,7 @@ Ok(()) Then we check for the standard token function names and verify that for these function we don't exceed the spending limits. -### Tests +### Tests {#tests} Open the [`account/src/test.rs`] file to follow along. diff --git a/docs/build/smart-contracts/example-contracts/custom-types.mdx b/docs/build/smart-contracts/example-contracts/custom-types.mdx index aa485af99..0bf1c621f 100644 --- a/docs/build/smart-contracts/example-contracts/custom-types.mdx +++ b/docs/build/smart-contracts/example-contracts/custom-types.mdx @@ -29,7 +29,7 @@ The [custom types example] demonstrates how to define your own data structures t [custom types example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/custom_types [storing data example]: ../getting-started/storing-data.mdx -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -55,7 +55,7 @@ running 1 test test test::test ... ok ``` -## Code +## Code {#code} ```rust title="custom_types/src/lib.rs" #[contracttype] @@ -99,13 +99,13 @@ impl IncrementContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/custom_types -## How it Works +## How it Works {#how-it-works} Custom types are defined using the `#[contracttype]` attribute on either a `struct` or an `enum`. Open the `custom_types/src/lib.rs` file to follow along. -### Custom Type: Struct +### Custom Type: Struct {#custom-type-struct} Structs are stored on ledger as a map of key-value pairs, where the key is up to a 32 character string representing the field name, and the value is the value encoded. @@ -120,7 +120,7 @@ pub struct State { } ``` -### Custom Type: Enum +### Custom Type: Enum {#custom-type-enum} The example does not contain enums, but enums may also be contract types. @@ -149,7 +149,7 @@ pub enum Enum { } ``` -### Using Types in Functions +### Using Types in Functions {#using-types-in-functions} Types that have been annotated with `#[contracttype]` can be stored as contract data and retrieved later. @@ -172,7 +172,7 @@ pub fn get_state(env: Env) -> State { } ``` -## Tests +## Tests {#tests} Open the `custom_types/src/test.rs` file to follow along. @@ -232,7 +232,7 @@ assert_eq!( ); ``` -## Build the Contract +## Build the Contract {#build-the-contract} To build the contract, use the `stellar contract build` command. @@ -246,7 +246,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_custom_types_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract functions in the Wasm using it. diff --git a/docs/build/smart-contracts/example-contracts/deployer.mdx b/docs/build/smart-contracts/example-contracts/deployer.mdx index 3044067da..d0706877e 100644 --- a/docs/build/smart-contracts/example-contracts/deployer.mdx +++ b/docs/build/smart-contracts/example-contracts/deployer.mdx @@ -38,7 +38,7 @@ In this example there are two contracts that are compiled separately, and the te [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v21.6.0 [deployer example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/deployer -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -64,7 +64,7 @@ running 1 test test test::test ... ok ``` -## Code +## Code {#code} ```rust title="deployer/deployer/src/lib.rs" #[contract] @@ -110,7 +110,7 @@ impl Deployer { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/deployer -## How it Works +## How it Works {#how-it-works} Contracts can deploy other contracts using the SDK `deployer()` method. @@ -118,13 +118,13 @@ The contract address of the deployed contract is deterministic and is derived fr Open the `deployer/deployer/src/lib.rs` file to follow along. -### Contract Wasm Upload +### Contract Wasm Upload {#contract-wasm-upload} Before deploying the new contract instances, the Wasm code needs to be uploaded on-chain. Then it can be used to deploy an arbitrary number of contract instances. The upload should typically happen outside of the deployer contract, as it needs to happen just once. However, it is possible to use `env.deployer().upload_contract_wasm()` function to upload Wasm from a contract as well. See the [tests](#tests) for an example of uploading the contract code programmatically. For the actual on-chain installation see the general deployment [tutorial](../../smart-contracts/getting-started/deploy-to-testnet.mdx). -### Authorization +### Authorization {#authorization} :::info @@ -150,7 +150,7 @@ While `deployer().with_address()` performs authorization as well, we want to mak See more details on the actual authorization payloads in [tests](#tests). -### `deployer()` +### `deployer()` {#deployer} The `deployer()` SDK function comes with a few deployment-related utilities. Here we use the most generic deployer kind, `with_address(deployer_address, salt)`. @@ -173,7 +173,7 @@ Only the `wasm_hash` itself is stored per contract ID thus saving the ledger spa When only deploying the contract on behalf of the current contract, i.e. when `deployer` address is always `env.current_contract_address()` it is possible to use `deployer().with_current_contract(salt)` function for brevity. -### Initialization +### Initialization {#initialization} The contract can be called immediately after deployment, which is useful for initialization. @@ -191,7 +191,7 @@ The contract returns the deployed contract's address and the result of executing (deployed_address, res) ``` -### Tests +### Tests {#tests} Open the `deployer/deployer/src/test.rs` file to follow along. @@ -230,7 +230,7 @@ This test contract will be used when testing the deployer. The deployer contract There are two tests: deployment from the current contract without authorization and deployment from an arbitrary address with authorization. Besides authorization, these tests are very similar. -#### Curent contract deployer +#### Curent contract deployer {#curent-contract-deployer} In the first test we deploy contract from the `Deployer` contract instance itself. @@ -308,7 +308,7 @@ let sum = client.value(); assert_eq!(sum, 5); ``` -#### External deployer +#### External deployer {#external-deployer} The second test is very similar to the first one. @@ -432,7 +432,7 @@ let sum = client.value(); assert_eq!(sum, 5); ``` -## Build the Contracts +## Build the Contracts {#build-the-contracts} To build the contract into a `.wasm` file, use the `stellar contract build` command. Build both the deployer contract and the test contract. @@ -450,7 +450,7 @@ target/wasm32-unknown-unknown/release/soroban_deployer_contract.wasm target/wasm32-unknown-unknown/release/soroban_deployer_test_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke the contract function to deploy the test contract. diff --git a/docs/build/smart-contracts/example-contracts/errors.mdx b/docs/build/smart-contracts/example-contracts/errors.mdx index 234a34c44..b7436285e 100644 --- a/docs/build/smart-contracts/example-contracts/errors.mdx +++ b/docs/build/smart-contracts/example-contracts/errors.mdx @@ -29,7 +29,7 @@ The [errors example] demonstrates how to define and generate errors in a contrac [errors example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/errors [storing data example]: ../getting-started/storing-data.mdx -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -77,7 +77,7 @@ test test::test_panic - should panic ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.33s ``` -## Code +## Code {#code} ```rust title="errors/src/lib.rs" #[contracterror] @@ -122,11 +122,11 @@ impl IncrementContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/errors -## How it Works +## How it Works {#how-it-works} Open the `errors/src/lib.rs` file to follow along. -### Defining an Error +### Defining an Error {#defining-an-error} Contract errors are Rust u32 enums where every variant of the enum is assigned an integer. The `#[contracterror]` attribute is used to set the error up so it can be used in the return value of contract functions. @@ -153,7 +153,7 @@ If an error is returned from a function anything the function has done is rolled ::: -### Returning an Error +### Returning an Error {#returning-an-error} Errors can be returned from contract functions by returning `Result<_, E>`. @@ -172,7 +172,7 @@ pub fn increment(env: Env) -> Result { } ``` -### Panicking with an Error +### Panicking with an Error {#panicking-with-an-error} Errors can also be panicked instead of being returned from the function. @@ -197,7 +197,7 @@ Functions that do not return a `Result<_, E>` type do not include in their speci ::: -## Tests +## Tests {#tests} Open the `errors/src/test.rs` file to follow along. @@ -255,7 +255,7 @@ let client = IncrementContractClient::new(&env, &contract_id); Two functions are generated for every contract function, one that returns a `Result<>`, and the other that does not handle errors and panicks if an error occurs. -### `try_increment` +### `try_increment` {#try_increment} In the first test the `try_increment` function is called and returns `Result, Result>`. @@ -272,7 +272,7 @@ assert_eq!(client.try_increment(), Err(Ok(Error::LimitReached))); - If the function call is unsuccessful but returns an error code not in the `Error` enum, or returns a system error code, `Err(Err(Status))` is returned and the `Status` can be inspected. -### `increment` +### `increment` {#increment} In the second test the `increment` function is called and returns `u32`. When the last call is made the function panicks. @@ -287,7 +287,7 @@ client.increment(); - If the function call is unsuccessful, a panic occurs. -## Build the Contract +## Build the Contract {#build-the-contract} To build the contract, use the `stellar contract build` command. @@ -301,7 +301,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_errors_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} Let's deploy the contract to Testnet so we can run it. The value provided as `--source` was set up in our Getting Started guide; please change accordingly if you created a different identity. diff --git a/docs/build/smart-contracts/example-contracts/events.mdx b/docs/build/smart-contracts/example-contracts/events.mdx index 5c26f69fb..ea6350722 100644 --- a/docs/build/smart-contracts/example-contracts/events.mdx +++ b/docs/build/smart-contracts/example-contracts/events.mdx @@ -26,7 +26,7 @@ The [events example] demonstrates how to publish events from a contract. This ex [events example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/events [storing data example]: ../getting-started/storing-data.mdx -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -52,7 +52,7 @@ running 1 test test test::test ... ok ``` -## Code +## Code {#code} ```rust title="events/src/lib.rs" const COUNTER: Symbol = symbol_short!("COUNTER"); @@ -89,7 +89,7 @@ impl IncrementContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/events -## How it Works +## How it Works {#how-it-works} This example contract extends the increment example by publishing an event each time the counter is incremented. @@ -101,7 +101,7 @@ Contracts can publish events using the environments events publish function. env.events().publish(topics, data); ``` -### Event Topics +### Event Topics {#event-topics} Topics are conveniently defined using a tuple. In the sample code two topics of `Symbol` type are used. @@ -115,7 +115,7 @@ The topics don't have to be made of the same type. ::: -### Event Data +### Event Data {#event-data} An event also contains a data object of any value or type including types defined by contracts using `#[contracttype]`. In the example the data is the `u32` count. @@ -123,7 +123,7 @@ An event also contains a data object of any value or type including types define env.events().publish(..., count); ``` -### Publishing +### Publishing {#publishing} Publishing an event is done by calling the `publish` function and giving it the topics and data. The function returns nothing on success, and panics on failure. Possible failure reasons can include malformed inputs (e.g. topic count exceeds limit) and running over the resource budget (TBD). Once successfully published, the new event will be available to applications consuming the events. @@ -137,7 +137,7 @@ Published events are discarded if a contract invocation fails due to a panic, bu ::: -## Tests +## Tests {#tests} Open the `events/src/test.rs` file to follow along. @@ -217,7 +217,7 @@ assert_eq!( ); ``` -## Build the Contract +## Build the Contract {#build-the-contract} To build the contract, use the `stellar contract build` command. @@ -231,7 +231,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_events_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract functions in the using it. diff --git a/docs/build/smart-contracts/example-contracts/fuzzing.mdx b/docs/build/smart-contracts/example-contracts/fuzzing.mdx index f927325c4..0febf2789 100644 --- a/docs/build/smart-contracts/example-contracts/fuzzing.mdx +++ b/docs/build/smart-contracts/example-contracts/fuzzing.mdx @@ -31,7 +31,7 @@ The [fuzzing example] demonstrates how to fuzz test Soroban contracts with [`car [`proptest-arbitrary-interop`]: https://docs.rs/proptest-arbitrary-interop [timelock example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/timelock -## Run the Example +## Run the Example {#run-the-example} First go through the [setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -84,7 +84,7 @@ INFO: seed corpus: files: 105 min: 32b max: 61b total: 3558b rss: 86Mb The rest of this tutorial will explain how to set up this fuzz test, interpret this output, and remedy fuzzing failures. -## Background: Fuzz Testing and Rust +## Background: Fuzz Testing and Rust {#background-fuzz-testing-and-rust} Fuzzing is a kind of testing where new inputs are repeatedly fed into a program in hopes of finding unexpected bugs. This style of testing is commonly employed to increase confidence in the correctness of security-sensitive software. @@ -108,7 +108,7 @@ In Rust, multiple fuzzers are maintained by the [`rust-fuzz`] GitHub organizatio [`rust-fuzz`]: https://github.com/rust-fuzz -## About the Example +## About the Example {#about-the-example} The example used for this tutorial is based on the [`timelock`] example program, with some changes to demonstrate fuzzing. @@ -155,7 +155,7 @@ pub enum TimeBoundKind { `deposit` may only be successfully called once, after which `claim` may be called multiple times until the balance is completely drained, at which point the contract becomes dormant and may no longer be used. -## Fuzz Testing Setup +## Fuzz Testing Setup {#fuzz-testing-setup} For these examples, the fuzz tests have been created for you, but normally you would use the `cargo fuzz init` command to create a fuzzing project as a subdirectory of the contract under test. @@ -239,7 +239,7 @@ path = ".." features = ["testutils"] ``` -## A Simple Fuzz Test +## A Simple Fuzz Test {#a-simple-fuzz-test} First let's look at [`fuzz_target_1.rs`]. This fuzz test does two things: it first deposits an arbitrary amount, then it claims an arbitrary amount. @@ -396,7 +396,7 @@ fn assert_invariants( } ``` -## Interpreting `cargo-fuzz` Output +## Interpreting `cargo-fuzz` Output {#interpreting-cargo-fuzz-output} If you run `cargo-fuzz` with `fuzz_target_1`, from inside the `soroban-examples/fuzzing` directory, you will see output similar to: @@ -619,7 +619,7 @@ See the [`libfuzzer` documentation] for more. [`libfuzzer` documentation]: https://llvm.org/docs/LibFuzzer.html#output -## Accepting Soroban Types as Input with the `SorobanArbitrary` Trait +## Accepting Soroban Types as Input with the `SorobanArbitrary` Trait {#accepting-soroban-types-as-input-with-the-sorobanarbitrary-trait} Inputs to the `fuzz_target!` macro must implement the [`Arbitrary`] trait, which accepts bytes from the fuzzer driver and converts them to Rust values. Soroban types though are managed by the host environment, and so must be created from an [`Env`] value, which is not available to the fuzzer driver. The [`SorobanArbitrary`] trait, implemented for all Soroban contract types, exists to bridge this gap: it defines a _prototype_ pattern whereby the `fuzz_target` macro creates prototype values that the fuzz program can convert to contract values with the standard soroban conversion traits, [`FromVal`] or [`IntoVal`]. @@ -658,7 +658,7 @@ Types that implement `SorobanArbitrary` include: All user-defined contract types, those with the [`contracttype`] attribute, automatically derive `SorobanArbitrary`. Note that `SorobanArbitrary` is only derived when the "testutils" Cargo feature is active. This implies that, in general, to make a Soroban contract fuzzable, the contract crate must define a "testutils" Cargo feature, that feature should turn on the "soroban-sdk/testutils" feature, and the fuzz test, which is its own crate, must turn that feature on. -## A More Complex Fuzz Test +## A More Complex Fuzz Test {#a-more-complex-fuzz-test} The [`fuzz_target_2.rs`] example, demonstrates the use of `SorobanArbitrary`, the advancement of time, and more advanced fuzzing techniques. @@ -785,7 +785,7 @@ for step in &config.input.steps { } ``` -## Converting a Fuzz Test to a Property Test +## Converting a Fuzz Test to a Property Test {#converting-a-fuzz-test-to-a-property-test} In addition to fuzz testing, Soroban supports property testing in the style of quickcheck, by using the [`proptest`] and [`proptest-arbitrary-interop`] crates in conjunction with the `SorobanArbitrary` trait. diff --git a/docs/build/smart-contracts/example-contracts/liquidity-pool.mdx b/docs/build/smart-contracts/example-contracts/liquidity-pool.mdx index 0671ac727..e244c8cb7 100644 --- a/docs/build/smart-contracts/example-contracts/liquidity-pool.mdx +++ b/docs/build/smart-contracts/example-contracts/liquidity-pool.mdx @@ -39,7 +39,7 @@ The Stellar network already has liquidity pool functionality built right in to t [liquidity pool example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/liquidity_pool [source code]: https://github.com/stellar/soroban-examples/blob/v21.6.0/liquidity_pool/src/lib.rs#L143 -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -65,7 +65,7 @@ test test::test ... ok [setup]: ../getting-started/setup.mdx -## Code +## Code {#code} :::info @@ -469,7 +469,7 @@ pub fn create_contract( Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/liquidity_pool -## How it Works +## How it Works {#how-it-works} Every asset created on Stellar starts with zero liquidity. The same is true of tokens created on Soroban (unless a Stellar asset with existing liquidity token is "wrapped" for use in Soroban). In simple terms, "liquidity" means how much of an asset in a market is available to be bough or sold. In the "old days," you could generate liquidity in a market by creating buy/sell orders on an order book. @@ -477,7 +477,7 @@ Liquidity pools automate this process by substituting the orders with math. Depo Open the `liquidity_pool/src/lib.rs` file or see the code above to follow along. -### Initialize the Contract +### Initialize the Contract {#initialize-the-contract} When this contract is first deployed, it could create a liquidity pool for _any_ pair of tokens available on Soroban. It must first be initialized with the following information: @@ -508,7 +508,7 @@ fn initialize(e: Env, token_wasm_hash: BytesN<32>, taken_a: Address, token_b: Ad [`token` example contract]: ./tokens.mdx [lexicographical order]: ../../../learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx#liquidity-pool-participation -### A "Constant Product" Liquidity Pool +### A "Constant Product" Liquidity Pool {#a-constant-product-liquidity-pool} The _type_ of liquidity pool this example contract implements is called a "constant product" liquidity pool. While this isn't the only type of liquidity pool out there, it is the most common variety. These liquidity pools are designed to keep the _total_ value of each asset in _relative_ equilibrium. The "product" in the constant product (also called an "invariant") will change every time the liquidity pool is interacted with (deposit, withdraw, or token swaps). However, the invariant **must** only increase with every interaction. @@ -532,7 +532,7 @@ We have much more in-depth information about how this kind of liquidity pool wor [stellar quest: series 3, quest 5]: https://quest.stellar.org/learn/series/3/quest/5 -### Interacting with Token Contracts in Another Contract +### Interacting with Token Contracts in Another Contract {#interacting-with-token-contracts-in-another-contract} This liquidity pool contract will operate with a total of three different Soroban tokens: @@ -541,7 +541,7 @@ This liquidity pool contract will operate with a total of three different Soroba [token interface]: ../../../tokens/token-interface.mdx -#### Creating a Custom `POOL` Token for LP Shares +#### Creating a Custom `POOL` Token for LP Shares {#creating-a-custom-pool-token-for-lp-shares} We are utilizing the compiled `token` example contract as our asset contract for the `POOL` token. This means it follows all the conventions of the [Token Interface], and can be treated just like any other token. They could be transferred, burned, minted, etc. It also means the LP developer _could_ take advantage of the administrative features such as clawbacks, authorization, and more. @@ -611,7 +611,7 @@ fn deposit(e: Env, to: Address, desired_a: i128, min_a: i128, desired_b: i128, m } ``` -#### Token Transfers to/from the LP Contract +#### Token Transfers to/from the LP Contract {#token-transfers-tofrom-the-lp-contract} As we've already discussed, the liquidity pool contract will make use of the [Token Interface] available in the token contracts that were supplied as `token_a` and `token_b` arguments at the time of initialization. Throughout the rest of the contract, the liquidity pool will make use of that interface to make transfers of those tokens to/from itself. @@ -659,7 +659,7 @@ fn withdraw(e: Env, to: Address, share_amount: i128, min_a: i128, min_b: i128) - You'll notice that by holding the balance of `token_a` and `token_b` on the liquidity pool contract itself it makes, it very easy for us to perform any of the [Token Interface] actions inside the contract. As a bonus, any outside observer could query the balances of `token_a` or `token_b` held by the contract to verify the reserves are actually in line with the values the contract reports when its own `get_rsvs` function is invoked. -## Tests +## Tests {#tests} Open the [`liquidity_pool/src/test.rs`] file to follow along. @@ -880,7 +880,7 @@ These tests examine the "typical" use-case of a liquidity pool, ensuring that th 3. The user performs a swap, buying `token_b` in exchange for `token_a`. The same checks as the previous step are made now, excepting the balances of `POOL`, since a swap has no effect on `POOL` tokens. 4. The user then withdraws all of the deposits it made, trading all of its `POOL` tokens in the process. The same checks are made here as were made in the `deposit` step. -## Build the Contract +## Build the Contract {#build-the-contract} To build the contract, use the `stellar contract build` command. @@ -894,7 +894,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_liquidity_pool_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract functions using it. diff --git a/docs/build/smart-contracts/example-contracts/logging.mdx b/docs/build/smart-contracts/example-contracts/logging.mdx index adec66c2e..28dbd709e 100644 --- a/docs/build/smart-contracts/example-contracts/logging.mdx +++ b/docs/build/smart-contracts/example-contracts/logging.mdx @@ -42,7 +42,7 @@ Logs are not accessible by dapps and other applications. See the [events example [testing]: ../getting-started/hello-world.mdx#run-the-tests [events example]: events.mdx -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -69,7 +69,7 @@ Hello Symbol(Dev) test test::test ... ok ``` -## Code +## Code {#code} ```toml title="Cargo.toml" [profile.release-with-logs] @@ -94,7 +94,7 @@ impl Contract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/logging -## How it Works +## How it Works {#how-it-works} The [`log!`] macro logs a string. Any logs that occur during execution are outputted to stdout in [`stellar-cli`] and available for tests to assert on or print. @@ -104,7 +104,7 @@ Logs are only recorded in Soroban environments that have logging enabled. The on Open the files above to follow along. -### `Cargo.toml` Profile +### `Cargo.toml` Profile {#cargotoml-profile} Logs are only outputted if the contract is built with the `debug-assertions` compiler option enabled. @@ -122,7 +122,7 @@ To build without logs use the `--release` or `--profile release` option. To build with logs use the `--profile release-with-logs` option. -### Using the `log!` Macro +### Using the `log!` Macro {#using-the-log-macro} The [`log!`] macro builds a string from the format string, and a list of arguments. Arguments are substituted wherever the `{}` value appears in the format string. @@ -142,7 +142,7 @@ The values outputted are currently relatively limited. While primitive values li ::: -## Tests +## Tests {#tests} Open the `logging/src/test.rs` file to follow along. @@ -206,11 +206,11 @@ They can be printed to stdout. std::println!("{}", logs.join("\n")); ``` -## Build the Contract +## Build the Contract {#build-the-contract} To build the contract, use the `stellar contract build` command. -### Without Logs +### Without Logs {#without-logs} To build the contract without logs, use the `--release` option. @@ -224,7 +224,7 @@ A `.wasm` file should be outputted in the `target` directory, in the `release` s target/wasm32-unknown-unknown/release/soroban_logging_contract.wasm ``` -### With Logs +### With Logs {#with-logs} To build the contract with logs, use the `--profile release-with-logs` option. @@ -238,7 +238,7 @@ A `.wasm` file should be outputted in the `target` directory, in the `release-wi target/wasm32-unknown-unknown/release-with-logs/soroban_logging_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract functions in the using it. Specify the `-v` option to enable verbose logs. diff --git a/docs/build/smart-contracts/example-contracts/tokens.mdx b/docs/build/smart-contracts/example-contracts/tokens.mdx index 7eb1b8c61..a85d2cb53 100644 --- a/docs/build/smart-contracts/example-contracts/tokens.mdx +++ b/docs/build/smart-contracts/example-contracts/tokens.mdx @@ -29,7 +29,7 @@ The [token example] demonstrates how to write a token contract that implements t [token example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/token [token interface]: ../../../tokens/token-interface.mdx -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -62,7 +62,7 @@ test test::test ... ok [setup]: ../getting-started/setup.mdx -## Code +## Code {#code} :::note @@ -527,7 +527,7 @@ pub enum DataKey { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/token -## How it Works +## How it Works {#how-it-works} Tokens created on a smart contract platform can take many different forms, include a variety of different functionalities, and meet very different needs or use-cases. While each token can fulfill a unique niche, there are some "normal" features that almost all tokens will need to make use of (e.g., payments, transfers, balance queries, etc.). In an effort to minimize repetition and streamline token deployments, Soroban implements the [Token Interface], which provides a uniform, predictable interface for developers and users. @@ -537,7 +537,7 @@ This example contract, however, demonstrates how a smart contract token might be [stellar asset contract]: ../../../tokens/stellar-asset-contract.mdx -### Separation of Functionality +### Separation of Functionality {#separation-of-functionality} You have likely noticed that this example contract is broken into discrete modules, with each one responsible for a siloed set of functionality. This common practice helps to organize the code and make it more maintainable. @@ -570,7 +570,7 @@ fn mint(e: Env, to: Address, amount: i128) { This same convention is used to separate from the "main" contract code the metadata for the token, the storage type definitions, etc. -### Standardized Interface, Customized Behavior +### Standardized Interface, Customized Behavior {#standardized-interface-customized-behavior} This example contract follows the standardized [Token Interface], implementing all of the same functions as the [Stellar Asset Contract]. This gives wallets, users, developers, etc. a predictable interface to interact with the token. Even though we are implementing the same _interface_ of functions, that doesn't mean we have to implement the same _behavior_ inside those functions. While this example contract doesn't actually modify any of the functions that would be present in a deployed instance of the Stellar Asset Contract, that possibility remains open to the contract developer. @@ -602,7 +602,7 @@ Of course, you will want your token to behave in an _intuitive_ and _transparent ::: -## Tests +## Tests {#tests} Open the `token/src/test.rs` file to follow along. @@ -968,7 +968,7 @@ The eight tests created for this example contract test a range of possible condi - **`initialize_already_initialized()`** - This function checks that the contract cannot have it's `initialize()` function invoked a second time. - **`decimal_is_over_eighteen()`** - This function tests that invoking `initialize()` with too high of a decimal precision will not succeed. -## Build the Contract +## Build the Contract {#build-the-contract} To build the contract, use the `stellar contract build` command. @@ -982,7 +982,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_token_contract.wasm ``` -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract functions using it. diff --git a/docs/build/smart-contracts/example-contracts/workspace.mdx b/docs/build/smart-contracts/example-contracts/workspace.mdx index 85b3c9914..bd65cadb8 100644 --- a/docs/build/smart-contracts/example-contracts/workspace.mdx +++ b/docs/build/smart-contracts/example-contracts/workspace.mdx @@ -15,7 +15,7 @@ The [workspace example] demonstrates how multiple smart contracts can be develop [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/main [workspace example]: https://github.com/stellar/soroban-examples/tree/main/workspace -## Run the Example +## Run the Example {#run-the-example} First go through the [Setup] process to get your development environment configured, then clone the `soroban-examples` repository: @@ -41,7 +41,7 @@ running 1 test test test::test_token_auth ... ok ``` -## Code +## Code {#code} @@ -132,7 +132,7 @@ fn test() { Ref: https://github.com/stellar/soroban-examples/tree/main/workspace -## How It Works +## How It Works {#how-it-works} There are three crates that are part of the workspace. @@ -142,7 +142,7 @@ There are three crates that are part of the workspace. Let's take a look at each crate, and see how they all work together. -### Contract A Interface: The Trait +### Contract A Interface: The Trait {#contract-a-interface-the-trait} The `contract_a_interface` crate defines a trait containing a contract interface. This interface is defined separate from the implementation and only defines what the exported functions of the implementation. @@ -150,7 +150,7 @@ The interface defines `add` as the only function the contract will contain. The The use of `contractclient` as an attribute macro on `ContractAInterface` means a client will be created, conforming to this interface, that can be used by contracts existing outside of the `contract_a_interface` crate. As you'll see later, the client, `ContractAClient`, is used in the `contract_b` crate to call the `add` function. -### Contract A: The Logic +### Contract A: The Logic {#contract-a-the-logic} The `contract_a` crate contains the implementation for Contract A, defining for each function what it should actually _do_. @@ -166,7 +166,7 @@ All that is required to make use of the previously defined `ContractAInterface` This crate uses the `contractimpl` attribute macro on the `ContractA` implementation, making the `add` function public and invocable by others on the Stellar network. -### Contract B: The Invocation +### Contract B: The Invocation {#contract-b-the-invocation} Now that we've created a trait in `contract_a_interface`, and implemented it in `contract_a`, we can use the `contract_b` crate to invoke the `add` function and get the sum of our integers. @@ -185,14 +185,14 @@ Defining the contract interface with a `trait` separately is optional. It's a gr `ContractB` invokes `ContractA`'s `add` function, returning its value back to the original invoker. It's a bit of a long round-trip for this simple example, but it illustrates a really powerful way you can separate out interface/trait definitions from contract logic and share it and its client in a multi-contract workspace. -## Practical Use-Case Examples +## Practical Use-Case Examples {#practical-use-case-examples} Beyond this simple example, this technique is versatile and useful. For example, this strategy could be used to: - Create and reference a standardized, consistent token interface. - Reuse a single interface that you want to incorporate across many different contracts. -## Build the Contracts +## Build the Contracts {#build-the-contracts} To build the contracts into a set of `.wasm` files, use the `stellar contract build` command. Both `workspace/contract_a` and `workspace/contract_b` will be built, and you can use a single command, since our workspace defines its `members` in the `Cargo.toml` file: @@ -209,7 +209,7 @@ target/wasm32-unknown-unknown/release/soroban_workspace_contract_b.wasm The [`stellar-cli`] knows the `contract_a_interface` is not intended to be compiled into a .wasm, because the `contract_a_interface`'s `Cargo.toml` has its `crate-type` configured as `rlib` (rust library). Nice! -## Run the Contract +## Run the Contract {#run-the-contract} If you have [`stellar-cli`] installed, you can invoke contract the functions. Both contracts must be deployed. diff --git a/docs/build/smart-contracts/getting-started/deploy-increment-contract.mdx b/docs/build/smart-contracts/getting-started/deploy-increment-contract.mdx index 29d26e123..9b4c2315d 100644 --- a/docs/build/smart-contracts/getting-started/deploy-increment-contract.mdx +++ b/docs/build/smart-contracts/getting-started/deploy-increment-contract.mdx @@ -21,7 +21,7 @@ import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; import { getPlatform } from "@site/src/helpers/getPlatform"; -## Two-step deployment +## Two-step deployment {#two-step-deployment} It's worth knowing that `deploy` is actually a two-step process. @@ -125,7 +125,7 @@ You should see the following output: Run it a few more times to watch the count change. -## Run your own network/node +## Run your own network/node {#run-your-own-networknode} Sometimes you'll need to run your own node: @@ -134,6 +134,6 @@ Sometimes you'll need to run your own node: The RPC team maintains Docker containers that makes this as straightforward as possible. See the [RPC](../../../data/rpc/admin-guide.mdx) reference for details. -## Up next +## Up next {#up-next} Ready to turn these deployed contracts into a simple web application? Head over to the [Build a Dapp Frontend section](../../apps/dapp-frontend.mdx). diff --git a/docs/build/smart-contracts/getting-started/deploy-to-testnet.mdx b/docs/build/smart-contracts/getting-started/deploy-to-testnet.mdx index 1a287dead..b6417aa98 100644 --- a/docs/build/smart-contracts/getting-started/deploy-to-testnet.mdx +++ b/docs/build/smart-contracts/getting-started/deploy-to-testnet.mdx @@ -29,7 +29,7 @@ To recap what we've done so far, in [Setup](setup.mdx): In [Hello World](./hello-world.mdx) we created a `hello-world` project, and learned how to test and build the `HelloWorld` contract. Now we are ready to deploy that contract to Testnet, and interact with it. -## Deploy +## Deploy {#deploy} To deploy your HelloWorld contract, run the following command: @@ -61,7 +61,7 @@ stellar contract deploy ` This returns the contract's id, starting with a `C`. In this example, we're going to use `CACDYF3CYMJEJTIVFESQYZTN67GO2R5D5IUABTCUG3HXQSRXCSOROBAN`, so replace it with your actual contract id. -## Interact +## Interact {#interact} Using the code we wrote in [Write a Contract](./hello-world.mdx#contract-source-code) and the resulting `.wasm` file we built in [Build](hello-world.mdx#build-the-contract), run the following command to invoke the `hello` function. @@ -127,7 +127,7 @@ stellar contract invoke ... -- hello --help ::: -## Summary +## Summary {#summary} In this lesson, we learned how to: diff --git a/docs/build/smart-contracts/getting-started/hello-world.mdx b/docs/build/smart-contracts/getting-started/hello-world.mdx index b6582da17..4b946b17b 100644 --- a/docs/build/smart-contracts/getting-started/hello-world.mdx +++ b/docs/build/smart-contracts/getting-started/hello-world.mdx @@ -21,7 +21,7 @@ import TabItem from "@theme/TabItem"; Once you've [set up](./setup.mdx) your development environment, you're ready to create your first smart contract. -## Create a New Project +## Create a New Project {#create-a-new-project} Create a new project using the `init` command to create a `soroban-hello-world` project. @@ -44,11 +44,11 @@ The `init` command will create a Rust workspace project, using the recommended s └── test.rs ``` -### Cargo.toml +### Cargo.toml {#cargotoml} The `Cargo.toml` file at the root of the project is set up as Rust Workspace, which allows us to include multiple smart contracts in one project. -#### Rust Workspace +#### Rust Workspace {#rust-workspace} The `Cargo.toml` file sets the workspace’s members as all contents of the `contracts` directory and sets the workspace’s `soroban-sdk` dependency version including the `testutils` feature, which will allow test utilities to be generated for calling the contract in tests. @@ -69,7 +69,7 @@ The `testutils` are automatically enabled inside [Rust unit tests] inside the sa ::: -#### `release` Profile +#### `release` Profile {#release-profile} Configuring the `release` profile to optimize the contract build is critical. Soroban contracts have a maximum size of 64KB. Rust programs, even small ones, without these configurations almost always exceed this size. @@ -87,7 +87,7 @@ codegen-units = 1 lto = true ``` -#### `release-with-logs` Profile +#### `release-with-logs` Profile {#release-with-logs-profile} Configuring a `release-with-logs` profile can be useful if you need to build a `.wasm` file that has logs enabled for printing debug logs when using the [`stellar-cli`]. Note that this is not necessary to access debug logs in tests or to use a step-through-debugger. @@ -101,11 +101,11 @@ See the [logging example] for more information about how to log. [logging example]: ../example-contracts/logging.mdx -### Contracts Directory +### Contracts Directory {#contracts-directory} The `contracts` directory is where Soroban contracts will live, each in their own directory. There is already a `hello_world` contract in there to get you started. -#### Contract-specific Cargo.toml file +#### Contract-specific Cargo.toml file {#contract-specific-cargotoml-file} Each contract should have its own `Cargo.toml` file, which relies on the top-level `Cargo.toml` that we just discussed. @@ -137,7 +137,7 @@ soroban-sdk = { workspace = true } soroban-sdk = { workspace = true, features = ["testutils"] } ``` -#### Contract Source Code +#### Contract Source Code {#contract-source-code} Creating a Soroban contract involves writing Rust code in the project’s `lib.rs` file. @@ -196,7 +196,7 @@ mod test; Note the `mod test` line at the bottom, this will tell Rust to compile and run the test code, which we’ll take a look at next. -#### Contract Unit Tests +#### Contract Unit Tests {#contract-unit-tests} Writing tests for Soroban contracts involves writing Rust code using the test facilities and toolchain that you'd use for testing any Rust code. @@ -276,7 +276,7 @@ assert_eq!( ); ``` -## Run the Tests +## Run the Tests {#run-the-tests} Run `cargo test` and watch the unit test run. You should see the following output: @@ -297,7 +297,7 @@ The first time you run the tests you may see output in the terminal of cargo com ::: -## Build the contract +## Build the contract {#build-the-contract} To build a smart contract to deploy or run, use the `stellar contract build` command. @@ -321,7 +321,7 @@ A `.wasm` file will be outputted in the `target` directory, at `target/wasm32-un The `.wasm` file contains the logic of the contract, as well as the contract's [specification / interface types](../../../learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx), which can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. -## Optimizing Builds +## Optimizing Builds {#optimizing-builds} Use `stellar contract optimize` to further minimize the size of the `.wasm`. First, re-install stellar-cli with the `opt` feature: @@ -343,7 +343,7 @@ Building optimized contracts is only necessary when deploying to a network with ::: -## Summary +## Summary {#summary} In this section, we wrote a simple contract that can be deployed to a Soroban network. diff --git a/docs/build/smart-contracts/getting-started/setup.mdx b/docs/build/smart-contracts/getting-started/setup.mdx index 9faf8bbeb..18a62588b 100644 --- a/docs/build/smart-contracts/getting-started/setup.mdx +++ b/docs/build/smart-contracts/getting-started/setup.mdx @@ -34,7 +34,7 @@ To build and develop contracts you need only a couple prerequisites: - An editor that supports Rust - [Stellar CLI] -## Install Rust +## Install Rust {#install-rust} @@ -70,7 +70,7 @@ For other methods of installing [Rust], see: https://www.rust-lang.org/tools/ins -## Install the target +## Install the target {#install-the-target} Install the `wasm32-unknown-unknown` target. @@ -78,7 +78,7 @@ Install the `wasm32-unknown-unknown` target. rustup target add wasm32-unknown-unknown ``` -## Configure an Editor +## Configure an Editor {#configure-an-editor} Many editors have support for Rust. Visit the following link to find out how to configure your editor: https://www.rust-lang.org/tools @@ -92,13 +92,13 @@ A popular editor is Visual Studio Code: [rust analyzer]: https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer [codelldb]: https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb -## Install the Stellar CLI +## Install the Stellar CLI {#install-the-stellar-cli} The [Stellar CLI](https://github.com/stellar/stellar-cli) can execute smart contracts on futurenet, testnet, mainnet, as well as in a local sandbox. The latest stable release is [v{latestVersion}](https://github.com/stellar/stellar-cli/releases/latest). -### Install +### Install {#install} There are a few ways to install the [latest release](https://github.com/stellar/stellar-cli/releases) of Stellar CLI. @@ -144,11 +144,11 @@ Report issues and share feedback about the Stellar CLI [here](https://github.com ::: -### Documentation +### Documentation {#documentation} The auto-generated comprehensive reference documentation is available [here](../../../tools/developer-tools/cli/stellar-cli.mdx). -### Autocompletion +### Autocompletion {#autocompletion} You can use `stellar completion` to generate shell completion for different shells. You should absolutely try it out. It will feel like a super power! @@ -245,9 +245,9 @@ echo "source (stellar completion --shell elvish)" >> ~/.elvish/rc.elv -### Configuring the CLI for Testnet +### Configuring the CLI for Testnet {#configuring-the-cli-for-testnet} -### Configure an Identity +### Configure an Identity {#configure-an-identity} When you deploy a smart contract to a network, you need to specify an identity that will be used to sign the transactions. diff --git a/docs/build/smart-contracts/getting-started/storing-data.mdx b/docs/build/smart-contracts/getting-started/storing-data.mdx index fac668fbf..48d3e3c47 100644 --- a/docs/build/smart-contracts/getting-started/storing-data.mdx +++ b/docs/build/smart-contracts/getting-started/storing-data.mdx @@ -25,7 +25,7 @@ This is going to follow along with the [increment example](https://github.com/st This tutorial assumes that you've already completed the previous steps in Getting Started: [Setup](./setup.mdx), [Hello World](./hello-world.mdx), and [Deploy to Testnet](./deploy-to-testnet.mdx). -## Adding the increment contract +## Adding the increment contract {#adding-the-increment-contract} The `stellar contract init` command allows us to initialize a new project with any of the example contracts from the [soroban-examples](https://github.com/stellar/soroban-examples) repo, using the `--with-example` (or `-w`) flag. @@ -79,7 +79,7 @@ impl IncrementorContract { mod test; ``` -### Imports +### Imports {#imports} This contract begins similarly to our Hello World contract, with an annotation to exclude the Rust standard library, and imports of the types and macros we need from the `soroban-sdk` crate. @@ -88,7 +88,7 @@ This contract begins similarly to our Hello World contract, with an annotation t use soroban_sdk::{contract, contractimpl, log, symbol_short, Env, Symbol}; ``` -### Contract Data Keys +### Contract Data Keys {#contract-data-keys} ```rust const COUNTER: Symbol = symbol_short!("COUNTER"); @@ -100,7 +100,7 @@ Contract data is associated with a key, which can be used at a later time to loo The `symbol_short!()` macro is a convenient way to pre-compute short symbols up to 9 characters in length at compile time using `Symbol::short`. It generates a compile-time constant that adheres to the valid character set of letters (a-zA-Z), numbers (0-9), and underscores (\_). If a symbol exceeds the 9-character limit, `Symbol::new` should be utilized for creating symbols at runtime. -### Contract Data Access +### Contract Data Access {#contract-data-access} ```rust let mut count: u32 = env @@ -126,7 +126,7 @@ env.storage() The `set()` function stores the new count value against the key, replacing the existing value. -### Managing Contract Data TTLs with `extend_ttl()` +### Managing Contract Data TTLs with `extend_ttl()` {#managing-contract-data-ttls-with-extend_ttl} ```rust env.storage().instance().extend_ttl(100, 100); @@ -136,7 +136,7 @@ All contract data has a Time To Live (TTL), measured in ledgers, that must be pe For now, it's worth knowing that there are three kinds of storage: `Persistent`, `Temporary`, and `Instance`. This contract only uses `Instance` storage: `env.storage().instance()`. Every time the counter is incremented, this storage's TTL gets extended by 100 [ledgers](../../../learn/fundamentals/stellar-data-structures/ledgers.mdx), or about 500 seconds. -### Build the contract +### Build the contract {#build-the-contract} From inside `soroban-hello-world`, run: @@ -152,7 +152,7 @@ ls target/wasm32-unknown-unknown/release/*.wasm You should see both `hello_world.wasm` and `soroban_increment_contract.wasm`. -## Tests +## Tests {#tests} The following test has been added to the `contracts/increment/src/test.rs` file. @@ -198,11 +198,11 @@ count: U32(2) test test::incrementor ... ok ``` -## Take it further +## Take it further {#take-it-further} Can you figure out how to add `get_current_value` function to the contract? What about `decrement` or `reset` functions? -## Summary +## Summary {#summary} In this section, we added a new contract to this project, that made use of Soroban's storage capabilities to store and retrieve data. We also learned about the different kinds of storage and how to manage their TTLs. diff --git a/docs/build/smart-contracts/overview.mdx b/docs/build/smart-contracts/overview.mdx index b40d7dd5d..314feea6c 100644 --- a/docs/build/smart-contracts/overview.mdx +++ b/docs/build/smart-contracts/overview.mdx @@ -7,7 +7,7 @@ Soroban is the smart contracts platform on the Stellar network. Contracts are sm To begin writing contracts, [install a Rust toolchain](https://www.rust-lang.org/tools/install), configure your [editor to support Rust programs](https://www.rust-lang.org/tools), and [learn some basic Rust concepts](https://www.rust-lang.org/learn). -## Rust on Stellar +## Rust on Stellar {#rust-on-stellar} Stellar smart contracts have several characteristics (such as resource limits, security considerations, and more) that force contracts to use only a narrow subset of the full Rust language and must use specialized libraries for most tasks. Read more in the [Contract Rust Dialect section](../../learn/encyclopedia/contract-development/rust-dialect.mdx). @@ -15,7 +15,7 @@ In particular, the Rust standard library and most third-party libraries (called Support for other languages may be supported in the future, but at this time, only Rust is supported. -## Soroban Rust SDK +## Soroban Rust SDK {#soroban-rust-sdk} Contracts are developed using a software development kit (SDK). The [Soroban Rust SDK](../../tools/sdks/library.mdx#soroban-rust-sdk) consists of a Rust crate and a command-line tool. @@ -23,7 +23,7 @@ The SDK crate acts as a substitute for the Rust standard library — providing d The Soroban SDK command-line tool provides a developer-focused front-end for compiling, testing, inspecting, versioning, and deploying contracts. It also includes a complete implementation of the contract host environment that is identical to the one that runs on-chain, called **local testing mode**. With this capability, contracts can be run locally on a developer's workstation and can be [tested and debugged] directly with a local debugger within a standard IDE, as well as a native test harness for fast-feedback unit testing and high-speed fuzzing or property testing. -## Host environment +## Host environment {#host-environment} The host environment is a set of Rust crates compiled into the SDK command-line tool and stellar-core. It comprises a set of host objects and functions, an interface to on-chain storage and contract invocation, a resource-accounting and fee-charging system, and a Wasm interpreter. @@ -31,7 +31,7 @@ Most contract developers will not frequently need to interact with the host envi Read more in the [Environment Concepts section](../../learn/encyclopedia/contract-development/environment-concepts.mdx). -## Soroban FAQs +## Soroban FAQs {#soroban-faqs} **What is Soroban to Stellar? Is it a new blockchain?​** diff --git a/docs/data/README.mdx b/docs/data/README.mdx index 4a983a068..8dabf2094 100644 --- a/docs/data/README.mdx +++ b/docs/data/README.mdx @@ -27,7 +27,7 @@ This section will walk you through the differences between the various platforms -## [RPC](./rpc/README.mdx) +## [RPC](./rpc/README.mdx) {#rpc} The RPC primarily provides information that the Stellar network currently has in view, i.e., **the current state**, which includes the current balances of all accounts, the current state of smart contracts, and any other relevant information that constitutes the present condition of the blockchain. It has the ability to send a transaction to the network and query the network for the status of previous transactions (subject to the retention window of seven days, transactions older than that will return a `NOT_FOUND` response). The RPC is meant to be simple, minimal, and scalable. @@ -39,7 +39,7 @@ If the RPC does not otherwise serve your needs, please tell us why in the [Stell You have the option of [setting up your own RPC instance](./rpc/admin-guide.mdx) or using a publicly available service from [an infrastructure provider](./rpc/rpc-providers.mdx). -## [Hubble](./hubble/README.mdx) +## [Hubble](./hubble/README.mdx) {#hubble} Hubble is an SDF-maintained, open-source, publicly available BigQuery data warehouse that provides a complete, holistic historical record of the Stellar network. It is a read-only platform and does not have the capability to send transactions to the network like you can with RPC. @@ -49,7 +49,7 @@ Hubble is not good for use cases that need real-time data availability, like wal The [Hubble documentation](./hubble/README.mdx) focuses on exploratory data analysis, outlines different ways developers or end users can connect to Hubble (programmatically or through a UI), and provides guidance on query optimization (users are charged per query, so it’s important to craft your query thoughtfully). -## [Horizon](./horizon/README.mdx) +## [Horizon](./horizon/README.mdx) {#horizon} Horizon is an API for accessing and interacting with the Stellar network data. It does not store smart contract data. Horizon does, however, have a limited view of the Stellar Asset Contract (SAC) and smart contract operation types (i.e., it ingests transactions with invokeHostFunction operations and asset-related operations, whether they’re made through an asset’s SAC or using the built-in transaction operations). @@ -57,11 +57,11 @@ Horizon stores three types of data (current state, historical state, and derived You can [run your own instance of Horizon](./horizon/admin-guide/README.mdx) or use one of the publicly available Horizon services from [these infrastructure providers](./horizon/horizon-providers.mdx). -## [Galexie](./galexie/README.mdx) +## [Galexie](./galexie/README.mdx) {#galexie} Galexie is a tool for exporting Stellar ledger metadata to external data storage. Learn more about its [use cases](./galexie/README.mdx) and how to [run](./galexie/admin_guide/README.mdx) your own instance of Galexie. -## [Data Indexers](../tools/developer-tools/data-indexers.mdx) +## [Data Indexers](../tools/developer-tools/data-indexers.mdx) {#data-indexers} Data indexers are specialized tools that process and index blockchain data, making it more accessible and queryable to end users. They transform raw blockchain data into a more structured format that’s easier for end users to interact with. @@ -69,7 +69,7 @@ Data indexers have advanced querying capabilities and enhanced analytics. They p Data indexers are a potentially more user-friendly, cost-effective choice for users. Check out several available data indexers for the Stellar network in our [Tools section](../tools/developer-tools/data-indexers.mdx). -## [Analytics Platforms](../tools/developer-tools/analytics-platforms.mdx) +## [Analytics Platforms](../tools/developer-tools/analytics-platforms.mdx) {#analytics-platforms} Analytics Platforms are specialized tools that process and make historical Stellar network data available. The Stellar network data is loaded into database tables for large data analytics using SQL. Users can create complex ad hoc analysis, dashboarding, and curate actionable data insights (e.g., business intelligence or business analytics). diff --git a/docs/data/galexie/README.mdx b/docs/data/galexie/README.mdx index b91893eda..a74bfbc5b 100644 --- a/docs/data/galexie/README.mdx +++ b/docs/data/galexie/README.mdx @@ -3,11 +3,11 @@ title: Galexie Introduction sidebar_position: 0 --- -## What is Galexie? +## What is Galexie? {#what-is-galexie} Galexie is a tool for extracting, processing, exporting Stellar ledger metadata to external storage, and creating a data lake of pre-processed ledger metadata. Galexie is the foundation of the Composable Data Pipeline (CDP) and serves as the first step in extracting raw Stellar ledger metadata and making it accessible. Learn more about CDP’s benefits and applications in this [blog post](https://stellar.org/blog/developers/composable-data-platform). -## What Are the Key Features of Galexie? +## What Are the Key Features of Galexie? {#what-are-the-key-features-of-galexie} Galexie is designed to make streamlined and efficient export of ledger metadata via a simple user-friendly interface. Its key features include: @@ -18,15 +18,15 @@ Galexie is designed to make streamlined and efficient export of ledger metadata ![](/assets/galexie-architecture.png) -## Why XDR Format? +## Why XDR Format? {#why-xdr-format} Exporting data in XDR—the native Stellar Core format—enables Galexie to preserve full transaction metadata, ensuring data integrity while keeping storage efficient. The XDR format maintains compatibility with all Stellar components, providing a solid foundation for applications that require consistent access to historical data. Refer to the [XDR](/docs/learn/encyclopedia/data-format/xdr) documentation for more information on this format. -## Why Run Galexie? +## Why Run Galexie? {#why-run-galexie} Galexie enables you to make a copy of Stellar ledger metadata over which you have complete control. Galexie can continuously sync your data lake with the latest ledger data freeing you up from tedious data ingestion and allowing you to focus on building customized applications that consume and analyze exported data. -## What Can You Do with the Data Lake Created by Galexie? +## What Can You Do with the Data Lake Created by Galexie? {#what-can-you-do-with-the-data-lake-created-by-galexie} Once data is stored in the cloud, it becomes easily accessible for integration with modern data processing and analytics tools, enabling various workflows and insights. diff --git a/docs/data/galexie/admin_guide/configuring.mdx b/docs/data/galexie/admin_guide/configuring.mdx index a98f03758..35a30e696 100644 --- a/docs/data/galexie/admin_guide/configuring.mdx +++ b/docs/data/galexie/admin_guide/configuring.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 # Configuring -## Steps to Configure Galexie +## Steps to Configure Galexie {#steps-to-configure-galexie} 1. **Copy the Sample Configuration** diff --git a/docs/data/galexie/admin_guide/monitoring.mdx b/docs/data/galexie/admin_guide/monitoring.mdx index 90b2146c3..06c4f185a 100644 --- a/docs/data/galexie/admin_guide/monitoring.mdx +++ b/docs/data/galexie/admin_guide/monitoring.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 # Monitoring -### Metrics +### Metrics {#metrics} Galexie publishes metrics through an HTTP-based admin endpoint, which makes it easier to monitor its performance. This endpoint is configurable in the `config.toml` file, where you can specify the port on which metrics are made available. The data is exposed in Prometheus format, enabling easy integration with existing monitoring and alerting systems. @@ -40,7 +40,7 @@ Use these metrics to build queries that monitor Galexie’s performance and expo For a quick start, download our pre-built Grafana dashboard for Galexie [here](https://grafana.com/grafana/dashboards/22285-stellar-galexie/). This dashboard provides pre-configured queries and visualizations to help you monitor Galexie's health. You can customize it to fit your specific needs. -### Logging +### Logging {#logging} Galexie emits logs to stdout and generates a log line for every object being exported to help monitor progress. diff --git a/docs/data/galexie/admin_guide/prerequisites.mdx b/docs/data/galexie/admin_guide/prerequisites.mdx index c610a1846..0f8aa4d6b 100644 --- a/docs/data/galexie/admin_guide/prerequisites.mdx +++ b/docs/data/galexie/admin_guide/prerequisites.mdx @@ -5,27 +5,27 @@ sidebar_position: 10 # Prerequisites -### 1. Google Cloud Platform (GCP) Account +### 1. Google Cloud Platform (GCP) Account {#1-google-cloud-platform-gcp-account} Galexie exports Stellar ledger metadata to Google Cloud Storage (GCS), so you need a GCP account with: - Permissions to create a new GCS bucket, or - Access to an existing bucket with read/write permissions. -### 2. Docker (Recommended) +### 2. Docker (Recommended) {#2-docker-recommended} > **_NOTE:_** While it is possible to natively install Galexie (without Docker), this requires manual dependency management and is recommended only for advanced users.] Galexie is available as a Docker image, which simplifies installation and setup. Ensure you have Docker Engine installed on your system ([Docker installation guide](https://docs.docker.com/engine/install/)). -## Hardware Requirements +## Hardware Requirements {#hardware-requirements} The minimum hardware requirements for running Galexie are:\ **RAM**: 8 GB\ **CPU**: 2 vCPUs\ **Disk**: 100 GB with at least 5K IOPS -### Full History Export +### Full History Export {#full-history-export} Exporting the full history (as of November 2024): diff --git a/docs/data/galexie/admin_guide/running.mdx b/docs/data/galexie/admin_guide/running.mdx index 6651889a4..680a8a018 100644 --- a/docs/data/galexie/admin_guide/running.mdx +++ b/docs/data/galexie/admin_guide/running.mdx @@ -7,9 +7,9 @@ sidebar_position: 40 With the Docker image available and the configuration file set up, you're now ready to run Galexie and start exporting Stellar ledger data to the GCS bucket. -## Command Line Usage +## Command Line Usage {#command-line-usage} -### Append Command +### Append Command {#append-command} This is the primary way of running Galexie. The `append` command operates in two distinct modes: @@ -64,11 +64,11 @@ append --start 350000 --end 450000 --config-file config.toml - The Docker image name. -#### Data Integrity and Resumability: +#### Data Integrity and Resumability: {#data-integrity-and-resumability} The append command maintains strict sequential integrity within each export session. If interrupted and then restarted with the same range, it automatically resumes from where it left off before interruption, ensuring no ledgers are missed within a session. -### Scan-and-fill Command +### Scan-and-fill Command {#scan-and-fill-command} The `scan-and-fill` command is useful in cases where there are gaps in the exported ledgers in the data lake. The command works by scanning all ledgers in the specified range, identifying missing ledgers and exporting only the missing ledgers while skipping existing ledgers in the data lake. diff --git a/docs/data/galexie/admin_guide/setup.mdx b/docs/data/galexie/admin_guide/setup.mdx index 70632debb..354eec8e5 100644 --- a/docs/data/galexie/admin_guide/setup.mdx +++ b/docs/data/galexie/admin_guide/setup.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 # Setup -### Google Cloud Platform (GCP) credentials +### Google Cloud Platform (GCP) credentials {#google-cloud-platform-gcp-credentials} Create application default credentials by using your user account for your GCP project by following these steps: @@ -14,7 +14,7 @@ Create application default credentials by using your user account for your GCP p 3. Create [application default credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc#google-idp) and it should automatically store in this location: `$HOME/.config/gcloud/application_default_credentials.json.` 4. Verify that this file exists before moving on to the next step. -### Google Cloud Storage (GCS) bucket +### Google Cloud Storage (GCS) bucket {#google-cloud-storage-gcs-bucket} If you already have a GCS bucket with read and write permissions, you can skip this section. If not, follow these steps: diff --git a/docs/data/horizon/README.mdx b/docs/data/horizon/README.mdx index c5de28872..48dbc20fb 100644 --- a/docs/data/horizon/README.mdx +++ b/docs/data/horizon/README.mdx @@ -17,7 +17,7 @@ This guide describes how to administer a production Horizon instance (refer to t Before we begin, it's worth reiterating the sentiment echoed in the [Core Node](../../validators/README.mdx) documentation: **we do not endorse running Horizon backed by a standalone Stellar Core instance**, and especially not by a _validating_ Stellar Core. These are two separate concerns, and decoupling them is important for both reliability and performance. Horizon instead manages its own, pared-down version of Stellar Core optimized for its own subset of needs (we'll refer to this as a "Captive Core" instance). -## Why Run Horizon? +## Why Run Horizon? {#why-run-horizon} Running Horizon within your own infrastructure provides a number of benefits. You can: @@ -29,7 +29,7 @@ The Stellar Development Foundation (SDF) runs two instances of Horizon: - [horizon-testnet.stellar.org](https://horizon-testnet.stellar.org/) for interacting with the [testnet](../../learn/fundamentals/networks.mdx) - [horizon-futurenet.stellar.org](https://horizon-futurenet.stellar.org/) for interacting with the [futurenet](../../learn/fundamentals/networks.mdx) -## In These Docs +## In These Docs {#in-these-docs} - [Admin Guide](./admin-guide/README.mdx): how to set up your own Horizon instance. - [Structure](./api-reference/structure/README.mdx): how Horizon is structured. diff --git a/docs/data/horizon/admin-guide/configuring.mdx b/docs/data/horizon/admin-guide/configuring.mdx index ed0ca352d..0ddf756ec 100644 --- a/docs/data/horizon/admin-guide/configuring.mdx +++ b/docs/data/horizon/admin-guide/configuring.mdx @@ -5,7 +5,7 @@ sidebar_position: 30 import { Alert } from "@site/src/components/Alert"; -## Prerequisites +## Prerequisites {#prerequisites} - You have identified the [installation](./installing.mdx) method for the host system: @@ -23,7 +23,7 @@ You are now ready to identify the configuration parameters needed to perform thr To perform these roles, you can choose from one of two deployment modes below (single instance deployment or multiple instance deployment). Each has its own configuration parameters. -## Single Instance Deployment +## Single Instance Deployment {#single-instance-deployment} Run `stellar-horizon` in a single o/s process and it will perform all three roles simultaneously. @@ -33,11 +33,11 @@ Run `stellar-horizon` in a single o/s process and it will perform all three role | `NETWORK` | pubnet | | `HISTORY_RETENTION_COUNT` | 518400 | -## Multiple Instance Deployment +## Multiple Instance Deployment {#multiple-instance-deployment} In this scalable deployment variant, you run multiple instances of `stellar-horizon`, each performing a subset of the roles. This allows you to horizontally scale each of the role functions independently. -### Ingestion Role Instance +### Ingestion Role Instance {#ingestion-role-instance} You must allocate **at least** one instance to perform ongoing ingestion to capture network activity. This will default to limiting storage of ingested network activity in the database to our recommendation of a sliding window of the last 30 days. @@ -48,7 +48,7 @@ You must allocate **at least** one instance to perform ongoing ingestion to capt | `HISTORY_RETENTION_COUNT` | 518400 | | `DISABLE_TX_SUB` | true | -### API Role Instance +### API Role Instance {#api-role-instance} You can run none or multiple instances to serve read-only API requests. Notice there is no need to define network settings here, as Horizon only reads from database. @@ -58,7 +58,7 @@ You can run none or multiple instances to serve read-only API requests. Notice t | `INGEST` | false | | `DISABLE_TX_SUB` | true | -### Transaction Submission Role Instance +### Transaction Submission Role Instance {#transaction-submission-role-instance} You can run none or multiple instances to serve transaction submission requests. If you run an instance with transaction submission enabled, the Horizon deployment is required to have at least one instance perform the ingestion role on the same database. Horizon transaction submission depends on this **live** ingestion taking place against the database in order to confirm tx submission status. @@ -72,40 +72,40 @@ If setting `INGEST=false`, then **must** define the `STELLAR_CORE_URL` variable | `STELLAR_CORE_URL` | http://example.watcher.core:11626 | | `INGEST` | false | -## Notes +## Notes {#notes} -### Ingestion +### Ingestion {#ingestion} If you have configured your deployment to perform the ingestion role, then it is **strongly** recommended to review [Ingestion](./ingestion.mdx) first and [Filtering](./ingestion-filtering.mdx) second and factor that into configuration parameters to achieve best performance related to your application requirements before proceeding further. - Horizon will create a sub-directory under the current working directory of the o/s process to store captive core runtime data files. Refer to [Prerequisites](./prerequisites.mdx) for the type and amount of storage recommended. You can override this location with the optional `CAPTIVE_CORE_STORAGE_PATH` environment variable, set to a directory on the file system where captive core will store the runtime files. -### `DISABLE_TX_SUB` +### `DISABLE_TX_SUB` {#disable_tx_sub} This config parameter is optional, set as FALSE by default. Controls whether Horizon will accept HTTP requests to the `/tx` API endpoint and forward to the network. Refer to [Channel Accounts](../../../learn/encyclopedia/transactions-specialized/channel-accounts.mdx) for some recommendations on optional client transaction submission optimizations. - When set to FALSE, it requires **live** ingestion process to be running on the same database because Horizon depends on new ledgers from the network to confirm a transaction submission status, Horizon will report a startup error if it detects no **live** ingestion. Requires `INGEST=true` or `STELLAR_CORE_URL` to be defined for access to a Core instance. - When transaction submission is disabled by setting it to TRUE, Horizon will return 405 on POSTs to /tx. -### `NETWORK` +### `NETWORK` {#network} This config parameter is optional, can be one of Stellar's public networks, 'pubnet', or 'testnet'. Triggers Horizon to automatically set configurations for remaining Horizon settings and generate the correct core toml/cfg settings. If you only need Horizon to connect to one of those public Stellar networks, this will take care of all related configurations. - If you want to connect Horizon to a different Stellar network other than pubnet or testnet or override any of the defaults that `NETWORK` usage will initiate, the key environment variables that can be set are: `HISTORY_ARCHIVE_URLS`, `CAPTIVE_CORE_CONFIG_PATH`, `NETWORK_PASSPHRASE`, `CAPTIVE_CORE_STORAGE_PATH`, `STELLAR_CORE_URL`. -### `DB_URL` +### `DB_URL` {#db_url} This config parameter is required, specifies the Horizon database. It's value follows this format: `dbname= user= password= host=` -### `LOG_LEVEL` +### `LOG_LEVEL` {#log_level} This config parameter is optional, can be one of 'info', 'error', 'debug'. -### `HISTORY_RETENTION_COUNT` +### `HISTORY_RETENTION_COUNT` {#history_retention_count} This config parameter is optional, it determines the maximum sliding window of historical network data to retain on the database from ingestion. The value is expressed as absolute ledger count, which is an indirect way to define a duration of time, each ledger being approximately 5 seconds. It is defaulted to 0, which means it will not purge any history from the database. To enact the recommended sliding window of one month, set this to 518400, which is the approximate number of ledgers in 30 days. Refer to [Compute Resources](./prerequisites.mdx) for how database storage space is closely related to this setting. -## Passing Configurations to Horizon +## Passing Configurations to Horizon {#passing-configurations-to-horizon} The `stellar-horizon` binary searches process environment variables for configuration. Depending on how Horizon was installed, the method you perform to configure the process environment will differ: @@ -122,7 +122,7 @@ The `stellar-horizon` binary searches process environment variables for configur - Non-Helm: pass all configuration parameters to the horizon docker image as [docker environment variables](https://docs.docker.com/engine/reference/commandline/run/#env). - Helm: pass all configuration parameters in the [Helm install command](https://helm.sh/docs/helm/helm_install/) as a values file. -## Initialize Horizon Database +## Initialize Horizon Database {#initialize-horizon-database} Before running the Horizon server for the first time, you must initialize the Horizon database. This database will be used for all of the information produced by Horizon, most notably historical information about transactions that have occurred on the Stellar network. @@ -151,7 +151,7 @@ $ export DATABASE_URL="dbname=horizon user=horizon password= host=:/ingestion/filters/asset`. diff --git a/docs/data/horizon/admin-guide/ingestion.mdx b/docs/data/horizon/admin-guide/ingestion.mdx index b2e386964..1b74f9cff 100644 --- a/docs/data/horizon/admin-guide/ingestion.mdx +++ b/docs/data/horizon/admin-guide/ingestion.mdx @@ -7,14 +7,14 @@ import { CodeExample } from "@site/src/components/CodeExample"; Horizon API provides most of its utility through ingested data, and your Horizon server can be configured to listen for and ingest transaction results from the Stellar network. Ingestion enables API access to both current state (e.g. someone's balance) and historical state (e.g. someone's transaction history). -## Ingestion Types +## Ingestion Types {#ingestion-types} There are two primary ingestion use cases for Horizon operations: - Ingesting **live** data to stay up to date with the latest ledgers from the network, accumulating a sliding window of aged ledgers; - Ingesting **historical** data to retroactively add network data from a time range in the past to the database. -## Determine Storage Space +## Determine Storage Space {#determine-storage-space} You should think carefully about the historical timeframe of ingested data you'd like to retain in Horizon's database. The storage requirements for transactions on the Stellar network are substantial and are growing unbounded over time. This is something that you may need to continually monitor and reevaluate as the network continues to grow. We have found that most organizations need only a small fraction of recent historical data to satisfy their use cases. Through analyzing traffic patterns on SDF's Horizon instance, we see that most requests are for very recent data. @@ -25,13 +25,13 @@ To keep your storage footprint small, we recommend the following: - If your application can work on a [filtered network dataset](./ingestion-filtering.mdx) based on specific accounts and assets, then we recommend applying ingestion filter rules. When using filter rules, it provides benefit of choice in longer historical retention timeframe since the filtering is reducing the overall database size to such a degree, historical retention(`HISTORY_RETENTION_COUNT`) can be set in terms of years rather than months or even disabled(`HISTORY_RETENTION_COUNT=0`). - If you cannot limit your history retention window to 30 days and cannot use filter rules, we recommend considering [Stellar Hubble Data Warehouse](../../hubble/README.mdx) for any historical data. -### Ingesting Live Data +### Ingesting Live Data {#ingesting-live-data} This option is enabled by default and is the recommended mode of ingestion to run. It is controlled with environment configuration flag `INGEST`. Refer to [Configuration](./configuring.mdx) for how an instance of Horizon performs the ingestion role. For high availability requirements, **we recommend deploying more than one live ingesting instance**, as this makes it easier to avoid downtime during upgrades and adds resilience, ensuring you always have the latest network data (refer to [Ingestion Role Instance](./configuring.mdx#multiple-instance-deployment)). -### Ingesting Historical Data +### Ingesting Historical Data {#ingesting-historical-data} Import network data from a past date range into the database: @@ -49,7 +49,7 @@ Typically the only time you need to run historical ingestion is once when boot-s You can run historical ingestion in parallel in background while your main Horizon server separately performs **live** ingestion. If the range specified overlaps with data already in the database, it is ok and will simply be overwritten, effectively idempotent. -#### Parallel Ingestion Workers +#### Parallel Ingestion Workers {#parallel-ingestion-workers} You can parallelize the ingestion of target historical ledger range by dividing it into sequential slices of smaller ranges and run the db reingest range command for each sub-range in parallel as a separate process on the same or a different machine. The shorthand rule for best performance is to identify the number of CPU cores available per target machine, if multi-core, then add `--parallel-workers ` to the command, this will enable the command to further parallelize internally within a single process using multiple threads and sub-divided smaller ranges. @@ -69,13 +69,13 @@ horizon2> stellar-horizon db reingest range 15001 30000 --parallel-workers 2 -### Notes +### Notes {#notes} -#### Some endpoints may report not available during **live** ingestion +#### Some endpoints may report not available during **live** ingestion {#some-endpoints-may-report-not-available-during-live-ingestion} - Endpoints that display current state information from **live** ingestion may return `503 Service Unavailable`/`Still Ingesting` error. An example is the `/paths` endpoint (built using offers). Such endpoints will become available after **live** ingestion has finished network synchronization and catch up (usually within a couple of minutes). -#### If more than five minutes has elapsed with no new ingested data: +#### If more than five minutes has elapsed with no new ingested data: {#if-more-than-five-minutes-has-elapsed-with-no-new-ingested-data} - Verify the host machine meets recommended [Prerequisites](./prerequisites.mdx). @@ -92,6 +92,6 @@ horizon2> stellar-horizon db reingest range 15001 30000 --parallel-workers 2 sudo dd if=/dev/zero of=/tmp/test_speed.img bs=1G count=1 ``` -#### Monitoring Ingestion Process +#### Monitoring Ingestion Process {#monitoring-ingestion-process} For high-availability deployments, it is recommended to implement monitoring of ingestion process for visibility on performance/health. Refer to [Monitoring](./monitoring.mdx) for accessing logs and metrics from Horizon. Stellar publishes the example [Horizon Grafana Dashboard](https://grafana.com/grafana/dashboards/13793-stellar-horizon/), which demonstrates queries against key horizon ingestion metrics, specifically look at the `Local Ingestion Delay [Ledgers]` and `Last ledger age` in the `Health Summary` panel. diff --git a/docs/data/horizon/admin-guide/installing.mdx b/docs/data/horizon/admin-guide/installing.mdx index e244cd482..3fc27d341 100644 --- a/docs/data/horizon/admin-guide/installing.mdx +++ b/docs/data/horizon/admin-guide/installing.mdx @@ -7,21 +7,21 @@ import { CodeExample } from "@site/src/components/CodeExample"; To install Horizon in production or non-development environments, we recommend the following based on target infrastructure: -### Bare-Metal +### Bare-Metal {#bare-metal} - If host is Debian Linux, install prebuilt binaries [from repositories](#package-manager) using a package manager. - For any other hosts, download [prebuilt release binaries](#prebuilt-releases) of Stellar Horizon and Core for host target architecture and operation system or [compile from the source](https://github.com/stellar/go/blob/master/services/horizon/internal/docs/GUIDE_FOR_DEVELOPERS.md#building-horizon). -### Containerized +### Containerized {#containerized} - Non-Orchestrated: if the target deployment environment does not include a container orchestrator such as Kubernetes, then this means you intend to run the Horizon release image from [dockerhub.com/stellar/stellar-horizon](https://hub.docker.com/r/stellar/stellar-horizon) as a container directly with Docker daemon on host. Choose the tag of the Horizon image for the specific release version and then pull the image using `docker pull stellar/stellar-horizon:` to get it locally onto host. - Orchestrated: when the target environment has container orchestration, such as Kubernetes cluster, we recommend using the [Horizon Helm Chart](https://github.com/stellar/helm-charts/tree/main/charts/horizon) to manage the installation and deployment lifecycle of the Horizon image as container(s) on the cluster. To install Horizon in development environments, refer to the [Horizon README](https://github.com/stellar/go/blob/master/services/horizon/README.md#try-it-out) from the source code repo for options available. -### Notes on Installation +### Notes on Installation {#notes-on-installation} -#### Package Manager +#### Package Manager {#package-manager} SDF publishes new releases to its custom Ubuntu repositories. Follow [this guide](https://github.com/stellar/packages/blob/master/docs/adding-the-sdf-stable-repository-to-your-system.md#adding-the-sdf-stable-repository-to-your-system) to add the stable SDF repository to your host system. If you are interested in installing release candidate versions of software that have yet to reach stable, refer to [Adding the Bleeding Edge Testing Repository](https://github.com/stellar/packages/blob/master/docs/adding-the-sdf-stable-repository-to-your-system.md#adding-the-bleeding-edge-testing-repository). Lastly, [install package](https://github.com/stellar/packages/blob/master/docs/installing-individual-packages.md#installing-individual-packages) outlines the various commands that these packages make available. @@ -36,17 +36,17 @@ sudo apt install stellar-horizon stellar-core -#### Prebuilt Releases +#### Prebuilt Releases {#prebuilt-releases} Refer to the list of [Horizon releases](https://github.com/stellar/go/releases) and [Core releases](https://github.com/stellar/stellar-core/releases). Copy the binaries to host PATH. -#### Verify Bare-Metal Installations +#### Verify Bare-Metal Installations {#verify-bare-metal-installations} Run `stellar-horizon --help` from a terminal. If the help for Horizon is displayed, your installation was successful. Some shells (such as [zsh](https://www.zsh.org/)) cache PATH lookups. You may need to clear your cache (by using `rehash` in zsh, for example) or restart your shell before trying to run the command above. -#### Helm Chart Installation +#### Helm Chart Installation {#helm-chart-installation} If the deployment can be done on Kubernetes, there is a [Horizon Helm Chart](https://github.com/stellar/helm-charts/blob/main/charts/horizon) available. Install the [Helm CLI tool](https://helm.sh/docs/intro/install/), if you haven't already on your workstation, minimum of version 3. Next, add the Stellar repo to the helm client's list of repos and confirm that you can view the list of available chart versions for the repo: @@ -73,6 +73,6 @@ helm template -f charts/horizon/values.yaml charts/horizon/ -## Next Step +## Next Step {#next-step} After installation is complete, you are now ready to proceed to [Configuring Horizon](./configuring.mdx)! diff --git a/docs/data/horizon/admin-guide/monitoring.mdx b/docs/data/horizon/admin-guide/monitoring.mdx index 2b0389e43..91fc394dc 100644 --- a/docs/data/horizon/admin-guide/monitoring.mdx +++ b/docs/data/horizon/admin-guide/monitoring.mdx @@ -5,11 +5,11 @@ sidebar_position: 60 import { CodeExample } from "@site/src/components/CodeExample"; -## Metrics +## Metrics {#metrics} Metrics are emitted from Horizon over HTTP in [the de facto text-based exposition format](https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#text-based-format). The Metrics are published on the _private_ `/metrics` path of Horizon Admin port, which is an optional service to be started and will be bound by the Horizon process onto the host machine loopback network(localhost or 127.0.0.1). To enable the Admin port, add environment configuration parameter `ADMIN_PORT=XXXXX`, the metrics endpoint will be reachable on the host machine as `localhost:/metrics`. You can verify this by pointing any browser that can reach this address, it will print out all metrics keys. -### Exporting +### Exporting {#exporting} Once the Admin port is enabled, the Horizon metrics endpoint can be 'scraped' by external monitoring infrastructure. Since the metrics output is encoded to [standard text-based format](https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#text-based-format) it will be compatible for usage with many types of monitoring infrastructure that interoperate with the same standard format. @@ -19,7 +19,7 @@ One real-world example for exporting from a bare metal Horizon installation (Hor In container-orchestrated environments such as Kubernetes, you can use the same exporter strategy. We assume you already have a metrics infrastructure deployment like Prometheus and Grafana setup on the cluster via the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator), and will just need to configure that infrastructure to scrape the Horizon pod based on the ADMIN_PORT. -### Data model +### Data model {#data-model} There are numerous application metrics keys emitted by Horizon at runtime, encoded in four types of exposition formats: `counter`, `gauge`, `histogram`, `summary`. Each key is further qualified with labels for more granularity. To summarize, we can highlight the groupings of metrics keys by common function denoted in the prefix of their name: @@ -52,7 +52,7 @@ horizon_http_requests_duration_seconds{method="GET",route="/",status="200",strea ``` -### Queries +### Queries {#queries} Build queries against the metrics data model to highlight the performance of a given Horizon deployment. Refer to Stellar's [Grafana Horizon Dashboard](https://grafana.com/grafana/dashboards/13793-stellar-horizon/) for examples of metrics queries to derive application performance: @@ -70,7 +70,7 @@ Build queries against the metrics data model to highlight the performance of a g Choose the [revisions tab](https://grafana.com/grafana/dashboards/13793-stellar-horizon/?tab=revisions), and download the dashboard source file to have access to the Grafana dashboard source code and metrics queries that build each panel in dashboards. -### Alerts +### Alerts {#alerts} Once queries are developed on a Grafana dashboard, it enables a convenient follow-on step to add [alert rules](https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-grafana-managed-rule/) based on specific queries to trigger notifications when thresholds are exceeded. @@ -82,7 +82,7 @@ Here are some example alerts to consider with potential causes and solutions. | Ingestion is slow | host server compute resources are low | increase compute specs | | HTTP API responses are returning errors | host server compute resources are low or networking to DB is lost | check the [Horizon logs](#logs) to see what errors are being emitted, narrow down root cause from there | -## Logs +## Logs {#logs} Horizon will output logs to operating system's standard out. It will log on all aspects of runtime, including HTTP requests and ingestion. Typically, there are very few `warn` or `error` severity level messages emitted. The default severity level logged in Horizon is configured to `LOG_LEVEL=info`, this environment configuration parameter can be set to one of `trace, debug, info, warn, error`. The verbosity of log output is inverse of the severity level chosen. I.e. for most verbose logs use 'trace', for least verbose logs use 'error'. @@ -91,7 +91,7 @@ For production deployments, we recommend using the default severity setting of ` - Bare metal deployment direct to operating system, redirect the standard out from Horizon process to a file on disk and apply a log rotation tool on the file such as [logrotate](https://man7.org/linux/man-pages/man8/logrotate.8.html) to manage disk space usage. - Orchestrated deployment on Kubernetes, use an EFK/ELK stack on the cluster and it can be configured to capture the standard out from Horizon pod. -## Runtime Profiling +## Runtime Profiling {#runtime-profiling} Horizon is written in Golang, therefore it has been enabled to optionally emit the Golang runtime diagnostics and profiling output [pprof](https://go.dev/doc/diagnostics). The pprof HTTP endpoints are hosted on Horizon's admin HTTP port, it can be enabled by adding environment configuration parameter `ADMIN_PORT=XXXXX`, since the admin port binding is disabled by default. @@ -113,6 +113,6 @@ Entering interactive mode (type "help" for commands, "o" for options) (pprof) web ``` -## I'm Stuck! Help! +## I'm Stuck! Help! {#im-stuck-help} If any of the above steps don't work or you are otherwise prevented from correctly setting up Horizon, please join our community and let us know. Either post a question at [our Stack Exchange](https://stellar.stackexchange.com/) or chat with us on [Horizon Discord](https://discord.com/channels/897514728459468821/912466080960766012) to ask for help. diff --git a/docs/data/horizon/admin-guide/overview.mdx b/docs/data/horizon/admin-guide/overview.mdx index 54ff38779..d1acf65d7 100644 --- a/docs/data/horizon/admin-guide/overview.mdx +++ b/docs/data/horizon/admin-guide/overview.mdx @@ -9,7 +9,7 @@ This guide describes how to administer a production Horizon instance (refer to t Before we begin, it's worth reiterating the sentiment echoed in the [Run a Core Node](../../../validators/README.mdx) guide: **we do not endorse running Horizon backed by a standalone Stellar Core instance**, and especially not by a _validating_ Stellar Core. These are two separate concerns, and decoupling them is important for both reliability and performance. Horizon instead manages its own, pared-down version of Stellar Core optimized for its own subset of needs (we'll refer to this as a "Captive Core" instance). -## Why Run Horizon? +## Why Run Horizon? {#why-run-horizon} Running Horizon within your own infrastructure provides a number of benefits. You can: diff --git a/docs/data/horizon/admin-guide/prerequisites.mdx b/docs/data/horizon/admin-guide/prerequisites.mdx index f6a68526f..8e4578ba1 100644 --- a/docs/data/horizon/admin-guide/prerequisites.mdx +++ b/docs/data/horizon/admin-guide/prerequisites.mdx @@ -7,18 +7,18 @@ The Horizon service is responsible for synchronizing with the Stellar network an The Horizon service can be [installed](./installing.mdx) on bare metal or a virtual machine. It is natively supported on both Linux and Windows operating systems. -## Single Instance Deployment Model +## Single Instance Deployment Model {#single-instance-deployment-model} For a basic setup using the [Single Instance Deployment model](./configuring.mdx#single-instance-deployment), you will need a sum of two distinct compute profiles: - One for hosting the Horizon service - Another for hosting the PostgreSQL server -### Hardware requirements +### Hardware requirements {#hardware-requirements} The minimum hardware specifications to effectively run Horizon are as follows: -#### Horizon Compute Instance: +#### Horizon Compute Instance: {#horizon-compute-instance} | Node Type | CPU | RAM | Disk | AWS SKU | Google Cloud SKU | | --- | --- | --- | --- | --- | --- | @@ -26,7 +26,7 @@ The minimum hardware specifications to effectively run Horizon are as follows: _\* Assuming a 30-day retention window for data storage._ -#### PostgreSQL Database Server Compute Instance: +#### PostgreSQL Database Server Compute Instance: {#postgresql-database-server-compute-instance} | Node Type | CPU | RAM | Disk | AWS SKU | Google Cloud SKU | | --- | --- | --- | --- | --- | --- | @@ -38,11 +38,11 @@ Please note that a minimum of PostgreSQL version 12 is required. These specifications assume a 30-day retention window for data storage. For a longer retention window, the system requirements will be higher. For more information about data ingestion, history retention, and managing storage, check the [ingestion](./ingestion.mdx) section. -## Multiple Instance Deployment +## Multiple Instance Deployment {#multiple-instance-deployment} To achieve high availability, redundancy, and high throughput, refer to the [scaling](./scaling.mdx) documentation. It provides a detailed overview of several different deployment strategies you can employ, depending on the SLA you need your Horizon instance to achieve. -## Network Access +## Network Access {#network-access} - Ensure that the Horizon instance can establish a connection with the PostgreSQL database instance. The default port for PostgreSQL is 5432. diff --git a/docs/data/horizon/admin-guide/running.mdx b/docs/data/horizon/admin-guide/running.mdx index 2877ec23c..b4916a5bd 100644 --- a/docs/data/horizon/admin-guide/running.mdx +++ b/docs/data/horizon/admin-guide/running.mdx @@ -7,19 +7,19 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once you have [established the Horizon database](./configuring.mdx#initialize-horizon-database) and have [identified the Horizon runtime config per host](./configuring.mdx#prerequisites), you're ready to run Horizon. -## Bare-metal installation +## Bare-metal installation {#bare-metal-installation} Run the `stellar-horizon` binary with the [appropriate environment parameters](./configuring.mdx#passing-configurations-to-horizon) set (or `stellar-horizon-cmd serve` if you [installed via the package manager](./installing.mdx#package-manager), which will automatically import your configuration from `/etc/default/stellar-horizon`). -## Containerized installation +## Containerized installation {#containerized-installation} You don't execute the Horizon binary directly, instead the [stellar/stellar-horizon](https://hub.docker.com/r/stellar/stellar-horizon) image has a pre-defined entrypoint that will start running Horizon at image startup time. The Horizon process will get all configuration settings from container environment variables. -### Docker daemon +### Docker daemon {#docker-daemon} Use `docker run stellar/stellar-horizon: --env-file `, and specify each Horizon configuration flag identified during [Configuring](./configuring.mdx) as a separate line in `` of `HORIZON_CONFIG_PARAM=value`. -### Kubernetes using Helm Chart +### Kubernetes using Helm Chart {#kubernetes-using-helm-chart} Ensure you have followed the [pre-requisite](./installing.mdx#helm-chart-installation) of installing the Helm CLI tool and added the Stellar chart repo to Helm client. diff --git a/docs/data/horizon/admin-guide/scaling.mdx b/docs/data/horizon/admin-guide/scaling.mdx index a80602aca..f473faf6b 100644 --- a/docs/data/horizon/admin-guide/scaling.mdx +++ b/docs/data/horizon/admin-guide/scaling.mdx @@ -9,7 +9,7 @@ Horizon enables different logical tiers that can be scaled independently for inc - Captive Core (ingestion and transaction submission) - Database (storage) -## Single Instance Deployment +## Single Instance Deployment {#single-instance-deployment} It is recommend to start with a [single instance deployment](./prerequisites.mdx), and scale up based on the needs of your particular use-case. @@ -19,7 +19,7 @@ In this setup, a single instance of Horizon performs all three [roles](./configu ![](/assets/horizon-scaling/Topology-single.png) -## Scaling to Multiple Instances +## Scaling to Multiple Instances {#scaling-to-multiple-instances} There are a few reasons you may choose to scale to multiple instances of Horizon. @@ -33,7 +33,7 @@ When scaling Horizon, it is worth it to note that Horizon's [rate limiting](../a ![](/assets/horizon-scaling/Topology-multiple.png) -## Logically Isolating Ingestion +## Logically Isolating Ingestion {#logically-isolating-ingestion} Ingestion is the process by which new ledgers are propagated into Horizon's database. It's health is critical, as degredations in performance can result in falling behind the last closed ledger, leaving your end-users unaware of the current state of the network, and unable to successfully submit new transactions. Any lag in ingestion would likely be considered downtime for your service @@ -48,7 +48,7 @@ The Horizon API role requires only read-only permissions to a database for all a ![](/assets/horizon-scaling/Topology-ingestion-isolation.png) -## Logically Isolating Transaction Submission +## Logically Isolating Transaction Submission {#logically-isolating-transaction-submission} In the above example, ingestion is safely isolated from most API traffic, which has historically been the large majority of traffic. However, transaction submission still needs to be served by a core instance, and so API instances must passthrough their transaction submission requests to an ingesting instance. diff --git a/docs/data/horizon/admin-guide/upgrading.mdx b/docs/data/horizon/admin-guide/upgrading.mdx index 3d15a16ba..9c24e2e96 100644 --- a/docs/data/horizon/admin-guide/upgrading.mdx +++ b/docs/data/horizon/admin-guide/upgrading.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Here we'll describe the recommended steps for upgrading a Horizon 2.x installation. -### Pre-requisites +### Pre-requisites {#pre-requisites} - An existing Horizon deployment consisting of one or more instances of Horizon. - All instances are on same 2.x version to begin. @@ -16,7 +16,7 @@ Here we'll describe the recommended steps for upgrading a Horizon 2.x installati - If [deployed direct on Docker daemon](./installing.mdx#containerized), you have command line access to the host that is running the Docker daemon. - If [deployed on Kubernetes with Helm chart](./installing.mdx#helm-chart-installation), you have kubectl and helm command line tools on your workstation and a user login with appropriate access levels to change resources in target namespace of Horizon deployment on the cluster. -### Assess current installation +### Assess current installation {#assess-current-installation} - Identify the list of all instances of Horizon that need to be upgraded. @@ -42,11 +42,11 @@ Here we'll describe the recommended steps for upgrading a Horizon 2.x installati - All instances should report the same version, if not, the system may be inconsistent, use this upgrade as opportunity to establish consistency and get them all on same version. -### Determine the target version for upgrade +### Determine the target version for upgrade {#determine-the-target-version-for-upgrade} Now that you know your current Horizon version, visit [Horizon Releases](https://github.com/stellar/go/releases) and choose the next greater version above your current version to upgrade. Follow steps [recommended by GitHub to compare releases](https://docs.github.com/en/repositories/releasing-projects-on-github/comparing-releases), click on the `Compare` dropdown of the chosen release, and then select your current release and GH will display the differences between versions, select the `Files changed` tab, and go to the `services/horizon/CHANGELOG.md`, it will highlight the new release notes for changes that have occurred between your current version and the new version you selected. Review this and look for any `Breaking Changes`, `State Rebuild` and `DB Schema Migration` sections for consideration, as the latter two will also mention expected time for the state rebuild or db migration to apply respectively. -### Install the new version +### Install the new version {#install-the-new-version} Now that you have indentified the new version and are aware of the potential impacts from upgrading to new version based on release notes, such as state rebuilds and db migrations, you are informed and ready to proceed with upgrade. @@ -95,7 +95,7 @@ A good strategy for upgrading Horizon and applicable to single or multi-instance -### Confirming the upgrade on single ingestion instance first +### Confirming the upgrade on single ingestion instance first {#confirming-the-upgrade-on-single-ingestion-instance-first} If you have [monitoring](./monitoring.mdx) infrastructure in place, then you have two options for assessing the upgrade status: @@ -122,7 +122,7 @@ If metrics and/or the Horizon 'status' url respones don't indicate healthy statu 2023/09/22 18:27:01 successfully applied 5 Horizon migrations ``` -### Upgrade all remaining instances +### Upgrade all remaining instances {#upgrade-all-remaining-instances} At this point, you have upgraded one ingesting instance to the new Horizon version, it has automatically updated the database if required and the instance is running with healthy status. Now, install the same Horizon software version on the remainder of instances, restarting each after the upgrade. For bare-metal and docker daemon installations that will likely be self explanatory on how to accomplish that for remainder of instances, on helm chart installations, run the helm upgrade again, setting the image tag and also restoring original `replicaCount`s: diff --git a/docs/data/horizon/api-reference/errors/error-handling.mdx b/docs/data/horizon/api-reference/errors/error-handling.mdx index 1f711da82..bc51615d6 100644 --- a/docs/data/horizon/api-reference/errors/error-handling.mdx +++ b/docs/data/horizon/api-reference/errors/error-handling.mdx @@ -16,7 +16,7 @@ There are many possible error codes when executing these actions, and you can ty - Request adjustments: adjusting the request to resolve structural errors with queries or transaction submissions. Suppose you’ve included a bad parameter, malformed your XDR, or otherwise didn’t follow the endpoint’s specification. In these cases, resolve the error by referencing the details or result codes of the error response. - Polling and retrying: this is the recommended way to work around latency or congestion issues encountered along the pipeline between your computer and the Stellar network, which can sometimes happen due to the nature of distributed systems. -## Error Handling for Queries +## Error Handling for Queries {#error-handling-for-queries} Many `GET` requests have specific parameter requirements, and while the SDKs can help enforce them, you can still pass invalid arguments (for example, an asset string that isn’t [SEP-11](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0011.md#asset-trustlineasset) compatible) that error out every time. In this scenario, there’s nothing you can do aside from following the API specification. The `extras` field of the error response will often clue you in on where to look and what to look for. @@ -34,7 +34,7 @@ curl -s https://horizon-testnet.stellar.org/claimable_balances/0000 | jq '.extra Note that the SDKs make it a point to distinguish an invalid request (as above) versus a missing resource (a `404 Not Found`) (for example, the generic `NetworkError` versus a `NotFoundError` in the JavaScript SDK), where the latter might not be considered an error depending on your situation. -## Error Handling for Transaction Submissions +## Error Handling for Transaction Submissions {#error-handling-for-transaction-submissions} Horizon currently supports two types of transaction submission endpoints: @@ -45,16 +45,16 @@ Note that polling the transaction hash will return a 404 until it gets included There are some resolution strategies that are common between the 2 endpoints while others strategies are more endpoint specific. -### Request Adjustments +### Request Adjustments {#request-adjustments} Certain transaction submission failures also need adjustments to succeed. - If the XDR is malformed, or the transaction is otherwise invalid, you’ll encounter a `400 Bad Request` (for example, an invalid source account). Both transactions and their operations can be easily malformed or invalid: look at the `extras.result_codes` field for details and cross-reference them with the appropriate result codes documentation to determine specifics. - Transaction fees are also a safe adjustment by modifying the fees via a [fee-bump transaction](../../../../learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx) if you get a `tx_insufficient_fee` error. Refer to the [Insufficient Fees and Surge Pricing](#insufficient-fees-and-surge-pricing) section later in this document for more information on managing fees and strategies around it. -### Polling and Retrying Transactions +### Polling and Retrying Transactions {#polling-and-retrying-transactions} -#### Async Transaction Submission +#### Async Transaction Submission {#async-transaction-submission} Submissions using the `/transactions_async` endpoint return an immediate response back from Stellar-Core. There are different actions that clients can take based on the specific `tx_status` returned: @@ -108,7 +108,7 @@ server -#### Synchronous Transaction Submission +#### Synchronous Transaction Submission {#synchronous-transaction-submission} Due to the blocking nature of this endpoint, things are a little different compared to the asynchronous strategy. There are 3 possible scenarios that clients can encounter: @@ -124,7 +124,7 @@ Do note that resubmitting a transaction is only safe when it is unchanged - same ::: -### Example: Using Time Bounds +### Example: Using Time Bounds {#example-using-time-bounds} Timebounds are optional but **highly** recommended as they put a definitive time limit on the transaction's finality - after it times out, you will know for sure whether it made it into a ledger. For example, you submit a transaction, and it enters the queue of the Stellar network, but Horizon crashes while giving you a response. Uncertain about the transaction status, you resubmit the transaction (with no changes!) until either (a) Horizon comes back up to give you a reply or (b) your time bounds are exceeded. @@ -168,7 +168,7 @@ function submitTransaction(tx, timeout) { We assume the existence of a sleep implementation similar to the one [here](https://stackoverflow.com/a/39914235). Be sure to integrate backoff into your retry mechanism. In our example error-handling code above, we implement a simple linear backoff, but there are [plenty of recommendations](https://backoff-utils.readthedocs.io/en/latest/strategies.html#why-are-backoff-strategies-useful) for various other strategies. Backoff is important both for maintaining performance and avoiding rate-limiting issues. -### Example: Invalid Sequence Numbers +### Example: Invalid Sequence Numbers {#example-invalid-sequence-numbers} These errors typically occur when you have an outdated view of an account. This could be because multiple devices are using this account, you have concurrent submissions happening, or other reasons. The solution is relatively simple: retrieve the account details and try again with an updated sequence number. @@ -196,7 +196,7 @@ Despite the solution’s simplicity, things can go wrong fast if you don’t und Suppose you submit transactions from multiple places in your application simultaneously, and your user spammed a _Send Payment_ button a few times in their impatience. If you send the exact same payment transaction for each tap, naturally, only one will succeed. The others will fail with an invalid sequence number (`tx_bad_seq`), and if you resubmit blindly with an updated sequence number (as we do above), these payments will also succeed, resulting in more than one payment being made when only one was intended. So **be very careful when resubmitting transactions** that have been modified to work around an error. -## Managing specific Errors +## Managing specific Errors {#managing-specific-errors} Here, we will cover specific errors commonly encountered during transaction submission and direct you to the appropriate resolution. @@ -217,15 +217,15 @@ Here, we will cover specific errors commonly encountered during transaction subm | `FEE_BUMP_INNER_FAILED` | -13 | The inner transaction of a fee-bump transaction failed | | `BAD_SPONSORSHIP` | -14 | The sponsorship is not confirmed | -### Insufficient fees and surge pricing +### Insufficient fees and surge pricing {#insufficient-fees-and-surge-pricing} See the [Fees section](../../../../learn/fundamentals/fees-resource-limits-metering.mdx) -### Rate limiting +### Rate limiting {#rate-limiting} Horizon may rate limit requests and return `429 Too Many Requests` error when exceeding the rate limits. If using your own instance, you may want to either increase or disable rate limiting. If you're using a third-party Horizon instance, you may want to deploy your own to have more control over this configuration or send requests less frequently. -### Insufficient XLM balance +### Insufficient XLM balance {#insufficient-xlm-balance} Any transaction that would reduce an account’s balance to less than the minimum will be rejected with an `INSUFFICIENT_BALANCE` error. Likewise, lumen selling liabilities that would reduce an account’s balance to less than the minimum plus lumen selling liabilities will be rejected with an `INSUFFICIENT_BALANCE` error. diff --git a/docs/data/horizon/api-reference/resources/effects/types.mdx b/docs/data/horizon/api-reference/resources/effects/types.mdx index 8abd3bd16..e58a36b77 100644 --- a/docs/data/horizon/api-reference/resources/effects/types.mdx +++ b/docs/data/horizon/api-reference/resources/effects/types.mdx @@ -8,7 +8,7 @@ import { AttributeTable } from "@site/src/components/AttributeTable"; There are eight groups of effect types. Each effect type has its own set of attributes. -### Account Effects +### Account Effects {#account-effects} @@ -42,7 +42,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Signer Effects +### Signer Effects {#signer-effects} @@ -61,7 +61,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Trustline Effects +### Trustline Effects {#trustline-effects} @@ -86,7 +86,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Trading Effects +### Trading Effects {#trading-effects} @@ -108,7 +108,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Data Effects +### Data Effects {#data-effects} @@ -127,7 +127,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Claimable Balance Effects +### Claimable Balance Effects {#claimable-balance-effects} @@ -146,7 +146,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Sponsorship Effects +### Sponsorship Effects {#sponsorship-effects} @@ -201,7 +201,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Liquidity Pool Effects +### Liquidity Pool Effects {#liquidity-pool-effects} @@ -229,7 +229,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Miscellaneous Effects +### Miscellaneous Effects {#miscellaneous-effects} diff --git a/docs/data/horizon/horizon-providers.mdx b/docs/data/horizon/horizon-providers.mdx index 704046896..5dc68b193 100644 --- a/docs/data/horizon/horizon-providers.mdx +++ b/docs/data/horizon/horizon-providers.mdx @@ -3,7 +3,7 @@ sidebar_position: 70 title: Ecosystem Horizon Providers --- -## Ecosystem Horizon Providers +## Ecosystem Horizon Providers {#ecosystem-horizon-providers} :::info @@ -36,6 +36,6 @@ SDF provides a Horizon endpoint but it is rate-limited and subject to changes su | `Futurenet` | `https://horizon-futurenet.stellar.org` | `https://friendbot-futurenet.stellar.org` | [SDF](http://www.stellar.org) | | `Testnet` | `https://horizon-testnet.stellar.org` | `https://friendbot.stellar.org` | [SDF](http://www.stellar.org) | -## Run Your Own Horizon +## Run Your Own Horizon {#run-your-own-horizon} If you are interested in running your own Horizon, please checkout [this page](./admin-guide/overview.mdx). diff --git a/docs/data/hubble/README.mdx b/docs/data/hubble/README.mdx index 92e20d2cf..88bca51dd 100644 --- a/docs/data/hubble/README.mdx +++ b/docs/data/hubble/README.mdx @@ -3,13 +3,13 @@ title: Hubble Introduction sidebar_position: 0 --- -## What is Hubble? +## What is Hubble? {#what-is-hubble} Hubble is an open-source, publicly available dataset that provides a complete historical record of the Stellar network. Similar to Horizon, it ingests and presents the data produced by the Stellar network in a format that is easier to consume than the performance-oriented data representations used by Stellar Core. The dataset is hosted on BigQuery–meaning it is suitable for large, analytic workloads, historical data retrieval and complex data aggregation. **Hubble should not be used for real-time data retrieval and cannot submit transactions to the network.** For real time use cases, we recommend [running an API server](../horizon/admin-guide/README.mdx). This guide describes when to use Hubble and how to connect. To view the underlying data structures, queries and examples, use the [Viewing Metadata](./analyst-guide/viewing-metadata.mdx) and [Optimizing Queries](./analyst-guide/optimizing-queries.mdx) tutorials. -## Why Use Hubble? +## Why Use Hubble? {#why-use-hubble} Some questions are hard to answer with the Horizon API and its underlying PostgreSQL database. This is because its infrastructure is optimized for quick database reads and writes so that it can process online transactions. Horizon can accurately store the results of these smaller transactions, however it sacrifices the ability to execute complex queries easily. The Stellar Network’s data footprint has also increased exponentially, which is creating space constraints and performance issues for Horizon instances that store the full historical record. @@ -21,7 +21,7 @@ Users should be aware of the following limitations: - The database is updated in intraday batches. There is no guarantee for same-day data availability. - The SDF hosts a public instance of Hubble, and end users incur the cost to execute queries. Visit the [BigQuery Pricing Page](https://cloud.google.com/bigquery/pricing#analysis_pricing_models) to learn more. -## Why We Chose BigQuery +## Why We Chose BigQuery {#why-we-chose-bigquery} BigQuery is Google Cloud’s data warehouse that comes with some key features that fulfill Stellar’s analytic needs. diff --git a/docs/data/hubble/admin-guide/data-curation/architecture.mdx b/docs/data/hubble/admin-guide/data-curation/architecture.mdx index 001650067..f2d5d6d22 100644 --- a/docs/data/hubble/admin-guide/data-curation/architecture.mdx +++ b/docs/data/hubble/admin-guide/data-curation/architecture.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import stellar_dbt_arch from "/img/hubble/stellar_dbt_architecture.png"; -## Architecture Overview +## Architecture Overview {#architecture-overview} diff --git a/docs/data/hubble/admin-guide/data-curation/getting-started.mdx b/docs/data/hubble/admin-guide/data-curation/getting-started.mdx index dfd520ed1..936177bb7 100644 --- a/docs/data/hubble/admin-guide/data-curation/getting-started.mdx +++ b/docs/data/hubble/admin-guide/data-curation/getting-started.mdx @@ -7,9 +7,9 @@ sidebar_position: 20 [stellar/stellar-dbt-public docker images](https://hub.docker.com/r/stellar/stellar-dbt-public) -## Recommended Usage +## Recommended Usage {#recommended-usage} -### Docker Image +### Docker Image {#docker-image} Generally if you do not need to modify any of the stellar-dbt-public code, it is recommended that you use the [stellar/stellar-dbt-public docker images](https://hub.docker.com/r/stellar/stellar-dbt-public) @@ -19,7 +19,7 @@ Example to run locally with docker: docker run --platform linux/amd64 -ti stellar/stellar-dbt-public:latest ``` -### Import stellar-dbt-public as a dbt Package +### Import stellar-dbt-public as a dbt Package {#import-stellar-dbt-public-as-a-dbt-package} Alternatively, if you need to build your own models on top of stellar-dbt-public, you can import stellar-dbt-public as a dbt package into a separate dbt project. @@ -94,28 +94,28 @@ models: - Models from the stellar-dbt-public package/repo will now be available in your new dbt project -## Building and Running Locally +## Building and Running Locally {#building-and-running-locally} -### Clone the repo +### Clone the repo {#clone-the-repo} ``` git clone https://github.com/stellar/stellar-dbt-public ``` -### Install required python packages +### Install required python packages {#install-required-python-packages} ``` pip install --upgrade pip && pip install -r requirements.txt ``` -### Install required dbt packages +### Install required dbt packages {#install-required-dbt-packages} ``` dbt deps ``` -### Running dbt +### Running dbt {#running-dbt} - There are many useful commands that come with dbt which can be found in the [dbt documentation](https://docs.getdbt.com/reference/dbt-commands#available-commands) - stellar-dbt-public is designed to use the `dbt build` command which will `run` the model and `test` the model table output diff --git a/docs/data/hubble/admin-guide/data-curation/overview.mdx b/docs/data/hubble/admin-guide/data-curation/overview.mdx index b97d88254..5adf654d6 100644 --- a/docs/data/hubble/admin-guide/data-curation/overview.mdx +++ b/docs/data/hubble/admin-guide/data-curation/overview.mdx @@ -7,7 +7,7 @@ Data curation in Hubble is done through [stellar-dbt-public](https://github.com/ It is worth noting that most users will not need to standup and run their own stellar-dbt-public instance. The Stellar Development Foundation provides public access to fully transformed Stellar network data through the public datasets and tables in GCP BigQuery. Instructions on how to access this data can be found in the [Connecting](../../analyst-guide/connecting.mdx) section. -## Why Run stellar-dbt-public? +## Why Run stellar-dbt-public? {#why-run-stellar-dbt-public} Running stellar-dbt-public within your own infrastructure provides a number of benefits. You can: diff --git a/docs/data/hubble/admin-guide/scheduling-and-orchestration/architecture.mdx b/docs/data/hubble/admin-guide/scheduling-and-orchestration/architecture.mdx index 21be8c3df..f174c0a81 100644 --- a/docs/data/hubble/admin-guide/scheduling-and-orchestration/architecture.mdx +++ b/docs/data/hubble/admin-guide/scheduling-and-orchestration/architecture.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import stellar_etl_airflow_arch from "/img/hubble/stellar_etl_airflow_architecture.png"; -## Architecture Overview +## Architecture Overview {#architecture-overview} diff --git a/docs/data/hubble/admin-guide/scheduling-and-orchestration/getting-started.mdx b/docs/data/hubble/admin-guide/scheduling-and-orchestration/getting-started.mdx index 52ae47ba8..b220feca9 100644 --- a/docs/data/hubble/admin-guide/scheduling-and-orchestration/getting-started.mdx +++ b/docs/data/hubble/admin-guide/scheduling-and-orchestration/getting-started.mdx @@ -9,13 +9,13 @@ import dbt_enriched_base_tables from "/img/hubble/dbt_enriched_base_tables.png"; [stellar-etl-airflow GitHub repository](https://github.com/stellar/stellar-etl-airflow/tree/master) -## GCP Account Setup +## GCP Account Setup {#gcp-account-setup} The Stellar Development Foundation runs Hubble in GCP using Composer and BigQuery. To follow the same deployment you will need to have access to GCP project. Instructions can be found in the [Get Started](https://cloud.google.com/docs/get-started) documentation from Google. Note: BigQuery and Composer should be available by default. If they are not you can find instructions for enabling them in the [BigQuery](https://cloud.google.com/bigquery?hl=en) or [Composer](https://cloud.google.com/composer?hl=en) Google documentation. -## Create GCP Composer Instance to Run Airflow +## Create GCP Composer Instance to Run Airflow {#create-gcp-composer-instance-to-run-airflow} Instructions on bringing up a GCP Composer instance to run Hubble can be found in the [Installation and Setup](https://github.com/stellar/stellar-etl-airflow?tab=readme-ov-file#installation-and-setup) section in the [stellar-etl-airflow](https://github.com/stellar/stellar-etl-airflow) repository. @@ -25,7 +25,7 @@ Hardware requirements can be very different depending on the Stellar network dat ::: -## Configuring GCP Composer Airflow +## Configuring GCP Composer Airflow {#configuring-gcp-composer-airflow} There are two things required for the configuration and setup of GCP Composer Airflow: @@ -34,17 +34,17 @@ There are two things required for the configuration and setup of GCP Composer Ai For more detailed instructions please see the [stellar-etl-airflow Installation and Setup](https://github.com/stellar/stellar-etl-airflow?tab=readme-ov-file#installation-and-setup) documentation. -### Uploading DAGs +### Uploading DAGs {#uploading-dags} Within the [stellar-etl-airflow](https://github.com/stellar/stellar-etl-airflow) repo there is an [upload_static_to_gcs.sh](https://github.com/stellar/stellar-etl-airflow/blob/master/upload_static_to_gcs.sh) shell script that will upload all the DAGs and schemas into your Composer Airflow bucket. This can also be done using the [gcloud CLI or console](https://cloud.google.com/storage/docs/uploading-objects) and manually selecting the dags and schemas you wish to upload. -### Configuring Airflow Variables +### Configuring Airflow Variables {#configuring-airflow-variables} Please see the [Airflow Variables Explanation](https://github.com/stellar/stellar-etl-airflow?tab=readme-ov-file#airflow-variables-explanation) documentation for more information about what should and needs to be configured. -## Running the DAGs +## Running the DAGs {#running-the-dags} To run a DAG all you have to do is toggle the DAG on/off as seen below @@ -52,11 +52,11 @@ To run a DAG all you have to do is toggle the DAG on/off as seen below More information about each DAG can be found in the [DAG Diagrams](https://github.com/stellar/stellar-etl-airflow?tab=readme-ov-file#dag-diagrams) documentation. -## Available DAGs +## Available DAGs {#available-dags} More information can be found [here](https://github.com/stellar/stellar-etl-airflow/blob/master/README.md#public-dags) -### History Table Export DAG +### History Table Export DAG {#history-table-export-dag} [This DAG](https://github.com/stellar/stellar-etl-airflow/blob/master/dags/history_tables_dag.py): @@ -66,7 +66,7 @@ More information can be found [here](https://github.com/stellar/stellar-etl-airf -### State Table Export DAG +### State Table Export DAG {#state-table-export-dag} [This DAG](https://github.com/stellar/stellar-etl-airflow/blob/master/dags/state_table_dag.py) @@ -75,7 +75,7 @@ More information can be found [here](https://github.com/stellar/stellar-etl-airf -### DBT Enriched Base Tables DAG +### DBT Enriched Base Tables DAG {#dbt-enriched-base-tables-dag} [This DAG](https://github.com/stellar/stellar-etl-airflow/blob/master/dags/dbt_enriched_base_tables_dag.py) diff --git a/docs/data/hubble/admin-guide/scheduling-and-orchestration/overview.mdx b/docs/data/hubble/admin-guide/scheduling-and-orchestration/overview.mdx index 6890d8dd9..a7a1b00b1 100644 --- a/docs/data/hubble/admin-guide/scheduling-and-orchestration/overview.mdx +++ b/docs/data/hubble/admin-guide/scheduling-and-orchestration/overview.mdx @@ -7,7 +7,7 @@ Hubble uses [stellar-etl-airflow](https://github.com/stellar/stellar-etl-airflow It is worth noting that most users will not need to standup and run their own Hubble. The Stellar Development Foundation provides public access to the data through the public datasets and tables in GCP BigQuery. Instructions on how to access this data can be found in the [Connecting](../../analyst-guide/connecting.mdx) section. -## Why Run stellar-etl-ariflow? +## Why Run stellar-etl-ariflow? {#why-run-stellar-etl-ariflow} Running stellar-etl-airflow within your own infrastructure provides a number of benefits. You can: diff --git a/docs/data/hubble/admin-guide/source-system-ingestion/architecture.mdx b/docs/data/hubble/admin-guide/source-system-ingestion/architecture.mdx index 36abdd1aa..98c5ff7a2 100644 --- a/docs/data/hubble/admin-guide/source-system-ingestion/architecture.mdx +++ b/docs/data/hubble/admin-guide/source-system-ingestion/architecture.mdx @@ -6,7 +6,7 @@ sidebar_position: 10 import stellar_arch from "/img/hubble/stellar_overall_architecture.png"; import stellar_etl_arch from "/img/hubble/stellar_etl_architecture.png"; -## Architecture Overview +## Architecture Overview {#architecture-overview} diff --git a/docs/data/hubble/admin-guide/source-system-ingestion/getting-started.mdx b/docs/data/hubble/admin-guide/source-system-ingestion/getting-started.mdx index 8b09a67a7..ccd5942c6 100644 --- a/docs/data/hubble/admin-guide/source-system-ingestion/getting-started.mdx +++ b/docs/data/hubble/admin-guide/source-system-ingestion/getting-started.mdx @@ -7,7 +7,7 @@ sidebar_position: 20 [stellar/stellar-etl docker images](https://hub.docker.com/r/stellar/stellar-etl) -## Recommended Usage +## Recommended Usage {#recommended-usage} Generally if you do not need to modify any of the stellar-etl code, it is recommended that you use the [stellar/stellar-etl docker images](https://hub.docker.com/r/stellar/stellar-etl). @@ -17,20 +17,20 @@ Example to run locally with docker: docker run --platform linux/amd64 -ti stellar/stellar-etl:latest ``` -## Building and Running Locally +## Building and Running Locally {#building-and-running-locally} -### Install Golang +### Install Golang {#install-golang} - Make sure your golang version >= `1.22.1` - Instructions to install golang can be found at [go.dev/doc/install](https://go.dev/doc/install) -### Clone the repo +### Clone the repo {#clone-the-repo} ``` git clone https://github.com/stellar/stellar-etl ``` -### Build stellar-etl +### Build stellar-etl {#build-stellar-etl} - Run `go build` in the cloned stellar-etl repo @@ -38,7 +38,7 @@ git clone https://github.com/stellar/stellar-etl go build ``` -### Run stellar-etl +### Run stellar-etl {#run-stellar-etl} - A `stellar-etl` executable should have been created in your stellar-etl repo - Example stellar-etl command: @@ -54,9 +54,9 @@ This should create a `exported_ledgers.txt` file with the output of ledgers from {"base_fee":100,"base_reserve":100000000,"closed_at":"2024-02-06T17:34:17Z","failed_transaction_count":0,"fee_pool":0,"id":47244640256,"ledger_hash":"5b9ac11c6040f4e2fa6a120b3dee9a4b338b7a25bcb8437dab0c0a5c557a41f5","ledger_header":"AAAAAPfImzXFD3TcaerNndqOnsnxrza2opKLd2GcG+tfXKjUK858NP5gM0pneHF0nRowsJBAzMwWDx0+tmbYIZkIT+8AAAAAZcJtmQAAAAAAAAABAAAAANVyadliUPdJbQeb4ug1Ejbv/+jTnC4Gv6uxQh8X/GccAAAAQDhZKPKBdeD4Sthcu+EsuzEtSyiXzXkHboOsgYT1tuV/juZyKqgrsVmg+RmMoRun+NKCdcB8LV9gaehiFm+XDgnfP2GYBKkv20BXGS3EPddI6neK3FK8SYzoBSTAFLgRGfBr+YHFQTIEJ0Y81WEOYClgyjOER8vd4qMQb3gM9nRvAAAACw3gtrOnZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkBfXhAAAAAGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","max_tx_set_size":100,"operation_count":0,"previous_ledger_hash":"f7c89b35c50f74dc69eacd9dda8e9ec9f1af36b6a2928b77619c1beb5f5ca8d4","protocol_version":0,"sequence":11,"soroban_fee_write_1kb":0,"successful_transaction_count":0,"total_coins":1000000000000000000,"transaction_count":0,"tx_set_operation_count":"0"} ``` -## stellar-etl Commands +## stellar-etl Commands {#stellar-etl-commands} -### export_ledgers +### export_ledgers {#export_ledgers} ``` stellar-etl export_ledgers --start-ledger 1000 --end-ledger 500000 --output exported_ledgers.txt @@ -64,7 +64,7 @@ stellar-etl export_ledgers --start-ledger 1000 --end-ledger 500000 --output expo This command exports ledgers within the provided range. -### export_transactions +### export_transactions {#export_transactions} ``` stellar-etl export_transactions --start-ledger 1000 --end-ledger 500000 --output exported_transactions.txt @@ -72,7 +72,7 @@ stellar-etl export_transactions --start-ledger 1000 --end-ledger 500000 --output This command exports transactions within the provided range. -### export_operations +### export_operations {#export_operations} ``` stellar-etl export_operations --start-ledger 1000 --end-ledger 500000 --output exported_operations.txt @@ -80,7 +80,7 @@ stellar-etl export_operations --start-ledger 1000 --end-ledger 500000 --output e This command exports operations within the provided range. -### export_effects +### export_effects {#export_effects} ``` stellar-etl export_effects --start-ledger 1000 --end-ledger 500000 --output exported_effects.txt @@ -88,7 +88,7 @@ stellar-etl export_effects --start-ledger 1000 --end-ledger 500000 --output expo This command exports effects within the provided range. -### export_assets +### export_assets {#export_assets} ``` stellar-etl export_assets --start-ledger 1000 --end-ledger 500000 --output exported_assets.txt @@ -96,7 +96,7 @@ stellar-etl export_assets --start-ledger 1000 --end-ledger 500000 --output expor Exports the assets that are created from payment operations over a specified ledger range. -### export_trades +### export_trades {#export_trades} ``` stellar-etl export_trades --start-ledger 1000 --end-ledger 500000 --output exported_trades.txt @@ -104,7 +104,7 @@ stellar-etl export_trades --start-ledger 1000 --end-ledger 500000 --output expor Exports trade data within the specified range to an output file -### export_diagnostic_events +### export_diagnostic_events {#export_diagnostic_events} ``` stellar-etl export_diagnostic_events --start-ledger 1000 --end-ledger 500000 --output export_diagnostic_events.txt @@ -112,7 +112,7 @@ stellar-etl export_diagnostic_events --start-ledger 1000 --end-ledger 500000 --o Exports diagnostic events data within the specified range to an output file -### export_ledger_entry_changes +### export_ledger_entry_changes {#export_ledger_entry_changes} ``` stellar-etl export_ledger_entry_changes --start-ledger 1000 --end-ledger 500000 --output exported_changes_folder/ diff --git a/docs/data/hubble/admin-guide/source-system-ingestion/overview.mdx b/docs/data/hubble/admin-guide/source-system-ingestion/overview.mdx index f41d45095..692168c76 100644 --- a/docs/data/hubble/admin-guide/source-system-ingestion/overview.mdx +++ b/docs/data/hubble/admin-guide/source-system-ingestion/overview.mdx @@ -7,7 +7,7 @@ Stellar network data ingestion in Hubble is done through [stellar-etl](https://g It is worth noting that most users will not need to standup and run their own stellar-etl instance. The Stellar Development Foundation provides public access to fully transformed Stellar network data through the public datasets and tables in GCP BigQuery. Instructions on how to access this data can be found in the [Connecting](../../analyst-guide/connecting.mdx) section. -## Why Run stellar-etl? +## Why Run stellar-etl? {#why-run-stellar-etl} Running stellar-etl within your own infrastructure provides a number of benefits. You can: diff --git a/docs/data/hubble/admin-guide/visualization/getting-started.mdx b/docs/data/hubble/admin-guide/visualization/getting-started.mdx index 8600d0495..b7f009768 100644 --- a/docs/data/hubble/admin-guide/visualization/getting-started.mdx +++ b/docs/data/hubble/admin-guide/visualization/getting-started.mdx @@ -7,11 +7,11 @@ This sections goes through using [Google's Looker Studio](https://lookerstudio.g There are many other free/paid visualization tools available. Hubble is compatible with any visualization tool with a BigQuery connector. -## Creating your first visualization +## Creating your first visualization {#creating-your-first-visualization} - Follow [Google's Quick Start Guide](https://support.google.com/looker-studio/answer/9171315?hl=en) -## Hooking Up Data Sources +## Hooking Up Data Sources {#hooking-up-data-sources} The following will use the Stellar Development Foundations public datasets and tables as an example to hook up data sources to Looker Studio @@ -25,7 +25,7 @@ The following will use the Stellar Development Foundations public datasets and t When you create a new report you should be able to now access data from `crypto-stellar.crypto_stellar.` -## Making your first pie chart +## Making your first pie chart {#making-your-first-pie-chart} - Click `Create` in [Google's Looker Studio](https://lookerstudio.google.com/u/0/navigation/reporting) - Click `Report` diff --git a/docs/data/hubble/analyst-guide/connecting.mdx b/docs/data/hubble/analyst-guide/connecting.mdx index 2224d3384..fb750321a 100644 --- a/docs/data/hubble/analyst-guide/connecting.mdx +++ b/docs/data/hubble/analyst-guide/connecting.mdx @@ -9,13 +9,13 @@ BigQuery offers multiple connection methods to Hubble. This guide details three - [BigQuery SDK](#bigquery-sdk) - developers that need to integrate data into applications - [Looker Studio](#looker-studio) - business people that need to visualize data -## Prerequisites +## Prerequisites {#prerequisites} To access Hubble, you will need a Google Cloud Project with billing and the BigQuery API enabled. For more information, please follow the instructions provided by [Google Cloud](https://cloud.google.com/bigquery/docs/quickstarts/query-public-dataset-console). Google does provide a BigQuery Sandbox for free that allows users to explore datasets in a limited capacity. -## BigQuery UI +## BigQuery UI {#bigquery-ui} 1. From a browser, open the [crypto-stellar.crypto_stellar](http://console.cloud.google.com/bigquery?ws=!1m4!1m3!3m2!1scrypto-stellar!2scrypto_stellar) dataset. 2. This will open the public dataset `crypto_stellar`, where you can browse its contents in the **Explorer** pane. @@ -43,7 +43,7 @@ order by balance desc; This query will return the XLM balances for all Stellar wallet addresses, ordered from largest to smallest amounts. -## BigQuery SDK +## BigQuery SDK {#bigquery-sdk} There are multiple [BigQuery API Client Libraries](https://cloud.google.com/bigquery/docs/reference/libraries) available. @@ -121,7 +121,7 @@ for row in query_job: There are various ways to extract and load data using BigQuery. See the [BigQuery Client Documentation](https://cloud.google.com/python/docs/reference/bigquery/latest/google.cloud.bigquery.client.Client) for more information. -## Looker Studio +## Looker Studio {#looker-studio} [Looker Studio](https://cloud.google.com/looker-studio) is a business intelligence tool that can be used to connect to and visualize data from the Hubble dataset. diff --git a/docs/data/hubble/analyst-guide/creating-visualizations.mdx b/docs/data/hubble/analyst-guide/creating-visualizations.mdx index 96f78e954..6aad7b8ca 100644 --- a/docs/data/hubble/analyst-guide/creating-visualizations.mdx +++ b/docs/data/hubble/analyst-guide/creating-visualizations.mdx @@ -31,15 +31,15 @@ By the end of the tutorial you will have created two graphs that will help visua As you can see, persistent contract data entries account for roughly 25% of all contract data entries with the rest being temporary. There are also a lot more expired temporary contract data entries. This is expected because temporay entries cannot be bumped whereas persistent entries can be bumped/restored. For more information, you can read about [State Archival and the Contract Data Lifecycle](https://developers.stellar.org/docs/learn/encyclopedia/storage/state-archival#contract-data-type-descriptions). -## Prerequisites +## Prerequisites {#prerequisites} 1. Make sure you have connected to Hubble by following the instructions in the [Connecting](./connecting.mdx) page 2. You have access to [Google Looker Studio](https://cloud.google.com/looker-studio?hl=en) 3. You have read and understand the general [Best Practices](https://developers.stellar.org/docs/data/hubble/analyst-guide/optimizing-queries#best-practices) for querying BigQuery data -## Create a Report in Looker Studio +## Create a Report in Looker Studio {#create-a-report-in-looker-studio} -### Attach Data Sources to Looker Studio +### Attach Data Sources to Looker Studio {#attach-data-sources-to-looker-studio} 1. Select `Create --> Data source` @@ -54,7 +54,7 @@ As you can see, persistent contract data entries account for roughly 25% of all -### Create a New Report (Dashboard) +### Create a New Report (Dashboard) {#create-a-new-report-dashboard} 1. Select `Create --> Report` @@ -80,7 +80,7 @@ As you can see, persistent contract data entries account for roughly 25% of all -### Use Custom SQL to Create a Chart +### Use Custom SQL to Create a Chart {#use-custom-sql-to-create-a-chart} 1. In your report, click `Add Data` which will be near the bottom right of your window @@ -147,7 +147,7 @@ order by 1 desc, 2 -### Applying a Global Filter +### Applying a Global Filter {#applying-a-global-filter} 1. Click `+Add quick filter` to apply a filter throughout the whole report diff --git a/docs/data/hubble/analyst-guide/optimizing-queries.mdx b/docs/data/hubble/analyst-guide/optimizing-queries.mdx index e7cb9323c..06f0d4b58 100644 --- a/docs/data/hubble/analyst-guide/optimizing-queries.mdx +++ b/docs/data/hubble/analyst-guide/optimizing-queries.mdx @@ -7,9 +7,9 @@ Hubble has terabytes of data to explore—that’s a lot of data! With acces One of the strengths of BigQuery is also its pitfall: you have access to tremendous compute capabilities, but you pay for what you use. If you fine-tune your queries, you will have access to powerful insights at the fraction of the cost of maintaining a data warehouse yourself. It is, however, easy to incur burdensome costs if you are not careful. -## Best Practices +## Best Practices {#best-practices} -### Pay attention to table structure. +### Pay attention to table structure. {#pay-attention-to-table-structure} Large tables are partitioned and clustered according to common access patterns. Prune only the partitions you need, and filter or aggregate by clustered fields when possible. @@ -17,7 +17,7 @@ Joining tables on strings is expensive. Refrain from joining on string keys if y Read the docs on [Viewing Metadata](./viewing-metadata.mdx) to learn more about table metadata. -#### Example - Profiling Operation Types +#### Example - Profiling Operation Types {#example---profiling-operation-types} Let’s say you wanted to profile the [types of operations](../../../learn/fundamentals/transactions/list-of-operations.mdx) submitted to the Stellar Network monthly. ======== Let’s say you wanted to profile the [types of operations](../../../learn/fundamentals/transactions/list-of-operations.mdx) submitted to the Stellar Network monthly. @@ -84,11 +84,11 @@ By pruning partitions and aggregating on a clustered field, the query processing | Improved Query 1 | 83.06 GB | $0.415 | | Improved Query 2 | 54.8 GB | $0.274 | -### Be as specific as possible. +### Be as specific as possible. {#be-as-specific-as-possible} Do not write `SELECT *` statements unless you need every column returned in the query response. Since BigQuery is a columnar database, it can skip reading data entirely if the columns are not included in the select statement. The wider the table is, the more crucial it is to select _only_ what you need. -#### Example - Transaction Fees +#### Example - Transaction Fees {#example---transaction-fees} Let’s say you needed to view the fees for all transactions submitted in May 2023. What happens if you write a `SELECT *`? @@ -142,7 +142,7 @@ The BigQuery console lets you preview table data for free, which is the equivale ::: -### Filter early. +### Filter early. {#filter-early} When writing complex queries, filter the data as early as possible. Push `WHERE` and `GROUP BY` clauses up in the query to reduce the amount of data scanned. @@ -154,11 +154,11 @@ When writing complex queries, filter the data as early as possible. Push `WHERE` Push transformations and mathematical functions to the end of the query when possible. Functions like `TRIM()`, `CAST()`, `SUM()`, and `REGEXP_*` are resource intensive and should only be applied to final table results. -## Estimating Costs +## Estimating Costs {#estimating-costs} If you need to estimate costs before running a query, there are several options available to you: -### BigQuery Console +### BigQuery Console {#bigquery-console} The BigQuery Console comes with a built-in query validator. It verifies query syntax and provides an estimate of the number of bytes processed. The validator can be found in the upper right hand corner of the Query Editor, next to the green checkmark. @@ -187,7 +187,7 @@ The validator estimates that 51.95MB of data will be read. 0.00005195 TB \* $5 = $0.000259. _That’s a cheap query!_ -### dryRun Config Parameter +### dryRun Config Parameter {#dryrun-config-parameter} If you are submitting a query through a [BigQuery client library](https://cloud.google.com/bigquery/docs/reference/libraries), you can perform a dry run to estimate the total bytes processed before submitting the query job. diff --git a/docs/data/hubble/analyst-guide/queries-for-horizon-like-data.mdx b/docs/data/hubble/analyst-guide/queries-for-horizon-like-data.mdx index d2e3068bb..0dc2d364d 100644 --- a/docs/data/hubble/analyst-guide/queries-for-horizon-like-data.mdx +++ b/docs/data/hubble/analyst-guide/queries-for-horizon-like-data.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 [Horizon](../../horizon/README.mdx) and [RPC](../../rpc/README.mdx) both provide API endpoints to retrieve data from the Stellar network. The following example queries retrieve the same data by using Hubble with the added benefit of being able to return historical data. -## Accounts +## Accounts {#accounts} [horizon/accounts](../../horizon/api-reference/resources/accounts/README.mdx) @@ -13,7 +13,7 @@ Users interact with the Stellar network through accounts. Everything else in the Learn more about [accounts](../../../learn/glossary.mdx#account). -### General account information and XLM balance +### General account information and XLM balance {#general-account-information-and-xlm-balance} ```sql select @@ -35,7 +35,7 @@ where true order by closed_at desc ``` -### Non-XLM asset balance information +### Non-XLM asset balance information {#non-xlm-asset-balance-information} ```sql select @@ -54,7 +54,7 @@ where true order by closed_at desc ``` -### Account signer information +### Account signer information {#account-signer-information} ```sql select @@ -70,7 +70,7 @@ where true order by closed_at desc ``` -### List all accounts +### List all accounts {#list-all-accounts} ```sql select @@ -81,7 +81,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Transactions +### Retrieve an Account’s Transactions {#retrieve-an-accounts-transactions} ```sql select @@ -101,7 +101,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Operations +### Retrieve an Account’s Operations {#retrieve-an-accounts-operations} ```sql select @@ -120,7 +120,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Payments +### Retrieve an Account’s Payments {#retrieve-an-accounts-payments} ```sql select @@ -147,7 +147,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Effects +### Retrieve an Account’s Effects {#retrieve-an-accounts-effects} ```sql select @@ -172,7 +172,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Offers +### Retrieve an Account’s Offers {#retrieve-an-accounts-offers} ```sql select @@ -188,7 +188,7 @@ where true and seller_id= ``` -### Retrieve an Account’s Trades +### Retrieve an Account’s Trades {#retrieve-an-accounts-trades} ```sql with selling_side as ( @@ -242,7 +242,7 @@ union_data as ( select * from union_data ``` -## Assets +## Assets {#assets} [horizon/assets](../../horizon/api-reference/resources/assets/README.mdx) @@ -250,7 +250,7 @@ Assets are representations of value issued on the Stellar network. An asset cons Learn more about [assets](../../../learn/glossary.mdx#asset). -### List all Assets +### List all Assets {#list-all-assets} ```sql with assets as ( @@ -320,7 +320,7 @@ from assets join claimable_balances on true ``` -### Getting Stellar Asset Contract Information for an Asset +### Getting Stellar Asset Contract Information for an Asset {#getting-stellar-asset-contract-information-for-an-asset} ```sql select @@ -332,13 +332,13 @@ where true and balance != "" ``` -## Claimable Balances +## Claimable Balances {#claimable-balances} [horizon/claimable_balances](../../horizon/api-reference/resources/claimablebalances/README.mdx) A Claimable Balance represents the transfer of ownership of some amount of an asset. Claimable balances provide a mechanism for setting up a payment which can be claimed in the future. This allows you to make payments to accounts which are currently not able to accept them. -### List All Claimable Balances +### List All Claimable Balances {#list-all-claimable-balances} ```sql current_claimable_balances as ( @@ -370,7 +370,7 @@ where true --and claimants.destination = ``` -### Retrieve a Claimable Balance +### Retrieve a Claimable Balance {#retrieve-a-claimable-balance} ```sql with assets as ( @@ -411,7 +411,7 @@ where true and balance_id = ``` -### Retrieve Related Operations and Transactions +### Retrieve Related Operations and Transactions {#retrieve-related-operations-and-transactions} ```sql select @@ -425,13 +425,13 @@ where true and closed_at between and ``` -## Effects +## Effects {#effects} [horizon/effects](../../horizon/api-reference/resources/effects/README.mdx) Effects represent specific changes that occur in the ledger as a result of successful operations, but are not necessarily directly reflected in the ledger or history, as transactions and operations are. -### List All Effects +### List All Effects {#list-all-effects} ```sql select @@ -448,7 +448,7 @@ where true and closed_at between and ``` -## Ledgers +## Ledgers {#ledgers} [horizon/ledgers](../../horizon/api-reference/resources/ledgers/README.mdx) @@ -456,7 +456,7 @@ Each ledger stores the state of the network at a point in time and contains all Learn more about [ledgers](../../../learn/glossary.mdx#ledger). -### List All Ledgers +### List All Ledgers {#list-all-ledgers} ```sql select @@ -468,7 +468,7 @@ where true and closed_at between and ``` -### Retrieve a Ledger’s Transactions and Operations +### Retrieve a Ledger’s Transactions and Operations {#retrieve-a-ledgers-transactions-and-operations} ```sql select @@ -481,7 +481,7 @@ where true and closed_at between and ``` -### Retrieve a Ledger’s Payments +### Retrieve a Ledger’s Payments {#retrieve-a-ledgers-payments} ```sql select @@ -495,13 +495,13 @@ where true and closed_at between and ``` -## Liquidity Pools +## Liquidity Pools {#liquidity-pools} [horizon/liquidity_pools](../../horizon/api-reference/resources/liquiditypools/README.mdx) Liquidity Pools provide a simple, non-interactive way to trade large amounts of capital and enable high volumes of trading. -### List Liquidity Pools +### List Liquidity Pools {#list-liquidity-pools} ```sql select @@ -516,7 +516,7 @@ from `crypto-stellar.crypto_stellar_dbt.liquidity_pools_current` where true ``` -### Retrieve a Liquidity Pool +### Retrieve a Liquidity Pool {#retrieve-a-liquidity-pool} ```sql select @@ -532,7 +532,7 @@ where true and liquidity_pool_id = ``` -### Retrieve a Liquidity Pool’s Transactions and Operations +### Retrieve a Liquidity Pool’s Transactions and Operations {#retrieve-a-liquidity-pools-transactions-and-operations} ```sql select @@ -544,7 +544,7 @@ where true and liquidity_pool_id = ``` -### Retrieve a Liquidity Pool’s Related Trades +### Retrieve a Liquidity Pool’s Related Trades {#retrieve-a-liquidity-pools-related-trades} ```sql select @@ -557,7 +557,7 @@ where true and selling_liquidity_pool_id = ``` -## Offers +## Offers {#offers} [horizon/offers](../../horizon/api-reference/resources/offers/README.mdx) @@ -565,7 +565,7 @@ Offers are statements about how much of an asset an account wants to buy or sell Learn more about [offers](../../../learn/glossary.mdx#decentralized-exchange). -### List All Offers +### List All Offers {#list-all-offers} ```sql select @@ -582,7 +582,7 @@ where true and closed_at between and ``` -### Retrieve an Offer +### Retrieve an Offer {#retrieve-an-offer} ```sql select @@ -598,7 +598,7 @@ where true and closed_at between and ``` -### Retrieve an Offer’s Trades +### Retrieve an Offer’s Trades {#retrieve-an-offers-trades} ```sql select @@ -612,7 +612,7 @@ where true --and buying_offer_id = ``` -## Operations +## Operations {#operations} [horizon/operations](../../horizon/api-reference/resources/operations/README.mdx) @@ -620,7 +620,7 @@ Operations are objects that represent a desired change to the ledger: payments, Each of Stellar’s operations have a unique operation object. -### List All Operations +### List All Operations {#list-all-operations} ```sql select @@ -638,7 +638,7 @@ where true and closed_at between and ``` -### List All Payments +### List All Payments {#list-all-payments} ```sql select @@ -657,7 +657,7 @@ where true and closed_at between and ``` -### Retrieve an Operation +### Retrieve an Operation {#retrieve-an-operation} ```sql select @@ -670,7 +670,7 @@ where true and closed_at between and ``` -### Retrieve an Operation’s Effects +### Retrieve an Operation’s Effects {#retrieve-an-operations-effects} ```sql select @@ -683,7 +683,7 @@ where true and closed_at between and ``` -## Trades +## Trades {#trades} [horizon/trades](../../horizon/api-reference/resources/trades/README.mdx) @@ -693,7 +693,7 @@ A trade occurs between two parties—`base` and `counter`. Which is which is eit Learn more about [trades](../../../learn/glossary.mdx#decentralized-exchange). -### List All Trades +### List All Trades {#list-all-trades} ```sql select @@ -719,7 +719,7 @@ where true and closed_at between and ``` -## Transactions +## Transactions {#transactions} [horizon/transactions](../../horizon/api-reference/resources/transactions/README.mdx) @@ -727,7 +727,7 @@ Transactions are commands that modify the ledger state and consist of one or mor Learn more about [transactions](../../../learn/glossary.mdx#transaction). -### List All Transactions +### List All Transactions {#list-all-transactions} ```sql select @@ -744,7 +744,7 @@ where true and closed_at between and ``` -### Retrieve a Transaction +### Retrieve a Transaction {#retrieve-a-transaction} ```sql select @@ -761,7 +761,7 @@ where true and closed_at between and ``` -### Retrieve a Transaction’s Operations +### Retrieve a Transaction’s Operations {#retrieve-a-transactions-operations} ```sql select @@ -779,13 +779,13 @@ where true and closed_at between and ``` -## Trade Aggregations +## Trade Aggregations {#trade-aggregations} [horizon/trade_aggregations](../../horizon/api-reference/aggregations/trade-aggregations/README.mdx) A trade aggregation represents aggregated statistics on an asset pair (base and counter) for a specific time period. Trade aggregations are useful to developers of trading clients and provide historical trade data. -### List Trade Aggregations +### List Trade Aggregations {#list-trade-aggregations} ```sql select @@ -807,13 +807,13 @@ where true group by 1,2,3,4,5 ``` -## Fee Stats +## Fee Stats {#fee-stats} [horizon/fee-stats](../../horizon/api-reference/aggregations/fee-stats/README.mdx) Fee stats are used to predict what fee to set for a transaction before submitting it to the network. -### Retrieve Fee Stats +### Retrieve Fee Stats {#retrieve-fee-stats} ```sql select @@ -826,7 +826,7 @@ where true and day_agg between and ``` -## getEvents +## getEvents {#getevents} [rpc/getEvents](../../rpc/api-reference/methods/getEvents.mdx) @@ -844,13 +844,13 @@ where true and closed_at between and ``` -## getLedgerEntries +## getLedgerEntries {#getledgerentries} [rpc/getLedgerEntries](../../rpc/api-reference/methods/getLedgerEntries.mdx) Enables the retrieval of various ledger states, such as accounts, trustlines, offers, data, claimable balances, and liquidity pools. It also provides direct access to inspect a contract's current state, its code, or any other ledger entry -### Contract Data Entries +### Contract Data Entries {#contract-data-entries} ```sql select @@ -863,7 +863,7 @@ where true and ledger_key_hash = ``` -### Contract Code Entries +### Contract Code Entries {#contract-code-entries} ```sql select @@ -874,7 +874,7 @@ where true and ledger_key_hash = ``` -## getTransaction +## getTransaction {#gettransaction} [rpc/getTransaction](../../rpc/api-reference/methods/getTransaction.mdx) diff --git a/docs/data/hubble/analyst-guide/viewing-metadata.mdx b/docs/data/hubble/analyst-guide/viewing-metadata.mdx index bbd3717b9..b76e67e8f 100644 --- a/docs/data/hubble/analyst-guide/viewing-metadata.mdx +++ b/docs/data/hubble/analyst-guide/viewing-metadata.mdx @@ -7,7 +7,7 @@ Hubble publishes metadata which can help users determine which tables to query, There are two ways to access this information: -## BigQuery Explorer +## BigQuery Explorer {#bigquery-explorer} When accessing Hubble from its starred link, the Explorer pane will load metadata about the `crypto-stellar.crypto_stellar` dataset. @@ -17,7 +17,7 @@ Use the Toggle to view the contents of the Dataset. Clicking a table name will l - _Details_ - general information about the table itself, including partitioning, clustering and table size. Viewing details helps with query optimization - _Preview_ - raw sample data from the table. The data presented is the equivalent of running a `SELECT *` statement -## INFORMATION_SCHEMA +## INFORMATION_SCHEMA {#information_schema} BigQuery supports read-only, system-defined views that provide metadata information about BigQuery objects. The views can be queried via SQL from the BigQuery UI or Client Libraries. diff --git a/docs/data/hubble/analytics-platforms.mdx b/docs/data/hubble/analytics-platforms.mdx index ca3fe07fe..449590b86 100644 --- a/docs/data/hubble/analytics-platforms.mdx +++ b/docs/data/hubble/analytics-platforms.mdx @@ -3,7 +3,7 @@ sidebar_position: 1000 title: Ecosystem Data Analytics Platforms --- -## Ecosystem Data Analytics Platforms +## Ecosystem Data Analytics Platforms {#ecosystem-data-analytics-platforms} The following is a list of data analytics platforms that make a complete historical record of Pubnet Stellar network data available. @@ -12,10 +12,10 @@ The following is a list of data analytics platforms that make a complete histori | [Dune](https://docs.dune.com/home) | [Access](https://dune.com/) | [Stellar Dashboard](https://dune.com/scoffie/stellar) | | [Ortege](https://www.ortege.ai/) | [Access](https://app.ortege.ai/login/) | | -## SDF Provided Data Analytics +## SDF Provided Data Analytics {#sdf-provided-data-analytics} SDF provides a publicly available dataset with a complete historical record of Stellar network data available. Please see the [Analyst Guide](./analyst-guide) for more information. -## Run Your Own Hubble +## Run Your Own Hubble {#run-your-own-hubble} If you are interested in running your own Hubble, please checkout the [Admin Guide](./admin-guide). diff --git a/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx b/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx index 92b0b409d..d0e3a2342 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | account_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.accounts) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx b/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx index 430d0b02b..03d9cd89e 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | asset_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.claimable_balances) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx b/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx index db511097c..4b55ebda4 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | last_modified_ledger, contract_code_hash | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.contract_code) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx b/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx index da0370de6..570b84468 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | last_modified_ledger, contract_id | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.contract_data) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx b/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx index 3131a564b..6b430d76a 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | ledger_sequence, transaction_id, op_account_id, type | | Documentation | [dbt_docs](http://www.stellar-dbt-docs.com/#!/model/model.stellar_dbt_public.enriched_history_operations) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Source Table | Notes | | --- | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx index 8d792ebcc..93b104350 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | asset_code, asset_issuer, asset_type | | Documentation | [dbt_docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_assets_staging) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx index eeac11dc3..2b9215c88 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx @@ -162,7 +162,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -171,7 +171,7 @@ description: "" | Clustered Field(s) | address, operation_id, type | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_effects) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx index 5c80119a7..7cf418507 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | sequence, closed_at | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_ledgers) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx index 344ee147d..e536ab2c4 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | transaction_id, source_account, type | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_operations) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx index 171bc87e4..83d4e6c6b 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | selling_asset_id, buying_asset_id, trade_type | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_trades) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx index e2d5d3691..0c2362a27 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | account, ledger_sequence, successful | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_transactions) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx b/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx index 16799b825..b9e3aaab6 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | liquidity_pool_id, asset_a_id, asset_b_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.liquidity_pools) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/offers.mdx b/docs/data/hubble/data-catalog/data-dictionary/offers.mdx index 92d8ac20d..540c47084 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/offers.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/offers.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | selling_asset_id, buying_asset_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.offers) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx b/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx index 6f1120709..fd6d3c014 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | account_id, asset_id, liquidity_pool_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.trust_lines) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx b/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx index cb7522181..912175ebd 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata +## Table Metadata {#table-metadata} | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | last_modified_ledger, key_hash | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.ttl) | -## Column Details +## Column Details {#column-details} | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/rpc/README.mdx b/docs/data/rpc/README.mdx index 8012b38d9..a21273c5e 100644 --- a/docs/data/rpc/README.mdx +++ b/docs/data/rpc/README.mdx @@ -22,7 +22,7 @@ Stellar-RPC should support the developer from local testing (via the [quickstart - This implies it should be easy to deploy, and easy to maintain; with low cost, and little "admin" needed. - The developer should be able to simply run the [quickstart] docker image, and quickly be ready to serve requests without needing to set up or maintain dependent infrastructure. -## Anti-Goals +## Anti-Goals {#anti-goals} - Stellar-RPC is not a Horizon replacement. Horizon is better suited for historical reporting and analytics queries. Horizon is more concerned with "classic" Stellar data. - Stellar-RPC should not depend on Horizon. Horizon is expensive and difficult to run, so if Stellar-RPC depended on Horizon, it would inherit that. diff --git a/docs/data/rpc/admin-guide.mdx b/docs/data/rpc/admin-guide.mdx index c6afe6286..0714dce14 100644 --- a/docs/data/rpc/admin-guide.mdx +++ b/docs/data/rpc/admin-guide.mdx @@ -9,7 +9,7 @@ For example, you can build an application and have it [send a transaction](./api Alternatively, you can use one of Soroban's [client SDKs](/docs/tools/sdks/library), such as the [@stellar/stellar-sdk](/docs/tools/sdks/library#javascript-sdk), which will need to communicate with an RPC instance to access the network. -## Run Your Own Instance for Development +## Run Your Own Instance for Development {#run-your-own-instance-for-development} For local development, we recommend [downloading](https://hub.docker.com/r/stellar/quickstart) and running a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and running a standalone network or communicating with a live development [Testnet]. @@ -31,7 +31,7 @@ The Quickstart image with the RPC service can run on a standard laptop with 8GB [Horizon server]: https://github.com/stellar/go/tree/master/services/horizon [Friendbot server]: https://github.com/stellar/go/tree/master/services/friendbot -### Standalone +### Standalone {#standalone} To run a local standalone network with the Stellar Quickstart Docker image, run the following command: @@ -95,7 +95,7 @@ When you're done with your Standalone node, you can close it with ctrl meth.name === "getLedgerEntries")[0]} /> -### Generating `keys` Parameters +### Generating `keys` Parameters {#generating-keys-parameters} The example above is querying a deployment of the [`increment` example contract] to find out what value is stored in the `COUNTER` ledger entry. This value can be derived using the following code snippets. You should be able to extrapolate from the provided examples how to get `keys` parameters for other types and values. -#### Python +#### Python {#python} :::note @@ -48,7 +48,7 @@ print( ) ``` -#### JavaScript +#### JavaScript {#javascript} If you are using the [JavaScript](https://stellar.github.io/js-stellar-sdk/) `stellar-sdk` to generate these keys, you will need to install the latest pre-release version of the SDK. This can be done like so: @@ -78,7 +78,7 @@ console.log( ); ``` -### Requesting an Account +### Requesting an Account {#requesting-an-account} :::note @@ -149,22 +149,22 @@ const parsed = xdr.LedgerEntryData.fromXDR( console.log(parsed); ``` -### Requesting a Contract's Wasm Code +### Requesting a Contract's Wasm Code {#requesting-a-contracts-wasm-code} This can be a bit tricky to wrap your head around, but the conventions do make sense once you let it sink in. In the previous examples, the `COUNTER` _key_ was used as a `LedgerKey` while the incremented _value_ was stored in a **`LedgerEntry`**. "Ledger Entry" is the relevant term to keep in mind during this discussion. That `LedgerEntry` was stored on the Stellar ledger, and was associated with a corresponding `LedgerKey`. `LedgerKey: LedgerEntry` works the same way you would think of almost any `key: value` storage system. -#### How Soroban Contract Deployment Works +#### How Soroban Contract Deployment Works {#how-soroban-contract-deployment-works} When you deploy a contract, first the code is "installed" (i.e. it is uploaded onto the blockchain). This creates a `LedgerEntry` containing the Wasm byte-code, which is uniquely identified by its hash (that is, the hash of the uploaded code itself). Then, when the contract is "deployed," we create a `LedgerEntry` with a reference to that code's hash. So fetching the contract code is a two-step process: 1. First, we look up the contract itself, to see which code hash it is referencing. 2. Then, we can look up the raw Wasm byte-code using that hash. -#### Request the `LedgerKey` for the Contract Code +#### Request the `LedgerKey` for the Contract Code {#request-the-ledgerkey-for-the-contract-code} -##### Python +##### Python {#python-1} ```python from stellar_sdk import xdr, Address @@ -188,7 +188,7 @@ print( # OUTPUT: AAAABgAAAAGfjJVEBc55drW3U87N1Py0Rw0/nlqUA6tQ6r28khEl4gAAABQAAAAB ``` -##### JavaScript +##### JavaScript {#javascript-1} ```javascript import { Contract } from "@stellar/stellar-sdk"; @@ -238,11 +238,11 @@ And the response we get contains the `LedgerEntryData` that can be used to find } ``` -#### Request the `ContractCode` Using the Retrieved `LedgerKey` +#### Request the `ContractCode` Using the Retrieved `LedgerKey` {#request-the-contractcode-using-the-retrieved-ledgerkey} Now take the `xdr` field from the previous response's `result` object, and create a `LedgerKey` from the hash contained inside. -##### Python +##### Python {#python-2} ```python from stellar_sdk import xdr @@ -269,7 +269,7 @@ print( # OUTPUT: AAAAB+QzbW3JDhlUbDVW/C+1/5SIQDstqORuhpCyl73O1vH6 ``` -##### JavaScript +##### JavaScript {#javascript-2} ```javascript import { xdr } from "@stellar/stellar-sdk"; diff --git a/docs/data/rpc/api-reference/methods/getTransaction.mdx b/docs/data/rpc/api-reference/methods/getTransaction.mdx index 2f0a0fbd8..f6c275495 100644 --- a/docs/data/rpc/api-reference/methods/getTransaction.mdx +++ b/docs/data/rpc/api-reference/methods/getTransaction.mdx @@ -11,7 +11,7 @@ import rpcSpec from "@site/static/stellar-rpc.openrpc.json"; method={rpcSpec.methods.filter((meth) => meth.name === "getTransaction")[0]} /> -### SDK Guide +### SDK Guide {#sdk-guide} The example above is querying details of a transaction using RPC methods directly. If you are using the Stellar SDK to build applications, you can use the native functions to get the same information. diff --git a/docs/data/rpc/api-reference/methods/sendTransaction.mdx b/docs/data/rpc/api-reference/methods/sendTransaction.mdx index a92e7ef5f..7b47bf10c 100644 --- a/docs/data/rpc/api-reference/methods/sendTransaction.mdx +++ b/docs/data/rpc/api-reference/methods/sendTransaction.mdx @@ -10,7 +10,7 @@ import rpcSpec from "@site/static/stellar-rpc.openrpc.json"; method={rpcSpec.methods.filter((meth) => meth.name === "sendTransaction")[0]} /> -### SDK Guide +### SDK Guide {#sdk-guide} The example above is sending a transaction using RPC methods directly. If you are using the Stellar SDK to build applications, you can use the native functions to get the same information. diff --git a/docs/data/rpc/rpc-providers.mdx b/docs/data/rpc/rpc-providers.mdx index 94c202bbe..d6ec6240b 100644 --- a/docs/data/rpc/rpc-providers.mdx +++ b/docs/data/rpc/rpc-providers.mdx @@ -3,7 +3,7 @@ sidebar_position: 60 title: Ecosystem RPC Providers --- -## Ecosystem Providers +## Ecosystem Providers {#ecosystem-providers} Multiple infrastructure providers have made Stellar RPC endpoint services available, and offer plans ranging from free to high throughput endpoints. These providers can be used for development, testing, and production. @@ -23,7 +23,7 @@ These providers allow access to the Testnet network and Mainnet network. \*_Blockdaemon, Validation Cloud, and Quicknode combine Horizon and RPC in the same endpoint._ -## Publicly Accessible RPC URLs +## Publicly Accessible RPC URLs {#publicly-accessible-rpc-urls} | Provider | Mainnet RPC Endpoint | Testnet RPC Endpoint | Futurenet RPC Endpoint | | --- | --- | --- | --- | @@ -42,6 +42,6 @@ SDF will not be providing a publicly available RPC endpoint for Mainnet. Develop | `Futurenet` | `https://rpc-futurenet.stellar.org` | `https://friendbot-futurenet.stellar.org` | [SDF](http://www.stellar.org) | | `Testnet` | `https://soroban-testnet.stellar.org` | `https://friendbot.stellar.org` | [SDF](http://www.stellar.org) | -## Run Your Own RPC +## Run Your Own RPC {#run-your-own-rpc} If you are interested in running your own RPC, please checkout [this page](./admin-guide.mdx). diff --git a/docs/learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx b/docs/learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx index 16471ea21..d06a63171 100644 --- a/docs/learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx +++ b/docs/learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx @@ -23,7 +23,7 @@ toc_max_heading_level: 4 import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -## Example SDK Usage +## Example SDK Usage {#example-sdk-usage} Some (but not all yet) of the Stellar SDKs have functions built-in to handle most of the process of building a Stellar transaction to interact with a Soroban smart contract. Below, we demonstrate in JavaScript and Python how to build and submit a Stellar transaction that will invoke an instance of the [increment example](../../../../build/smart-contracts/getting-started/storing-data.mdx) smart contract. @@ -374,7 +374,7 @@ public class SorobanExample { -## XDR Usage +## XDR Usage {#xdr-usage} Stellar supports invoking and deploying contracts with a new operation named `InvokeHostFunctionOp`. The [`stellar-cli`] abstracts these details away from the user, but not all SDKs do yet. If you're building a dapp you'll probably find yourself building the XDR transaction to submit to the network. @@ -388,7 +388,7 @@ The `InvokeHostFunctionOp` can be used to perform the following Soroban operatio There is only a single `InvokeHostFunctionOp` allowed per transaction. Contracts should be used to perform multiple actions atomically, for example, to deploy a new contract and initialize it atomically. -### InvokeHostFunctionOp +### InvokeHostFunctionOp {#invokehostfunctionop} The XDR of `HostFunction` and `InvokeHostFunctionOp` below can be found [here][xdr]. @@ -414,7 +414,7 @@ struct InvokeHostFunctionOp }; ``` -#### Function +#### Function {#function} The `hostFunction` in `InvokeHostFunctionOp` will be executed by the Soroban host environment. The supported functions are: @@ -501,7 +501,7 @@ The `hostFunction` in `InvokeHostFunctionOp` will be executed by the Soroban hos - `CONTRACT_ID_PREIMAGE_FROM_ADDRESS` specifies that the contract will be created using the provided address and salt. This operation has to be authorized by `address` (see the following section for details). - `CONTRACT_ID_FROM_ASSET` specifies that the contract will be created using the Stellar asset. This is only supported when `executable == CONTRACT_EXECUTABLE_TOKEN`. Note, that the asset doesn't need to exist when this is applied, however the issuer of the asset will be the initial token administrator. Anyone can deploy asset contracts. -##### JavaScript Usage +##### JavaScript Usage {#javascript-usage} Each of these variations of host function invocation has convenience methods in the [JavaScript SDK](../../../../tools/sdks/library.mdx#javascript-sdk): @@ -510,7 +510,7 @@ Each of these variations of host function invocation has convenience methods in - [`Operation.createStellarAssetContract`](https://stellar.github.io/js-stellar-sdk/Operation.html#.createStellarAssetContract) and [`Operation.createCustomContract`](https://stellar.github.io/js-stellar-sdk/Operation.html#.createCustomContract) are abstractions to instantiate contracts: the former is for wrapping an existing [Stellar asset](../../../../tokens/how-to-issue-an-asset.mdx) into a smart contract and the latter is for deploying your own contract. - [`Operation.uploadContractWasm`](https://stellar.github.io/js-stellar-sdk/Operation.html#.uploadContractWasm) corresponds to the above `HOST_FUNCTION_TYPE_UPLOAD_CONTRACT_WASM` variant, letting you upload the raw WASM buffer to the ledger. -#### Authorization Data +#### Authorization Data {#authorization-data} Soroban's [authorization framework](../../security/authorization.mdx) provides a standardized way for passing authorization data to the contract invocations via `SorobanAuthorizationEntry` structures. @@ -588,7 +588,7 @@ Building `SorobanAuthorizedInvocation` trees may be simplified by using the reco [envelope-xdr]: https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-transaction.x#L703 [simulate-transaction-doc]: transaction-simulation.mdx#authorization -##### Stellar Account Signatures +##### Stellar Account Signatures {#stellar-account-signatures} `signatureArgs` format is user-defined for the [custom accounts], but it is protocol-defined for the Stellar accounts. @@ -605,7 +605,7 @@ pub struct AccountEd25519Signature { [structures]: https://github.com/stellar/rs-soroban-env/blob/99d8c92cdc7e5cd0f5311df8f88d04658ecde7d2/soroban-env-host/src/native_contract/account_contract.rs#L51 [custom accounts]: ../../security/authorization.mdx#account-abstraction -##### JavaScript Usage +##### JavaScript Usage {#javascript-usage-1} There are a couple of helpful methods in the SDK to make dealing with authorization easier: @@ -631,7 +631,7 @@ const signedEntries = simTx.auth.map(async (entry) => - If you, instead, want to _build_ an authorization entry from scratch rather than relying on simulation, you can use [`authorizeInvocation`](https://stellar.github.io/js-stellar-sdk/global.html#authorizeInvocation), which will build the structure with the appropriate fields. -### Transaction resources +### Transaction resources {#transaction-resources} Every Soroban transaction has to have a `SorobanTransactionData` transaction [extension] populated. This is needed to compute the [Soroban resource fee](../../../fundamentals/fees-resource-limits-metering.mdx). @@ -668,6 +668,6 @@ The `SorobanResources` structure includes the ledger footprint and the resource The simplest method to determine the values in `SorobanResources` and `refundableFee` is to use the [`simulateTransaction` mechanism](transaction-simulation.mdx). -#### JavaScript Usage +#### JavaScript Usage {#javascript-usage-2} You can use the [`SorobanDataBuilder`](https://stellar.github.io/js-stellar-sdk/SorobanDataBuilder.html) to leverage the [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) and get/set all of the above resources accordingly. Then, you call `.build()` and pass the resulting structure to the [`setSorobanData`](https://stellar.github.io/js-stellar-sdk/TransactionBuilder.html#setSorobanData) method of the corresponding [`TransactionBuilder`](https://stellar.github.io/js-stellar-sdk/TransactionBuilder.html). diff --git a/docs/learn/encyclopedia/contract-development/contract-interactions/tests.mdx b/docs/learn/encyclopedia/contract-development/contract-interactions/tests.mdx index 3738b906f..c1d6dd81b 100644 --- a/docs/learn/encyclopedia/contract-development/contract-interactions/tests.mdx +++ b/docs/learn/encyclopedia/contract-development/contract-interactions/tests.mdx @@ -19,6 +19,6 @@ Some contracts, such as the token contract, also provide a [friendlier interface Note that everything described in this section is only available if the `testutils` feature is enabled. -### Example +### Example {#example} This machinery can also be used to test multiple contracts together. For example, the single offer contract test case [creates a token](https://github.com/stellar/soroban-examples/blob/56fef787395b5aed7cd7b19772cca28e21b3feb5/single_offer/src/test.rs#L22). diff --git a/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx b/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx index c9aee7940..f9c8bd440 100644 --- a/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx +++ b/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx @@ -4,7 +4,7 @@ title: Transaction Simulation description: Simulate a contract interaction contained in a Stellar transaction. --- -## Footprint +## Footprint {#footprint} As mentioned in the [persisting data](../../storage/persisting-data.mdx) section, a contract can only load or store `CONTRACT_DATA` entries that are declared in a _footprint_ associated with its invocation. @@ -18,7 +18,7 @@ This simulation-provided footprint can then be used to accompany a "real" submis In any event (whether successful or failing), the real transaction will execute atomically, deterministically, and with serializable consistency semantics. An inaccurate footprint simply causes deterministic transaction failure, not a stale-read anomaly. All effects of such a failed transaction are discarded, as they would be in the presence of any other error. -## Authorization +## Authorization {#authorization} See the [authorization overview](../../security/authorization.mdx) docs and authorization in transactions [section][auth-data] for general information on Soroban authorization. diff --git a/docs/learn/encyclopedia/contract-development/contract-lifecycle.mdx b/docs/learn/encyclopedia/contract-development/contract-lifecycle.mdx index 4c5dd22be..b3be92558 100644 --- a/docs/learn/encyclopedia/contract-development/contract-lifecycle.mdx +++ b/docs/learn/encyclopedia/contract-development/contract-lifecycle.mdx @@ -19,7 +19,7 @@ description: The process of developing, deploying, and maintaining smart contrac /> -## Development +## Development {#development} Contract development can be done on a local computer with as little as 3 necessary components: an IDE, a copy of the Rust toolchain, and a copy of the Soroban SDK. @@ -29,7 +29,7 @@ To make the local development process even more convenient and fast, the contrac The SDK-provided local contract host also contains a local web server that serves the necessary HTTP API endpoint used for client applications to interact with a contract. This can be used for local development of applications, again without needing to deploy contracts to any test or live network. -## Deployment +## Deployment {#deployment} Once a contract has been tested and debugged locally, it can be deployed. To do this it must be compiled to Wasm code, and then included by value in a transaction sent to the intended deployment network. @@ -39,7 +39,7 @@ Before submitting to the network, developers should inspect the resulting Wasm b The SDK command-line utility can also build and submit the transaction deploying a Wasm contract to the network. Deployment requires sufficient network credentials to sign a transaction performing the deployment and pay its fees. Contracts should be deployed to test networks and thoroughly tested there before being deployed to the live network. -## Execution +## Execution {#execution} Deployed contracts live on chain in a CONTRACT_DATA ledger entry. They are executed within a VM sandbox managed by a host environment inside stellar-core. Each transaction that leads to a contract execution is run in a separate host environment, and each contract called by such a transaction (either directly or indirectly from another contract) is executed in a separate guest Wasm VM contained within the transaction’s host environment. @@ -51,12 +51,12 @@ Each contract execution continues until the contract either completes successful A variety of conditions in either the guest or host environments can cause a contract to trap. If a host function is called with invalid arguments, for example, the host will trap. Similarly if the contract performs an erroneous Wasm bytecode such as a division by zero or access to memory out of bounds, the Wasm VM will trap. Also if the contract uses more resources than its enclosing transaction has paid for, the contract will trap. -## Monitoring +## Monitoring {#monitoring} Contracts can be monitored in two main ways: by observing events emitted during their execution, and by examining the ledger entries written by them. TBD: expand this section. -## Upgrading contracts +## Upgrading contracts {#upgrading-contracts} See the [Upgrading Contracts page](../../../build/guides/conventions/upgrading-contracts.mdx) for details on this. diff --git a/docs/learn/encyclopedia/contract-development/environment-concepts.mdx b/docs/learn/encyclopedia/contract-development/environment-concepts.mdx index 3fdf35392..f3094411d 100644 --- a/docs/learn/encyclopedia/contract-development/environment-concepts.mdx +++ b/docs/learn/encyclopedia/contract-development/environment-concepts.mdx @@ -22,7 +22,7 @@ description: The interface that defines objects, functions, and data available t The contract environment is an _interface_ that defines the facilities -- objects, functions, data sources, etc. -- available to contracts. -## Host and Guest +## Host and Guest {#host-and-guest} As an interface, the environment has two sides, which we refer to as the host environment and the guest environment. Code in the host environment _implements_ the environment interface; code in the guest environment _uses_ the environment interface. @@ -30,7 +30,7 @@ The **host environment** is provided by a known set of Rust crates, compiled onc In contrast, a new **guest environment** is established for each invocation of each smart contract. Each contract sees a single environment interface, and can only call functions provided by the environment interface. In other words, the guest environment is a sandbox for executing arbitrary code within safe parameters. -## WebAssembly +## WebAssembly {#webassembly} The on-chain guest environment is isolated inside a WebAssembly (Wasm) virtual machine ("VM"). This means that deployed contract code is compiled to Wasm bytecode rather than native machine code. The host environment includes an interpreter for the VM, and a new short-lived VM is instantiated for each call to a contract, running the bytecode for the contract and then exiting. @@ -44,7 +44,7 @@ As a result, programs compiled to Wasm bytecode often face a dilemma: if they wa The way out of this dilemma is for the environment itself to provide support code for rich standard functionality, in the form of host objects and functions that guest code can use by reference. Each contract refers to the same functionality implemented in the host, ensuring much smaller code size, higher performance, and greater interoperability between contracts. This is what Soroban does. -## Host objects and functions +## Host objects and functions {#host-objects-and-functions} Shared, standard functionality available to all contract guest code is provided through the environment interface in terms of host objects and host functions. @@ -54,11 +54,11 @@ There is also a slightly larger set of host functions that act on host objects: There are also host functions for interacting with select components of the host environment beyond the host object repertoire, such as reading and writing ledger entries, emitting events, calling other contracts, and accessing information about the transaction context in which guest code is executing. -### Serialization +### Serialization {#serialization} Host objects can be passed (by handle) directly to storage routines or between collaborating contracts. **No serialization or deserialization code needs to exist in the guest**: the host knows how to serialize and deserialize all of its object types and does so transparently whenever necessary. -## Values and types +## Values and types {#values-and-types} All host functions can accept as arguments and return values from, at most, the limited Wasm VM repertoire of machine-level types. To simplify matters, Soroban further limits all host functions to passing and returning values from within a single specialized form of 64-bit integers called "value" or "the value type". Through careful bit-packing, the value type can encode any of several separate types more meaningful to users than just "integers". diff --git a/docs/learn/encyclopedia/contract-development/events.mdx b/docs/learn/encyclopedia/contract-development/events.mdx index 9bddcce2f..e189e9540 100644 --- a/docs/learn/encyclopedia/contract-development/events.mdx +++ b/docs/learn/encyclopedia/contract-development/events.mdx @@ -19,7 +19,7 @@ description: Monitor off-chain smart contract changes. Events are the mechanism that applications off-chain can use to monitor changes and events in contracts on-chain. -## How are events emitted? +## How are events emitted? {#how-are-events-emitted} `ContractEvents` are emitted in Stellar Core's `TransactionMeta`. You can see in the [TransactionMetaV3] XDR below that there is a list of `OperationEvents` called `events`. Each `OperationEvent` corresponds to an operation in a transaction, and itself contains a list of `ContractEvents`. Note that `events` will only be populated if the transaction succeeds. Take a look at the [events guides](../../../build/guides/events/README.mdx) and [this example](../../../build/smart-contracts/example-contracts/events.mdx) to learn more about how to work with events. @@ -31,7 +31,7 @@ Events are ephemeral, the data retention window is a maximum of 7 days. See the [transactionmetav3]: #transactionmetav3 -### ContractEvent +### ContractEvent {#contractevent} An events topics don't have to be made of the same type. You can mix different types. @@ -60,7 +60,7 @@ struct ContractEvent }; ``` -### OperationEvents +### OperationEvents {#operationevents} ```cpp struct OperationEvents @@ -69,7 +69,7 @@ struct OperationEvents }; ``` -### TransactionMetaV3 +### TransactionMetaV3 {#transactionmetav3} ```cpp struct TransactionMetaV3 @@ -95,7 +95,7 @@ struct TransactionMetaV3 [Link](https://github.com/stellar/stellar-xdr/blob/eab1622f18b8101aa0cea76361c08beaeaa8d715/Stellar-ledger.x#L444) to the XDR above. -### Event types +### Event types {#event-types} There are three `ContractEventType`'s - @@ -103,11 +103,11 @@ There are three `ContractEventType`'s - 2. `SYSTEM` events are events emitted by the host. At the moment, there's only one system event emitted by the host. It is emitted when the `update_current_contract_wasm` host function is called, where `topics = ["executable_update", old_executable: ContractExecutable, old_executable: ContractExecutable]` and `data = []`. 3. `DIAGNOSTIC` events are meant for debugging and will not be emitted unless the host instance explictly enables it. You can read more about this below. -## What are diagnosticEvents? +## What are diagnosticEvents? {#what-are-diagnosticevents} While looking at the `TransactionMetaV3` XDR struct above, you may have noticed the `diagnosticEvents` field. This list will be empty by default unless your stellar-core instance has `ENABLE_SOROBAN_DIAGNOSTIC_EVENTS=true` in its config file. If diagnostic events are enabled, this list will not only include all ContractEvents in `events`, but will also include events from failed contract calls, errors from the host, events to trace the contract call stack, and logs from the `log_from_linear_memory` host function. These events can be identified by `type == DIAGNOSTIC`. The diagnostic events emitted by the host to track the call stack are defined below. -### fn_call +### fn_call {#fn_call} The `fn_call` diagnostic event is emitted when a contract is called and contains - @@ -118,7 +118,7 @@ The `fn_call` diagnostic event is emitted when a contract is called and contains - Data 1. A vector of the arguments passed to the function being called. -### fn_return +### fn_return {#fn_return} The `fn_return` diagnostic event is emitted when a contract call completes and contains - @@ -128,7 +128,7 @@ The `fn_return` diagnostic event is emitted when a contract call completes and c - Data 1. The value returned by the contract function. -### When should diagnostic events be enabled? +### When should diagnostic events be enabled? {#when-should-diagnostic-events-be-enabled} `events` contain `ContractEvents` that should convey information about state changes. `diagnosticEvents` on the other hand contain events that are not useful for most users, but may be helpful in debugging issues or building the contract call stack. Because they won't be used by most users, they can be optionally enabled because they are not hashed into the ledger, and therefore are not part of the protocol. This is done so a stellar-core node can stay in sync with the network while emitting these events that normally would not be useful for most users. diff --git a/docs/learn/encyclopedia/contract-development/rust-dialect.mdx b/docs/learn/encyclopedia/contract-development/rust-dialect.mdx index 5e51b7e6f..3855c2f38 100644 --- a/docs/learn/encyclopedia/contract-development/rust-dialect.mdx +++ b/docs/learn/encyclopedia/contract-development/rust-dialect.mdx @@ -27,7 +27,7 @@ Note: these constraints and priorities are **not enforced when building in local The "contract dialect" has the following characteristics: -## No floating point +## No floating point {#no-floating-point} Floating-point arithmetic in the guest is completely prohibited. Floating-point operations in Wasm have a few nondeterministic or platform-specific aspects: mainly NaN bit patterns, as well as floating-point environment settings such as rounding mode. @@ -35,7 +35,7 @@ While it is theoretically possible to force all floating-point code into determi This restriction may be revisited in a future version. -## Limited (ideally zero) dynamic memory allocation +## Limited (ideally zero) dynamic memory allocation {#limited-ideally-zero-dynamic-memory-allocation} Dynamic memory allocation within the guest is **strongly** discouraged, but not completely prohibited. @@ -49,7 +49,7 @@ This restriction is due to the limited ability of Wasm to support code-sharing: Many instances where dynamic memory allocation might _seem_ to be required can also be addressed just as well with a library such as [heapless](https://docs.rs/heapless/latest/heapless/). This library (and others of its kind) provide data structures with familiar APIs that _appear_ dynamic, but are actually implemented in terms of a single stack or static allocation, with a fixed maximum size established at construction: attempts to grow the dynamic size beyond the maximum size simply fail. In the context of a contract, this can sometimes be perferable behaviour, and avoids the question of dynamic allocation entirely. -## Non-standard I/O +## Non-standard I/O {#non-standard-io} All standard I/O facilities and access to the operating system that a typical Rust program would expect to perform using the Rust standard library is prohibited; programs that try to import such functions from the host through (for example) the WASI interface will fail to instantiate, since they refer to functions not provided by the host. @@ -57,19 +57,19 @@ No operating system, nor any simulation thereof, is present in the contract sand This restriction arises from the fact that contracts need to run with _stronger_ guarantees than those made by typical operating-system APIs. Specifically contracts must perform I/O with all-or-nothing, transactional semantics (relative to their successful execution or failure) as well as serializable consistency. This eliminates most APIs that would relate to typical file I/O. Furthermore contracts must be isolated from all sources of nondeterminism such as networking or process control, which eliminates most of the remaining APIs. Once files, networking and process control are gone, there simply isn't enough left in the standard operating system I/O facililties to bother trying to provide them. -## No multithreading +## No multithreading {#no-multithreading} Multithreading is not available. As with I/O functions, attempting to import any APIs from the host related to multithreading will fail at instantiation time. This restriction is similarly based on the need for contracts to run in an environment with strong determinism and serializable consistency guarantees. -## Immediate panic +## Immediate panic {#immediate-panic} The Rust `panic!()` facility for unrecoverable errors will trap the Wasm virtual machine immediately, halting execution at the instruction that traps rather than unwinding. This means that `Drop` code in Rust types will not run during a panic. This behaviour is similar to the `panic = "abort"` profile that Rust code can (and often is) compiled with. This is not a hard restriction enforced by the host, but a soft configuration made through a mixture of SDK functions and flags used when compiling, in the interest of minimizing code size and limiting execution costs. It can be bypassed with some effort if unwinding and `Drop` code is desired, at the cost of greatly increased code size. -## Pure-functional collections +## Pure-functional collections {#pure-functional-collections} Host objects have significantly different semantics than typical Rust data structures, especially those implementing _collections_ such as maps and vectors. diff --git a/docs/learn/encyclopedia/contract-development/types/built-in-types.mdx b/docs/learn/encyclopedia/contract-development/types/built-in-types.mdx index 2c11cb76d..1733536b8 100644 --- a/docs/learn/encyclopedia/contract-development/types/built-in-types.mdx +++ b/docs/learn/encyclopedia/contract-development/types/built-in-types.mdx @@ -28,31 +28,31 @@ Custom types like structs, enums, and unions are also supported. See [Custom Typ ::: -## Primitive Types +## Primitive Types {#primitive-types} The following primitive types are supported: -### Unsigned 32-bit Integer (`u32`) +### Unsigned 32-bit Integer (`u32`) {#unsigned-32-bit-integer-u32} -### Signed 32-bit Integer (`i32`) +### Signed 32-bit Integer (`i32`) {#signed-32-bit-integer-i32} -### Unsigned 64-bit Integer (`u64`) +### Unsigned 64-bit Integer (`u64`) {#unsigned-64-bit-integer-u64} -### Signed 64-bit Integer (`i64`) +### Signed 64-bit Integer (`i64`) {#signed-64-bit-integer-i64} -### Unsigned 128-bit Integer (`u128`) +### Unsigned 128-bit Integer (`u128`) {#unsigned-128-bit-integer-u128} -### Signed 128-bit Integer (`i128`) +### Signed 128-bit Integer (`i128`) {#signed-128-bit-integer-i128} -### Bool (`bool`) +### Bool (`bool`) {#bool-bool} -## Symbol (`Symbol`) +## Symbol (`Symbol`) {#symbol-symbol} Symbols are small efficient strings up to 32 characters in length and limited to `a-z` `A-Z` `0-9` `_` that are encoded into 64-bit integers. Symbols are primarily used for function names and other identifiers that are exported in the public API of a contract. They can also be used wherever short strings are needed to keep resource costs down. -## Bytes, Strings (`Bytes`, `BytesN`, `String`) +## Bytes, Strings (`Bytes`, `BytesN`, `String`) {#bytes-strings-bytes-bytesn-string} Byte arrays and strings can be passed to contracts and stores using the `Bytes` type. @@ -60,7 +60,7 @@ For byte arrays of fixed length, `BytesN` can be used. For example, contract IDs Note that the bytes contained in `String`s do not necessarily conform to any standard text encoding such as ASCII or Unicode UTF-8. They are plain uninterpreted bytes, and users expecting a particular encoding need to enforce that encoding manually. -## Vec (`Vec`) +## Vec (`Vec`) {#vec-vec} Vec is a sequential and indexable growable collection type. @@ -68,7 +68,7 @@ Values are stored in the environment and are available to contract through the f The values in a Vec are not guaranteed to be of any specific type and conversion will fail if they are not of the expected type. Most functions on Vec return a Result due to this. -## Map (`Map`) +## Map (`Map`) {#map-map} Map is a ordered key-value dictionary. @@ -80,7 +80,7 @@ The keys and values in a Map are not guaranteed to be of type K/V and conversion Maps have at most one entry per key. Setting a value for a key in the map that already has a value for that key replaces the value. -## Address (`Address`) +## Address (`Address`) {#address-address} Address is a universal opaque identifier to use in contracts. It may represent a 'classic' Stellar account, a custom account implemented in Soroban or just an arbitrary contract. diff --git a/docs/learn/encyclopedia/contract-development/types/custom-types.mdx b/docs/learn/encyclopedia/contract-development/types/custom-types.mdx index 9adff35ff..2111639e7 100644 --- a/docs/learn/encyclopedia/contract-development/types/custom-types.mdx +++ b/docs/learn/encyclopedia/contract-development/types/custom-types.mdx @@ -33,7 +33,7 @@ Error enum types are another type contracts can define that have some unique beh ::: -## Structs (with Named Fields) +## Structs (with Named Fields) {#structs-with-named-fields} Structs with named fields are stored on ledger as a map of key-value pairs, where the key is a 32 character string representing the field name, and the value is the value encoded. @@ -59,7 +59,7 @@ When converted to XDR, the value becomes an `ScVal`, containing an `ScMap`, cont } ``` -## Structs (with Unnamed Fields) +## Structs (with Unnamed Fields) {#structs-with-unnamed-fields} Structs with unnamed fields are stored on ledger as a vector of values, and are interchangeable with tuples and vectors. The elements are placed in the vector in order that they appear in the field list. @@ -75,7 +75,7 @@ When converted to XDR, the value becomes an `ScVal`, containing an `ScVec`, cont { "vec": [{ "u32": 0 }, { "u32": 0 }] } ``` -## Enum (Unit and Tuple Variants) +## Enum (Unit and Tuple Variants) {#enum-unit-and-tuple-variants} Enums containing unit and tuple variants are are stored on ledger as a two element vector, where the first element is the name of the enum variant as a string up to 32 characters in length, and the value is the value if the variant has one. @@ -104,7 +104,7 @@ When a tuple variant, such as `Enum::B`, is converted to XDR, the value becomes When tuple variants containing multiple values are implemented, the values will be included into the vector. -## Enum (Integer Variants) +## Enum (Integer Variants) {#enum-integer-variants} Enums containing integer values are stored on ledger as the `u32` value. diff --git a/docs/learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx b/docs/learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx index 7070c250e..d4d47d2ae 100644 --- a/docs/learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx +++ b/docs/learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx @@ -25,7 +25,7 @@ When you compile a contract created with [soroban-sdk](../../../../tools/sdks/li These interface types are formatted using [XDR](../../data-format/xdr.mdx), a data format used widely throughout Stellar. It can be tricky to create or consume XDR manually, but tooling can fetch these interface types to make your life easier. [Stellar CLI](../../../../tools/developer-tools/cli/README.mdx#cli) and [Stellar SDK](../../../../tools/sdks/library.mdx#javascript-sdk) are two such tools to do so. Let's look at each. -## Stellar CLI: `stellar contract invoke` +## Stellar CLI: `stellar contract invoke` {#stellar-cli-stellar-contract-invoke} Really, every smart contract is its own program, and deserves its own CLI. @@ -74,7 +74,7 @@ If you're unfamiliar with the `--` double dash separator, this is a pattern used ::: -## Stellar JS SDK: `contract.Client` +## Stellar JS SDK: `contract.Client` {#stellar-js-sdk-contractclient} To create a contract client for the same contract as shown for `contract invoke` above, you would use this JavaScript: @@ -104,7 +104,7 @@ stellar contract bindings typescript \ This creates a fully-typed NPM module for the given contract. -## Already the best; just getting started +## Already the best; just getting started {#already-the-best-just-getting-started} We love that Soroban had all contract interface types available on-chain right from day one. No secondary API calls to external services, no secondary API token management, no signing in or creating an account anywhere else, and near-perfect reliability. It's a game-changer within the blockchain space. diff --git a/docs/learn/encyclopedia/data-format/xdr.mdx b/docs/learn/encyclopedia/data-format/xdr.mdx index 2fe3f403e..0532f2826 100644 --- a/docs/learn/encyclopedia/data-format/xdr.mdx +++ b/docs/learn/encyclopedia/data-format/xdr.mdx @@ -4,17 +4,17 @@ title: XDR Stellar stores and communicates ledger data, transactions, results, history, and messages in a binary format called External Data Representation (XDR). XDR is optimized for network performance but not human readable. Horizon and the Stellar SDKs convert XDRs into friendlier formats. -## .X files +## .X files {#x-files} Data structures in XDR are specified in an interface definition file (IDL). The IDL files used for the Stellar Network are available on [GitHub](https://github.com/stellar/stellar-xdr). -## JSON and XDR Conversion Schema +## JSON and XDR Conversion Schema {#json-and-xdr-conversion-schema} The canonical JSON and XDR Schema is defined by the [stellar-xdr crate](https://docs.rs/stellar-xdr) and also exposed by the [@stellar/stellar-xdr-json-web npm package](https://www.npmjs.com/package/@stellar/stellar-xdr-json-web). The schema provides a round-trippable means for converting any Stellar XDR type to JSON and converting that JSON back to the identical XDR. This conversion is visible in the Stellar CLI, Lab View XDR, and Hubble events table. -### Key Characteristics of the JSON and XDR Conversion Schema +### Key Characteristics of the JSON and XDR Conversion Schema {#key-characteristics-of-the-json-and-xdr-conversion-schema} - **Round-Trippable:** The JSON format allows for converting from XDR to JSON and back to XDR without loss of information. - **Self-Describing:** The JSON format describes the internals of the type but does not identify the type that is encoded. This is similar to XDR, which also does not identify the encoded type. @@ -25,7 +25,7 @@ The defined schema (linked above) is **not** backwards compatible between a give ::: -## More About XDR +## More About XDR {#more-about-xdr} XDR is specified in [RFC 4506](http://tools.ietf.org/html/rfc4506.html) and is similar to tools like Protocol Buffers or Thrift. XDR provides a few important features: @@ -33,7 +33,7 @@ XDR is specified in [RFC 4506](http://tools.ietf.org/html/rfc4506.html) and is s - Data encoded in XDR is reliably and predictably stored. Fields are always in the same order, which makes cryptographically signing and verifying XDR messages simple. - XDR definitions include rich descriptions of data types and structures, which is not possible in simpler formats like JSON, TOML, or YAML. -## Parsing XDR +## Parsing XDR {#parsing-xdr} Since XDR is a binary format and not as widely known as simpler formats like JSON, the Stellar SDKs all include tools for parsing XDR and will do so automatically when retrieving data. diff --git a/docs/learn/encyclopedia/errors-and-debugging/debugging-errors.mdx b/docs/learn/encyclopedia/errors-and-debugging/debugging-errors.mdx index bfb159d0b..85885cab8 100644 --- a/docs/learn/encyclopedia/errors-and-debugging/debugging-errors.mdx +++ b/docs/learn/encyclopedia/errors-and-debugging/debugging-errors.mdx @@ -6,7 +6,7 @@ description: Debug and Understanding Soroban Errors through the General Transact To understand how to debug Soroban errors, first we must understand how the errors are associated with each step of the transaction flow, and the likely and common errors in each step of the transaction flow. -## General Transaction Flow +## General Transaction Flow {#general-transaction-flow} The typical transaction submission process can be broken down into the following sequential steps, excluding external interactions like wallet interactions. Each step has its own set of potential errors: @@ -31,9 +31,9 @@ The typical transaction submission process can be broken down into the following _For more information about fees, please visit [Fees, Resource Limits, and Metering](https://developers.stellar.org/docs/learn/fundamentals/fees-resource-limits-metering#inclusion-fee)._ -## Detailed Soroban Errors +## Detailed Soroban Errors {#detailed-soroban-errors} -### 1. Preflight +### 1. Preflight {#1-preflight} Errors here are returned by the host and propagated through RPC. This doesn’t cover other possible errors (e.g. network errors, errors in RPC itself etc.) @@ -44,7 +44,7 @@ Errors here are returned by the host and propagated through RPC. This doesn’t | `HostError(WasmVm, InvalidAction)` | There was a failure in some Wasm contract, typically a `panic!()`. Diagnostic events might provide more detailed information, but not always, as the `panic!()` messages are not included in the Wasm builds. | Fix the contract logic or invocation arguments. Since the most typical reason for encountering this is `panic!()`, it might be a good idea to use `panic_with_error!()` instead of `panic!()` everywhere. Writing more unit tests is recommended. | | `HostError()` | An arbitrary execution error, like accessing a value out of container bounds, overflow in i128 arithmetics, incorrect invocation argument type etc. The error code should provide a general idea of what is failing, but refer to diagnostic events for details. | Fix the contract logic or invocation arguments. Additional debugging can be done via unit tests. | -### 2. Core Accepts the Transaction +### 2. Core Accepts the Transaction {#2-core-accepts-the-transaction} The error is returned by the core immediately as a response to the transaction being sent and surfaced to the user through RPC. There are a few error-related fields in the Core’s response: @@ -65,7 +65,7 @@ The error is returned by the core immediately as a response to the transaction b | status: `ERROR`, error: `txFAILED`, operation error: `RESTORE_FOOTPRINT_MALFORMED` | One of the footprint requirements for RestoreFootprint operation has not been fulfilled: Only persistent Soroban ledger entries can be restored; Only readWrite footprint should be populated. | Make sure that footprints conform to the requirements. Ideally, client-side libraries should ensure that the restoration transactions are well-formed. | | status: `ERROR`, error: `tx$CODE` | The remaining error codes have the same semantics for Soroban as they do for Stellar; these include errors like insufficient account balance, bad seq num, etc. These errors are usually straightforward to interpret according to the name. | Fix the issue corresponding to the code. There is nothing Soroban specific here. | -### 3. Core Includes the Transaction in the Ledger +### 3. Core Includes the Transaction in the Ledger {#3-core-includes-the-transaction-in-the-ledger} There are instances when the Core does not appear to include the transaction in the ledger, The following best practice is recommended: @@ -79,7 +79,7 @@ It is strongly recommended that all transactions should include a time bound or ::: -### 4. Core Applies the Transaction to the Ledger +### 4. Core Applies the Transaction to the Ledger {#4-core-applies-the-transaction-to-the-ledger} The errors and diagnostic events are recorded in the transaction meta stream emitted by the Core instance when the ledger is being closed. Then, the RPC ingests the transaction metadata (tx meta) and allows developers to query the tx meta. diff --git a/docs/learn/encyclopedia/errors-and-debugging/debugging.mdx b/docs/learn/encyclopedia/errors-and-debugging/debugging.mdx index 5685a92ff..d6d6f1e5f 100644 --- a/docs/learn/encyclopedia/errors-and-debugging/debugging.mdx +++ b/docs/learn/encyclopedia/errors-and-debugging/debugging.mdx @@ -23,7 +23,7 @@ The debugging facilities available differ significantly depending on whether a c Deciding between these two modes and making the most of them while debugging requires a **careful understanding** of which code is compiled-in to deployed contracts and which code is only available for local testing. -## Local-testing mode +## Local-testing mode {#local-testing-mode} It is possible (and encouraged during development) to compile Soroban contracts **natively** (eg. as x86-64 or AArch64 code) and link against the host environment **directly**, such that the contract is not a guest running in a Wasm virtual machine at all: it is simply one native library calling another -- its host -- and both host and contract are linked together as a single program, together with a test harness. @@ -39,7 +39,7 @@ This configuration is referred to as **"local-testing mode"** and since it elimi Local-testing mode is the **default** configuration when compiling code targeting your local computer's CPU and operating system, which is what cargo will do if you set up a new Rust project and don't specify a target. -## Wasm mode +## Wasm mode {#wasm-mode} If on the other hand you wish to compile for deployment, you must tell cargo to build for the Wasm target. diff --git a/docs/learn/encyclopedia/errors-and-debugging/errors.mdx b/docs/learn/encyclopedia/errors-and-debugging/errors.mdx index 6d08488c1..0e1d61aaf 100644 --- a/docs/learn/encyclopedia/errors-and-debugging/errors.mdx +++ b/docs/learn/encyclopedia/errors-and-debugging/errors.mdx @@ -26,7 +26,7 @@ The [errors example] demonstrates how to define your own error types. [errors example]: ../../../build/smart-contracts/example-contracts/errors.mdx -## Error Enums +## Error Enums {#error-enums} Errors are a special type of enum integer type that are stored on ledger as `Status` values containing a `u32` code. diff --git a/docs/learn/encyclopedia/network-configuration/federation.mdx b/docs/learn/encyclopedia/network-configuration/federation.mdx index cfb40f249..f0da9a942 100644 --- a/docs/learn/encyclopedia/network-configuration/federation.mdx +++ b/docs/learn/encyclopedia/network-configuration/federation.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 The [Stellar federation protocol](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0002.md) maps Stellar addresses to an email-like identifier that provides more information about a given user. It’s a way for Stellar client software to resolve email-like addresses such as `name*yourdomain.com` into account IDs like: `GCCVPYFOHY7ZB7557JKENAX62LUAPLMGIWNZJAFV2MITK6T32V37KEJU`. Federated addresses provide an easy way for users to share payment details by using a syntax that interoperates across different domains and providers. -## Federated addresses +## Federated addresses {#federated-addresses} Stellar federated addresses are divided into two parts separated by the asterisk character (`*`): the username and the domain. For example: `jed*stellar.org:` @@ -16,7 +16,7 @@ The domain can be any valid RFC 1035 domain name. The username is limited to pri Note that the `@` symbol is allowed in the username. This means you can use email addresses in the username of a federated address. For example: `maria@gmail.com*stellar.org`. -## Supporting federation +## Supporting federation {#supporting-federation} To support federation, first, create a stellar.toml file, and publish it at `https://YOUR_DOMAIN/.well-known/stellar.toml`. Complete instructions for doing that can be found in the stellar.toml specification (aka SEP-1). @@ -30,7 +30,7 @@ Once you’ve published the location of your federation server, implement federa To make it easier to set up a federation server, you can use the [reference implementation](https://github.com/stellar/go/tree/master/services/federation) designed to be dropped into your existing infrastructure. -## Federation requests +## Federation requests {#federation-requests} You can use the federation endpoint to look up an account ID if you have a Stellar address. You can also do reverse federation and look up a Stellar address from an account ID or a transaction ID. This is useful to see who has sent you a payment. @@ -45,7 +45,7 @@ Supported types: - Id Not supported by all federation servers. Reverse federation will return the federation record of the Stellar address associated with the given account ID. In some cases, this is ambiguous. For instance, if an anchor sends transactions on behalf of its users, the account id will be of the anchor, and the federation server won’t be able to resolve the particular user that sent the transaction. In cases like that, you may need to use txid instead. Example: https://YOUR_FEDERATION_SERVER/federation?q=GD6WU64OEP5C4LRBH6NK3MHYIA2ADN6K6II6EXPNVUR3ERBXT4AN4ACD&type=id - Txid Not supported by all federation servers. Will return the federation record of the sender of the transaction if known by the server. Example: https://YOUR_FEDERATION_SERVER/federation?q=c1b368c00e9852351361e07cc58c54277e7a6366580044ab152b8db9cd8ec52a&type=txid -## Federation Response +## Federation Response {#federation-response} The federation server should respond with an appropriate HTTP status code, headers, and a JSON response. @@ -74,10 +74,10 @@ When a record has not been found 404 Not Found http status code should be return } ``` -## Looking up federation provider via a home domain entry +## Looking up federation provider via a home domain entry {#looking-up-federation-provider-via-a-home-domain-entry} Accounts may optionally have a home domain specified. This allows an account to programmatically specify the main federation provider for that account. -## Caching +## Caching {#caching} You shouldn’t cache responses from federation servers. Some organizations may generate random IDs to protect their users’ privacy. Those IDs may change over time. diff --git a/docs/learn/encyclopedia/network-configuration/ledger-headers.mdx b/docs/learn/encyclopedia/network-configuration/ledger-headers.mdx index e64d71307..f6a8c40f8 100644 --- a/docs/learn/encyclopedia/network-configuration/ledger-headers.mdx +++ b/docs/learn/encyclopedia/network-configuration/ledger-headers.mdx @@ -15,72 +15,72 @@ stateDiagram The genesis ledger has a sequence number of 1. The ledger directly following a ledger with sequence number n has a sequence number of n+1. -## Ledger header fields +## Ledger header fields {#ledger-header-fields} -### Version +### Version {#version} The protocol version of this ledger. -### Previous ledger hash +### Previous ledger hash {#previous-ledger-hash} Hash of the previous ledger. -### SCP value +### SCP value {#scp-value} During consensus, all the validating nodes in the network run SCP and agree on a particular value, which is a transaction set they will apply to a ledger. This value is stored here and in the following three fields (transaction set hash, close time, and upgrades). -### Transaction set hash +### Transaction set hash {#transaction-set-hash} Hash of the transaction set applied to the previous ledger. -### Close time +### Close time {#close-time} The close time is a UNIX timestamp indicating when the ledger closes. Its accuracy depends on the system clock of the validator proposing the block. Consequently, SCP may confirm a close time that lags a few seconds behind or up to 60 seconds ahead. It's strictly monotonic – guaranteed to be greater than the close time of an earlier ledger. -### Upgrades +### Upgrades {#upgrades} How the network adjusts overall values (like the base fee) and agrees to network-wide changes (like switching to a new protocol version). This field is usually empty. When there is a network-wide upgrade, the SDF will inform and help coordinate participants using the #validators channel on the Dev Discord and the Stellar Validators Google Group. -### Transaction set result hash +### Transaction set result hash {#transaction-set-result-hash} Hash of the results of applying the transaction set. This data is not necessary for validating the results of the transactions. However, it makes it easier for entities to validate the result of a given transaction without having to apply the transaction set to the previous ledger. -### Bucket list hash +### Bucket list hash {#bucket-list-hash} Hash of all the objects in this ledger. The data structure that contains all the objects is called the bucket list. -### Ledger sequence +### Ledger sequence {#ledger-sequence} The sequence number of this ledger. -### Total coins +### Total coins {#total-coins} Total number of lumens in existence. -### Fee pool +### Fee pool {#fee-pool} Number of lumens that have been paid in fees. Note this is denominated in lumens, even though a transaction’s fee field is in stroops. -### Inflation sequence +### Inflation sequence {#inflation-sequence} Number of times inflation has been run. Note: the inflation operation was deprecated when validators voted to upgrade the network to Protocol 12 on 10/28/2019. Therefore, inflation no longer runs, so this sequence number no longer changes. -### ID pool +### ID pool {#id-pool} The last used global ID. These IDs are used for generating objects. -### Maximum number of transactions +### Maximum number of transactions {#maximum-number-of-transactions} The maximum number of operations validators have agreed to process in a given ledger. If more transactions are submitted than this number, the network will enter into surge pricing mode. For more about surge pricing and fee strategies, see our [Fees section](../../fundamentals/fees-resource-limits-metering.mdx). -### Base fee +### Base fee {#base-fee} The fee the network charges per operation in a transaction. Calculated in stroops. See the [Fees section](../../fundamentals/fees-resource-limits-metering.mdx) for more information. -### Base reserve +### Base reserve {#base-reserve} The reserve the network uses when calculating an account’s minimum balance. -### Skip list +### Skip list {#skip-list} Hashes of ledgers in the past. Allows you to jump back in time in the ledger chain without walking back ledger by ledger. There are four ledger hashes stored in the skip list. Each slot contains the oldest ledger that is mod of either 50 5000 50000 or 500000 depending on index skipList[0] mod(50), skipList[1] mod(5000), etc. diff --git a/docs/learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx b/docs/learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx index 30093fa5b..8c9f23fcc 100644 --- a/docs/learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx +++ b/docs/learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx @@ -14,11 +14,11 @@ Users can trade and convert assets on the Stellar network with the use of path p In this section, we will talk about the SDEX and liquidity pools. To learn about how these work together to execute transactions, see our [Path Payments Encyclopedia Entry](../transactions-specialized/path-payments.mdx). -## SDEX +## SDEX {#sdex} The Stellar network acts as a decentralized distributed exchange that allows users to trade and convert assets with the [Manage Buy Offer](../../../data/horizon/api-reference/resources/operations/object/buy-offer.mdx) and [Manage Sell Offer](../../../data/horizon/api-reference/resources/operations/object/sell-offer.mdx) operations. The Stellar ledger stores both the balances held by user accounts and orders that user accounts make to buy or sell assets. -### Order books +### Order books {#order-books} Stellar uses order books to operate its decentralized exchange. @@ -32,7 +32,7 @@ A couple of notes on order books on Stellar: To view an order book chart, see the [Order Book Wikipedia Page](https://en.wikipedia.org/wiki/Order_book). In addition, there are also plenty of video tutorials and articles out there that can help you understand how order books work in greater detail. -### Orders +### Orders {#orders} An account can create orders to buy or sell assets using the Manage Buy Offer, Manage Sell Offer, or Passive Order operations. The account must hold the asset it wants to exchange, and it must trust the issuer of the asset it is trying to buy. @@ -42,21 +42,21 @@ Each order constitutes a selling obligation for the selling asset and buying obl Orders are executed on a price-time priority, meaning orders will be executed based first on price; for orders placed at the same price, the order that was entered earlier is given priority and is executed before the newer one. -### Price and operations +### Price and operations {#price-and-operations} Each order in Stellar is quoted with an associated price and is represented as a ratio of the two assets in the order, one being the “quote asset” and the other being the “base asset”. This is to ensure there is no loss of precision when representing the price of the order (as opposed to storing the fraction as a floating-point number). Prices are specified as a {`numerator`, `denominator`} pair with both components of the fraction represented as 32-bit signed integers. The numerator is considered the base asset, and the denominator is considered the quote asset. When expressing a price of “Asset A in terms of Asset B”, the amount of B is the denominator (and therefore the quote asset), and A is the numerator (and therefore the base asset). As a good rule of thumb, it’s generally correct to be thinking about the base asset that is being bought/sold (in terms of the quote asset). -#### Manage Buy Offer +#### Manage Buy Offer {#manage-buy-offer} When creating a buy order in Stellar via the Manage Buy Offer operation, the price is specified as 1 unit of the base currency (the asset being bought), in terms of the quote asset (the asset that is being sold). For example, if you’re buying 100 XLM in exchange for 20 USD, you would specify the price as {20, 100}, which would be the equivalent of 5 XLM for 1 USD (or \$.20 per XLM). -#### Manage Sell Offer +#### Manage Sell Offer {#manage-sell-offer} When creating a sell order in Stellar via the Manage Sell Offer operation, the price is specified as 1 unit of base currency (the asset being sold), in terms of the quote asset (the asset that is being bought). For example, if you’re selling 100 XLM in exchange for 40 USD, you would specify the price as {40, 100}, which would be the equivalent of 2.5 XLM for 1 USD (or \$.40 per XLM). -#### Passive Order +#### Passive Order {#passive-order} Passive orders allow markets to have zero spread. If you want to exchange USD from anchor A for USD from anchor B at a 1:1 price, you can create two passive orders so the two orders don’t fill each other. @@ -64,23 +64,23 @@ A passive order is an order that does not execute against a marketable counter o An account can place a passive sell order via the Create Passive Sell Offer operation. -### Fees +### Fees {#fees} The order price you set is independent of the fee you pay for submitting that order in a transaction. Fees are always paid in XLM, and you specify them as a separate parameter when submitting the order to the network. To learn more about transaction fees, see our section on [Fees section](../../fundamentals/fees-resource-limits-metering.mdx). -## Liquidity pools +## Liquidity pools {#liquidity-pools} Liquidity pools enable automated market making on the Stellar network. Liquidity refers to how easily and cost-effectively one asset can be converted to another. -### Automated Market Makers (AMMs) +### Automated Market Makers (AMMs) {#automated-market-makers-amms} Instead of relying on the buy and sell orders of decentralized exchanges, AMMs keep assets in an ecosystem liquid 24/7 using liquidity pools. Automated market makers provide liquidity using a mathematical equation. AMMs hold two different assets in a liquidity pool, and the quantities of those assets (or reserves) are inputs for that equation (Asset A \* Asset B = k). If an AMM holds more of the reserve assets, the asset prices move less in response to a trade. -#### AMM pricing +#### AMM pricing {#amm-pricing} AMMs are willing to make some trades and unwilling to make others. For example, if 1 EUR = 1.17 USD, then the AMM might be willing to sell 1 EUR for 1.18 USD and unwilling to sell 1 EUR for 1.16 USD. To determine what trades are acceptable, the AMM enforces an invariant. There are many possible invariants, and Stellar enforces a constant product invariant and so is known as a constant product market maker. This means that AMMs on Stellar must never allow the product of the reserves to decrease. @@ -90,7 +90,7 @@ AMMs decide exchange rates based on the ratio of reserves in the liquidity pool. AMMs charge fees on every trade, which is a fixed percentage of the amount bought by the AMM. For example, if an automated market maker sells 100 EUR for 118 USD then the fee is charged on the USD. The fee is 30 bps, which is equal to 0.30%. If you actually wanted to make this trade, you would need to pay about 118.355 USD for 100 EUR. The automated market maker factors the fees into the constant product invariant, so in reality, the product of the reserves grows after every trade. -### Liquidity pool participation +### Liquidity pool participation {#liquidity-pool-participation} Any eligible participant can deposit assets into a liquidity pool, and in return, receive pool shares representing their ownership of that asset. If there are 150 total pool shares and one user owns 30, they are entitled to withdraw 20% of the liquidity pool asset at any time. @@ -100,7 +100,7 @@ A pool share has two representations. The full representation is used with `Chan AMMs charge a fee on all trades and the participants in the liquidity pool receive a share of the fee proportional to their share of the assets in the liquidity pool. Participants collect these fees when they withdraw their assets from the pool. The fee rate on Stellar is 30 bps, which is equal to 0.30%. These fees are completely separate from the network fees. -### Trustlines +### Trustlines {#trustlines} Users need to establish trustlines to three different assets to participate in a liquidity pool: both the reserve assets (unless one of them is XLM) and the pool share itself. @@ -109,7 +109,7 @@ An account needs a trustline for every pool share it wants to own. It is not pos 1. A pool share trustline cannot be created unless the account already has trustlines that are authorized or authorized to maintain liabilities for the assets in the liquidity pool. See below for more information about how authorization impacts pool share trustlines. 2. A pool share trustline requires 2 base reserves instead of 1. For example, an account (2 base reserves) with a trustline for asset A (1 base reserve), a trustline for asset B (1 base reserve), and a trustline for the A-B pool share (2 base reserves) would have a reserve requirement of 6 base reserves. -### Authorization +### Authorization {#authorization} Pool share trustlines cannot be authorized or de-authorized independently. Instead, the authorization of a pool share trustline is derived from the trustlines for the assets in the liquidity pool. This design is necessary because a liquidity pool may contain assets from two different issuers, and both issuers should have a say in whether the pool share trustline is authorized. @@ -126,17 +126,17 @@ There are a few possibilities with regard to authorization. The behavior of the If the issuer of A or B revokes authorization, then the account will automatically withdraw from every liquidity pool containing that asset and those pool share trustlines will be deleted. We say that these pool shares have been redeemed. For example, if the account participates in the A-B, A-C, and B-C liquidity pools and the issuer of A revokes authorization then the account will redeem from A-B and A-C but not B-C. For each redeemed pool share trustline, a Claimable Balance will be created for each asset contained in the pool if there is a balance being withdrawn and the redeemer is not the issuer of that asset. The claimant of the Claimable Balance will be the owner of the deleted pool share trustline, and the sponsor of the Claimable Balance will be the sponsor of the deleted pool share trustline. The BalanceID of each Claimable Balance is the SHA-256 hash of the `revokeID`. -### Operations +### Operations {#operations} There are two operations that facilitate participation in a liquidity pool: `LiquidityPoolDeposit` and `LiquidityPoolWithdraw`. Use `LiquidityPoolDeposit` to start providing liquidity to the market. Use `LiquidityPoolWithdraw` to stop providing liquidity to the market. However, users don’t need to participate in the pool to take advantage of what it’s offering: an easy way to exchange two assets. For that, just use `PathPaymentStrictReceive` or `PathPaymentStrictSend`. If your application is already using path payments, then you don’t need to change anything for users to take advantage of the prices available in liquidity pools. -### Examples +### Examples {#examples} Here we will cover basic liquidity pool participation and querying. -#### Preamble +#### Preamble {#preamble} For all of the following examples, we’ll be working with three funded Testnet accounts. If you’d like to follow along, generate some keypairs and fund them via the friendbot. @@ -286,7 +286,7 @@ Here, we use `distributeAssets()` to establish trustlines and set up initial bal Note the `orderAssets()` helper here. Operations related to liquidity pools refer to the asset pair arbitrarily as `A` and `B`; however, they must be “ordered” such that `A` < `B`. This ordering is defined by the protocol, but its details should not be relevant (if you’re curious, it’s essentially lexicographically ordered by asset type, code, then issuer). We can use the comparison methods built into the SDKs (like `Asset.compare`) to ensure we pass them in the right order and avoid errors. -#### Participation: Creation +#### Participation: Creation {#participation-creation} First, let's create a liquidity pool for the asset pair defined in the preamble. This involves establishing a trustline to the pool itself: @@ -331,7 +331,7 @@ def establish_pool_trustline(source: Keypair, pool_asset: LiquidityPoolAsset) -> This lets the participants hold pool shares, which means now they can perform deposits and withdrawals. -#### Participation: Deposits +#### Participation: Deposits {#participation-deposits} To work with a liquidity pool, you need to know its ID beforehand. It’s a deterministic value, and only a single liquidity pool can exist for a particular asset pair, so you can calculate it locally from the pool parameters. @@ -400,7 +400,7 @@ When depositing assets into a liquidity pool, you need to define your acceptable Notice that we also specify the maximum amount of each reserve we’re willing to deposit. This, alongside the minimum and maximum prices, helps define boundaries for the deposit, since there can always be a change in the exchange rate between submitting the operation and it getting accepted by the network. -#### Participation: Withdrawals +#### Participation: Withdrawals {#participation-withdrawals} If you own shares of a particular pool, you can withdraw reserves from it. The operation structure mirrors the deposit closely: @@ -471,7 +471,7 @@ def remove_liquidity( Notice here that we specify the minimum amount. Much like with a strict-receive path payment, we’re specifying that we’re not willing to receive less than this amount of each asset from the pool. This effectively defines a minimum withdrawal price. -#### Putting it all together +#### Putting it all together {#putting-it-all-together} Finally, we can combine these pieces together to simulate some participation in a liquidity pool. We’ll have everyone deposit increasing amounts into the pool, then one participant withdraws their shares. Between each step, we’ll retrieve the spot price. @@ -577,7 +577,7 @@ if __name__ == '__main__': -#### Watching Liquidity Pool Activity +#### Watching Liquidity Pool Activity {#watching-liquidity-pool-activity} You can access the transactions, operations, and effects related to a liquidity pool if you want to track its activity. Let’s see how we can track the latest deposits in a pool (suppose `poolId` is defined as before): diff --git a/docs/learn/encyclopedia/security/authorization.mdx b/docs/learn/encyclopedia/security/authorization.mdx index 6184e5f33..2ec5027fb 100644 --- a/docs/learn/encyclopedia/security/authorization.mdx +++ b/docs/learn/encyclopedia/security/authorization.mdx @@ -19,7 +19,7 @@ Authorization differs from _authentication_, which is the narrower problem of ju Authorization often uses cryptographic authentication (via signatures) to support its judgments, but is a broader, more general process. -## Soroban Authorization Framework +## Soroban Authorization Framework {#soroban-authorization-framework} Soroban aims to provide a light-weight, but flexible and extensible framework that allows contracts to implement arbitrarily complex authorization rules, while providing built-in implementation for some common tasks (such as replay prevention). The framework consists of the following components: @@ -33,13 +33,13 @@ Contracts that use Soroban authorization framework are interoperable with each o We realize that it's not possible to cover each and every case, but we hope that the vast majority of the contracts can operate within the framework and thus contribute to building a more cohesive ecosystem. Custom authorization frameworks are still possible to implement, but are not encouraged (unless there are no alternatives). -### Contract-Specific Authorization +### Contract-Specific Authorization {#contract-specific-authorization} -#### Contract storage +#### Contract storage {#contract-storage} Contracts have an exclusive read and write access to their [storage](../../../build/smart-contracts/getting-started/storing-data.mdx) in the ledger. This allows contracts to safely control and manage user access to their data. For example, a token contract may ensure that only the administrator can mint more of the token by storing the administrator identity in its storage. Similarly, it can make sure that only an owner of the balance may transfer that balance. -#### `Address` +#### `Address` {#address} The storage-based approach described in the previous section requires a way to represent the user identities and authenticate them. `Address` type is a host-managed type that performs these functions. @@ -51,7 +51,7 @@ Both functions ensure that the `Address` has authorized the call of the current [auth example]: ../../../build/smart-contracts/example-contracts/auth.mdx -#### Authorizing Sub-contract Calls +#### Authorizing Sub-contract Calls {#authorizing-sub-contract-calls} One of the key features of Soroban Authorization Framework is the ability to easily make authorized sub-contract calls. For example, it is possible for a contract to call `require_auth` for an `Address` and then call `token.xfer` authorized for the same `Address` (see [timelock example] that demonstrates this pattern). @@ -59,7 +59,7 @@ Contracts don't need to do anything special to benefit from this feature. Just c [timelock example]: ../../../build/smart-contracts/example-contracts/timelock.mdx -#### When to `require_auth` +#### When to `require_auth` {#when-to-require_auth} The main authorization-related decision a contract writer needs to make for any given `Address` is whether they need to call `require_auth` for it. While the decision needs to be made on case-by-case basis, here are some rules of thumb: @@ -67,7 +67,7 @@ The main authorization-related decision a contract writer needs to make for any - If the `Address` data in this contract is being modified in a way that's not strictly beneficial to the user, then `require_auth` is probably needed (e.g. reducing the user's token balance needs to be authorized, while increasing it doesn't need to be authorized) - If a contract calls another contract that will call `require_auth` for the `Address` (e.g. `token.xfer`), then adding `require_auth` in the caller would ensure that the authorization for the inner call can't be reused outside of your contract. For example, if you want to do something positive for the user, but only when they have transferred some token to your contract, then the contract call itself should `require_auth`. -#### Authorizing Multiple `Address`es +#### Authorizing Multiple `Address`es {#authorizing-multiple-addresses} There is no explicit restriction on how many `Address` entities the contract uses and how many `Address`es have `require_auth` called. That means that it is possible to authorize a contract call on behalf of multiple users, which may even have different authorization contexts (customized via arguments in `require_auth_for_args`). [Atomic swap] is an example that deals with authorization of two `Address`es. @@ -75,7 +75,7 @@ There is no explicit restriction on how many `Address` entities the contract use Note though, that contracts that deal with multiple authorized `Address`es need a bit more complex support on the client side (to collect and attach the proper signatures). -### Account Abstraction +### Account Abstraction {#account-abstraction} Account abstraction is a way to decouple the authentication logic from the contract-specific authorization rules. The `Address` defined above is in fact an identifier of an 'abstract' account. That is, the contracts know the `Address` and can require authorization from it, but they don't know how exactly it is implemented. @@ -83,13 +83,13 @@ For example, imagine a token contract. Its responsibilities are to manage the ba Account abstraction provides a convenient extension point for every contract that uses `Address` for authorization. It doesn't solve all the issues automatically - client-side tooling may still need to be adapted to support different authentication schemes or different wallets. But the on-chain state doesn't need to be modified and modifying the on-chain state is a much harder problem. -#### Types of Account Implementations +#### Types of Account Implementations {#types-of-account-implementations} Conceptually, every abstract account is a special contract that defines authentication rules and potentially some additional account-specific authorization policies. However, for the sake of optimization and integration with the existing Stellar accounts, Soroban supports 4 different kinds of the account implementations. Below are the general descriptions of these implementations. See the transaction [guide](../contract-development/contract-interactions/stellar-transaction.mdx) for the concrete information of how different accounts are represented. -##### Stellar Account +##### Stellar Account {#stellar-account} Corresponds to `Address::Account`. @@ -99,7 +99,7 @@ This supports the Stellar multisig with medium threshold. See Stellar [documenta [documentation]: ../../encyclopedia/security/signatures-multisig.mdx -##### Transaction Invoker +##### Transaction Invoker {#transaction-invoker} Corresponds to `Address::Account`. @@ -107,13 +107,13 @@ This is also a Stellar account, but its signature is inferred from the source ac This is purely an optimization of the [Stellar Account](#stellar-account) that can skip one signature in case the transaction source account also authorizes the contract invocation. -##### Contract Invoker +##### Contract Invoker {#contract-invoker} Corresponds to `Address::Contract`. This is a special case of an 'account' that may appear only when a contract calls another contract. We consider that since the contract makes a call, then it must be authorizing it (otherwise, it shouldn't have made that call). Hence all the `require_auth` calls made on behalf of the **direct** invoker contract `Address` are considered to be authorized (but not any calls on behalf of the contract deeper down the stack). -##### Custom Account +##### Custom Account {#custom-account} Corresponds to `Address::Contract`. @@ -127,15 +127,15 @@ For the exact interface and more details, see the [custom account example]. [custom account example]: ../../../build/smart-contracts/example-contracts/custom-account.mdx -### Secp256r1, passkeys and smart wallets +### Secp256r1, passkeys and smart wallets {#secp256r1-passkeys-and-smart-wallets} After a successful public validator vote to upgrade Stellar's Mainnet to Protocol 21, the secp256r1 signature scheme was enabled for smart contract transactions. This allows developers to implement passkeys to sign transactions instead of using secret keys or seed phrases. Official documentation is a work in progress, view all passkey and smart wallet information in the [Smart Wallets](../../../build/apps/smart-wallets.mdx) page in the docs. -### Advanced Concepts +### Advanced Concepts {#advanced-concepts} Most of the contracts shouldn't need the concepts described in this section. Refer to this when developing complex contracts that deal with deep contract call trees and/or multiple `Address`es. -#### `require_auth` implementation details +#### `require_auth` implementation details {#require_auth-implementation-details} When a Soroban transaction is executed on-chain, the host collects a list of `SorobanAuthorizationEntry` entries from the transaction ([XDR][soroban-auth-entry]). These entries contain signed authorizer credentials and authorized invocation trees. The host uses these entries to verify authorization during the contract execution. @@ -156,7 +156,7 @@ Notice, that authentication happens just once per tree, as the whole tree needs [soroban-auth-entry]: https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-transaction.x#L570 [signature payload preimage]: https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-transaction.x#L703 -#### Matching Authorized Invocation Trees +#### Matching Authorized Invocation Trees {#matching-authorized-invocation-trees} In order for authorizations to succeed, all the `require_auth`/`require_auth_for_args` calls have to be covered by the corresponding `SorobanAuthorizedInvocation` trees in a transaction (defined in transaction [XDR][invocation-xdr]). @@ -170,7 +170,7 @@ In simpler terms, `SorobanAuthorizedInvocation` trees for an `Address` are subse During the matching process that happens for every `require_auth` host tries to match the current path in `T` to a `SorobanAuthorizedInvocation` tree for the corresponding `Address`. The path is considered to be matched only when there is a corresponding path of _exhausted_ `R` nodes leading to the current call. This means that if the `Address` signs a sequence of calls `A.foo->B.bar->C.baz`, then its authorization check will fail in case if `A.foo` directly calls `C.baz` because `C.baz` strictly has to be called from `B.bar`. -##### Duplicate Addresses +##### Duplicate Addresses {#duplicate-addresses} In case if the same contract function calls `require_auth` for the same `Address` multiple times (e.g. when multiple operations from the same user are being batched), every `require_auth` call still has to have a corresponding node in the `SorobanAuthorizedInvocation` tree. Due to that, there might be multiple valid trees that make all the authorization checks pass. There is nothing wrong about that - the address still must have authorized all the invocations. The only requirement for such cases to be handled correctly is to ensure that the `require_auth` calls for an `Address` happen before the corresponding sub-contract calls. diff --git a/docs/learn/encyclopedia/security/securing-web-based-projects.mdx b/docs/learn/encyclopedia/security/securing-web-based-projects.mdx index e12a2237f..df52b9d3b 100644 --- a/docs/learn/encyclopedia/security/securing-web-based-projects.mdx +++ b/docs/learn/encyclopedia/security/securing-web-based-projects.mdx @@ -5,23 +5,23 @@ sidebar_position: 30 Any application managing cryptocurrency is a frequent target of malicious actors and needs to follow security best practices. The below checklist offers guidance on the most common vulnerabilities. However, even if you follow every piece of advice, security is not guaranteed. Web security and malicious actors are constantly evolving, so it’s good to maintain a healthy amount of paranoia. -## SSL/TLS +## SSL/TLS {#ssltls} Ensure that TLS is enabled. Redirect HTTP to HTTPS where necessary to ensure that Man in the Middle attacks can’t occur and sensitive data is securely transferred between the client and browser. Enable TLS and get an SSL certificate for free at [LetsEncrypt](https://letsencrypt.org/getting-started/). If you don’t have SSL/TLS enabled, stop everything and do this first. -## Content security policy (CSP) headers +## Content security policy (CSP) headers {#content-security-policy-csp-headers} CSP headers tell the browser where it can download static resources from. For example, if you astralwallet.io and it requests a JavaScript file from myevilsite.com, your browser will block it unless it was whitelisted with CSP headers. You can read about how to implement CSP headers [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). Most web frameworks have a configuration file or extensions to specify your CSP policy, and the headers are auto-generated for you. For example, see [Helmet](https://www.npmjs.com/package/helmet) for Node.js. This would have prevented the [Blackwallet Hack](https://www.ccn.com/yet-another-crypto-wallet-hack-causes-users-lose-400000/). -## HTTP strict-transport-security headers +## HTTP strict-transport-security headers {#http-strict-transport-security-headers} This is an HTTP header that tells the browser that all future connections to a particular site should use HTTPS. To implement this, add the [header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) to your website. Some web frameworks (like [Django](https://docs.djangoproject.com/en/2.0/topics/security/#ssl-https)) have this built-in. This would have prevented the [MyEtherWallet DNS Hack](https://bitcoinmagazine.com/articles/popular-ether-wallet-mew-hijacked-dns-attack/). -## Storing sensitive data +## Storing sensitive data {#storing-sensitive-data} Ideally, you don’t have to store much sensitive data. If you must, be sure to tread carefully. There are many strategies to store sensitive data: @@ -31,13 +31,13 @@ Ideally, you don’t have to store much sensitive data. If you must, be sure to - Consult a good cryptographer and read up on best practices. Look into the documentation of your favorite web framework. - Rolling your own crypto is a bad idea. Always use tried and tested libraries such as [NaCI](). -## Monitoring +## Monitoring {#monitoring} Attackers often need to spend time exploring your website for unexpected or overlooked behavior. Examining logs defensively can help you catch onto what they’re trying to achieve. You can at least block their IP or automate blocking based on suspicious behavior. It’s also worth setting up an error reporting (like [Sentry](https://sentry.io/welcome/)). Often, people trigger strange bugs when trying to hack things. -## Authentication weaknesses +## Authentication weaknesses {#authentication-weaknesses} You must build your authentication securely if you have logins for users. The best way to do this is to use something off the shelf. Both Ruby on Rails and Django have robust, built-in authentication schemes. @@ -49,22 +49,22 @@ We strongly prefer 2FA and require U2F or [TOTP](https://tools.ietf.org/html/rfc Finally, require strong passwords. Common and short passwords can be brute-forced. Dropbox has a great [open-source tool](https://blogs.dropbox.com/tech/2012/04/zxcvbn-realistic-password-strength-estimation/) that gauges password strength fairly quickly, making it usable for user interactions. -## Denial of service attacks (DOS) +## Denial of service attacks (DOS) {#denial-of-service-attacks-dos} DOS attacks are usually accomplished by overloading your web servers with traffic. To mitigate this risk, rate limit traffic from IPs and browser fingerprints. Sometimes people will use proxies to bypass IP rate-limiting. In the end, malicious actors can always find ways to spoof their identity, so the surest way to block DOS attacks is to implement proof of work checks in your client or use a managed service like [Cloudflare](https://www.cloudflare.com/ddos/). -## Lockdown unused ports +## Lockdown unused ports {#lockdown-unused-ports} Attackers will often scan your ports to see if you were negligent and left any open. Services like Heroku do this for you- [read about how to enable this on AWS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html). -## Phishing and social engineering +## Phishing and social engineering {#phishing-and-social-engineering} Phishing attacks will thwart any well-formed security infrastructure. Have clear policies published on your website and articulate them to users when they sign up (you will never ask for their password, etc.). Sign messages to your users and prompt users to check the website's domain they are on. -## Scan your website and libraries for vulnerabilities +## Scan your website and libraries for vulnerabilities {#scan-your-website-and-libraries-for-vulnerabilities} Use a tool like [Snyk](https://snyk.io/) to scan your third-party client libraries for vulnerabilities. Make sure to keep your third-party libraries up to date. Often, upgrades are triggered by security exploits. You can use [Mozilla Observatory](https://observatory.mozilla.org/) to check your HTTP security as well. -## Cross-Site Request Forgery Protection (CSRF), SQL injections +## Cross-Site Request Forgery Protection (CSRF), SQL injections {#cross-site-request-forgery-protection-csrf-sql-injections} Most modern web and mobile frameworks handle both CSRF protection and SQL injections. Ensure CSRF protection is enabled and that you are using a database ORM instead of running raw SQL based on user input. For example, see what [Ruby on Rails documentation](http://guides.rubyonrails.org/security.html#sql-injection) says about SQL injections. diff --git a/docs/learn/encyclopedia/security/signatures-multisig.mdx b/docs/learn/encyclopedia/security/signatures-multisig.mdx index 29f4db72d..2ca6c150f 100644 --- a/docs/learn/encyclopedia/security/signatures-multisig.mdx +++ b/docs/learn/encyclopedia/security/signatures-multisig.mdx @@ -15,7 +15,7 @@ Signatures are authorization for transactions on the network. Transactions alway Transaction signatures are created by signing the transaction object contents with a secret key. Stellar uses the ed25519 signature scheme, but there is also a mechanism for adding additional types of public and private key schemes. A transaction with an attached signature is considered to have authorization from that public key. -### Thresholds +### Thresholds {#thresholds} Each operation falls under a specific threshold category: low, medium, or high with a number level between 0-255 (to read more about this see our section on [Operations and Transactions](../../fundamentals/transactions/operations-and-transactions.mdx#operations)). This threshold determines what signature weight is needed to authorize an operation. @@ -25,13 +25,13 @@ Accounts can set their own signature weight, threshold values, and additional si If the master key’s weight is set at 0, it cannot be used to sign transactions, even for operations with a threshold value of 0. Be very careful setting your master key weight to 0. Doing so may permanently lock you out of your account (although if there are other signers listed on the account, they can still continue to sign transactions.) -### Authorization +### Authorization {#authorization} To determine if a transaction has the necessary authorization to run, the weights of all the signatures in the transaction envelope are added up. If this sum is equal to or greater than the threshold for that operation type, then the operation is authorized. This scheme is very flexible. You can require many signers to authorize payments from a particular account. You can have an account that any number of people can authorize for. You can have a master key that grants access or revokes access from others. It supports any m of n setup. -## Multisig +## Multisig {#multisig} In some cases, a transaction may need more than one signature: @@ -40,11 +40,11 @@ In some cases, a transaction may need more than one signature: Each additional signer beyond the master key increases the account’s minimum balance by one base reserve. Up to 20 signatures can be attached to one transaction. Once a signature threshold is met, if there are leftover signatures, the transaction will fail. For example, if your transaction requires three signatures, providing more than three signatures, even if they are all valid, will result in a failed transaction error: `TX_BAD_AUTH_EXTRA`. This design is because unnecessary signature verification has a large effect on performance before accepting transactions in consensus. -### Alternate signature types +### Alternate signature types {#alternate-signature-types} To enable some advanced smart contract features there are a couple of additional signature types. These signature types also have weights and can be added and removed similarly to normal signature types. But rather than check a cryptographic signature for authorization they have a different method of proving validity to the network. -#### Pre-authorized Transaction +#### Pre-authorized Transaction {#pre-authorized-transaction} It is possible for an account to pre-authorize a particular transaction by adding the hash of the future transaction as a signer on the account. To do that, you need to prepare the transaction beforehand with the proper sequence number. Then you can obtain the hash of this transaction and add it as a signer to the account. @@ -52,7 +52,7 @@ Signers of this type are automatically removed from the account when a matching This type of signer is especially useful in escrow accounts. You can pre-authorize two different transactions. Both could have the same sequence number but different destinations. This means that only one of them can be executed. -#### Hash(x) +#### Hash(x) {#hashx} :::note @@ -64,14 +64,14 @@ Adding a signature of type hash(x) allows anyone who knows x to sign the transac First, create a random 256-bit value, which we call x. The SHA256 hash of that value can be added as a signer of type hash(x). Then in order to authorize a transaction, x is added as one of the signatures of the transaction. Keep in mind that x will be known to the world as soon as a transaction is submitted to the network with x as a signature. This means anyone will be able to sign for that account with the hash(x) signer at that point. Often you want there to be additional signers so someone must have a particular secret key and know x in order to reach the weight threshold required to authorize transactions on the account. -## Examples +## Examples {#examples} - Example 1: Anchors - Example 2: Joint accounts - Example 3: Expense accounts - Example 4: Company accounts -### Example 1: Anchors +### Example 1: Anchors {#example-1-anchors} You run an anchor that would like to keep its issuing key offline. That way, it's less likely a bad actor can get ahold of the anchor's key and start issuing credit improperly. However, your anchor needs to authorize people holding credit by running the `Set Trust Line Flags` operation. Before you issue credit to an account, you need to verify that account is OK. @@ -91,7 +91,7 @@ High Threshold: 2 -### Example 2: Joint accounts +### Example 2: Joint accounts {#example-2-joint-accounts} You want to set up a joint account with Bilal and Carina such that any of you can authorize a payment. You also want to set up the account so that, if you choose to change signers (e.g., remove or add someone), a high-threshold operation, all 3 of you must agree. You add Bilal and Carina as signers to the joint account. You also ensure that it takes all of your key weights to clear the high threshold but only one to clear the medium threshold. @@ -110,7 +110,7 @@ Carina's Signing Key Weight: 1 -### Example 3: Expense accounts +### Example 3: Expense accounts {#example-3-expense-accounts} You fully control an expense account, but you want your two coworkers Diyuan and Emil to be able to authorize transactions from this account. You add Diyuan and Emil’s signing keys to the expense account. If either Diyuan or Emil leave the company, you can remove their signing key, a high-threshold operation. @@ -129,7 +129,7 @@ Emil's Key Weight: 1 -### Example 4: Company accounts +### Example 4: Company accounts {#example-4-company-accounts} **Warning**: this example involves setting the master key weight of an account to 0. Be very careful if you decide to do that: that key will no longer be able to sign any kind of transaction, so you are in danger of permanently locking yourself out of your account. Make sure you’ve thought carefully about what you’re doing, that you understand the implications, and that you change weights in the correct order. diff --git a/docs/learn/encyclopedia/storage/persisting-data.mdx b/docs/learn/encyclopedia/storage/persisting-data.mdx index 12d2297f1..a94d1cf07 100644 --- a/docs/learn/encyclopedia/storage/persisting-data.mdx +++ b/docs/learn/encyclopedia/storage/persisting-data.mdx @@ -14,7 +14,7 @@ description: Store and access smart contract data. /> -## Ledger entries +## Ledger entries {#ledger-entries} Contracts can access ledger entries of type `CONTRACT_DATA`. Host functions are provided to probe, read, write, and delete `CONTRACT_DATA` ledger entries. @@ -24,23 +24,23 @@ Each `CONTRACT_DATA` ledger entry also holds (in addition to its key) a single v No serialization or deserialization is required in contract code when accessing `CONTRACT_DATA` ledger entries: the host automatically serializes and deserializes any ledger entries accessed, exchanging them with the contract as deserialized values. If a contract wishes to use a custom serialization format, it can store a binary-valued `CONTRACT_DATA` ledger entry and provide its own code to serialize and deserialize, but Soroban has been designed with the intent to minimize the need for contracts to ever do this. -## Access Control +## Access Control {#access-control} Contracts are only allowed to read and write `CONTRACT_DATA` ledger entries owned by the contract: those keyed by the same contract ID as the contract performing the read or write. Attempting to access other `CONTRACT_DATA` ledger entries will cause a transaction to fail. There is no access control for TTL extension operations. Any user may invoke `ExtendFootprintTTLOp` on any LedgerEntry. -## Granularity +## Granularity {#granularity} A `CONTRACT_DATA` ledger entry is read or written from the ledger in its entirety; there is no way to read or write "only a part" of a `CONTRACT_DATA` ledger entry. There is also a fixed overhead cost to accessing any `CONTRACT_DATA` ledger entry. Contracts are therefore responsible for dividing logically "large" data structures into "pieces" with an appropriate size granularity, to use for reading and writing. If pieces are too large there may be unnecessary costs paid for reading and writing unused data, as well as unnecessary contention in parallel execution; but if pieces are too small there may be unnecessary costs paid for the fixed overhead of each entry. -## Footprints and parallel contention +## Footprints and parallel contention {#footprints-and-parallel-contention} Contracts are only allowed to access ledger entries specified in the footprint of their transaction. Transactions with overlapping footprints are said to contend, and will only execute sequentially with respect to one another, on a single thread. Transactions with non-overlapping footprints may execute in parallel. This means that a finer granularity of `CONTRACT_DATA` ledger entries may reduce artificial contention among transactions using a contract, and thereby increase parallelism. -## Contract Data Best Practices +## Contract Data Best Practices {#contract-data-best-practices} -### Account State vs. Shared State +### Account State vs. Shared State {#account-state-vs-shared-state} While there is no distinction between "account" state and "shared" state at the protocol level, it can be helpful to think of data in these terms when deciding what storage type and TTL Extension strategy to use for a given use case. As a guideline, account and shared state can be described as follows: @@ -57,7 +57,7 @@ While there is no distinction between "account" state and "shared" state at the - Note: Sometimes account and shared state can merge when the contract scope is small - I.e. smart wallet or a single nft, where a new contract instance is generated for each account -### Owned Contracts vs. Autonomous Contracts +### Owned Contracts vs. Autonomous Contracts {#owned-contracts-vs-autonomous-contracts} In addition to the types of state, it is also helpful to consider the type of contract instance being used. Again, these types are not enforced at the protocol level, but can be helpful. @@ -69,7 +69,7 @@ In addition to the types of state, it is also helpful to consider the type of co - Contract instance that have not clear owner, or have a decentralized group of owners - Most DeFi protocols, especially non-upgradable ones -### Best Practices +### Best Practices {#best-practices} - Prefer `Temporary` over `Persistent` and `Instance` storage - Anything that can have a timeout should be `Temporary` with TTL set to the timeout. See the [resource limits table](../../../networks/resource-limits-fees.mdx) for the current maximum TTL/timeout. diff --git a/docs/learn/encyclopedia/storage/state-archival.mdx b/docs/learn/encyclopedia/storage/state-archival.mdx index db558a929..6310c2c0c 100644 --- a/docs/learn/encyclopedia/storage/state-archival.mdx +++ b/docs/learn/encyclopedia/storage/state-archival.mdx @@ -23,18 +23,18 @@ All contract data has a Time To Live (TTL) that must be periodically extended. I - When a `Temporary` entry's TTL is 0, it is deleted from the ledger and is permanently inaccessible. - When a `Persistent` or `Instance` entry TTL is 0, it becomes inaccessible and is "archived", but can be "restored" and used again via the [`RestoreFootprintOp`](#restorefootprintop). -## Contract Data Type Descriptions +## Contract Data Type Descriptions {#contract-data-type-descriptions} The general usage and interface are identical for all storage types. They differ only in fees and archival behavior as follows: -### `Temporary` +### `Temporary` {#temporary} - Cheapest fees. - Permanently deleted when TTL goes to 0, cannot be restored. - Suitable for time-bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data. - Unlimited amount of storage. -### `Instance` +### `Instance` {#instance} - Most expensive fees (same price as `Persistent` storage). - Archived when TTL goes to 0, can be restored using the [`RestoreFootprintOp`](#restorefootprintop) operation. @@ -42,7 +42,7 @@ The general usage and interface are identical for all storage types. They differ - Limited amount of storage available. - Suitable for "shared" contract state that cannot be `Temporary` (i.e. admin accounts, contract metadata, etc.). -### `Persistent` +### `Persistent` {#persistent} - Most expensive fees (same price as `Instance` storage). - Archived when TTL goes to 0, can be restored using the [`RestoreFootprintOp`](#restorefootprintop) operation. @@ -50,7 +50,7 @@ The general usage and interface are identical for all storage types. They differ - Unlimited amount of storage. - Suitable for user data that cannot be `Temporary` (i.e. balances). -## Contract Data Best Practices +## Contract Data Best Practices {#contract-data-best-practices} As a general rule, `Temporary` storage should only be used for data that can be easily recreated or is only valid for a period of time, whereas `Persistent` or `Instance` storage should be used for data that cannot be recreated and should be kept permanently, such as a user's token balance. @@ -71,13 +71,13 @@ A call to `extend_ttl(N)` ensures that the current TTL of the contract instance In addition to contract-defined TTL extensions using the `extend_ttl()` function, a contract data entry's TTL can be extended via the [`ExtendFootprintTTLOp`](#extendfootprintttlop) operation. -## Contract Code and Contract Instance lifetimes +## Contract Code and Contract Instance lifetimes {#contract-code-and-contract-instance-lifetimes} Contract code entries and contract instances have lifetimes, and there are a couple ways to extend them. Methods like `env.storage().instance().extend_ttl()` and `env.deployer().extend_ttl()` extend both the contract code and contract instance. The threshold check and extensions are done independently for both the contract code and contract instance, so it’s possible that one is bumped but not the other depending on what the current TTL’s are. If you would like to extend the contract code or contract instance separately, you can use `env.deployer().extend_ttl_for_code()` and `env.deployer().extend_ttl_for_contract_instance()` respectively. Calling both with the same parameters is equivalent to calling only `env.deployer().extend_ttl()`. -## Behavior of transactions that try to access an archived Persistent entry +## Behavior of transactions that try to access an archived Persistent entry {#behavior-of-transactions-that-try-to-access-an-archived-persistent-entry} Here are some important points to keep in mind when it comes to archived entries - @@ -85,31 +85,31 @@ Here are some important points to keep in mind when it comes to archived entries 2. Due to the previous point that archived entries can never make it into smart contract logic, there is no reason to write code in your contract to handle archived entries. The same applies to contract test cases - while you may want to write tests that check if your extension logic is correct, you don't need to write archival tests because the transaction will fail before getting to the contract. It is possible though to access an archived entry in a Soroban test case, in which case the host will panic. You can read more about this in [Test TTL Extensions](../../../build/guides/archival/test-ttl-extension.mdx). 3. Archived persistent entries can never be re-created. They must instead be restored. Once they are restored, then they can be modified or deleted. -## Terms and Semantics +## Terms and Semantics {#terms-and-semantics} -### Live Until Ledger +### Live Until Ledger {#live-until-ledger} Each `ContractData` and `ContractCode` entry has a `liveUntilLedger` field stored in its `LedgerEntry`. The entry is no longer live (i.e. either archived or deleted depending on storage type) when `current_ledger > liveUntilLedger`. -### TTL +### TTL {#ttl} An entry's Time To Live (TTL) is defined as how many ledgers remain until the entry is no longer live. For example, if the current ledger is 5 and an entry's live until ledger is 15, then the entry's TTL is 10 ledgers. -### Minimum TTL +### Minimum TTL {#minimum-ttl} For each entry type, there is a minimum TTL that the entry will have when being created or restored. This TTL minimum is enforced automatically at the protocol level. Minimum TTL is a network parameter. Refer to the [resource reference](../../../networks/resource-limits-fees.mdx) to find the current values. -### Maximum TTL +### Maximum TTL {#maximum-ttl} On any given ledger, an entry's TTL can be extended up to the maximum TTL. This is a network parameter (see the [resource limits table](../../../networks/resource-limits-fees.mdx) for the current maximum TTL). Maximum TTL is not enforced based on when an entry was created, but based on the current ledger. For example, if an entry is created on January 1st, 2024, its TTL could initially be extended up to January 1st, 2025. After this initial TTL extension, if the entry received another TTL extension later on January 10th, 2024, the TTL could be extended up to January 10th, 2025. The `max_ttl()` function can be used to determine the current maximum allowed TTL. -## Operations +## Operations {#operations} -### ExtendFootprintTTLOp +### ExtendFootprintTTLOp {#extendfootprintttlop} -#### Semantics +#### Semantics {#semantics} XDR: @@ -143,11 +143,11 @@ entry2 and entry3 will not be updated because they already have an liveUntilLedger that is large enough. ``` -#### Transaction resources +#### Transaction resources {#transaction-resources} `ExtendFootprintTTLOp` is a Soroban operation, and therefore must be the only operation in a transaction. The transaction also needs to populate `SorobanTransactionData` transaction extension explained [here](../contract-development/contract-interactions/stellar-transaction.mdx#transaction-resources). To fill out `SorobanResources`, use the transaction simulation mentioned in the provided link, or make sure `readBytes` includes the key and entry size of every entry in the `readOnly` set. -### RestoreFootprintOp +### RestoreFootprintOp {#restorefootprintop} XDR: @@ -168,17 +168,17 @@ The restored entry will have its live until ledger extended to the [minimum] the [minimum]: https://github.com/stellar/stellar-core/blob/2109a168a895349f87b502ae3d182380b378fa47/src/ledger/NetworkConfig.h#L77-L78 -#### Transaction resources +#### Transaction resources {#transaction-resources-1} `RestoreFootprintOp` is a Soroban operation, and therefore must be the only operation in a transaction. The transaction also needs to populate `SorobanTransactionData` transaction extension explained [here](../contract-development/contract-interactions/stellar-transaction.mdx#transaction-resources). To fill out `SorobanResources`, use the transaction simulation mentioned in the provided link, or make sure `writeBytes` includes the key and entry size of every entry in the `readWrite` set and make sure `extendedMetaDataSizeBytes` is at least double of `writeBytes`. --- -## Examples +## Examples {#examples} We've done our best to build tooling around state archival in both the Stellar RPC server as well as the JavaScript SDK to make it easier to deal with, and this set of examples demonstrates how to leverage it. -### Overview +### Overview {#overview} Both restoring and extending the TTL of ledger entries follows a three-step process regardless of their nature (contract data, instances, etc.): @@ -195,13 +195,13 @@ Each of the examples below will follow a structure like this. We'll work our way Remember, though, that any combination of these scenarios can occur in reality. -### Preparation +### Preparation {#preparation} In order to help the scaffolding of the code, we'll reuse the rudimentary, retry-enabled transaction polling function `yeetTx` which we outlined in [another guide](/build/guides/transactions/submit-transaction-wait-js.mdx). In the following code, we will also leverage [`Server.prepareTransaction`](https://stellar.github.io/js-soroban-client/Server.html#prepareTransaction). This is a helpful method that, given a transaction, will simulate it, then amend the transaction with the simulation results (fees, etc.) and return that. Then, it can just be signed and submitted. We will also use [`SorobanDataBuilder`](https://stellar.github.io/js-stellar-sdk/SorobanDataBuilder.html), a convenient abstraction that lets us use a [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) to set the appropriate storage footprints for a transaction. -### Example: My data is archived! +### Example: My data is archived! {#example-my-data-is-archived} We'll start with the likeliest occurrence: my piece of persistent data is archived because I haven't interacted with my contract in a while. How do I make it accessible again? @@ -291,7 +291,7 @@ Notice that when restoration is required, **simulation still succeeds**. The way This is great, as it means fewer round-trips to get going again! -### Example: My contract is archived! +### Example: My contract is archived! {#example-my-contract-is-archived} As you can imagine, if your deployed contract instance or the code that backs it is archived, it can't be loaded to execute your invocations. Remember, there's a distinct, one-to-many relationship on the chain between a contract's code and deployed instances of that contract: diff --git a/docs/learn/encyclopedia/transactions-specialized/claimable-balances.mdx b/docs/learn/encyclopedia/transactions-specialized/claimable-balances.mdx index 6d0756885..7aadb3036 100644 --- a/docs/learn/encyclopedia/transactions-specialized/claimable-balances.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/claimable-balances.mdx @@ -18,13 +18,13 @@ Each ClaimableBalanceEntry is a ledger entry, and each claimant in that entry in Once a ClaimableBalanceEntry has been claimed, it is deleted. -## Operations +## Operations {#operations} -### Create Claimable Balance +### Create Claimable Balance {#create-claimable-balance} For basic parameters, see the Create Claimable Balance entry in our [List of Operations section](../../fundamentals/transactions/list-of-operations.mdx#create-claimable-balance). -#### Additional parameters +#### Additional parameters {#additional-parameters} `Claim_Predicate_` Claimant — an object that holds both the destination account that can claim the ClaimableBalanceEntry and a ClaimPredicate that must evaluate to true for the claim to succeed. @@ -42,13 +42,13 @@ A ClaimPredicate is a recursive data structure that can be used to construct com A successful Create Claimable Balance operation will return a Balance ID, which is required when claiming the ClaimableBalanceEntry with the Claim Claimable Balance operation. -### Claim Claimable Balance +### Claim Claimable Balance {#claim-claimable-balance} For basic parameters, see the Claim Claimable Balance entry in our [List of Operations section](../../fundamentals/transactions/list-of-operations#claim-claimable-balance). This operation will load the ClaimableBalanceEntry that corresponds to the Balance ID and then search for the source account of this operation in the list of claimants on the entry. If a match on the claimant is found, and the ClaimPredicate evaluates to true, then the ClaimableBalanceEntry can be claimed. The balance on the entry will be moved to the source account if there are no limit or trustline issues (for non-native assets), meaning the claimant must establish a trustline to the asset before claiming it. -### Clawback Claimable Balance +### Clawback Claimable Balance {#clawback-claimable-balance} This operation claws back a claimable balance, returning the asset to the issuer account, burning it. You must claw back the entire claimable balance, not just part of it. Once a claimable balance has been claimed, use the regular clawback operation to claw it back. @@ -56,7 +56,7 @@ Clawback claimable balances require the claimable balance ID. Learn more about clawbacks in our [Clawback Encyclopedia Entry](./clawbacks.mdx). -## Example +## Example {#example} The below code demonstrates via both the JavaScript and Go SDKs how an account (Account A) creates a ClaimableBalanceEntry with two claimants: Account A (itself) and Account B (another recipient). diff --git a/docs/learn/encyclopedia/transactions-specialized/clawbacks.mdx b/docs/learn/encyclopedia/transactions-specialized/clawbacks.mdx index 878391b99..5327b0319 100644 --- a/docs/learn/encyclopedia/transactions-specialized/clawbacks.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/clawbacks.mdx @@ -15,37 +15,37 @@ Clawbacks are useful for: - Responding to regulatory actions - Enabling identity-proofed persons to recover an enabled asset in the event of loss of key custody or theft -## Operations +## Operations {#operations} -### Set Options +### Set Options {#set-options} The issuer sets up their account to enable clawbacks using the `AUTH_CLAWBACK_ENABLED` flag. This causes every subsequent trustline established from the account to have the `TRUSTLINE_CLAWBACK_ENABLED_FLAG` set automatically. If an issuing account wants to set the `AUTH_CLAWBACK_ENABLED_FLAG`, it must have the `AUTH_REVOCABLE_FLAG` set. This allows an asset issuer to claw back balances locked up in offers by first revoking authorization from a trustline, which pulls all offers that involve that trustline. The issuer can then perform the clawback. -### Clawback +### Clawback {#clawback} The issuing account uses this operation to claw back some or all of an asset. Once an account holds a particular asset for which clawbacks have been enabled, the issuing account can claw it back, burning it. You need to provide the asset, a quantity, and the account from which you’re clawing back the asset. -### Clawback Claimable Balance +### Clawback Claimable Balance {#clawback-claimable-balance} This operation claws back a claimable balance, returning the asset to the issuer account, burning it. You must claw back the entire claimable balance, not just part of it. Once a claimable balance has been claimed, use the regular clawback operation to claw it back. Clawback claimable balances require the claimable balance ID. -### Set Trust Line Flag +### Set Trust Line Flag {#set-trust-line-flag} Remove clawback capabilities on a specific trustline by removing the `TRUSTLINE_CLAWBACK_ENABLED_FLAG` via the `SetTrustLineFlags` operation. You can only clear a flag, not set it. So clearing a clawback flag on a trustline is irreversible. This is done so that you don’t retroactively change the rules on your asset holders. If you’d like to enable clawbacks again, holders must reissue their trustlines. -## Examples +## Examples {#examples} Here we’ll cover the following approaches to clawing back an asset. **Example 1:** Issuing account (Account A) creates a clawback-enabled asset and sends it to Account B. Account B sends that asset to Account C. Account A will then clawback the asset from C. **Example 2:** Account B creates a claimable balance for Account C, and Account A claws back the claimable balance. **Example 3:** Account A issues a clawback-enabled asset to Account B. A claws back some of the asset from B, then removes the clawback enabled flag from the trustline and can no longer clawback the asset. -### Preamble: Issuing a Clawback-able Asset +### Preamble: Issuing a Clawback-able Asset {#preamble-issuing-a-clawback-able-asset} First, we’ll set up an account to enable clawbacks and issue an asset accordingly. @@ -139,7 +139,7 @@ function showBalances(accounts) { -### Example 1: Payments +### Example 1: Payments {#example-1-payments} With the shared setup code out of the way, we can now demonstrate how clawback works for payments. This example will highlight how the asset issuer holds control over their asset regardless of how it gets distributed to the world. @@ -221,7 +221,7 @@ Notice that `GCIHA` (Account A, the issuer) holds none of the asset despite claw (It may be strange that A never holds any tokens of its custom asset, but that’s exactly how issuing works: you create value where there used to be none. Sending an asset to its issuing account is equivalent to burning it, and auditing the total amount of an asset in existence is one of the benefits of properly distributing an asset via a distribution account, which we avoid doing here for example brevity.) -### Example 2: Claimable Balances +### Example 2: Claimable Balances {#example-2-claimable-balances} Direct payments aren’t the only way to transfer assets between accounts: claimable balances also do this. Since they are a separate payment mechanism, they need a separate clawback mechanism. @@ -294,7 +294,7 @@ GDS5N: 500 GC2BK: 0 ``` -### Example 3: Selectively Enabling Clawback +### Example 3: Selectively Enabling Clawback {#example-3-selectively-enabling-clawback} When you enable the `AUTH_CLAWBACK_ENABLED_FLAG` on your account, it will make all future trustlines have clawback enabled for any of your issued assets. This may not always be desirable as you may want certain assets to behave as they did before. Though you could work around this by reissuing assets from a “dedicated clawback” account, you can also simply disable clawbacks for certain trustlines by clearing the `TRUST_LINE_CLAWBACK_ENABLED_FLAG` on a trustline. diff --git a/docs/learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx b/docs/learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx index 1db55ff21..c0eb6dc7d 100644 --- a/docs/learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx @@ -12,7 +12,7 @@ A fee-bump transaction is made of two parts: 1. An inner transaction envelope with its signature(s) 2. An outer transaction envelope with the fee-bump transaction and fee account signature -## Common use cases +## Common use cases {#common-use-cases} You may want to consider using fee bumps when: @@ -20,31 +20,31 @@ You may want to consider using fee bumps when: - You want to increase the fee on an existing transaction so it has a better chance of making it to the ledger during surge pricing - You need to adjust the fee on a pre-authorized transaction so it can make it to the ledger if minimum network fees have increased -## Attributes +## Attributes {#attributes} -### Existing transaction envelope (inner transaction) +### Existing transaction envelope (inner transaction) {#existing-transaction-envelope-inner-transaction} Before creating a fee-bump transaction, you must first have a transaction wrapped with its signatures in a transaction envelope. We’ll call this transaction the inner transaction. -### Fee account +### Fee account {#fee-account} The account that will pay the fee for the fee-bump transaction. This account will incur the fee instead of the source account specified in the inner transaction. The sequence number is still taken from the source account, however. -### Fee +### Fee {#fee} The maximum per-operation fee you’re willing to pay for the fee-bump transaction. The fee-bump transaction is one operation. Therefore, the total number of operations is equal to the number of operations in the inner transaction plus one. Read more about transaction fees in our [Fees section](../../fundamentals/fees-resource-limits-metering.mdx). -### Replace-by-fee +### Replace-by-fee {#replace-by-fee} You can apply a fee-bump transaction to increase a fee originating from your own account. However, if you submit two distinct transactions with the same source account and sequence number with the second transaction being a fee-bump transaction, the second transaction will replace the first transaction in the queue if and only if the fee bid of the second transaction is 10x the fee bid of the first transaction. This number may seem random, it is a deliberate design decision to limit DOS attacks without introducing too much complexity to the protocol. -### Fee-bump transaction envelope +### Fee-bump transaction envelope {#fee-bump-transaction-envelope} When a fee-bump transaction is ready to be signed, it’s wrapped in a transaction envelope. This envelope contains the fee-bump transaction and the signature of the specified fee account. -## Validity of a fee-bump transaction +## Validity of a fee-bump transaction {#validity-of-a-fee-bump-transaction} A fee-bump transaction goes through a series of checks in its lifecycle to determine validity. The following conditions must be met: @@ -57,13 +57,13 @@ A fee-bump transaction goes through a series of checks in its lifecycle to deter - **Fee account balance** — the fee account must have a sufficient XLM balance to cover the fee - **Inner transaction** — the inner transaction must be valid, which means it must meet the requirements described in the [Validity of a Transaction section](../../fundamentals/transactions/operations-and-transactions.mdx#transaction-and-operation-validity). If validation of the inner transaction is successful, then the result is `FEE_BUMP_INNER_SUCCESS`, and the validation results from the validation of the inner transaction appear in the inner result. If the inner transaction is invalid, the result is `FEE_BUMP_INNER_FAILED`, and the fee-bump transaction is invalid because the inner transaction is invalid. -## Application +## Application {#application} The sole purpose of a fee-bump transaction is to get an inner transaction included in a transaction set. Since the fee-bump transaction has no side effects other than paying a fee — and at the time the fee is paid the outer transaction must have been valid (otherwise nodes would not have voted for it) — there is no reason to check the validity of the fee-bump transaction at apply time. Therefore, the sequence number of the inner transaction is always consumed at apply time. The inner transaction, however, will still have its validity checked at apply time. Every fee-bump transaction result contains a complete inner transaction result. This inner-transaction result is exactly what would have been produced had there been no fee-bump transaction, except that the inner fee will always be 0. -## Example: implementing a fee-bump transaction +## Example: implementing a fee-bump transaction {#example-implementing-a-fee-bump-transaction} This example shows how to create and submit a fee-bump transaction on the Stellar network. Replace secret key values, `SECREY_KEY_1` and `SECREY_KEY_2` of keypairs of your choosing. This is not a production example, and you should take care to never expose your secret keys on the web. diff --git a/docs/learn/encyclopedia/transactions-specialized/memos.mdx b/docs/learn/encyclopedia/transactions-specialized/memos.mdx index 9ac512dad..8c838f194 100644 --- a/docs/learn/encyclopedia/transactions-specialized/memos.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/memos.mdx @@ -16,7 +16,7 @@ Memos can be one of the following types: `MEMO_HASH`: A 32-byte hash. `MEMO_RETURN`: A 32-byte hash intended to be interpreted as the hash of the transaction the sender is refunding. -## Memo content examples +## Memo content examples {#memo-content-examples} - Notifying that the transaction is a refund or reimbursement - Reference to an invoice the transaction is paying diff --git a/docs/learn/encyclopedia/transactions-specialized/path-payments.mdx b/docs/learn/encyclopedia/transactions-specialized/path-payments.mdx index 1b98630aa..9c438ab8b 100644 --- a/docs/learn/encyclopedia/transactions-specialized/path-payments.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/path-payments.mdx @@ -13,19 +13,19 @@ It is possible for path payments to fail if there are no viable exchange paths. For more information on the Stellar Decentralized Exchange and Liquidity Pools, see our [Liquidity on Stellar: SDEX and Liquidity Pools Encyclopedia Entry](../sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx) -## Operations +## Operations {#operations} Path payments use the Path Payment Strict Send or Path Payment Strict Receive operations. -### Path Payment Strict Send +### Path Payment Strict Send {#path-payment-strict-send} Allows a user to specify the amount of the asset to send. The amount received will vary based on offers in the order books and/or liquidity pools. -### Path Payment Strict Receive +### Path Payment Strict Receive {#path-payment-strict-receive} Allows a user to specify the amount of the asset received. The amount sent will vary based on the offers in the order books/liquidity pools. -## Path payments - more info +## Path payments - more info {#path-payments---more-info} - Path payments don’t allow intermediate offers to be from the source account as this would yield a worse exchange rate. You’ll need to either split the path payment into two smaller path payments or ensure that the source account’s offers are not at the top of the order book. - Balances are settled at the very end of the operation. diff --git a/docs/learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx b/docs/learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx index f12a6dfce..8bcf06650 100644 --- a/docs/learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx @@ -11,13 +11,13 @@ You can create a Stellar account for each user, but most custodial services, inc Note that we used memos in the past for this purpose, however, using muxed accounts is better in the long term. At this time, there isn't support for muxed accounts by all wallets, exchanges, and anchors, so you may want to support both memos and muxed accounts, at least for a while. -## Pooled accounts +## Pooled accounts {#pooled-accounts} A pooled account allows a single Stellar account ID to be shared across many users. Generally, services that use pooled accounts track their customers in a separate, internal database and use the muxed accounts feature to map an incoming and outgoing payment to the corresponding internal customer. The benefits of using a pooled account are lower costs – no base reserves are needed for each account – and lower key complexity – you only need to manage one account keypair. However, with a single pooled account, it is now your responsibility to manage all individual customer balances and payments. You can no longer rely on the Stellar ledger to accumulate value, handle errors and atomicity, or manage transactions on an account-by-account basis. -## Muxed accounts +## Muxed accounts {#muxed-accounts} Muxed accounts are embedded into the protocol for convenience and standardization. They distinguish individual accounts that all exist under a single, traditional Stellar account. They combine the familiar `GABC…` address with a 64-bit integer ID. @@ -29,7 +29,7 @@ It is safe for all wallets to implement sending to muxed accounts. If you wish to receive deposits to muxed accounts please keep in mind that they are not yet supported by all wallets and exchanges. -### Address format +### Address format {#address-format} Muxed accounts have their own address format that starts with an M prefix. For example, from a traditional Stellar account address: `GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ`, we can create new muxed accounts with different IDs. The IDs are embedded into the address itself- when you parse the muxed account addresses, you get the G address from above plus another number. @@ -38,7 +38,7 @@ Muxed accounts have their own address format that starts with an M prefix. For e Both of these addresses will act on the underlying `GA7Q…` address when used with one of the supported operations. -### Supported operations +### Supported operations {#supported-operations} Not all operations can be used with muxed accounts. Here is what you can use them for: @@ -55,7 +55,7 @@ We will demonstrate some of these in the examples section. There’s no validation on IDs and as far as the Stellar network is concerned, all supported operations operate exactly as if you did not use a muxed account. For example, if you make two payments from two muxed accounts that share an underlying Stellar account (same G… address but different M… addresses) this is exactly the same as that single Stellar account sending two payments according to the ledger. Even though only the underlying `G…` account truly exists on the Stellar ledger, the Horizon API will make an effort to interpret and track the muxed accounts responsible for certain actions. -### Examples +### Examples {#examples} In this section, we’ll demonstrate how to create muxed accounts and how they interface with their supported operations. Since custodial account workarounds based on transaction memos are unnecessary now, we’ll use that as a skeleton for our example structure. @@ -67,7 +67,7 @@ Example 3: Fully muxed payments (i.e. M to M) But use a shared function for all of them that does the real work, highlighting the ease of implementing muxed account support. -#### Preamble +#### Preamble {#preamble} First, let’s create two accounts and then a handful of virtual accounts representing “custodial customers” that the parent account manages: @@ -127,7 +127,7 @@ Customers: With the accounts out of the way, let’s look at how we can manage the difference between traditional Stellar accounts (G...) and these virtual muxed accounts (M...). -#### Muxed Operations Model +#### Muxed Operations Model {#muxed-operations-model} The introduction of muxed addresses as a higher-level abstraction—and their experimental, opt-in nature—means there are mildly diverging branches of code depending on whether the source is a muxed account or not. We still need to, for example, load accounts by their underlying address, because the muxed versions don’t actually live on the Stellar ledger: @@ -151,7 +151,7 @@ function showBalance(acc) { For payments—our focus for this set of examples—the divergence only matters because we want to show the balances for the custodian account. -#### Payments +#### Payments {#payments} The actual code to build payments is almost exactly the same as it would be without the muxed situation: @@ -190,7 +190,7 @@ function doPayment(source, dest) { We can use this block to make a payment between normal Stellar accounts with ease: doPayment("GCIHA...", "GDS5N..."). The main divergence from the standard payments code—aside from the stubs to show XLM balances before and after—is the inclusion of the opt-in withMuxing flag. -#### Muxed to Unmuxed +#### Muxed to Unmuxed {#muxed-to-unmuxed} The codeblock above covers all payment operations, abstracting away any need for differentiating between muxed (M...) and unmuxed (G...) addresses. From a high level, then, it’s still trivial to make payments between one of our “customers” and someone outside of the “custodian’s” organization. @@ -220,7 +220,7 @@ GCIHA: 9509.9997600 XLM Of course, there’s also a fee charged for the transaction itself. -#### Muxed to Muxed +#### Muxed to Muxed {#muxed-to-muxed} As we’ve mentioned, muxed account actions aren’t represented in the Stellar ledger explicitly. When two muxed accounts sharing an underlying Stellar account communicate, it’s as if the underlying account is talking to itself. A payment between two such accounts, then, is essentially a no-op. @@ -250,11 +250,11 @@ Notice that the account’s balance is essentially unchanged, yet it was charged If we were to make a payment between two muxed accounts that had different underlying Stellar accounts, this would be equivalent to a payment between those two respective G... accounts. -#### More Examples +#### More Examples {#more-examples} As is the case for most protocol-level features, you can find more usage examples and inspiration in the relevant test suite for your favorite SDK. For example, [here](https://github.com/stellar/js-stellar-base/blob/master/test/unit/muxed_account_test.js) are some of the JavaScript test cases. -### FAQs +### FAQs {#faqs} **What happens if I pay a muxed address, but the recipient doesn’t support them?** @@ -329,13 +329,13 @@ namespace StrKey { There are also abstractions for constructing and managing both muxed and regular accounts; consult your SDK documentation for details. -## Memo - differentiated accounts +## Memo - differentiated accounts {#memo---differentiated-accounts} Prior to the introduction of muxed accounts, products and services that relied on pooled accounts often used transaction memos to differentiate between users. Supporting muxed accounts is better in the long term, but for now you may want to support both memos and muxed accounts as all exchanges, anchors, and wallets may not support muxed accounts. To learn about what other purposes memos can be used for, see our [Memos Encyclopedia Entry](./memos.mdx). -## Why are muxed accounts better in the long term? +## Why are muxed accounts better in the long term? {#why-are-muxed-accounts-better-in-the-long-term} Muxed accounts are a better approach to differentiating between individuals in a pooled account because they have better: diff --git a/docs/learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx b/docs/learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx index 489afa155..812072fb5 100644 --- a/docs/learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx @@ -13,9 +13,9 @@ Anything that increases the minimum balance can be sponsored (account creation, To learn about base reserves, see our section on [Lumens](../../fundamentals/lumens.mdx#base-reserves). -## Sponsored reserves operations +## Sponsored reserves operations {#sponsored-reserves-operations} -### Begin and end sponsorships +### Begin and end sponsorships {#begin-and-end-sponsorships} To create a sponsored reserve, you have to use a sandwich transaction that includes three operations. @@ -31,7 +31,7 @@ At the end of any transaction, there must be no ongoing is-sponsoring-future-res View operation details in our [List of Operations section](../../fundamentals/transactions/list-of-operations.mdx). -### Revoke sponsorship +### Revoke sponsorship {#revoke-sponsorship} Allows the sponsoring account to remove or transfer sponsorships of existing ledgerEntries and signers. If the ledgerEntry or signer is not sponsored, the owner of the ledgerEntry or signer can establish a sponsorship if it is the beneficiary of an is-sponsoring-future-reserves-for relationship. @@ -50,7 +50,7 @@ Operation logic View operation details in our [List of Operations section](../../fundamentals/transactions/list-of-operations.mdx#begin-sponsoring-future-reserves). -## Effect on minimum balance +## Effect on minimum balance {#effect-on-minimum-balance} Once sponsorships are introduced, the minimum balance calculation is: (2 base reserves + `numSubEntries` + `numSponsoring` - `numSponsored`) \* `baseReserve` + `liabilities.selling`. @@ -60,13 +60,13 @@ When a sponsored entry or subentry is removed, `numSponsoring` is decreased on t To learn more about minimum balance requirements, see our section on [Lumens](../../fundamentals/lumens.mdx#minimum-balance). -## Effect on claimable balances +## Effect on claimable balances {#effect-on-claimable-balances} All claimable balances are sponsored through built-in logic in the claimable balance operations. The account that creates the claimable balance pays the base reserve to get the claimable balance on the ledger. When the claimable balance is claimed by the claimant(s), the claimable balance is removed from the ledger, and the account that created it gets the base reserve back. Read more about claimable balances in our [Claimable Balances Encyclopedia Entry](./claimable-balances.mdx). -## Examples +## Examples {#examples} Each of the following examples builds on itself, referencing variables from previous snippets. The following examples will demonstrate: @@ -77,7 +77,7 @@ Each of the following examples builds on itself, referencing variables from prev For brevity in the Golang examples, we’ll assume the existence of a `SignAndSend`(...) method (defined below) which creates and submits a transaction with the proper parameters and basic error-checking. -### Preamble +### Preamble {#preamble} We’ll start by including the boilerplate of account and asset creation. @@ -169,7 +169,7 @@ func main() { -### 1. Sponsoring trustlines +### 1. Sponsoring trustlines {#1-sponsoring-trustlines} Now, let’s sponsor trustlines for Account A. Notice how the `CHANGE_TRUST` operation is sandwiched between the begin and end sponsoring operations and that all relevant accounts need to sign the transaction. @@ -310,7 +310,7 @@ console.log("Sponsored two trustlines of", A.publicKey()); -### 2. Transferring sponsorship +### 2. Transferring sponsorship {#2-transferring-sponsorship} Suppose that now Signer 1 wants to transfer the responsibility of sponsoring reserves for the trustline to Sponsor 2. This is accomplished by sandwiching the transfer between the `BEGIN/END_SPONSORING_FUTURE_RESERVES` operations. Both of the participants must sign the transaction, though either can submit it. @@ -381,7 +381,7 @@ console.log("Transferred sponsorship for", A.publicKey()); At this point, Signer 1 is only sponsoring the first asset (arbitrarily coded as ABCD), while Signer 2 is sponsoring the other two assets. (Recall that initially Signer 1 was also sponsoring EFGH.) -### 3. Sponsorship revocation +### 3. Sponsorship revocation {#3-sponsorship-revocation} Finally, we can demonstrate complete revocation of sponsorships. Below, Signer 2 removes themselves from all responsibility over the two asset trustlines. Notice that Account A is not involved at all, since revocation should be performable purely at the sponsor’s discretion. @@ -443,7 +443,7 @@ Finally, we can demonstrate complete revocation of sponsorships. Below, Signer 2 -### Sponsorship Source Accounts +### Sponsorship Source Accounts {#sponsorship-source-accounts} When it comes to the SourceAccount fields of the sponsorship sandwich, it's important to refer to the wisdom of [CAP-33](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#abstract): @@ -477,11 +477,11 @@ For example, the following is an identical expression of the earlier Golang exam -### Other examples +### Other examples {#other-examples} If you’d like other examples or want to view a more-generic pseudo-code breakdown of these sponsorship scenarios, you can refer to [CAP-0033](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#example-revoke-sponsorship) directly. -### Footnote +### Footnote {#footnote} For the above examples, an implementation of SignAndSend (Golang) and some (very) rudimentary error checking code (all languages) might look something like this: diff --git a/docs/learn/fundamentals/anchors.mdx b/docs/learn/fundamentals/anchors.mdx index 1f94f3cad..ad3eab6db 100644 --- a/docs/learn/fundamentals/anchors.mdx +++ b/docs/learn/fundamentals/anchors.mdx @@ -13,7 +13,7 @@ You can set up an anchor by using the SDF-maintained [Anchor Platform](/platform Learn how to integrate anchor services into your blockchain-based application by viewing the [Build Apps section](../../build/apps/overview.mdx). If you’re looking specifically for MoneyGram Access, see the Integrate with MoneyGram Access tutorial. -### Stellar Ecosystem Proposals (SEPs) +### Stellar Ecosystem Proposals (SEPs) {#stellar-ecosystem-proposals-seps} Stellar is an open-source network that is designed to interoperate with traditional financial institutions, various types of assets, and other networks. Network participants implement Stellar Ecosystem Proposals (SEPs) to ensure they can interoperate with other products and services on the network. SEPs are publicly created, open-source documents that live in a [GitHub repository](https://github.com/stellar/stellar-protocol/tree/master/ecosystem#stellar-ecosystem-proposals-seps.mdx) and they define how anchors, asset issuers, applications, exchanges, and other service providers should interact and interoperate. diff --git a/docs/learn/fundamentals/fees-resource-limits-metering.mdx b/docs/learn/fundamentals/fees-resource-limits-metering.mdx index 9f2dd3c1d..9955c7705 100644 --- a/docs/learn/fundamentals/fees-resource-limits-metering.mdx +++ b/docs/learn/fundamentals/fees-resource-limits-metering.mdx @@ -5,7 +5,7 @@ sidebar_position: 70 import CanvasFeeGraphs from "@site/src/components/CanvasFeeGraphs"; -## Fees overview +## Fees overview {#fees-overview} Stellar requires a fee for all transactions to make it to the ledger. This helps prevent spam and prioritizes transactions during traffic surges. All fees are paid using the native Stellar token, the [lumen (or XLM)](./lumens.mdx). @@ -19,7 +19,7 @@ When competing for space on the ledger, smart contract transactions are _only_ c The lumens collected from transaction fees go into a locked account and are not given to or used by anyone. -## Resource fee +## Resource fee {#resource-fee} All smart contract transactions require a resource fee in addition to an inclusion fee: @@ -50,7 +50,7 @@ Find current resource fees in the [Resource Limits & Fees](../../networks/resour For help in analyzing smart contract cost and efficiency, see this [How-To Guide](../../build/guides/fees/analyzing-smart-contract-cost.mdx). -### Refundable and non-refundable resource fees +### Refundable and non-refundable resource fees {#refundable-and-non-refundable-resource-fees} The resource fee is calculated with a non-refundable fees portion and a refundable fees portion: `ResourceFee(sorobanData.resourceFee) = Non-refundable resource fee + Refundable resource fees`. @@ -58,11 +58,11 @@ The resource fee is calculated with a non-refundable fees portion and a refundab **Refundable fees:** calculated from rent, events, and return value. Refundable fees are charged from the source account before the transaction is executed and then refunded based on actual usage. However, the transaction will fail if `refundableFee` is not enough to cover the actual resource usage. -### Find a transaction’s resource fee +### Find a transaction’s resource fee {#find-a-transactions-resource-fee} The best way to find the required resource fee for any smart contract transaction is to use the [`simulateTransaction` endpoint](../encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx) from the RPC, which enables you to send a preflight transaction that will return the necessary resource values and resource fee. -### Resource limitations +### Resource limitations {#resource-limitations} :::note @@ -76,7 +76,7 @@ Resource limits are determined by a validator vote and can be adjusted based on Find current resource limits in the [Resource Limits & Fees](../../networks/resource-limits-fees.mdx) page in the Networks section. -## Inclusion fee +## Inclusion fee {#inclusion-fee} The inclusion fee is the maximum bid (a bid denotes a dynamic fee, meaning it varies based on certain network conditions) the submitter is willing to pay for the transaction to be included in the ledger. The inclusion fee equals the number of operations in the transaction multiplied by the effective base fee for the given ledger: `inclusion fee = # of operations * effective base fee` @@ -96,9 +96,9 @@ Alternatively, your transaction may not make it to the ledger if the effective b Fees are deducted from the source account unless there is a fee-bump transaction that states otherwise. Learn about fee-bump transactions in the [Fee-Bump Transaction section](../encyclopedia/transactions-specialized/fee-bump-transactions.mdx). -## Surge and dynamic pricing +## Surge and dynamic pricing {#surge-and-dynamic-pricing} -### Surge pricing +### Surge pricing {#surge-pricing} The network can enter surge pricing mode under two circumstances: 1. when the number of operations submitted to a ledger exceeds the network capacity (1,000 operations for transactions that do not execute smart contracts), or 2. if there is competition between smart contract transactions for a particular resource (instructions, ledger entry accesses (reads and writes), ledger IO (bytes read and bytes written), and the total size of transactions to be applied). During this time, the network uses market dynamics to decide which transactions to include in the ledger. Transactions that offer a higher maximum base fee bid make it to the ledger first. @@ -114,7 +114,7 @@ It is recommended to apply [ledger bounds](./transactions/operations-and-transac **You are more likely to pay a higher inclusion fee when submitting smart contract transactions.** Smart contract transactions have tighter ledger limits than transactions that don’t interact with smart contracts and will therefore experience surge pricing more often. You are more likely to pay your maximum inclusion fee bid or, at least, the minimum inclusion fee bid in your transaction set. So, you must plan your fee bidding strategy accordingly. -### Dynamic pricing for storage +### Dynamic pricing for storage {#dynamic-pricing-for-storage} Stellar’s storage database size is determined by two forces: the rate of additions (writes) and the rate of deletions (evictions). Stellar has set a ledger growth threshold to a constant value (the `BucketListTargetSizeBytes` network parameter, implemented to prevent explosive state growth and subject to change based on validator vote). Because there is a fixed capacity, write fees are based on the ledger size and can alter dynamically based on that size. @@ -122,7 +122,7 @@ When the ledger size is large, there is a higher demand for storage space, which Write fees will grow gradually over time when the database size is below the ledger growth threshold and will grow linearly, but with a 1,000x factor after exceeding that threshold. This is a safeguard against spam and is not anticipated under normal circumstances. -## Metering +## Metering {#metering} Metering is a mechanism in the host environment that accounts for the resource costs incurred during the execution of a smart contract. The outcomes of metering act as the canonical truth of a smart contract’s execution cost and serve as an input for fee computations. @@ -134,11 +134,11 @@ Consider two contracts: A and B, both comprising the same number of Wasm instruc Metering ensures fairness, thwarts resource manipulation and attacks, and generates a deterministic and reproducible measure of runtime resource costs. -### Methodology +### Methodology {#methodology} To maintain equivalence in metering between the host and guest, computation costs on both sides are expressed in terms of CPU instructions and memory bytes (representing CPU and RAM usage). Metering and limit-checking occur within the host environment, and pre-calibrated numerical models ensure results are deterministic. -### Cost types +### Cost types {#cost-types} Metering is segmented into host components, referred to as **cost types**. Each cost type can be viewed as a “meta instruction” symbolizing a specific host operation with a known complexity that depends on a runtime input. For instance, cost type `ComputeSha256Hash` represents the cost of computing the SHA256 hash of a byte array. @@ -150,7 +150,7 @@ Execution of Wasm instructions is accounted for as a host cost type `WasmInsnExe Find a complete list of host cost types and their definitions here: [`ContractCostType`](https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-contract-config-setting.x#L92-L155). -### Cost parameters +### Cost parameters {#cost-parameters} Cost types are carefully selected to: @@ -161,7 +161,7 @@ Each cost type has a separate model for both resource types (CPU and memory). The parameters for each model, `a` and `b`, are calibrated and fitted offline against inputs of various sizes. The collection of all model cost parameters from the network configurable entries (see [`ConfigSettingsEntry`](https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-contract-config-setting.x#L223-L226) can be updated through network consensus. -### Metering process +### Metering process {#metering-process} Before contract execution, the host environment is prepared with the cost parameters and a budget defining the resource limits. Metering is then implemented to measure the cumulative resource consumption during host execution. @@ -169,7 +169,7 @@ During execution, whenever a component (a code block defining a cost type) is en If the contract execution concludes within the specified resource limits, the metered total of CPU instructions is recorded and utilized as the input for fee calculation. While memory usage is not included in the fee computation, it is nevertheless subject to the resource limits. -## Inclusion fee pricing strategies +## Inclusion fee pricing strategies {#inclusion-fee-pricing-strategies} For the past three hours, inclusion fee statistics on the Mainnet network can be seen below. @@ -180,13 +180,13 @@ There are two primary methods to deal with inclusion fee fluctuations and surge - [**Method 1:**](#set-the-highest-fee-youre-comfortable-paying) set the highest fee you’re comfortable paying. This does not mean that you’ll pay that amount on every transaction — you will only pay what’s necessary to get into the ledger. Under normal (non-surge) circumstances, you will only pay the standard fee even with a higher maximum fee set. This method is simple, convenient, and efficient but can still potentially fail. - [**Method 2:**](#fee-bumps-on-past-transactions) resubmit a transaction with a higher fee using a fee-bump transaction -### Set the highest fee you’re comfortable paying​ +### Set the highest fee you’re comfortable paying​ {#set-the-highest-fee-youre-comfortable-paying} In general, it’s a good idea to choose the highest fee you’re willing to pay per operation for your transaction to make it to the ledger. Wallet developers may want to offer users a chance to specify their own base fee, though it may make more sense to set a persistent global base fee that’s above the market rate since the average user probably doesn’t care if they’re paying 0.8 cents or 0.00008 cents. Remember that you’re more likely to pay your maximum fee bid with smart contract transactions. -### Fee-bumps on past transactions​ +### Fee-bumps on past transactions​ {#fee-bumps-on-past-transactions} Even with a liberal fee-paying policy, your transaction may fail to make it into the ledger due to insufficient funds or untimely surges. Fee-bump transactions can solve this problem. The following snippet shows you how to resubmit a transaction with a higher fee (as long as you have the original transaction envelope): diff --git a/docs/learn/fundamentals/lumens.mdx b/docs/learn/fundamentals/lumens.mdx index 7beaa964b..0ca9bfdcb 100644 --- a/docs/learn/fundamentals/lumens.mdx +++ b/docs/learn/fundamentals/lumens.mdx @@ -7,7 +7,7 @@ Lumens (XLM) are the native currency of the Stellar network. The lumen is the on To read up on the basics of lumens, head over to our Stellar Learn site: [Stellar Learn: Lumens](https://www.stellar.org/lumens) -## Transaction fees +## Transaction fees {#transaction-fees} Stellar requires a small fee for all transactions to prevent ledger spam and prioritize transactions during surge pricing. Transaction fees are paid in lumens. @@ -15,13 +15,13 @@ To learn about fees on Stellar, see our [Fees section](./fees-resource-limits-me Smart contract transactions on Stellar employ a different fee structure based on an inclusion fee and resource consumption (which includes [rent](#rent)). Read more in the [Fees and Metering section](./fees-resource-limits-metering.mdx). -## Base reserves +## Base reserves {#base-reserves} A unit of measurement used to calculate an account’s minimum balance. One base reserve is currently 0.5 XLM. Validators can vote to change the base reserve, but that’s uncommon and should only happen every few years. -## Minimum balance +## Minimum balance {#minimum-balance} Stellar accounts must maintain a minimum balance to exist, which is calculated using the base reserve. An account must always maintain a minimum balance of two base reserves (currently 1 XLM). Every subentry after that requires an additional base reserve (currently 0.5 XLM) and increases the account’s minimum balance. Subentries include trustlines (for both traditional assets and pool shares), offers, signers, and data entries. An account cannot have more than 1,000 subentries. @@ -33,11 +33,11 @@ For example, an account with one trustline, two offers, and a claimable balance When you close a subentry, the associated base reserve will be added to your available balance. An account must always pay its own minimum balance unless a subentry is being sponsored by another account. For information about this, see our [Sponsored Reserves Encyclopedia Entry](../encyclopedia/transactions-specialized/sponsored-reserves.mdx). -## Rent +## Rent {#rent} Smart contract data does not require any base reserves in order to live on the ledger, so every smart contract entry must pay rent instead. The rent charged for an entry to exist on the ledger is based on how big the entry is and how long the it should be live on the ledger before being archived. There are different rent requirements for each storage type `Persistent`, `Temporary`, and `Instance`, which you can read about in the [State Archival section](../encyclopedia/storage/state-archival.mdx). -## Lumen Supply Metrics +## Lumen Supply Metrics {#lumen-supply-metrics} import { CodeExample } from "@site/src/components/CodeExample"; @@ -49,7 +49,7 @@ Unlike many other blockchains, the native network currency is not created throug Please reference our [Ecosystem Horizon API Providers](../../data/horizon/horizon-providers.mdx) to access more Stellar network data via Horizon. -### Dashboard API +### Dashboard API {#dashboard-api} As of May 28th, 2024, the Dashboard API shows: @@ -72,7 +72,7 @@ As of May 28th, 2024, the Dashboard API shows: -### Definitions +### Definitions {#definitions} **originalSupply** One hundred billion lumens [were created](https://stellar.expert/explorer/public/ledger/2) when the Stellar network went live. That’s the Original Supply for the network. diff --git a/docs/learn/fundamentals/networks.mdx b/docs/learn/fundamentals/networks.mdx index 08006a16e..4d7dfe2a0 100644 --- a/docs/learn/fundamentals/networks.mdx +++ b/docs/learn/fundamentals/networks.mdx @@ -5,9 +5,9 @@ sidebar_position: 20 Stellar has three networks: the public network (Mainnet, also called Pubnet or the Public Network), the test network (Testnet), and a dev network (Futurenet). Mainnet is the main network used by applications in production. It connects to real financial rails and requires XLM to cover minimum balances, transaction fees, and rent. The Testnet is a smaller, free-to-use network maintained by SDF that functions like the Mainnet but doesn’t connect to real money. It has a built-in testnet XLM faucet (called Friendbot), and it resets on a regular cadence, so it's the best place for developers to test applications when they need a stable environment that mirrors Mainnet functionality. Futurenet is a dev network you can use to test more bleeding edge features that also has access to its own Friendbot. It resets whenever a reset is necessary, so it's not as predictable as Testnet, but it is where new features may be introduced before the are implemented in stable releases. -## Stats: Mainnet versus Testnet versus Futurenet +## Stats: Mainnet versus Testnet versus Futurenet {#stats-mainnet-versus-testnet-versus-futurenet} -### Mainnet +### Mainnet {#mainnet} - Validator nodes are run by the public - SDF offers free [Horizon Testnet and Futurenet Instances](../../data/horizon/horizon-providers.mdx#sdf-provided-horizon) to interact with the Testnet and Futurenet. The ecosystem has [Horizon providers](../../data/horizon/horizon-providers.mdx#ecosystem-horizon-providers) whom offer instances for Testnet and Mainnet. You can [run your own Horizon](../../data/horizon/admin-guide/overview.mdx) or use an instance offered by an [infrastructure provider](../../data/horizon/horizon-providers.mdx#ecosystem-horizon-providers). @@ -16,7 +16,7 @@ Stellar has three networks: the public network (Mainnet, also called Pubnet or t - See more detailed smart contract network settings in the section on [Fees and Metering](./fees-resource-limits-metering.mdx). - No publicly available RPC, see RPC service providers [here](../../data/rpc/rpc-providers.mdx) -### Testnet +### Testnet {#testnet} - SDF runs three core validator nodes - SDF offers a free [Horizon instance](https://horizon-testnet.stellar.org/) you can use to interact with the Testnet @@ -24,7 +24,7 @@ Stellar has three networks: the public network (Mainnet, also called Pubnet or t - Testnet is limited to 100 operations per ledger and one smart contract transaction per ledger - SDF offers free RPC endpoints, more information [here](../../data/rpc/rpc-providers.mdx#sdf-provided-rpc) -### Futurenet +### Futurenet {#futurenet} - SDF runs core validator nodes - SDF offers a free [Horizon instance](https://horizon-futurenet.stellar.org) you can use to interact with the Futurenet @@ -32,13 +32,13 @@ Stellar has three networks: the public network (Mainnet, also called Pubnet or t - Futurenet is limited to 100 operations per ledger and one smart contract transaction per ledger - SDF offers free RPC endpoints, more information [here](../../data/rpc/rpc-providers.mdx#sdf-provided-rpc) -## Friendbot +## Friendbot {#friendbot} Friendbot is a bot that funds accounts with fake XLM on Testnet or Futurenet. You can request XLM from Friendbot using the [Stellar Lab](../../tools/developer-tools/lab/account.mdx) or with various SDKs. Requests to Friendbot are rate limited, so use it wisely. Friendbot provides 10,000 fake XLM when funding a new account. If you are creating multiple accounts, you can fund your first account with Friendbot and then use that first account to fund your subsequent accounts using the Create Account operation. -## Testnet and Futurenet data reset +## Testnet and Futurenet data reset {#testnet-and-futurenet-data-reset} Testnet and Futurenet are reset periodically to the genesis ledger to declutter the network, remove spam, reduce the time needed to catch up on the latest ledger, and help maintain the system. Resets clear all ledger entries (accounts, trustlines, offers, smart contract data, etc.), transactions, and historical data from Stellar Core, Horizon, and the Stellar RPC- which is why developers should not rely on the persistence of accounts or the state of any balances when using Testnet or Futurenet. @@ -57,7 +57,7 @@ If you run a Testnet or Futurenet Horizon instance, you need to re-join and re-s Check out [this How-To Guide](../../build/guides/basics/automate-reset-data.mdx) on automating Testnet and Futurenet reset data. -## Test data automation +## Test data automation {#test-data-automation} It is recommended that you have testing infrastructure that can repopulate the Testnet and Futurenet with useful data after a reset. This will make testing more reliable and will help you scale your testing infrastructure to a private network if you choose to do so. For example, you may want to: @@ -70,16 +70,16 @@ If you maintain an application, you should think about creating a data set that A script can automate this entire process by creating an account with Friendbot and submitting a set of transactions that are predefined as a part of your testing infrastructure. -## What Testnet and Futurenet should and should not be used for +## What Testnet and Futurenet should and should not be used for {#what-testnet-and-futurenet-should-and-should-not-be-used-for} -### Testnet and Futurenet are good for +### Testnet and Futurenet are good for {#testnet-and-futurenet-are-good-for} - Creating test accounts (with funding from Friendbot); - Developing applications and contracts and exploring tutorials on Stellar without the potential to lose any assets; - Testing existing applications against new releases or release candidates of Stellar Core, Horizon, and the Stellar RPC; - Performing data analysis on a smaller, non-trivial data set compared to the Mainnet. -### Testnet and Futurenet are bad for +### Testnet and Futurenet are bad for {#testnet-and-futurenet-are-bad-for} - Load and stress testing; - High availability test infrastructure- SDF does not guarantee Testnet availability; @@ -88,7 +88,7 @@ A script can automate this entire process by creating an account with Friendbot - The ability to control the data reset frequency; - The need to secure private or sensitive data (before launching on the Mainnet). You can always run your own test network for use cases that don’t work well with SDF’s Testnet. -## Moving your project from Testnet or Futurenet to production +## Moving your project from Testnet or Futurenet to production {#moving-your-project-from-testnet-or-futurenet-to-production} Mainnet, Testnet, and Futurenet each have their own unique passphrase, which is used to validate signatures on a given transaction. diff --git a/docs/learn/fundamentals/stellar-consensus-protocol.mdx b/docs/learn/fundamentals/stellar-consensus-protocol.mdx index 68471c1f7..25ef64580 100644 --- a/docs/learn/fundamentals/stellar-consensus-protocol.mdx +++ b/docs/learn/fundamentals/stellar-consensus-protocol.mdx @@ -19,31 +19,31 @@ There are three desired properties of consensus mechanisms: fault tolerance, saf Consensus mechanisms can typically only prioritize two out of three of these properties. SCP prioritizes fault tolerance and safety over liveness. Because of prioritizing safety, blocks can sometimes get stuck while waiting for nodes to agree. -## SCP components +## SCP components {#scp-components} -### Quorum set +### Quorum set {#quorum-set} As mentioned above, each Core node decides on which other nodes it would like to trust to reach agreement. A node’s trusted set of nodes is called a **quorum set**. Validators might add each other to their quorum sets due to innate trust associated with real-world identities. -### Thresholds and quorum slices +### Thresholds and quorum slices {#thresholds-and-quorum-slices} In addition to choosing a quorum set, Core nodes must also choose a **threshold**. A threshold is the minimum number of nodes in a quorum set that must agree to reach consensus. For example, let’s say node B has nodes [A, C, D] in its quorum set and sets the threshold to 2. This means that any combination of 2 nodes in the quorum set agreeing is valid: either [A,C], [C,D], or [A,D] must agree for the node to proceed. The combination of agreeing nodes within the quorum set are called **quorum slices**. -### Node blocking sets +### Node blocking sets {#node-blocking-sets} Nodes can be blocked from reaching consensus by **node blocking sets**. Node blocking sets are any set of nodes in a quorum set that prevent a node from reaching agreement. For example, if a node requires 3 out of 4 of the nodes in its quorum set to agree, any combination of two nodes is considered a node blocking set. -### Quorum +### Quorum {#quorum} A **quorum** is a set of nodes sufficient to reach an agreement wherein each node is part of a quorum slice. -### Statement +### Statement {#statement} Valid **statements** on Stellar express the different opinions of nodes regarding transaction sets to agree on for a given ledger. For example: “I propose this transaction set for ledger number 800”. A node’s opinion on a statement depends on the opinions of its quorum set. -## Federated voting +## Federated voting {#federated-voting} In the SCP, agreement is achieved using federated voting. A node reasons about the state of the network based on what it learns from its quorum set- before a statement is 100% agreed upon by every honest node in the network, it goes through three steps of federated voting: (1) Vote, (2) Accept, and (3) Confirm. @@ -67,17 +67,17 @@ To transition between the states above, federated voting has the following rules - Confirm A if every node in a quorum slice accepted A -## Consensus rounds +## Consensus rounds {#consensus-rounds} Each consensus round is separated into two stages: -### Nomination protocol +### Nomination protocol {#nomination-protocol} In the nomination protocol, candidate transaction sets are selected to be included in a ledger. Once a node confirms its first candidate, it stops voting to nominate any new transaction sets. It may still accept or confirm previously nominated statements. This guarantees that at some point, all nodes will converge on a candidate set. If every node on the network stops introducing new values but continues to confirm what other nodes confirmed, eventually, everyone will end up with the same list of candidates. A node may start the ballot protocol as soon as it confirms a candidate. After it confirms its first candidate and starts the ballot protocol, nomination continues running in the background. -### Ballot protocol +### Ballot protocol {#ballot-protocol} The ballot protocol ensures that the network can unanimously confirm and apply nominated transaction sets. It consists of two steps: diff --git a/docs/learn/fundamentals/stellar-data-structures/accounts.mdx b/docs/learn/fundamentals/stellar-data-structures/accounts.mdx index 68659ae9c..4649a227b 100644 --- a/docs/learn/fundamentals/stellar-data-structures/accounts.mdx +++ b/docs/learn/fundamentals/stellar-data-structures/accounts.mdx @@ -21,15 +21,15 @@ Accounts are made up of the below fields. Click on the field to learn more about - [Signers](../../encyclopedia/security/signatures-multisig.mdx) - [Thresholds](../../encyclopedia/security/signatures-multisig.mdx#thresholds) -## Base reserves and subentries +## Base reserves and subentries {#base-reserves-and-subentries} Accounts store data in subentries, and each subentry increases the account’s required minimum balance. -### Base reserves +### Base reserves {#base-reserves} A base reserve is a unit of measurement used to calculate an account’s minimum balance. One base reserve is currently 0.5 XLM. -### Subentries +### Subentries {#subentries} Account data is stored in subentries, each of which increases an account’s minimum balance by one base reserve (0.5 XLM). An account cannot have more than 1,000 subentries. Possible subentries are: @@ -38,7 +38,7 @@ Account data is stored in subentries, each of which increases an account’s min - Additional signers - Data entries (includes data made with the `manageData` operation, not smart contract ledger entries) -## Trustlines +## Trustlines {#trustlines} Trustlines are an explicit opt-in for an account to hold and trade a particular asset. To hold a specific asset, an account must establish a trustline with the issuing account using the change_trust operation. Trustlines track the balance of an asset and can also limit the amount of an asset that an account can hold. diff --git a/docs/learn/fundamentals/stellar-data-structures/assets.mdx b/docs/learn/fundamentals/stellar-data-structures/assets.mdx index 534dff81a..ab4e0e1b2 100644 --- a/docs/learn/fundamentals/stellar-data-structures/assets.mdx +++ b/docs/learn/fundamentals/stellar-data-structures/assets.mdx @@ -9,9 +9,9 @@ Accounts on the Stellar network can be used to track, hold, and transfer any typ Assets on Stellar have two identifying characteristics: the asset code and the issuer. Since more than one organization can issue a credit representing the same asset, asset codes often overlap (for example, multiple companies offer a USD token on Stellar). Assets are uniquely identified by the combination of their asset code and issuer. -## Asset components +## Asset components {#asset-components} -### Asset code +### Asset code {#asset-code} An asset’s identifying code. There are three different formats: Alphanumeric 4, Alphanumeric 12, and liquidity pool shares. @@ -19,13 +19,13 @@ Learn about liquidity pool shares in the [Liquidity Pool Encyclopedia Entry](../ Learn more about asset codes in the [Naming an Asset section](../../../tokens/control-asset-access.mdx#naming-an-asset) -### Issuer +### Issuer {#issuer} There is no dedicated operation to create an asset on Stellar. Instead, assets are created with a payment operation: an issuing account makes a payment using the asset it’s issuing, and that payment creates the asset on the network. The public key of the issuing account is linked on the ledger to the asset. Responsibility for and control over an asset resides with the issuing account. Since settings are stored at the account level on the ledger, the issuing account is where you use set_options operations to link to meta-information about an asset and set authorization flags. -## Using Stellar assets in smart contracts +## Using Stellar assets in smart contracts {#using-stellar-assets-in-smart-contracts} Assets issued on the Stellar network are accessible to smart contracts. Every Stellar asset has reserved a Stellar Asset Contract that can be deployed by anyone who wants to be able to interact with the asset from a contract. @@ -33,7 +33,7 @@ The Stellar CLI can deploy a Stellar Asset Contract for a Stellar asset. Deployi Learn more in the [SAC section](../../../tokens/stellar-asset-contract.mdx). -## Representation +## Representation {#representation} In Horizon, assets are represented in a JSON object: @@ -75,7 +75,7 @@ astro_dollar = Asset("AstroDollar", "GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGS -## Amount precision +## Amount precision {#amount-precision} Each asset amount is encoded as a signed 64-bit integer in the XDR structures that Stellar uses to encode transactions. The asset amount unit seen by end-users is scaled down by a factor of ten million (10,000,000) to arrive at the native 64-bit integer representation. @@ -85,14 +85,14 @@ The smallest non-zero amount unit, also known as a stroop, is 0.0000001 (one ten The numbers are represented as int64s. Amount values are stored as only signed integers to avoid bugs that arise from mixing signed and unsigned integers. -## Relevance in Horizon and Stellar Client Libraries +## Relevance in Horizon and Stellar Client Libraries {#relevance-in-horizon-and-stellar-client-libraries} In Horizon and client-side libraries such as js-stellar-sdk, the integer encoded value is abstracted away. Many APIs expect an amount in unit value (the scaled-up amount displayed to end-users). Some programming languages (such as JavaScript) have problems maintaining precision on a number amount. It is recommended to use “big number” libraries that can record arbitrary-precision decimal numbers without a loss of precision. -## Deleting or burning assets +## Deleting or burning assets {#deleting-or-burning-assets} To delete, or "burn", an asset, you must send it back to the account that issued it. -## Custom token contracts +## Custom token contracts {#custom-token-contracts} Custom token contracts can be deployed on Stellar by deploying a contract that implements the [Token Interface](../../../tokens/token-interface.mdx), which is the same interface implemented by the [Stellar Asset Contract (SAC)](../../../tokens/stellar-asset-contract.mdx) for Stellar assets. diff --git a/docs/learn/fundamentals/stellar-data-structures/contracts.mdx b/docs/learn/fundamentals/stellar-data-structures/contracts.mdx index dcfdeb858..089f84bc1 100644 --- a/docs/learn/fundamentals/stellar-data-structures/contracts.mdx +++ b/docs/learn/fundamentals/stellar-data-structures/contracts.mdx @@ -11,11 +11,11 @@ Stellar has integrated a smart contracts platform called "[Soroban](../../../bui A smart contract is a programmed set of executable code and state that can be invoked or used on the Stellar network. -## Wasm +## Wasm {#wasm} Once a smart contract has been written by a developer and compiled into a WebAssembly (Wasm) executable file, it can then be "installed" onto the Stellar network. A `CONTRACT_DATA` [ledger entry](./ledgers.mdx) is created to store this binary data and its unique identifier is the hash of the executable file. This binary executable is stored independently from its deployed contract(s). When a Stellar transaction attempts to invoke a contract function, the Wasm bytecode is first retrieved from the ledger and a secure, isolated runtime virtual machine ("VM") is instantiated so it can run the bytecode for the contract and then exit. -## Contract Instances +## Contract Instances {#contract-instances} After the executable bytecode is installed on-chain, contract instances can be deployed that reference the aformentioned bytecode. A smart contract executable can have a one-to-many relationship with "contract instances" which function independently. This means the same executable code can be used by multiple contract instances that all behave identically (because of the shared executable code), while maintaining separate and distinct state data (because the data is tied to the contract instance). A contract instance is stored as its own ledger entry, and any of the contract's [instance storage](#instance-storage) is stored in that same ledger entry alongside the contract instance. @@ -24,18 +24,18 @@ flowchart LR A[my instance] & B[your instance]--> C[contract Wasm] ``` -## Contract Storage +## Contract Storage {#contract-storage} In addition to the ledger entries that are created during the contract install/deploy process, each contract can create and access its own set of ledger entries. These ledger entries (as well as the contract code and the contract instance ledger entries) are subject to [state archival](../../encyclopedia/storage/state-archival.mdx) lifetimes (a ledger entry's "TTL ledger"). While they all function similarly, each type has its own fee and TTL behavior. -### Temporary Storage +### Temporary Storage {#temporary-storage} - Cheapest fees. - Permanently deleted when its TTL ledger is reached, cannot be restored. - Suitable for time-bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data. - Unlimited amount of storage. -### Persistent Storage +### Persistent Storage {#persistent-storage} - Most expensive fees (same price as `Instance` storage). - Recoverable after archival, can be restored using the [`RestoreFootprintOp`](../transactions/list-of-operations.mdx#restore-footprint) operation. @@ -43,7 +43,7 @@ In addition to the ledger entries that are created during the contract install/d - Unlimited amount of storage. - Suitable for user data that cannot be `Temporary` (i.e. balances). -### Instance Storage +### Instance Storage {#instance-storage} :::info diff --git a/docs/learn/fundamentals/stellar-ecosystem-proposals.mdx b/docs/learn/fundamentals/stellar-ecosystem-proposals.mdx index 7dbb11863..34420d56d 100644 --- a/docs/learn/fundamentals/stellar-ecosystem-proposals.mdx +++ b/docs/learn/fundamentals/stellar-ecosystem-proposals.mdx @@ -11,13 +11,13 @@ SEPs define standards for building that infrastructure on top of the Stellar net SEPs are publicly-created, open-source documents that live in the [GitHub repository](https://github.com/stellar/stellar-protocol/tree/master/ecosystem) and have a lightweight approval process. New SEPs and upgrades are discussed constantly. We encourage participation in these discussions to help build new standards and make Stellar services more accessible. -## Notable SEPs +## Notable SEPs {#notable-seps} There are many SEPs, and they cover a wide variety of standards for interoperation. Whatever you're building, you may want to take a look at the complete list to see if there's a standard for your use case. Here, we'll cover a few notable SEPs that define the standards for the most common Stellar use cases. -### SEP-0001 - Stellar Info File +### SEP-0001 - Stellar Info File {#sep-0001---stellar-info-file} Defines how to create and host a stellar.toml file: a common place where the Internet can find information about your Stellar integration. You can store a lot of information in your stellar.toml file including organization information, currency information, and contact information. TOML is a simple and commonly used configuration file format designed to be readable by both humans and machines. @@ -27,7 +27,7 @@ Using the `set_options` operation, you can link your Stellar account to the doma [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md) -### SEP-0005 - Key Derivation Methods for Stellar Accounts +### SEP-0005 - Key Derivation Methods for Stellar Accounts {#sep-0005---key-derivation-methods-for-stellar-accounts} Describes methods for key derivation for Stellar, improving key storage and moving keys between wallets and applications. Guidance in this SEP improves the Stellar ecosystem by: @@ -40,7 +40,7 @@ Describes methods for key derivation for Stellar, improving key storage and movi [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md) -### SEP-0006 - Deposit and Withdrawal API +### SEP-0006 - Deposit and Withdrawal API {#sep-0006---deposit-and-withdrawal-api} Defines the standard way for anchors and wallets to interact on behalf of users. With this SEP’s guidance, wallets and other clients can interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. @@ -60,7 +60,7 @@ SEP-0024 is the alternative to SEP-0006 which supports hosted deposits and withd [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) -### SEP-0007 - URI Scheme to Facilitate Delegated Signing +### SEP-0007 - URI Scheme to Facilitate Delegated Signing {#sep-0007---uri-scheme-to-facilitate-delegated-signing} Defines the standard URI scheme that can be used to generate a URI that will serve as a request to sign a transaction. With this SEP’s guidance, non-wallet applications can have their their users sign a transaction without seeing the wallet user's secret key in any form since the URI (request) will typically be signed by the user’s trusted wallet where the secret keys are stored. @@ -75,7 +75,7 @@ This SEP defines a standard protocol enabling the following features within a wa [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md) -### SEP-0010 - Stellar Authentication +### SEP-0010 - Stellar Authentication {#sep-0010---stellar-authentication} Defines a standard way for clients (such as wallets or exchanges) to create authenticated web sessions for users holding a Stellar account. This SEP also supports authenticating users of shared or pooled Stellar accounts. Clients can use muxed accounts to distinguish users or sub-accounts of shared accounts. @@ -85,7 +85,7 @@ Proves that the user has a Stellar account and that they control the account wit [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) -### SEP-0012 - KYC API +### SEP-0012 - KYC API {#sep-0012---kyc-api} Allows for sharing of KYC data and defines a standard way for Stellar clients to upload KYC and other information to anchors and other services. This SEP was made with these goals in mind: @@ -100,7 +100,7 @@ Allows for sharing of KYC data and defines a standard way for Stellar clients to [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md) -### SEP-0020 - Self-Verification of Validator Nodes +### SEP-0020 - Self-Verification of Validator Nodes {#sep-0020---self-verification-of-validator-nodes} Defines how validators self-verify by setting the home domain of their Stellar account to their website, where they publish information on-chain about their node and organization in a stellar.toml file. This allows other participants to discover other nodes and add them to their quorum sets without needing a centralized database. @@ -108,7 +108,7 @@ Defines how validators self-verify by setting the home domain of their Stellar a [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0020.md) -### SEP-0024 - Hosted Deposit and Withdrawal +### SEP-0024 - Hosted Deposit and Withdrawal {#sep-0024---hosted-deposit-and-withdrawal} Defines the standard way for anchors and wallets to interact on behalf of users interactively. This means that the user’s application must open a webview hosted by a third-party anchor for the user to provide the information necessary to complete the transaction. @@ -120,7 +120,7 @@ SEP-0006 is the alternative to SEP-0024 that supports an API-style solution for [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md) -### SEP-0030 - Account Recovery: Multi-Party Recovery of Stellar Accounts +### SEP-0030 - Account Recovery: Multi-Party Recovery of Stellar Accounts {#sep-0030---account-recovery-multi-party-recovery-of-stellar-accounts} Defines the standard API that enables an individual (e.g., a user or wallet) to regain access to a Stellar account that it owns after the individual has lost its private key without providing any third-party control of the account. Using this protocol, the user or wallet will preregister the account and a phone number, email, or other form of authentication with one or more servers implementing the protocol and add those servers as signers of the account. If two or more servers are used with appropriate signer configuration no individual server will have control of the account, but collectively, they may help the individual recover access to the account. @@ -135,7 +135,7 @@ This SEP enables the following use cases for a user: [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0030.md) -### SEP-0031 - Cross-Border Payment API +### SEP-0031 - Cross-Border Payment API {#sep-0031---cross-border-payment-api} Defines the protocol for two financial accounts that exist outside the Stellar network (anchors) to interact with each other. diff --git a/docs/learn/fundamentals/stellar-stack.mdx b/docs/learn/fundamentals/stellar-stack.mdx index f530a7431..282b217f1 100644 --- a/docs/learn/fundamentals/stellar-stack.mdx +++ b/docs/learn/fundamentals/stellar-stack.mdx @@ -7,13 +7,13 @@ The Stellar stack is made up of the following components: the networks (Mainnet, ![Stellar Stack](/assets/stellar-tech-stack.png) -## Networks +## Networks {#networks} Stellar has three networks: the public network (Mainnet, also called Pubnet or the Public Network), the test network (Testnet), and a dev network (Futurenet). Mainnet is the main network used by applications in production. The Testnet is a smaller, free-to-use network maintained by SDF that functions like the Mainnet but doesn’t connect to real money and is the best place for developers to test their applications. Futurenet is a dev network you can use to test more bleeding edge features. Read more about the different networks in the [Networks section](./networks.mdx). -## Stellar Core +## Stellar Core {#stellar-core} Stellar Core is the program used by the individual nodes (or computers) that make up the network. Stellar Core keeps a common distributed ledger and engages in consensus to validate and process transactions. Generally, nodes reach consensus, apply a transaction set, and update the ledger every 5-7 seconds. @@ -21,7 +21,7 @@ Nodes reach consensus using the Stellar Consensus Protocol, which can you can le Anyone can run a Stellar Core node, but you don’t have to in order to build on Stellar. We recommend you do so if you issue an asset and want to ensure the accuracy of the ledger, if you want to participate in network governance by voting on protocol version, minimum fees, and resource and ledger limits, and/or if you want to contribute to Stellar’s overall health and decentralization. Check out our tutorial on installing, configuring, and maintaining your own node here: [Run a Validator Node Tutorial](../../validators/README.mdx). -## Horizon +## Horizon {#horizon} Horizon is the client-facing RESTful HTTP API server in the platform layer which allows programmatic access to submit transactions and query the network’s historical data. It acts as the interface for applications that want to access the Stellar network. You can communicate with Horizon using an SDK, a web browser, or with simple command tools like cURL. @@ -29,7 +29,7 @@ You do not need to run your own Horizon instance — when you're getting started Learn all there is to know about using Horizon in the Horizon [documentation](../../data/horizon/README.mdx). -## RPC +## RPC {#rpc} Stellar's RPC is a JSON RPC server that provides an interface for users and applications to interact with smart contracts on the Stellar blockchain. When an application would like to interact with smart contracts, it sends a request to the RPC server. The server interprets these requests, translates them into a format understandable by the blockchain nodes, and forwards them. After processing the requests, the blockchain nodes send back the results. The RPC server receives these results and sends them back to the requesting application. @@ -37,7 +37,7 @@ SDF has RPC endpoints available for Futurenet and Testnet. These services are fr SDF does not provide a publicly available RPC endpoint for Mainnet. Developers should [select an ecosystem provider](../../data/rpc/rpc-providers.mdx) that works for their project before migrating to Mainnet. In some cases, projects may choose to run their own RPC instance. -## SDKs +## SDKs {#sdks} SDKs simplify some of the work of accessing Horizon and the Stellar RPC by converting the data into friendlier formats and allowing you to program in the language of your choice. Stellar’s SDKs show you how to request data and create and submit transactions. Soroban's SDKs allow you to write smart contracts in Rust and interact with smart contracts in a myriad of other languages. diff --git a/docs/learn/fundamentals/transactions/list-of-operations.mdx b/docs/learn/fundamentals/transactions/list-of-operations.mdx index c06a3a515..9f19ac592 100644 --- a/docs/learn/fundamentals/transactions/list-of-operations.mdx +++ b/docs/learn/fundamentals/transactions/list-of-operations.mdx @@ -9,7 +9,7 @@ Learn more about transactions and operations in our [Operations and Transactions There are currently 26 operations you can use on the Stellar network, these operations, their definitions, SDKs, thresholds, parameters, and errors are listed below. -## Create account +## Create account {#create-account} Creates and funds a new account with the specified starting balance @@ -32,7 +32,7 @@ Creates and funds a new account with the specified starting balance | CREATE_ACCOUNT_LOW_RESERVE | -3 | This operation would create an account with fewer than the minimum number of XLM an account must hold. | | CREATE_ACCOUNT_ALREADY_EXIST | -4 | The `destination` account already exists. | -## Payment +## Payment {#payment} Sends an amount in a specific asset to a destination account @@ -60,7 +60,7 @@ Sends an amount in a specific asset to a destination account | PAYMENT_NOT_AUTHORIZED | -7 | The destination account is not authorized by the asset's issuer to hold the asset. | | PAYMENT_LINE_FULL | -8 | The destination account (receiver) does not have sufficient limits to receive `amount` and still satisfy its buying liabilities. | -## Path payment strict send +## Path payment strict send {#path-payment-strict-send} A payment where the asset sent can be different than the asset received; allows the user to specify the amount of the asset to send @@ -96,7 +96,7 @@ Learn more about path payments: [Path Payments Encyclopedia Entry](../../encyclo | PATH_PAYMENT_STRICT_SEND_OFFER_CROSS_SELF | -11 | The payment would cross one of its own offers. | | PATH_PAYMENT_STRICT_SEND_UNDER_DESTMIN | -12 | The paths that could send `destination amount` of `destination asset` would fall short of `destination min`. | -## Path payment strict receive +## Path payment strict receive {#path-payment-strict-receive} A payment where the asset received can be different from the asset sent; allows the user to specify the amount of the asset received @@ -132,7 +132,7 @@ Learn more about path payments: [Path Payments Encyclopedia Entry](../../encyclo | PATH_PAYMENT_STRICT_RECEIVE_OFFER_CROSS_SELF | -11 | The payment would cross one of its own offers. | | PATH_PAYMENT_STRICT_RECEIVE_OVER_SENDMAX | -12 | The paths that could send `destination amount` of `destination asset` would exceed `send max`. | -## Manage buy offer +## Manage buy offer {#manage-buy-offer} Creates, updates, or deletes an offer to buy a specific amount of an asset for another @@ -166,7 +166,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | MANAGE_BUY_OFFER_NOT_FOUND | -11 | An offer with that `offerID` cannot be found. | | MANAGE_BUY_OFFER_LOW_RESERVE | -12 | The account creating this offer does not have enough XLM to satisfy the minimum XLM reserve increase caused by adding a subentry and still satisfy its XLM selling liabilities. For every offer an account creates, the minimum amount of XLM that account must hold will increase. | -## Manage sell offer +## Manage sell offer {#manage-sell-offer} Creates, updates, or deletes an offer to sell a specific amount of an asset for another @@ -200,7 +200,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | MANAGE_SELL_OFFER_NOT_FOUND | -11 | An offer with that `offerID` cannot be found. | | MANAGE_SELL_OFFER_LOW_RESERVE | -12 | The account creating this offer does not have enough XLM to satisfy the minimum XLM reserve increase caused by adding a subentry and still satisfy its XLM selling liabilities. For every offer an account creates, the minimum amount of XLM that account must hold will increase. | -## Create passive sell offer +## Create passive sell offer {#create-passive-sell-offer} Creates an offer to sell one asset for another without taking a reverse offer of equal price @@ -233,7 +233,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | MANAGE_SELL_OFFER_NOT_FOUND | -11 | An offer with that `offerID` cannot be found. | | MANAGE_SELL_OFFER_LOW_RESERVE | -12 | The account creating this offer does not have enough XLM to satisfy the minimum XLM reserve increase caused by adding a subentry and still satisfy its XLM selling liabilities. For every offer an account creates, the minimum amount of XLM that account must hold will increase. | -## Set options +## Set options {#set-options} Set options for an account such as flags, inflation destination, signers, home domain, and master key weight @@ -272,7 +272,7 @@ Learn more about signers operations and key weight: [Signature and Multisignatur | SET_OPTIONS_BAD_SIGNER | -8 | Any additional signers added to the account cannot be the master key. | | SET_OPTIONS_INVALID_HOME_DOMAIN | -9 | Home domain is malformed. | -## Change trust +## Change trust {#change-trust} Creates, updates, or deletes a trustline @@ -301,7 +301,7 @@ Learn more about trustlines: [Trustlines section](../stellar-data-structures/acc | CHANGE_TRUST_CANNOT_DELETE | -7 | The asset trustline is still referenced by a liquidity pool. | | CHANGE_TRUST_NOT_AUTH_MAINTAIN_LIABILITIES | -8 | The asset trustline is deauthorized. | -## Allow trust +## Allow trust {#allow-trust} Updates the authorized flag of an existing trustline @@ -329,7 +329,7 @@ This operation is deprecated as of Protocol 17- prefer SetTrustlineFlags instead | ALLOW_TRUST_SELF_NOT_ALLOWED | -5 | The source account attempted to allow a trustline for itself, which is not allowed because an account cannot create a trustline with itself. | | ALLOW_TRUST_LOW_RESERVE | -6 | Claimable balances can't be created on revocation of asset (or pool share) trustlines associated with a liquidity pool due to low reserves. | -## Account merge +## Account merge {#account-merge} Transfers the XLM balance of an account to another account and removes the source account from the ledger @@ -354,7 +354,7 @@ Transfers the XLM balance of an account to another account and removes the sourc | ACCOUNT_MERGE_DEST_FULL | -6 | The `destination` account cannot receive the balance of the source account and still satisfy its lumen buying liabilities. | | ACCOUNT_MERGE_IS_SPONSOR | -7 | The source account is a sponsor. | -## Manage data +## Manage data {#manage-data} Sets, modifies, or deletes a data entry (name/value pair) that is attached to an account @@ -379,7 +379,7 @@ Learn more about entries and subentries: [Accounts section](../stellar-data-stru | MANAGE_DATA_LOW_RESERVE | -3 | This account does not have enough XLM to satisfy the minimum XLM reserve increase caused by adding a subentry and still satisfy its XLM selling liabilities. For every new DataEntry added to an account, the minimum reserve of XLM that account must hold increases. | | MANAGE_DATA_INVALID_NAME | -4 | Name not a valid string. | -## Bump sequence +## Bump sequence {#bump-sequence} Bumps forward the sequence number of the source account to the given sequence number, invalidating any transaction with a smaller sequence number @@ -398,7 +398,7 @@ Bumps forward the sequence number of the source account to the given sequence nu | --- | --- | --- | | BUMP_SEQUENCE_BAD_SEQ | -1 | The specified `bumpTo` sequence number is not a valid sequence number. It must be between 0 and `INT64_MAX` (9223372036854775807 or 0x7fffffffffffffff). | -## Create claimable balance +## Create claimable balance {#create-claimable-balance} Moves an amount of asset from the operation source account into a new ClaimableBalanceEntry @@ -425,7 +425,7 @@ Learn more about claimable balances: [Claimable Balances Encyclopedia Entry](../ | CREATE_CLAIMABLE_BALANCE_NOT_AUTHORIZED | -4 | The source account is not authorized to transfer this asset. | | CREATE_CLAIMABLE_BALANCE_UNDERFUNDED | -5 | The source account does not have enough funds to transfer amount of this asset to the ClaimableBalanceEntry. | -## Claim claimable balance +## Claim claimable balance {#claim-claimable-balance} Claims a ClaimableBalanceEntry that corresponds to the BalanceID and adds the amount of an asset on the entry to the source account @@ -450,7 +450,7 @@ Learn more about claimable balances and view more parameters: [Claimable Balance | CLAIM_CLAIMABLE_BALANCE_NO_TRUST | -4 | The source account does not trust the issuer of the asset it is trying to claim in the ClaimableBalanceEntry. | | CLAIM_CLAIMABLE_BALANCE_NOT_AUTHORIZED | -5 | The source account is not authorized to claim the asset in the ClaimableBalanceEntry. | -## Begin sponsoring future reserves +## Begin sponsoring future reserves {#begin-sponsoring-future-reserves} Allows an account to pay the base reserves for another account; sponsoring account establishes the is-sponsoring-future-reserves relationship @@ -475,7 +475,7 @@ Learn more about sponsored reserves: [Sponsored Reserves Encyclopedia Entry](../ | BEGIN_SPONSORING_FUTURE_RESERVES_ALREADY_SPONSORED | -2 | Source account is already sponsoring sponsoredID. | | BEGIN_SPONSORING_FUTURE_RESERVES_RECURSIVE | -3 | Either source account is currently being sponsored, or sponsoredID is sponsoring another account. | -## End sponsoring future reserves +## End sponsoring future reserves {#end-sponsoring-future-reserves} Terminates the current is-sponsoring-future-reserves relationship in which the source account is sponsored @@ -496,7 +496,7 @@ Learn more about sponsored reserves: [Sponsored Reserves Encyclopedia Entry](../ | --- | --- | --- | | END_SPONSORING_FUTURE_RESERVES_NOT_SPONSORED | -1 | Source account is not sponsored. | -## Revoke sponsorship +## Revoke sponsorship {#revoke-sponsorship} Sponsoring account can remove or transfer sponsorships of existing ledgerEntries and signers; the logic of this operation depends on the state of the source account @@ -527,7 +527,7 @@ Or | REVOKE_SPONSORSHIP_ONLY_TRANSFERABLE | -4 | Sponsorship cannot be removed from this ledgerEntry. This error will happen if the user tries to remove the sponsorship from a ClaimableBalanceEntry. | | REVOKE_SPONSORSHIP_MALFORMED | -5 | One or more of the inputs to the operation was malformed. | -## Clawback +## Clawback {#clawback} Burns an amount in a specific asset from a receiving account @@ -553,7 +553,7 @@ Learn more about clawbacks: [Clawback Encyclopedia Entry](../../encyclopedia/tra | CLAWBACK_NO_TRUST | -3 | The From account does not trust the issuer of the asset. | | CLAWBACK_UNDERFUNDED | -4 | The From account does not have a sufficient available balance of the asset (after accounting for selling liabilities). | -## Clawback claimable balance +## Clawback claimable balance {#clawback-claimable-balance} Claws back an unclaimed ClaimableBalanceEntry, burning the pending amount of the asset @@ -578,7 +578,7 @@ Learn more about claimable balances: [Claimable Balances Encyclopedia Entry](../ | CLAWBACK_CLAIMABLE_BALANCE_NOT_ISSUER | -2 | The source account is not the issuer of the asset in the claimable balance. | | CLAWBACK_CLAIMABLE_BALANCE_NOT_CLAWBACK_ENABLED | -3 | `The CLAIMABLE_BALANCE_CLAWBACK_ENABLED_FLAG` is not set for this trustline. | -## Set trustline flags +## Set trustline flags {#set-trustline-flags} Allows issuing account to configure authorization and trustline flags to an asset @@ -608,7 +608,7 @@ Learn more about flags: [Flags Glossary Entry](../../glossary.mdx#flags) | SET_TRUST_LINE_FLAGS_INVALID_STATE | -4 | If the final state of the trustline has both AUTHORIZED_FLAG (1) and AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG (2) set, which are mutually exclusive. | | SET_TRUST_LINE_FLAGS_LOW_RESERVE | -5 | Claimable balances can't be created on revocation of asset (or pool share) trustlines associated with a liquidity pool due to low reserves. | -## Liquidity pool deposit +## Liquidity pool deposit {#liquidity-pool-deposit} Deposits assets into a liquidity pool, increasing the reserves of a liquidity pool in exchange for pool shares @@ -643,7 +643,7 @@ Learn more about liquidity pools: [Liquidity Pools Encyclopedia Entry](../../enc | LIQUIDITY_POOL_DEPOSIT_BAD_PRICE | -6 | The deposit price is outside of the given bounds. | | LIQUIDITY_POOL_DEPOSIT_POOL_FULL | -7 | The liquidity pool reserves are full. | -## Liquidity pool withdraw +## Liquidity pool withdraw {#liquidity-pool-withdraw} Withdraw assets from a liquidity pool, reducing the number of pool shares in exchange for reserves of a liquidity pool @@ -673,7 +673,7 @@ Learn more about liquidity pools: [Liquidity Pools Encyclopedia Entry](../../enc | LIQUIDITY_POOL_WITHDRAW_LINE_FULL | -4 | The withdrawal would exceed the trustline limit for one of the assets. | | LIQUIDITY_POOL_WITHDRAW_UNDER_MINIMUM | -5 | Unable to withdraw enough to satisfy the minimum price. | -## Invoke Host Function +## Invoke Host Function {#invoke-host-function} Invoke and deploy Soroban smart contracts with `InvokeHostFunctionOp`. @@ -707,7 +707,7 @@ Learn more [here](../../encyclopedia/contract-development/contract-interactions/ | INVOKE_HOST_FUNCTION_ENTRY_ARCHIVED | -4 | A ledger entry required for this function's footprint is in an archived state, and must be restored. | | INVOKE_HOST_FUNCTION_INSUFFICIENT_REFUNDABLE_FEE | -5 | The refundable Soroban fee provided was not sufficient to pay for the compute resources required by this function invocation. | -## Extend Footprint TTL +## Extend Footprint TTL {#extend-footprint-ttl} Extend the time to live (TTL) of entries for Soroban smart contracts with the `ExtendFootprintTTLOp`. This operation extends the TTL of the entries specified in the `readOnly` footprint of the transaction so that they will live at least until the `extendTo` ledger sequence number is reached. @@ -733,7 +733,7 @@ Learn more in the [State Archival section](../../encyclopedia/storage/state-arch | EXTEND_FOOTPRINT_TTL_RESOURCE_LIMIT_EXCEEDED | -2 | The TTL extension could not be completed within the currently configured resource constraints of the network. | | EXTEND_FOOTPRINT_TTL_INSUFFICIENT_REFUNDABLE_FEE | -3 | The refundable Soroban fee provided was not sufficient to pay for TTL extension of the specified ledger entries. | -## Restore Footprint +## Restore Footprint {#restore-footprint} Make archived Soroban smart contract entries accessible again by restoring them with `RestoreFootprintOp`. This operation restores the archived entries specified in the `readWrite` footprint. diff --git a/docs/learn/fundamentals/transactions/operations-and-transactions.mdx b/docs/learn/fundamentals/transactions/operations-and-transactions.mdx index 2692a3397..ddb4c0456 100644 --- a/docs/learn/fundamentals/transactions/operations-and-transactions.mdx +++ b/docs/learn/fundamentals/transactions/operations-and-transactions.mdx @@ -3,11 +3,11 @@ title: Operations and Transactions sidebar_position: 10 --- -## Operations and transactions: how they work +## Operations and transactions: how they work {#operations-and-transactions-how-they-work} To perform actions with an account on the Stellar network, you compose operations, bundle them into a transaction, and then sign and submit the transaction to the network. Smart contract transactions (those with `InvokeHostFunctionOp`, `ExtendFootprintTTLOp`, or `RestoreFootprintOp` operations) can only have one operation per transaction. -### Operations +### Operations {#operations} Operations are individual commands that modify the ledger. Operations are used to send payments, invoke a smart contract function, enter orders into the decentralized exchange, change settings on accounts, and authorize accounts to hold assets. @@ -17,7 +17,7 @@ To learn more about signature weight, see the [Signature and Multisignature Ency View a comprehensive list of Stellar operations and their threshold levels in the [List of Operations section](./list-of-operations.mdx). -### Transactions +### Transactions {#transactions} The Stellar network encodes transactions using a standardized protocol called External Data Representation (XDR). You can read more about this in our [XDR Encyclopedia Entry](../../encyclopedia/data-format/xdr.mdx). @@ -33,7 +33,7 @@ Operations are executed for the source account of the transaction unless an oper Smart contract transactions also go through a simulation process where developers can test how the transaction would be executed on the network using the RPC endpoint `simulateTransaction`. Read more in the [Soroban docs](../../encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx). -#### Transaction attributes +#### Transaction attributes {#transaction-attributes} - [Fee](../fees-resource-limits-metering.mdx) - [List of operations](./list-of-operations.mdx) @@ -43,7 +43,7 @@ Smart contract transactions also go through a simulation process where developer - [Source account](../../glossary.mdx#source-account) - [Preconditions (optional)](#preconditions) -## Transaction and operation validity +## Transaction and operation validity {#transaction-and-operation-validity} Before being successfully submitted to the Stellar network, transactions go through several validity checks. These checks are grouped into three categories: @@ -53,7 +53,7 @@ Preconditions are checked first. All preconditions are optional. Time bounds are encouraged, but the other preconditions are used in more specialized circumstances. You can set multiple preconditions as long as the combination is logically sound. -#### Time bounds +#### Time bounds {#time-bounds} Valid if within set time bounds of the transaction @@ -63,7 +63,7 @@ Setting time bounds on transactions is highly encouraged, and many SDKs enforce If `maxTime` is 0, upper time bounds are not set. In this case, if a transaction does not make it to the transaction set, it is kept in memory and continuously tries to make it to the next transaction set. Because of this, we advise that all transactions are created with time bounds to invalidate transactions after a certain amount of time, especially if you plan to resubmit your transaction at a later time. -#### Ledger bounds +#### Ledger bounds {#ledger-bounds} Valid if within the set ledger bounds of the transaction @@ -73,7 +73,7 @@ The lower bound is inclusive (less than or equal to) while the upper bound is no If the upper bound is set to 0, this indicates there is no upper bound. -#### Minimum sequence number +#### Minimum sequence number {#minimum-sequence-number} If a minimum sequence number is set, the transaction will only be valid when its source account’s sequence number (call it S) is large enough. Specifically, it’s valid when S satisfies `minSeqNum <= S < tx.seqNum`. @@ -81,19 +81,19 @@ If this precondition is omitted, the default behavior applies: the transaction Note that after a transaction is executed, the account will always set its sequence number to the transaction’s sequence number. -#### Minimum sequence age +#### Minimum sequence age {#minimum-sequence-age} Transaction is valid after a particular duration (expressed in seconds) elapses since the account’s sequence number age. Minimum sequence age is a precondition relating to time, but unlike time bounds, which express absolute times, minimum sequence age is relative to when the transaction source account’s sequence number was touched. -#### Minimum sequence ledger gap +#### Minimum sequence ledger gap {#minimum-sequence-ledger-gap} Valid if submitted in a ledger meeting or exceeding the source account’s sequence number age This is similar to the minimum sequence age, except it is expressed as a number of ledgers rather than a duration of time. -#### Extra signers +#### Extra signers {#extra-signers} Valid if submitted with signatures that fulfill each of the extra signers @@ -101,52 +101,52 @@ A transaction can specify up to two extra signers as a precondition, meaning it The additional signers can be of any type besides the pre-authorized transaction signer since to pre-authorize a transaction, you need to know its hash, but be hash must include the extra signers. This Catch-22 relationship means including this type of extra signer will return an error. -### Operation validity +### Operation validity {#operation-validity} When a transaction is submitted to a node, the node checks the validity of each operation in the transaction before attempting to include it in a candidate transaction set. These initial operation validity checks are intended to be fast and simple, with more intensive checks coming after the fees have been consumed. For an operation to pass this validity check, it has to meet the following conditions: -#### The signatures on the transaction must be valid for the operation +#### The signatures on the transaction must be valid for the operation {#the-signatures-on-the-transaction-must-be-valid-for-the-operation} The signatures are from valid signers for the source account of the operation. The combined weight of all signatures for the source account of the operation meets the threshold for the operation. -#### The operation must be well-formed +#### The operation must be well-formed {#the-operation-must-be-well-formed} Typically this means checking the parameters for the operation to see if they’re in a valid format. For example, only positive values can be set for the amount of a payment operation. -#### The operation must be valid in the current protocol version of the network +#### The operation must be valid in the current protocol version of the network {#the-operation-must-be-valid-in-the-current-protocol-version-of-the-network} Deprecated operations, such as inflation, are invalid by design. -### Transaction validity +### Transaction validity {#transaction-validity} Finally, the following transaction checks take place: -#### Source account +#### Source account {#source-account} The source account must exist on the ledger. -#### Fee +#### Fee {#fee} The fee must be greater than or equal to the network minimum fee for the number of operations submitted as part of the transaction. This does not guarantee that the transaction will be applied, only that it is valid. In addition, the source account must be able to pay the fee specified. If multiple transactions are submitted but only a subset of them can be paid for, they are checked for validity in order of sequence number. -#### Fee-bump (if applicable) +#### Fee-bump (if applicable) {#fee-bump-if-applicable} See Validity of a [Fee-Bump Transaction section](../../encyclopedia/transactions-specialized/fee-bump-transactions.mdx#validity-of-a-fee-bump-transaction) -#### Sequence number +#### Sequence number {#sequence-number} The sequence number must be one greater than the sequence number stored in the source account entry when the transaction is applied unless sequence number preconditions are set. When checking the validity of multiple transactions with the same source account in a candidate transaction set, they must all be valid transactions and their sequence numbers must be offset by one. Then they are ordered and applied according to their sequence number. -#### List of operations +#### List of operations {#list-of-operations} Each operation must pass all the validity checks for an operation, described in the Operation Validity section above. -#### List of signatures +#### List of signatures {#list-of-signatures} - Meet signature requirements for each operation in the transaction - Appropriate network passphrase is part of the transaction hash signed by each signer - Combined weight of the signatures for the source account of the transaction meets the low threshold for the source account. -#### Memo (if applicable) +#### Memo (if applicable) {#memo-if-applicable} The memo type must be a valid type, and the memo itself must adhere to the formatting of the memo type. diff --git a/docs/learn/fundamentals/transactions/transaction-lifecycle.mdx b/docs/learn/fundamentals/transactions/transaction-lifecycle.mdx index 43a006886..c57866d06 100644 --- a/docs/learn/fundamentals/transactions/transaction-lifecycle.mdx +++ b/docs/learn/fundamentals/transactions/transaction-lifecycle.mdx @@ -9,31 +9,31 @@ This is the transaction lifecycle for a classic Stellar transaction. Adding smar ::: -### 1. Creation (Transaction Creator) +### 1. Creation (Transaction Creator) {#1-creation-transaction-creator} A user creates a transaction by setting the source account, sequence number, list of operations and their respective parameters, fee or fee-bump, and optionally a memo and/or preconditions. -### 2. Signing (Transaction Signers) +### 2. Signing (Transaction Signers) {#2-signing-transaction-signers} Once the transaction is complete, it becomes a transaction envelope containing the transaction itself and a list of signers. All the required signatures must be collected and added to the transaction envelope’s list of signers. Commonly, it’s just the signature of the account doing the transaction, but more complicated setups can require collecting signatures from multiple parties. -### 3. Submitting (Transaction Submitter) +### 3. Submitting (Transaction Submitter) {#3-submitting-transaction-submitter} After signing, the transaction can now be submitted to the Stellar network. If the transaction is invalid, it will be rejected immediately by Stellar Core, the account’s sequence number will not be incremented, and no fee will be consumed from the source account. Multiple transactions for the same account can be submitted, provided each sequence number is off by one (unless minimum sequence number preconditions are set). If they are all valid, Stellar Core will craft a transaction set with each of those transactions applied in sequence number order. Transactions are typically submitted using Horizon, but you can also submit the transaction directly to an instance of Stellar Core. -### 4. Propagating (Validator) +### 4. Propagating (Validator) {#4-propagating-validator} Once Stellar Core has determined that a transaction is valid, it will propagate the transaction to all other servers to which it’s connected. This way, a valid transaction is flooded to the entire Stellar network. -### 5. Crafting a candidate transaction set (Validator) +### 5. Crafting a candidate transaction set (Validator) {#5-crafting-a-candidate-transaction-set-validator} When it’s time to close the ledger, each Stellar Core validator takes all valid transactions it is aware of since the last ledger close and collects them into a candidate transaction set. If it hears about any incoming transactions now, it puts them aside for the next ledger close. If the number of operations in the candidate transaction set is greater than the maximum number of operations per ledger, transactions will be prioritized by their fee for inclusion in the set. -### 6. Nominating a transaction set (Validator) +### 6. Nominating a transaction set (Validator) {#6-nominating-a-transaction-set-validator} Once each validator has crafted a candidate transaction set, the set is nominated to the network. -### 7. Stellar Consensus Protocol (SCP) determines the final transaction set (Validator Network) +### 7. Stellar Consensus Protocol (SCP) determines the final transaction set (Validator Network) {#7-stellar-consensus-protocol-scp-determines-the-final-transaction-set-validator-network} SCP resolves any differences between candidate transaction sets and ultimately determines a single transaction set to apply, the close time of the ledger, and any upgrades to the protocol that need to be applied network-wide at the apply time. @@ -41,18 +41,18 @@ If a transaction doesn’t make it into the transaction set, it is kept around i If a transaction is kept in memory after a certain number of ledger closes, it will be banned for several additional ledgers. This means no attempt will be made to include it in a candidate transaction set additional ledgers during this time. -### 8. Transaction apply order is determined (Validator Network) +### 8. Transaction apply order is determined (Validator Network) {#8-transaction-apply-order-is-determined-validator-network} Once SCP agrees on a particular transaction set, the apply order is computed for the transaction set. This shuffles the set's order to create uncertainty for competing transactions and maintains the order of sequence numbers for multiple transactions per account. -### 9. Fees are collected (Validator) +### 9. Fees are collected (Validator) {#9-fees-are-collected-validator} Fees are collected for all transactions simultaneously. -### 10. Application (Validator) +### 10. Application (Validator) {#10-application-validator} Each transaction is applied in the previously-determined order. For each transaction, the account’s sequence number is consumed (increased by 1), the transaction’s validity is rechecked, and each operation is applied in the order they occur in the transaction. Operations may fail at this stage due to errors that can occur outside of the transaction and operation validity checks. For example, an insufficient balance for a payment is not checked at submission and would fail at this time. The entire transaction will fail if any operation fails, and all previous operations will be rolled back. -### 11. Protocol Upgrades (Validator) +### 11. Protocol Upgrades (Validator) {#11-protocol-upgrades-validator} Finally, upgrades are run if an upgrade took place. This can include arbitrary logic to upgrade the ledger state for protocol upgrades, along with ledger header modifications, including the protocol version, base fee, maximum number of operations per ledger, etc. Once this has been completed, the life cycle begins anew. diff --git a/docs/learn/glossary.mdx b/docs/learn/glossary.mdx index b48cd736f..7a8d3bff9 100644 --- a/docs/learn/glossary.mdx +++ b/docs/learn/glossary.mdx @@ -3,41 +3,41 @@ title: "Glossary" sidebar_position: 40 --- -### Account +### Account {#account} A central Stellar data structure to hold balances, sign transactions, and issue assets. See the [Accounts section](./fundamentals/stellar-data-structures/accounts.mdx) to learn more. -### Account ID +### Account ID {#account-id} The public key used to create an account. This key persists across different key assignments. It is [represented](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0023.md) in base32. -### Anchor +### Anchor {#anchor} The on and off-ramps on the Stellar network that facilitate one-to-one conversion of off-chain representations to and from tokenized assets, for example, digital tokens representing bank deposits. Read more in the [Anchor Encyclopedia entry](./fundamentals/anchors.mdx) -### Application (app) +### Application (app) {#application-app} A software program designed for users to carry out a specific task (other than operating the computer itself). -### Asset +### Asset {#asset} Fiat, physical, or other tokens of value that are tracked, held, or transferred by the Stellar distributed network. See the [Assets section](./fundamentals/stellar-data-structures/assets.mdx) to learn more. -### Balance +### Balance {#balance} The amount of a given asset an account holds. Each asset has its own balance and these balances are stored in trustlines for every asset except XLM, which is held directly by the account. -### BalanceID +### BalanceID {#balanceid} Parameter required when claiming a newly created entry via the Claim claimable balance operation. See [ClaimableBalanceID](#claimablebalanceid). -### Base fee +### Base fee {#base-fee} The fee you’re willing to pay per operation in a transaction. @@ -45,263 +45,263 @@ This differs from the Effective Base Fee which is the actual fee paid per operat Learn more in our [Fees section](./fundamentals/fees-resource-limits-metering.mdx). -### Base reserve +### Base reserve {#base-reserve} A unit of measurement used to calculate an account’s minimum balance. One base reserve is currently 0.5 XLM. Learn more in our [Lumens section](./fundamentals/lumens.mdx#base-reserves). -### Burn +### Burn {#burn} Remove an asset from circulation, which can happen in two ways: 1) a holder sends the asset back to the issuing account 2) an issuer claws back a clawback-enabled asset from a holder's account. -### Claim Predicate +### Claim Predicate {#claim-predicate} A recursive data structure used to construct complex conditionals with different values of ClaimPredicateType. -### ClaimableBalanceID +### ClaimableBalanceID {#claimablebalanceid} A SHA-256 hash of the OperationID for claimable balances. -### Claimant +### Claimant {#claimant} An object that holds both the destination account that can claim the ClaimableBalanceEntry and a ClaimPredicate that must evaluate to true for the claim to succeed. -### Clawback +### Clawback {#clawback} An amount of asset from a trustline or claimable balance removed (clawed back) from a recipient’s balance sheet. See the [Clawback](./encyclopedia/transactions-specialized/clawbacks.mdx) Encyclopedia Entry for more information. -### Core Advancement Proposals (CAPs) +### Core Advancement Proposals (CAPs) {#core-advancement-proposals-caps} Proposals of standards to improve the Stellar protocol- CAPs deal with changes to the core protocol of the Stellar network. -### Create account operation +### Create account operation {#create-account-operation} Makes a payment to a 0-balance public key (Stellar address), thereby creating the account. You must use this operation to initialize an account rather than a standard payment operation. -### Cross-asset payments +### Cross-asset payments {#cross-asset-payments} A payment that automatically handles the conversion of dissimilar assets. -### Decentralized exchange +### Decentralized exchange {#decentralized-exchange} A distributed exchange that allows the trading and conversion of assets on the network. Learn more in our [Liquidity on Stellar](./encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx#sdex) Encyclopedia Entry. -### External Data Representation (XDR) +### External Data Representation (XDR) {#external-data-representation-xdr} The type of encoding used operations and data running on stellar-core. -### Flags +### Flags {#flags} Flags control access to an asset on the account level. Learn more about flags in our [Controlling Access to an Asset section](../tokens/control-asset-access.mdx#controlling-access-to-an-asset-with-flags). -### Fuzzing +### Fuzzing {#fuzzing} An automated test that rapidly stuffs massive amounts of randomized, malformed data into a system to reveal adverse or unexpected results that indicate vulnerabilities. Read more in the [Fuzz Testing Tutorial](../build/smart-contracts/example-contracts/fuzzing.mdx). -### GitHub +### GitHub {#github} An online repository for documents that can be accessed and shared among multiple users; host for the Stellar platform’s source code, documentation, and other open-source repos. -### Home domain +### Home domain {#home-domain} A fully qualified domain name (FQDN) linked to a Stellar account, used to generate an on-chain link to a Stellar Info File, which holds off-chain metadata. See the Set Options operation. Can be up to 32 characters. -### Horizon +### Horizon {#horizon} The Stellar API, provides an HTTP interface to data in the Stellar network. -### JSON +### JSON {#json} A standardized human-readable and machine-readable format for the exchange of structured data. -### Keypair +### Keypair {#keypair} A combined public and private key used to secure transactions. You can use any Stellar wallet, SDK, or the Stellar Lab to generate a valid keypair. -### Keystore +### Keystore {#keystore} An encrypted store or file that serves as a repository of private keys, certificates, and public keys. -### Ledger +### Ledger {#ledger} A representation of the state of the Stellar universe at a given point in time, shared across all network nodes. Learn more in the [Ledgers section](./fundamentals/stellar-data-structures/ledgers.mdx). -### LedgerKey +### LedgerKey {#ledgerkey} LedgerKey holds information to identify a specific ledgerEntry. It is a union that can be any one of the LedgerEntryTypes (ACCOUNT, TRUSTLINE, OFFER, DATA, or CLAIMABLE_BALANCE). -### Liability +### Liability {#liability} A buying or selling obligation, required to satisfy (selling) or accommodate (buying) transactions. -### Lumen (XLM) +### Lumen (XLM) {#lumen-xlm} The native, built-in token on the Stellar network. Learn more about lumens in our [Lumens section](./fundamentals/lumens.mdx). -### Master key +### Master key {#master-key} The private key used in initial account creation. -### Minimum balance +### Minimum balance {#minimum-balance} The smallest permissible balance in lumens for a Stellar account, currently 1 lumen. Learn more in our [Lumens section](./fundamentals/lumens.mdx#minimum-balance). -### Network capacity +### Network capacity {#network-capacity} The maximum number of operations per ledger, as determined by validator vote. Currently 1,000 operations for the mainnet and 100 operations for the testnet. -### Number of subentries +### Number of subentries {#number-of-subentries} The number of entries owned by an account, used to calculate the account’s minimum balance. -### Operation +### Operation {#operation} An individual command that modifies the ledger. Learn more in our [Operations and Transactions](./fundamentals/transactions/operations-and-transactions.mdx) section. -### OperationID +### OperationID {#operationid} Contains the transaction source account, sequence number, and the operation index of the CreateClaimableBalance operation in a transaction. -### Order +### Order {#order} An offer to buy or sell an asset. Learn more in our [Liquidity on Stellar: SDEX and Liquidity Pools Encyclopedia Entry](./encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx#orders). -### Orderbook +### Orderbook {#orderbook} A record of outstanding orders on the Stellar network. Learn more in our [Liquidity on Stellar: SDEX and Liquidity Pools Encyclopedia Entry](./encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx#order-books). -### Passive order +### Passive order {#passive-order} An order that does not execute against a marketable counter order with the same price; filled only if the prices are not equal. -### Passphrase +### Passphrase {#passphrase} The Mainnet and Testnet each have their own unique passphrase, which are used to validate signatures on a given transaction. Learn more about network passphrases in the [Network Passphrases Encyclopedia Entry](./encyclopedia/network-configuration/network-passphrases.mdx). -### Pathfinding +### Pathfinding {#pathfinding} The process of determining the best path of a payment, evaluating the current orderbooks, and finding the series of conversions to achieve the best rate. -### Payment channel +### Payment channel {#payment-channel} Allows two parties who frequently transact with one another to move the bulk of their activity off-chain, while still recording opening balances and final settlement on-chain. -### Precondition +### Precondition {#precondition} Optional requirements you can add to control a transaction’s validity. See the [Operation and Transaction Validity section](./fundamentals/transactions/operations-and-transactions.mdx#preconditions) for more information. -### Price +### Price {#price} The ratio of the quote asset and the base asset in an order. -### Public key +### Public key {#public-key} The public part of a keypair that identifies a Stellar account. The public key is public- it is visible on the ledger, anyone can look it up, and it is used when sending payments to the account, identifying the issuer of an asset, and verifying that a transaction is authorized. -### Mainnet or Pubnet +### Mainnet or Pubnet {#mainnet-or-pubnet} The Stellar Public Network, aka mainnet, the main network used by applications in production. Read more in our [Networks section](./fundamentals/networks.mdx). -### Rate-limiting +### Rate-limiting {#rate-limiting} Horizon rate limits on a per-IP-address basis. By default, a client is limited to 3,600 requests per hour, or one request per second on average. -### Sequence number +### Sequence number {#sequence-number} Used to identify and verify the order of transactions with the source account. A transaction’s sequence number must always increase by one (unless minimum sequence number preconditions are set, or a bump sequence operation is used). SDKs and the Stellar Lab automatically increment the account’s sequence number by one when you build a transaction. -### Secret (private) key +### Secret (private) key {#secret-private-key} The private key is part of a keypair, which is associated with an account. Do not share your secret key with anyone. -### SEPs (Stellar Ecosystem Proposals) +### SEPs (Stellar Ecosystem Proposals) {#seps-stellar-ecosystem-proposals} Standards and protocols to allow the Stellar ecosystem to interoperate. Learn more in our [SEPs section](./fundamentals/stellar-ecosystem-proposals.mdx). -### Signer +### Signer {#signer} Refers to the master key or to any other signing keys added later. A signer is defined as the pair: public key + weight. Signers can be set with the Set Options operation. See our [Signature and Multisignature Encyclopedia Entry](./encyclopedia/security/signatures-multisig.mdx) for more information. -### Smart contract +### Smart contract {#smart-contract} Self-executing contracts with the terms of the agreement directly written into code, automatically enforceable without the need for intermediaries. -### Soroban +### Soroban {#soroban} The smart contract platform on the Stellar network. The name "Soroban" comes from the Japanese abacus, which is a traditional counting tool used for mathematical calculations. The Soroban abacus is a lightweight instrument known for its efficiency and accuracy in performing arithmetic operations. -### Source account +### Source account {#source-account} The account that originates a transaction. This account also provides the fee and sequence number for the transaction. -### Starlight +### Starlight {#starlight} Stellar’s layer 2 protocol that allows for bi-directional payment channels. -### Stellar +### Stellar {#stellar} A decentralized, federated peer-to-peer network that allows people to send payments in any asset anywhere in the world instantaneously, and with minimal fees. -### Stellar Consensus Protocol (SCP) +### Stellar Consensus Protocol (SCP) {#stellar-consensus-protocol-scp} Provides a way to reach consensus without relying on a closed system to accurately record financial transactions. See our [SCP section](./fundamentals/stellar-consensus-protocol.mdx) to learn more. -### Stellar Core +### Stellar Core {#stellar-core} A replicated state machine that maintains a local copy of a cryptographic ledger and processes transactions against it, in consensus with a set of peers; also, the reference implementation for the peer-to-peer agent that manages the Stellar network. -### Stellar Development Foundation (SDF) +### Stellar Development Foundation (SDF) {#stellar-development-foundation-sdf} A non-profit organization founded to support the development and growth of the Stellar network. -### Stellar.toml +### Stellar.toml {#stellartoml} A formatted configuration file containing published information about a node and an organization. For more, see the Stellar Info File spec (SEP-0001`) -### Stroop +### Stroop {#stroop} As cents are to dollars, stroops are to assets: the smallest unit of an asset, one ten-millionth. -### Testnet +### Testnet {#testnet} The Stellar Test Network is maintained by the Stellar Development Foundation, which developers can use to test applications. Testnet is free to use and provides the same functionality as the main (public) network. Read more in our [Networks](./fundamentals/networks.mdx). -### Threshold +### Threshold {#threshold} The level of access for an operation. @@ -311,56 +311,56 @@ Read more about operation thresholds in the [Operations and Transactions section Learn more about quorum set validators in our [Stellar Consensus Protocol section](./fundamentals/stellar-consensus-protocol.mdx). -### Time bounds +### Time bounds {#time-bounds} An optional feature you can apply to a transaction to enforce a time limit on the transaction; either the transaction makes it to the ledger or times out (fails) depending on your time parameters. Read more about time bounds in our [Operation and Transaction Validity section](./fundamentals/transactions/operations-and-transactions.mdx#transaction-and-operation-validity). -### Transaction +### Transaction {#transaction} A group of 1 to 100 operations that modify the ledger state. Read more in the [Operations and Transactions section](./fundamentals/transactions/operations-and-transactions.mdx#transactions). -### Transaction envelope +### Transaction envelope {#transaction-envelope} A wrapper for a transaction that carries signatures. -### Transaction fee +### Transaction fee {#transaction-fee} Stellar requires a small fee for all transactions to prevent ledger spam and prioritize transactions during surge pricing. Learn more in our [Lumens section](./fundamentals/lumens.mdx#transaction-fees). -### Trustline +### Trustline {#trustline} An explicit opt-in for an account to hold a particular asset that tracks liabilities, the balance of the asset, and can also limit the amount of an asset that an account can hold. Learn more in our [Accounts section](./fundamentals/stellar-data-structures/accounts.mdx#trustlines). -### TTL (Time To Live) +### TTL (Time To Live) {#ttl-time-to-live} A smart contract's TTL is how many ledgers remain until the data entry is no longer live. Read more in the [State Archival section](./encyclopedia/storage/state-archival.mdx#ttl). -### Type +### Type {#type} The classification of data that dictates the kind of data that can be stored and how it can be manipulated within a smart contract. -### UNIX timestamp +### UNIX timestamp {#unix-timestamp} An integer representing a given date and time, as used on UNIX and Linux computers. -### Validator +### Validator {#validator} A basic validator keeps track of the ledger and submits transactions for possible inclusion. It ensures reliable access to the network and sign-off on transactions. A full validator performs the functions of a basic validator, but also publishes a history archive containing snapshots of the ledger, including all network transactions and their results. -### XLM (lumens) +### XLM (lumens) {#xlm-lumens} The native currency of the Stellar network. -### Wallet +### Wallet {#wallet} An interface that gives a user access to an account stored on the ledger; that access is controlled by the account’s secret key. The wallet allows users to store and manage their assets. diff --git a/docs/learn/interactive/dapps/introduction.mdx b/docs/learn/interactive/dapps/introduction.mdx index 909480c90..1a47ede80 100644 --- a/docs/learn/interactive/dapps/introduction.mdx +++ b/docs/learn/interactive/dapps/introduction.mdx @@ -18,17 +18,17 @@ While the course specifically focuses on the Soroban platform, the knowledge you Through The Soroban Dapps Challenge, you'll have hands-on experience using Soroban's initial versions of the smart contracts environment, a Rust SDK, a CLI, and an RPC server. You'll learn how to write, test, and deploy smart contracts, and you'll get to see your code in action on Futurenet. -## What This Course Entails +## What This Course Entails {#what-this-course-entails} We've designed this course as a learning adventure. It's a way for developers from the Stellar ecosystem and other blockchain communities to experiment, provide feedback, and contribute to the Soroban development process. As you progress through The Soroban Dapps Challenge, anticipate your code to break and updates to shift things. We invite you to experiment and build but also remind you that changes are afoot as we prepare for the production release. -## Getting Started +## Getting Started {#getting-started} To get started, simply head over to the [Dashboard](/docs/learn/interactive/dapps/dashboard), [connect your wallet](../../../build/guides/freighter/connect-testnet.mdx), and see what challenges await you! -## Giving Your Feedback +## Giving Your Feedback {#giving-your-feedback} We value your input. Feel free to file issues in the Soroban repos or raise them in the soroban channel in the Stellar Developer [Discord](https://discord.gg/3qrBhbwE). diff --git a/docs/learn/interactive/dapps/scaffold-soroban.mdx b/docs/learn/interactive/dapps/scaffold-soroban.mdx index 0304ede10..e8d5cdda7 100644 --- a/docs/learn/interactive/dapps/scaffold-soroban.mdx +++ b/docs/learn/interactive/dapps/scaffold-soroban.mdx @@ -10,23 +10,23 @@ The Dapps Challenge is undergoing updates. Thank you for your patience as we wor ::: -## Demonstrative Soroban Dapps +## Demonstrative Soroban Dapps {#demonstrative-soroban-dapps} import ReactPlayer from "react-player"; The **Soroban** team has invested considerable effort into contract implementation. They’ve built CLI’s and libraries, enabling contract builders to create and invoke using Rust, which forms the “backend” of Soroban. However, the “frontend”, which involves JS client libraries, required attention. -## Background +## Background {#background} During the Soroban Hackathon, we recognized that while the frontend libraries were functional, their user experience was far from ideal. Furthermore, the lack of clear examples made it harder for dapp creators to design and understand Soroban's UX. To tackle this, the **Wallet Engineering** team, in collaboration with the Soroban team, has decided to launch “Scaffold Soroban”, a collection of demo dapps. These dapps demonstrate basic functionalities in a structured, easy-to-follow manner, primarily focusing on how to construct/deploy Soroban contract invocations. -## Dapp Demos +## Dapp Demos {#dapp-demos} For easy accessibility, we have compiled the dapps into a [single repository](https://github.com/stellar/scaffold-soroban), which contains the following dapps: -### [1. Payment Dapp](https://github.com/stellar/soroban-react-payment) +### [1. Payment Dapp](https://github.com/stellar/soroban-react-payment) {#1-payment-dapp} This dapp mirrors the Soroban payment flow in Freighter by using the wallet’s Soroban token balances to invoke the `xfer` method on the token’s contract. @@ -37,7 +37,7 @@ See the [demo](https://github.com/stellar/soroban-react-payment/releases/tag/v1. url="https://user-images.githubusercontent.com/6789586/244450707-2ca53a9c-7493-47a1-aee6-cb126d6e32f8.mp4" /> -### [2. Mint Token Dapp](https://github.com/stellar/soroban-react-mint-token) +### [2. Mint Token Dapp](https://github.com/stellar/soroban-react-mint-token) {#2-mint-token-dapp} This dapp allows a token admin to mint tokens by using the admin account to invoke the `mint` method on the token’s contract. @@ -48,7 +48,7 @@ See the [demo](https://github.com/stellar/soroban-react-mint-token/releases/tag/ url="https://user-images.githubusercontent.com/6886006/246495488-1b02da2c-5119-47c6-ab38-fbaa73a26f12.mov" /> -### [3. Atomic Swap Dapp](https://github.com/stellar/soroban-react-atomic-swap) +### [3. Atomic Swap Dapp](https://github.com/stellar/soroban-react-atomic-swap) {#3-atomic-swap-dapp} This dapp demonstrates a simplified swap between two tokens by using the wallet’s Soroban token balances to invoke the `swap` method on the atomic swap contract. @@ -59,7 +59,7 @@ See the [demo](https://github.com/stellar/soroban-react-atomic-swap/releases/tag url="https://user-images.githubusercontent.com/6886006/258894451-19f4363b-e6e3-4d32-973a-6d99fd0d9847.mov" /> -## How To Explore the Dapps on Scaffold-Soroban +## How To Explore the Dapps on Scaffold-Soroban {#how-to-explore-the-dapps-on-scaffold-soroban} To begin using these examples, navigate to [Scaffold-Soroban](https://scaffold-soroban.stellar.org/) and choose the name of the dapp you're interested in from the "select demo" dropdown: @@ -69,7 +69,7 @@ To begin using these examples, navigate to [Scaffold-Soroban](https://scaffold-s Dive in and discover the power of Soroban! -## Functionality Behind the Dapps +## Functionality Behind the Dapps {#functionality-behind-the-dapps} With the introduction of these dapps, let's delve deeper into some of their [standout features](https://github.com/stellar/soroban-react-atomic-swap/blob/main/src/helpers/soroban.ts) that showcase the power and innovation behind the dapps: @@ -81,7 +81,7 @@ Other utilities such as `accountToScVal` and `numberToI128` are also provided to The code referenced showcases various functionalities including sending transactions, retrieving token information, simulating transactions, building swaps, and authorizing contract calls, all of which are ready to be cloned, customized, and expanded upon to suit your unique needs and ideas. -## Conclusion +## Conclusion {#conclusion} We hope these dapps will help you understand the Soroban ecosystem better and inspire you to build your own dapps using tools like [stellar-sdk](https://www.npmjs.com/package/@stellar/stellar-sdk) and [freighter-api](https://www.npmjs.com/package/@stellar/freighter-api). We look forward to seeing what you create! diff --git a/docs/learn/migrate/evm/introduction-to-solidity-and-rust.mdx b/docs/learn/migrate/evm/introduction-to-solidity-and-rust.mdx index 02b108c0c..83a44e5f6 100644 --- a/docs/learn/migrate/evm/introduction-to-solidity-and-rust.mdx +++ b/docs/learn/migrate/evm/introduction-to-solidity-and-rust.mdx @@ -8,21 +8,21 @@ description: Explore the fundamentals of Solidity, Rust, and Soroban. We are excited to introduce you to Soroban, a powerful smart contracts platform designed to be sensible, built-to-scale, and developer-friendly, with a focus on Rust's performance and safety benefits. With its user-friendly interface and powerful features, Soroban offers an ideal platform for developers who are seeking a more efficient and effective way to build decentralized applications and transition from Solidity to Rust. In this article, we will explore the fundamentals of Solidity, Rust, and Soroban, and guide you through setting up the development environment to start your journey with Soroban's Rust smart contract compatibility. -## Solidity and Dapp Development +## Solidity and Dapp Development {#solidity-and-dapp-development} Solidity is a high-level, statically-typed programming language primarily used for developing smart contracts on the Ethereum Virtual Machine (EVM). It enables the creation of decentralized applications (dapps) that can run on various blockchain platforms, automating complex transactions and interactions without the need for a central authority. -## Rust: Performance and Safety +## Rust: Performance and Safety {#rust-performance-and-safety} Rust is a systems programming language that emphasizes safety, concurrency, and performance. Its unique features, such as a strong static type system, ownership model, and memory safety guarantees, make it an ideal choice for developing high-performance, secure applications, including smart contracts. -## Soroban: Programmable Logic +## Soroban: Programmable Logic {#soroban-programmable-logic} Soroban, a sensible and built-to-scale smart contracts platform, offers a developer-friendly and batteries-included experience. While it shares the same principles of scalability and practicality as Stellar, Soroban can also function as a standalone platform and integrate with other transaction processors, such as L2s, permissioned ledgers, and even other blockchains. With Soroban, Classic Stellar gains the added functionality of programmable logic in the form of custom operations encapsulated within smart contracts. You can learn more about Soroban's features and benefits in the [Soroban Overview](../../../build/smart-contracts). -## Setting Up the Development Environment for Rust and Soroban +## Setting Up the Development Environment for Rust and Soroban {#setting-up-the-development-environment-for-rust-and-soroban} To get started with Rust and Soroban, follow the steps on the [Setup Page](../../../build/smart-contracts/getting-started/setup.mdx). diff --git a/docs/learn/migrate/evm/smart-contract-deployment.mdx b/docs/learn/migrate/evm/smart-contract-deployment.mdx index 6d6fcee13..072244fda 100644 --- a/docs/learn/migrate/evm/smart-contract-deployment.mdx +++ b/docs/learn/migrate/evm/smart-contract-deployment.mdx @@ -11,42 +11,42 @@ import TabItem from "@theme/TabItem"; In this tutorial, we will discover the similarities in smart contract deployment by examining workflows with Soroban and [Hardhat](https://hardhat.org/). We will dive into the intricacies of each framework, learn to write secure and efficient smart contract code, and harness the power of Rust and Soroban to create customized contract logic. -## Table of Contents +## Table of Contents {#table-of-contents} 1. [Soroban and Hardhat Comparison](#soroban-and-hardhat-comparison) 2. [Hardhat vs Soroban SDKs](#hardhat-vs-soroban-sdks) 3. [Using Rust and Soroban for Smart Contract Development](#developing-smart-contracts-with-rust-and-soroban) 4. [Vault Contract Deployment and Interaction](#vault-contract-deployment-and-interaction) -## Soroban and Hardhat Comparison +## Soroban and Hardhat Comparison {#soroban-and-hardhat-comparison} -### Introduction +### Introduction {#introduction} Soroban and Hardhat are both frameworks that enable developers to build, test, and deploy smart contracts. In this section, we will delve into the similarities and distinctions between these two frameworks. -### Soroban Framework +### Soroban Framework {#soroban-framework} Soroban is a Rust-based framework tailored for developing smart contracts on the Stellar network. Designed as a lightweight framework, with [tools to support developers](../../../tools/developer-tools/README.mdx), Soroban allows developers to develop smart contracts through a simple and intuitive workflow. -### Hardhat +### Hardhat {#hardhat} Hardhat serves as a development environment for compiling, deploying, testing, and debugging smart contracts for the EVM. It assists developers in managing and automating recurring tasks inherent to building smart contracts. -### Similarities +### Similarities {#similarities} Soroban and Hardhat are powerful frameworks designed to streamline the process of building, testing, and deploying smart contracts. Equipped with a comprehensive suite of tools, these frameworks facilitate the development of smart contracts and their deployment on their respective virtual machines. -### Differences +### Differences {#differences} Soroban, with its lightweight design, offers developers an exceptional platform for writing Rust-based smart contracts and deploying them effortlessly on the Stellar network. In contrast, Hardhat serves primarily as a development environment tailored for the Ethereum Virtual Machine, providing a different focus and target audience. -## Hardhat vs. Soroban SDKs +## Hardhat vs. Soroban SDKs {#hardhat-vs-soroban-sdks} Hardhat offers a streamlined workflow for deploying smart contracts on the Ethereum Virtual Machine, with key components such as `ethers.js`, `scripts`, and `testing` playing crucial roles. On the other hand, Soroban presents a compelling alternative, boasting powerful SDKs that facilitate smart contract development and deployment. In the upcoming section, we will delve into [Soroban's SDKs](../../../tools/sdks/library.mdx), drawing comparisons with Hardhat components, and highlighting the unique advantages each platform brings to the table. -### Ethers.js +### Ethers.js {#ethersjs} `Ethers.js` is a widely-used `JavaScript` library designed for seamless interaction with the EVM. It offers a user-friendly interface that simplifies connecting to Ethereum nodes, managing accounts, and sending transactions. Additionally, `Ethers.js` provides a robust API for efficient communication with smart contracts. This library is a core component of the Hardhat framework and can be imported into scripts to streamline the deployment of smart contracts. @@ -60,11 +60,11 @@ async function main() { } ``` -### Soroban Client +### Soroban Client {#soroban-client} Soroban offers a comparable library, [`stellar-sdk`](../../../tools/sdks/library.mdx#javascript-sdk), that enables seamless interaction smart contracts deployed on the Stellar Network. This library supplies a comprehensive networking layer API for Stellar RPC methods as well as the traditional Horizon API, simplifying the process of building and signing transactions. Additionally, `stellar-sdk` streamlines communication with RPC instances and supports submitting transactions or querying network state with ease. -### Scripts +### Scripts {#scripts} Hardhat scripts streamline the automation of routine tasks, such as deploying and managing smart contracts. Developers can create these scripts using either JavaScript or TypeScript, catering to their preferred programming style. They are stored in the `scripts` directory of a Hardhat project and can be executed using the `npx hardhat run` command. @@ -87,7 +87,7 @@ main() }); ``` -### Soroban Scripts +### Soroban Scripts {#soroban-scripts} Soroban offers an extensive collection of SDKs that include scripting capabilities, ensuring a smooth workflow for deploying and managing smart contracts. Developers can automate tasks such as compiling, deploying, and interacting with smart contracts using a variety of SDKs that support scripting in languages like [`JavaScript`, `TypeScript`, `Python`, and others](../../../tools/sdks/library.mdx). @@ -129,7 +129,7 @@ tx = ( ... ``` -### Testing +### Testing {#testing} Hardhat provides a testing framework that allows developers to write tests for their smart contracts. These tests can be written in JavaScript or TypeScript and run using the `npx hardhat test` command. @@ -149,7 +149,7 @@ describe("MyContract", function () { }); ``` -### Soroban Testing +### Soroban Testing {#soroban-testing} Soroban enables users to leverage the power of Rust's testing framework to write tests for their smart contracts. These tests can be written in Rust and run using the `cargo test` command. @@ -175,15 +175,15 @@ fn test() { In summary, while Hardhat provides an excellent environment for deploying smart contracts on the EVM, Soroban's Rust-based framework offers significant advantages in terms of performance, making it an ideal choice for building secure and efficient smart contracts. -## Developing Smart Contracts with Rust and Soroban +## Developing Smart Contracts with Rust and Soroban {#developing-smart-contracts-with-rust-and-soroban} -### Introduction +### Introduction {#introduction-1} Now that we've examined the deployment workflow with Hardhat, let's explore developing and deploying smart contracts with Rust and Soroban. The key advantage of using Soroban is its ability to leverage Rust's safety features and performance, making it an excellent choice for developing secure and efficient smart contracts. We've learned that Smart contracts are self-executing contracts that can be programmed to automatically enforce the rules and regulations of a particular agreement. They are a core component of decentralized applications (dApps) and blockchain technology. In this section, we will learn how to use Rust and Soroban to develop and deploy custom smart contract logic. -### Setup +### Setup {#setup} If you haven't already setup up the dev environment for Soroban, you can get started by following the steps on the [Setup Page](../../../build/smart-contracts/getting-started/setup.mdx). @@ -220,7 +220,7 @@ soroban-examples Once we have the Token, let's create a new smart contract that uses it. -### Writing a Smart Contract +### Writing a Smart Contract {#writing-a-smart-contract} Let's start by writing a simple example of a vault contract that allows users to deposit funds and withdraw their funds with generated yield. @@ -902,7 +902,7 @@ If the user were to call the `withdraw` method with 100 shares, the following wo - 100 shares would be burned. - 100 + (100/100) tokens would be transferred from the vault contract to the withdrawer. -### Testing +### Testing {#testing-1} To test the vault contract, we will can simply run the following command in our terminal from our vault contract directory: @@ -918,7 +918,7 @@ running 1 test test test::test ... ok ``` -### Vault Contract Deployment and Interaction +### Vault Contract Deployment and Interaction {#vault-contract-deployment-and-interaction} Now that we have a working vault contract, we can deploy it to a network and interact with it. diff --git a/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.mdx b/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.mdx index 480945ffd..aae0e23db 100644 --- a/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.mdx +++ b/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.mdx @@ -11,16 +11,16 @@ import TabItem from "@theme/TabItem"; In this tutorial, we will cover advanced Solidity and Rust concepts such as inheritance, interfaces, libraries, and modifiers. Additionally, we will learn how to write safe and efficient Rust code for smart contracts. Finally, we will learn how to convert common Solidity concepts to Rust. -## Table of Contents +## Table of Contents {#table-of-contents} 1. [Advanced Solidity Concepts](#advanced-solidity-concepts) 2. [Advanced Rust Concepts](#advanced-rust-concepts) 3. [Writing Safe and Efficient Rust Code for Smart Contracts](#writing-safe-and-efficient-rust-code-for-smart-contracts) 4. [Solidity to Soroban: Common Concepts and Best Practices](#solidity-to-soroban-common-concepts-and-best-practices) -## Advanced Solidity Concepts +## Advanced Solidity Concepts {#advanced-solidity-concepts} -### Inheritance +### Inheritance {#inheritance} In Solidity, smart contracts can inherit properties and functions from other contracts. This is achieved using the `is` keyword. @@ -42,7 +42,7 @@ contract Child is Parent { In this example, the `Child` contract inherits the `messageFromParent` function from the `Parent` contract. The `Child` contract can then call the `messageFromParent` function directly. -### Interfaces +### Interfaces {#interfaces} Interfaces are similar to contracts, but they cannot have any function implementations. They only contain function signatures. Contracts can implement interfaces using the `is` keyword, similar to inheritance. @@ -65,7 +65,7 @@ contract SomeContract is SomeInterface { In this example, the `SomeContract` contract implements the `SomeInterface` interface. Its implementation returns a `u256` that is incremented each time the `doSomething` function is called. -### Libraries +### Libraries {#libraries} Libraries are similar to contracts, but they cannot have any state variables. They are used to store reusable code that can be used by other contracts. Libraries are deployed once and can be used by multiple contracts. They are defined using the `library` keyword. They are invoked by using the `using` keyword. @@ -92,7 +92,7 @@ contract MyContract { In this example, the `SafeMath` library is used in the `increment` function. The `increment` function uses the `add` function from the `SafeMath` library to increment the `value` variable. -### Modifiers +### Modifiers {#modifiers} Modifiers are used to change the behavior of functions in a declarative way. They are defined using the `modifier` keyword. Modifiers can be used to perform common checks such as validating inputs, checking permissions, and more. @@ -119,9 +119,9 @@ contract MyContract is Ownable { In this example, the `onlyOwner` modifier is used to restrict access to the `doSomething` function. The `doSomething` function can only be called by the `owner` of the contract which was defined during deployment as `msg.sender`. -## Advanced Rust Concepts +## Advanced Rust Concepts {#advanced-rust-concepts} -### Crates +### Crates {#crates} A crate in Rust is a collection of precompiled programs, scripts, or routines that can be easily reused by programmers when writing code. This allows them to avoid reinventing the wheel by not having to implement the same logic or program multiple times. There are two types of crates in Rust: [Binary crates and Library crates](https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html). @@ -172,7 +172,7 @@ In this example, the `alloc` crate is imported into the smart contract using the For more details on how to use the `alloc` crate, including a hands-on practical exercise, visit the [alloc example contract](../../../build/smart-contracts/example-contracts/alloc.mdx#how-it-works). -#### Inheriting Functionality from Other Crates +#### Inheriting Functionality from Other Crates {#inheriting-functionality-from-other-crates} We can illustrate another example of inheritance by importing functionality into a crate from other crates in the same project in the following example: @@ -255,7 +255,7 @@ fn mint(e: Env, to: Address, amount: i128) { As you can see, the `event.rs`, `admin.rs`, and `balance.rs` files are imported into the `contract.rs` file using the `use` keyword. This allows us to use the functions from those files in the `mint` function of our `contract.rs` file. -#### Inheriting Functionality using `contractimport!` +#### Inheriting Functionality using `contractimport!` {#inheriting-functionality-using-contractimport} The Soroban Rust SDK provides a powerful macro, [`contractimport`](https://docs.rs/soroban-sdk/latest/soroban_sdk/macro.contractimport.html), which allows a user to import a contract from its Wasm file, generating a client, types, and constant holding the contract file. @@ -294,11 +294,11 @@ impl LiquidityPoolTrait for LiquidityPool { In the above example, we use `contractimport` to interact with the token file via a `Client` that was generated for the `token` module. This `Client` was created using a Contract trait that matches the interface of the contract, a ContractClient struct that contains functions for each function in the contract, and types for all contract types defined in the contract. -#### A Note on Inheritance and Composability +#### A Note on Inheritance and Composability {#a-note-on-inheritance-and-composability} While we've been using the term "inheritance" to help make the transition from Solidity smoother, let's clarify an important aspect of Rust: it does not support inheritance as we traditionally understand it. Instead, Rust practices "composability", meaning it uses functions from different crates, which are akin to packages, in a modular fashion. So, when we discuss `contractimport!`, we're actually observing composability in action, not "inheritance". Rust does not foster the "is a" relationship inherent in OOP languages. Instead, it enables us to reuse and assemble code effectively across different scopes. This is a technical truth that is important to understand; however, it's worth noting that this fact doesn't impact the practical usage of Soroban throughout this guide. -### Modules +### Modules {#modules} In Rust, modules consist of a cohesive set of related functions and types that are often organized together for better organization and reusability. These modules can be reused across multiple projects by publishing them as crates. @@ -345,7 +345,7 @@ Notice that we use the `checked_add` function from the standard library to ensur Even when Rust code is compiled with the `#![no_std]` flag, it is still possible to use some of the standard library's features, such as the `checked_add` function. This is because Rust provides the option to selectively import modules and functions from the standard library, allowing developers to use only the specific features they need. -### Traits +### Traits {#traits} Rust does not have a built-in modifier system like Solidity. However, you can achieve similar functionality using `traits` and their implementations. @@ -405,7 +405,7 @@ Here's a breakdown of the code above: It's worth mentioning that the Soroban Rust SDK comes with several built-in requirements that developers can use, such as the [`require_auth`](https://docs.rs/soroban-sdk/latest/soroban_sdk/struct.Address.html#method.require_auth) method provided by the `Address` struct. -### Interfaces +### Interfaces {#interfaces-1} Interfaces are an essential part of building smart contracts with Soroban. @@ -417,7 +417,7 @@ There are many types of smart contract interfaces, and each has a specific purpo For more information on smart contract interfaces built with Soroban, including the Token Interface, visit the [tokens section](../../../tokens/README.mdx) of the documentation. -## Writing Safe and Efficient Rust Code for Smart Contracts +## Writing Safe and Efficient Rust Code for Smart Contracts {#writing-safe-and-efficient-rust-code-for-smart-contracts} When writing Rust code for smart contracts, it's important to focus on safety and efficiency. Some tips include: @@ -494,7 +494,7 @@ fn main() { } ``` -## Solidity to Soroban: Common Concepts and Best Practices +## Solidity to Soroban: Common Concepts and Best Practices {#solidity-to-soroban-common-concepts-and-best-practices} In this section we will explore key Solidity concepts and provide their Soroban equivalents. We will discuss the following topics: @@ -504,11 +504,11 @@ In this section we will explore key Solidity concepts and provide their Soroban - Function visibility specifiers - Time-based variables -### Message Properties +### Message Properties {#message-properties} The Soroban Rust SDK and Solidity provide a number of message properties that can be used to access information about the current transaction. These properties include: -#### Solidity +#### Solidity {#solidity} - `msg.sender`: The address of the account that sent the transaction. - `msg.value`: The amount of Ether sent with the transaction. @@ -536,7 +536,7 @@ contract SimpleContract { These are a part of Solidity's global variables, which are accessible from any function in the contract. -#### Soroban +#### Soroban {#soroban} In contrast to Solidity's global variables, Soroban relies on passing an [`Env`](https://docs.rs/soroban-sdk/latest/soroban_sdk/struct.Env.html) argument to all functions which provides access to the environment the contract is executing within. @@ -583,11 +583,11 @@ use soroban_sdk::{Env, Address}; } ``` -### Error Handling +### Error Handling {#error-handling} The Soroban Rust SDK and Solidity provide a number of ways to handle errors. These include: -#### Solidity +#### Solidity {#solidity-1} Solidity provides a `require` function that can be used to check for certain conditions and revert the transaction if they are not met. For example, the following code sets a minimum value for the amount of Ether sent with the transaction: @@ -599,7 +599,7 @@ function deposit() public payable { } ``` -#### Soroban +#### Soroban {#soroban-1} The [panic!](https://doc.rust-lang.org/book/ch09-00-error-handling.html) macro serves as Rust's error-handling mechanism, which closely resembles the `require` function in Solidity. @@ -612,11 +612,11 @@ pub fn simple_deposit(amount: u32) { } ``` -### Address-Related Functionality +### Address-Related Functionality {#address-related-functionality} Both Soroban and Solidity provide provide a number of functions for working with addresses. These functions include: -#### Solidity +#### Solidity {#solidity-2} - `address(this)`: Returns the address of the current contract. - `address payable(this)`: Returns the address of the current contract as a payable address. @@ -639,7 +639,7 @@ contract SimpleContract { There would be no difference in appearance between a regular address and a payable address in Solidity. -#### Soroban +#### Soroban {#soroban-2} - `e.current_contract_address()`: Returns the Address object corresponding to the current executing contract. @@ -664,7 +664,7 @@ impl SimpleContract { } ``` -#### Why Soroban Differs +#### Why Soroban Differs {#why-soroban-differs} Soroban has some differences from Solidity in terms of addresses and other functionalities. These differences arise due to the design principles and goals of Soroban. @@ -674,11 +674,11 @@ To further explain, the `Env` type offers a gateway to the environment where the Meanwhile, the `Address` object serves as a potent tool for authentication and [authorization](#authorization). For instance, it can be used to authorize token transfers, acting as a security gatekeeper within the system. This feature amplifies the functionality of addresses in Soroban, making them not just a means of identification or storage, but also a key player in verifying and authorizing transactions. -### Function Visibility Specifiers +### Function Visibility Specifiers {#function-visibility-specifiers} The Soroban Rust SDK and Solidity provide a number of function visibility specifiers that can be used to control who can call a function. These specifiers include: -#### Solidity +#### Solidity {#solidity-3} - `public`: Anyone can call the function. - `external`: Only other contracts can call the function. @@ -698,7 +698,7 @@ contract SimpleContract { } ``` -#### Soroban +#### Soroban {#soroban-3} - `pub`: The item (function, struct, etc.) is accessible from any module or scope. - `pub(crate)`: The item is accessible only within the current crate. @@ -763,11 +763,11 @@ impl OuterTrait for NewContract { } ``` -### Time-Based Variables +### Time-Based Variables {#time-based-variables} The Soroban Rust SDK and Solidity provide a number of time-based variables that can be used to access information about the current block(EVM) or ledger(Soroban). These variables include: -#### Solidity +#### Solidity {#solidity-4} - `block.timestamp`: The timestamp of the current block. - `block.number`: The number of the current block. @@ -788,7 +788,7 @@ contract SimpleContract { } ``` -#### Soroban +#### Soroban {#soroban-4} - `env.ledger().timestamp()`: Returns a unix timestamp for when the most recent ledger was closed. - `env.ledger().sequence()`: Returns the sequence number of the most recently closed ledger. @@ -811,11 +811,11 @@ impl SimpleContract { } ``` -### Authorization +### Authorization {#authorization} Soroban differs from Solidity in its approach to authorization and modifiers. While Solidity has a built-in modifier system, Sorotban does not. Instead, Soroban leverages traits, their implementations, and core features to achieve similar functionality. -#### Solidity +#### Solidity {#solidity-5} In Solidity, the ERC20 token standard includes the `approve` function, which allows a token holder to authorize another address to spend a certain amount of tokens on their behalf. This function is commonly used in decentralized exchanges and other token transfer scenarios. Furthermore, we're ensuring that the spender is authorized to spend the amount of tokens requested by the token holder. @@ -862,7 +862,7 @@ The approve function allows the token holder to authorize spender to spend amoun These Solidity examples illustrate some common authorization patterns used in Ethereum smart contracts. Soroban provides alternative approaches to achieve similar functionality, leveraging core functionality derived right from the soroban SDK. -#### Soroban +#### Soroban {#soroban-5} Soroban's design principles prioritize flexibility, security, and testability, which have led to differences in how authorization is handled compared to Solidity. @@ -900,7 +900,7 @@ Soroban's approach to authorization in this example offers several advantages ov Soroban authorization provides Contract-level Authorization, Account Abstraction Functionality, and more advanced Authorization checks. To learn more about these advantages, visit the [Authorization section](../../encyclopedia/security/authorization.mdx) of the documentation. -## Summary +## Summary {#summary} Overall the Soroban equivalents of Solidity concepts are very similar. However, there are notable differences worth highlighting. Soroban uses `env` instead of `msg` to access information about the entire contract execution environment, including the state of the contract, addresses involved, and more. Authorization is also handled differently in Soroban, as it is built into the core functionality of the SDK and is more robust than relying on smart contract code alone. diff --git a/docs/learn/migrate/evm/solidity-and-rust-basics.mdx b/docs/learn/migrate/evm/solidity-and-rust-basics.mdx index c780469f0..0d535cd7e 100644 --- a/docs/learn/migrate/evm/solidity-and-rust-basics.mdx +++ b/docs/learn/migrate/evm/solidity-and-rust-basics.mdx @@ -8,13 +8,13 @@ description: Explore the fundamentals of Solidity and Rust Syntax, Data Types, a In this tutorial, we'll explore Rust and Solidity, two powerful programming languages. Rust, a systems programming language, is renowned for its safety, concurrency, and performance features, which can be advantageous when building smart contracts. On the other hand, Solidity is a high-level language specifically designed for creating smart contracts on the Ethereum Virtual Machine. This section aims to provide a high-level overview of the similarities and differences between the two languages. -## Table of Contents +## Table of Contents {#table-of-contents} 1. [Solidity Syntax, Data Types, and Basic Constructs](#solidity-syntax) 2. [Rust Syntax, Data Types, and Ownership Model](#rust-syntax) 3. [Writing and Interacting With Simple Smart Contracts](#writing-and-interacting-with-simple-smart-contracts) -### Solidity Syntax +### Solidity Syntax {#solidity-syntax} Solidity is a programming language designed specifically for creating smart contracts on the Ethereum Virtual Machine (EVM). It has a syntax similar to JavaScript and supports a variety of data types and constructs. @@ -28,7 +28,7 @@ contract HelloWorld { } ``` -### Data Types +### Data Types {#data-types} Solidity supports various data types, such as: @@ -97,7 +97,7 @@ contract DataTypesExample { } ``` -### Basic Constructs +### Basic Constructs {#basic-constructs} Some of the basic constructs in Solidity include: @@ -109,7 +109,7 @@ Some of the basic constructs in Solidity include: We will explore some of these constructs in more detail in the next article, [Advanced Solidity Concepts](./solidity-and-rust-advanced-concepts.mdx#advanced-solidity-concepts). -### Rust Syntax +### Rust Syntax {#rust-syntax} Rust is a programming language that is well-suited for building smart contracts due to its emphasis on safety, concurrency, and performance. It enforces strict ownership and borrowing rules to prevent data races and other common bugs. @@ -119,11 +119,11 @@ fn main() { } ``` -### Data Types +### Data Types {#data-types-1} The [Soroban Rust SDK](https://docs.rs/soroban-sdk/latest/soroban_sdk/index.html) supports a variety of [Built-In Types](../../encyclopedia/contract-development/types/built-in-types.mdx) which consist of both Primitive and [Custom Types](../../encyclopedia/contract-development/types/custom-types.mdx), such as: -#### Primitive Data Types +#### Primitive Data Types {#primitive-data-types} - 32-bit Integers: signed (`i32`) and unsigned (`u32`) - 64-bit Integers: signed (`i64`) and unsigned (`u64`) @@ -142,7 +142,7 @@ The [Soroban Rust SDK](https://docs.rs/soroban-sdk/latest/soroban_sdk/index.html Both are limited to the characters `a-zA-Z0-9_` and are encoded into 64-bit integers. -#### Custom Data Types +#### Custom Data Types {#custom-data-types} - `Structs` (with Named Fields): A custom type consisting of named fields stored on the ledger as a `map` of key-value pairs. - `Structs` (with Unnamed Fields): A custom type consisting of unnamed fields stored on the ledger as a vector of values. @@ -209,13 +209,13 @@ pub enum Enum { } ``` -### A Brief Introduction to Modules, Macros, Structs, Traits, and Attribute Macros +### A Brief Introduction to Modules, Macros, Structs, Traits, and Attribute Macros {#a-brief-introduction-to-modules-macros-structs-traits-and-attribute-macros} In this section, we will provide a concise introduction to some fundamental concepts in Rust: `Modules`, `Macros`, `Structs`, `Traits`, and `Attribute Macros`. These concepts are essential for understanding and writing efficient Rust code, and they will assist you on your journey as a smart contract developer. -#### 1. Modules +#### 1. Modules {#1-modules} Modules in Rust are used to organize and separate code into different namespaces. They enable better code organization, reusability, and encapsulation. To define a module, use the `mod` keyword followed by a block containing the module's contents. @@ -227,7 +227,7 @@ mod my_module { } ``` -#### 2. Macros +#### 2. Macros {#2-macros} [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html) in Rust are powerful tools that allow you to do metaprogramming, enabling you to build chunks of reusable code at compile time. @@ -245,7 +245,7 @@ fn main() { } ``` -#### 3. Structs +#### 3. Structs {#3-structs} Structs are custom data types in Rust that enable you to bundle data together. They provide a way to define and create more complex data structures. @@ -263,7 +263,7 @@ fn main() { } ``` -#### 4. Traits +#### 4. Traits {#4-traits} Traits in Rust define a shared set of behaviors that types can then either use as-is (default implementations) or implement themselves. They can be thought of as interfaces in other languages. Traits are defined with the `trait` keyword, and their methods can be implemented for different types using the `impl` keyword. @@ -281,7 +281,7 @@ impl MyTrait for MyStruct { } ``` -#### 5. Attribute Macros +#### 5. Attribute Macros {#5-attribute-macros} Attribute macros in Rust are a form of procedural macros that enable you to define custom attributes for various language elements such as functions, structs, and enums. They can modify or generate code based on the annotated items. @@ -309,7 +309,7 @@ impl HelloContract { } ``` -### Ownership Model +### Ownership Model {#ownership-model} Rust enforces [**strict ownership rules**](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html) to manage memory and resources: @@ -318,17 +318,17 @@ Rust enforces [**strict ownership rules**](https://doc.rust-lang.org/book/ch04-0 - [`Borrowing`](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html): Values can be borrowed as immutable or mutable references. - [`Lifetimes`](https://doc.rust-lang.org/rust-by-example/scope/lifetime.html): Used to ensure that references remain valid. -### Smart Contract Dialect +### Smart Contract Dialect {#smart-contract-dialect} Contract development in Rust involves certain restrictions due to either unavailable features in the deployment environment or high runtime costs. Thus, the code written for contracts can be seen as a distinct _dialect_ of Rust, focusing on deterministic behavior and minimized code size. To learn more about Rust's Contract Dialect, check out the [Contract Rust Dialect Page](../../encyclopedia/contract-development/rust-dialect.mdx). -## Writing and Interacting with Simple Smart Contracts +## Writing and Interacting with Simple Smart Contracts {#writing-and-interacting-with-simple-smart-contracts} In this section, we'll learn how to write and interact with simple smart contracts in Solidity and Rust. -### Writing a Smart Counter in Solidity +### Writing a Smart Counter in Solidity {#writing-a-smart-counter-in-solidity} Here's an example of a simple Solidity smart contract for a counter: @@ -391,7 +391,7 @@ function increment() public { This is a function called `increment()` that increments the counter by 1. It doesn't return anything, but it modifies the state of the contract. Like `getCount()`, it's marked as `public`, which means it can be called from both inside and outside the contract. -### Interacting with the Solidity Smart Counter +### Interacting with the Solidity Smart Counter {#interacting-with-the-solidity-smart-counter} We can interact with the smart contract using the `Remix IDE`. To do so, follow these steps: @@ -417,7 +417,7 @@ The contract should appear under the `Deployed Contracts` tab: Up to this point, we've covered the basics of writing, deploying to a sandbox EVM, and interacting with a simple smart contract using Solidity. In the following section, we will extend our knowledge by learning how to achieve the same outcomes using Rust. -### Writing a Smart Counter in Rust +### Writing a Smart Counter in Rust {#writing-a-smart-counter-in-rust} In this section, we'll create a Rust program that simulates the functionality of the Counter smart contract. Here's an example of a simple counter in Rust: @@ -543,7 +543,7 @@ This is a repeat of the code we saw earlier, which retrieves the value associate Now that we have written our smart contract, it's time to explore how we can interact with it using the [Stellar CLI](../../../tools/developer-tools/cli/stellar-cli.mdx), one of many robust [Developer Tools](../../../tools/developer-tools/README.mdx) available. This powerful command-line tool allows us to interact with the Soroban Virtual Machine from a local machine, providing us with an efficient and flexible way to manage our smart contract. -### Interacting with the Rust Smart Counter +### Interacting with the Rust Smart Counter {#interacting-with-the-rust-smart-counter} To interact with the Rust counter, create a new Rust library using the cargo new command. diff --git a/docs/networks/resource-limits-fees.mdx b/docs/networks/resource-limits-fees.mdx index b49a2296d..e60e9bd02 100644 --- a/docs/networks/resource-limits-fees.mdx +++ b/docs/networks/resource-limits-fees.mdx @@ -5,13 +5,13 @@ title: Resource Limits & Fees import CanvasFeeGraphs from "@site/src/components/CanvasFeeGraphs"; -## Current Inclusion Fees +## Current Inclusion Fees {#current-inclusion-fees} For the past three hours, inclusion fee statistics for smart contract transactions on the Mainnet network are: -## Resource Limits +## Resource Limits {#resource-limits} :::note @@ -37,7 +37,7 @@ Resource limitations and fees only apply to smart contract transactions. Read mo | Max txs size in bytes per ledger | 130 KiB | | Eviction scan size | 500 KB | -## Resource Fees +## Resource Fees {#resource-fees} | Network Setting | Cost (stroops) | | :--------------------------------------------- | :------------------------ | diff --git a/docs/networks/software-versions.mdx b/docs/networks/software-versions.mdx index f89fb8d22..62646e577 100644 --- a/docs/networks/software-versions.mdx +++ b/docs/networks/software-versions.mdx @@ -12,9 +12,9 @@ Release candidates are software releases that are also released to the [Testnet] [testnet]: ./README.mdx -## Protocol 22 (Testnet, October , 2024) +## Protocol 22 (Testnet, October , 2024) {#protocol-22-testnet-october--2024} -### Software +### Software {#software} | Software | Version | | --- | --- | @@ -35,27 +35,27 @@ Release candidates are software releases that are also released to the [Testnet] | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Release notes +### Release notes {#release-notes} -#### Core +#### Core {#core} New features in Protocol 22: - Constructor support in Soroban: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0058.md. - Soroban host functions for BLS12-381: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0059.md. -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk} Key protocol-related changes: - Support for constructors - Support for BLS12-381 host functions -#### Stellar CLI (Previously Soroban CLI) +#### Stellar CLI (Previously Soroban CLI) {#stellar-cli-previously-soroban-cli} -## Protocol 21 (Mainnet, June 18, 2024) +## Protocol 21 (Mainnet, June 18, 2024) {#protocol-21-mainnet-june-18-2024} -### Software +### Software {#software-1} | Software | Version | | --- | --- | @@ -79,9 +79,9 @@ Key protocol-related changes: | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Release notes +### Release notes {#release-notes-1} -#### Core +#### Core {#core-1} New features in Protocol 21: @@ -90,14 +90,14 @@ New features in Protocol 21: - Use refined cost model for VM instantiation in order to reduce the VM instantiation metered costs: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0054.md - Intra-transaction VM module caching for the further Soroban cost reduction: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0055.md, https://github.com/stellar/stellar-protocol/blob/master/core/cap-0056.md -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-1} Key protocol-related changes: - Support for secp256r1 signature verification - Support for extending TTL of contract instance and code separate from each other -#### Stellar CLI (Previously Soroban CLI) +#### Stellar CLI (Previously Soroban CLI) {#stellar-cli-previously-soroban-cli-1} Note: Soroban CLI has been renamed to Stellar CLI. @@ -127,9 +127,9 @@ Note: Soroban CLI has been renamed to Stellar CLI. - Remove lab xdr command - Add xdr command to root -## Protocol 21 (Testnet only, May 20, 2024) +## Protocol 21 (Testnet only, May 20, 2024) {#protocol-21-testnet-only-may-20-2024} -### Software +### Software {#software-2} | Software | Version | | --- | --- | @@ -153,9 +153,9 @@ Note: Soroban CLI has been renamed to Stellar CLI. | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Release notes +### Release notes {#release-notes-2} -#### Core +#### Core {#core-2} This is the first stable Core release supporting protocol 21. New features in protocol 21: @@ -164,16 +164,16 @@ This is the first stable Core release supporting protocol 21. New features in pr - Use refined cost model for VM instantiation in order to reduce the VM instantiation metered costs: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0054.md - Intra-transaction VM module caching for the further Soroban cost reduction: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0055.md, https://github.com/stellar/stellar-protocol/blob/master/core/cap-0056.md -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-2} This is the first version of the Soroban SDK that supports protocol 21. It is marked as 'preview' because contracts built with SDK v21 will only be compatible with the networks upgraded to protocol 21. Key protocol-related changes: - Support for secp256r1 signature verification - Support for extending TTL of contract instance and code separate from each other -## Protocol 21: Preview 1 (Testnet only, April 12, 2024) +## Protocol 21: Preview 1 (Testnet only, April 12, 2024) {#protocol-21-preview-1-testnet-only-april-12-2024} -### Software +### Software {#software-3} | Software | Version | | --- | --- | @@ -197,9 +197,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Release notes +### Release notes {#release-notes-3} -#### Core +#### Core {#core-3} This is the first Core release supporting protocol 21. New features in protocol 21: @@ -208,16 +208,16 @@ This is the first Core release supporting protocol 21. New features in protocol - Use refined cost model for VM instantiation in order to reduce the VM instantiation metered costs: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0054.md - Intra-transaction VM module caching for the further Soroban cost reduction: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0055.md, https://github.com/stellar/stellar-protocol/blob/master/core/cap-0056.md -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-3} This is the first version of the Soroban SDK that supports protocol 21. It is marked as 'preview' because contracts built with SDK v21 will only be compatible with the networks upgraded to protocol 21. The API itself may be considered stable. Key changes: - Support for secp256r1 signature verification - Support for extending TTL of contract instance and code separate from each other -## Protocol 20: Soroban Phase 2 (March 19, 2024) +## Protocol 20: Soroban Phase 2 (March 19, 2024) {#protocol-20-soroban-phase-2-march-19-2024} -### Software +### Software {#software-4} | Software | Version | | --- | --- | @@ -244,9 +244,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Changelog +### Changelog {#changelog} -#### Core +#### Core {#core-4} - Remove use of C99 that looks like Cxx20 designated initializers - Reduce scan size in phase1 @@ -270,7 +270,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Fix noisy eviction scan warnings - Early initialization of soroban metrics -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-4} - Display String contents in Debug implementation - Add Bytes to_buffer and to_alloc_vec @@ -278,9 +278,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Add option to disable test snapshots on Env - Bump version to 20.4.0 -## Protocol 20: Soroban Phase 1 (February 27, 2024) +## Protocol 20: Soroban Phase 1 (February 27, 2024) {#protocol-20-soroban-phase-1-february-27-2024} -### Software +### Software {#software-5} | Software | Version | | --- | --- | @@ -307,9 +307,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Changelog +### Changelog {#changelog-1} -#### Soroban RPC +#### Soroban RPC {#soroban-rpc} - (tag: v20.3.3) Bump version to 20.3.3 - Update Dockerfile and Makefile to refer rpc instead of tools @@ -325,7 +325,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Add prometheus hook to count different log levels - Remove build-test-wasms from makefile -#### Soroban CLI +#### Soroban CLI {#soroban-cli} - (tag: v20.3.1) Bump version to 20.3.1 - Update references in end-to-end tests to point to the latest releases @@ -342,9 +342,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Revert "[Epic] Separating soroban-rpc to prepare for repo change" - [Epic] Separating soroban-rpc to prepare for repo change -## Protocol 20: Soroban Phase 1 (Mainnet Edition) (February 5, 2024) +## Protocol 20: Soroban Phase 1 (Mainnet Edition) (February 5, 2024) {#protocol-20-soroban-phase-1-mainnet-edition-february-5-2024} -### Software +### Software {#software-6} | Software | Version | | --- | --- | @@ -371,16 +371,16 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Changelog +### Changelog {#changelog-2} -#### XDR +#### XDR {#xdr} - Run CI for the msrv and latest rust version - Backfill changes to next for json rendering - Bump XDR - Bump version to 20.1.0 -#### Soroban Environment +#### Soroban Environment {#soroban-environment} - Allow small version-range wiggle room on curve25519-dalek to enable docs.rs nightly build - Bump version to 20.2.2 @@ -410,14 +410,14 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Bump wasmi to 0.31.1-soroban.20.0.1 - Bump version to 20.1.1 -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-5} - Update soroban-env-\* - Bump version to 20.3.2 - Update extend_ttl docs - Bug 1076 conversion error flattening -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-1} - Migrate Soroban Tools to Soroban RPC - Use soroban-tools Crates @@ -433,7 +433,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Add diagnostic events to sendTransaction response - Remove panics from internal codebase -#### Soroban CLI +#### Soroban CLI {#soroban-cli-1} - feat: soroban init command - Bump dependencies for pubnet release @@ -447,9 +447,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Update typescript bindings for latest versions - Warn about RC versions only when using pubnet -## Stable v20.1.0 (January 11, 2024) +## Stable v20.1.0 (January 11, 2024) {#stable-v2010-january-11-2024} -### Software +### Software {#software-7} | Software | Version | | --- | --- | @@ -473,18 +473,18 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | | Testnet Network Passphrase | `Test SDF Network ; September 2015` | -### Changelog +### Changelog {#changelog-3} -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-6} - Fix bug with Timepoint/Duration as parameters/returns - Add storage update fns - Export functions for creating Timepoint/Duration - Allow `&Env` in contract fns -## Stable v20.0.0 (December 18, 2023) +## Stable v20.0.0 (December 18, 2023) {#stable-v2000-december-18-2023} -### Software +### Software {#software-8} | Software | Version | | --- | --- | @@ -509,13 +509,13 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | | Testnet Network Passphrase | `Test SDF Network ; September 2015` | -### Changelog +### Changelog {#changelog-4} -#### XDR +#### XDR {#xdr-1} - Update the docs for extendTTL/restore ops to match the threshold change -#### Soroban Environment +#### Soroban Environment {#soroban-environment-1} - Make RecordedAuthPayload consistently return None for invoker. - Expiration-related fixes @@ -743,7 +743,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Remaining host code review - Bump version to 20.0.0 -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-7} - Token events - Update rust-version @@ -842,7 +842,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Update env - Bump version to 20.0.0 -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-2} - increased preflight instruction fee padding to 3 million - Enforce enabling diagnostics events @@ -885,7 +885,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Unify all ledger sequence types to uint32 and stop stringyfying integers < 53-bits wide - Restore CORS support -#### Soroban CLI +#### Soroban CLI {#soroban-cli-2} - Allow fetching contract from network - Each generated contract method adds -file-path @@ -907,9 +907,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Fix various typescript bindings - Make output consistent for all ways to get version -## Preview 11 (September 11, 2023): Testnet and Futurenet Edition +## Preview 11 (September 11, 2023): Testnet and Futurenet Edition {#preview-11-september-11-2023-testnet-and-futurenet-edition} -### Software +### Software {#software-9} | Software | Version | | --- | --- | @@ -940,9 +940,9 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te ::: -### Changelog +### Changelog {#changelog-5} -#### XDR +#### XDR {#xdr-2} - Generate for entry expired error - Bump XDR @@ -964,7 +964,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Bump XDR - Bump version to 20.0.0-rc1 -#### Soroban Environment +#### Soroban Environment {#soroban-environment-2} - Attach the auth in recording mode to any valid tracker when possible - Make RecordedAuthPayload consistently return None for invoker @@ -1054,7 +1054,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Update wasmi to 0.31.0-soroban - Bump version to 20.0.0-rc1 -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-8} - Implement deployer functions that return the deployed contract id - Add Vec::to_vals @@ -1097,7 +1097,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Adapt to removal of ConversionError from number type conversions - Bump version to 20.0.0-rc1 -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-3} - List --network under RPC options - Enforce enabling diagnostics events @@ -1125,7 +1125,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Fix set_authorization_entries bug in transaction simulation - Restore CORS support -#### Soroban CLI +#### Soroban CLI {#soroban-cli-3} - Add multi-party authorization + signing support - Add two new output types for contract inspect @@ -1148,9 +1148,9 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Return an error once contract read is unable to read any entry - wrap token no longer fails with valid inputs in sandbox mode -## Preview 10 (July 13, 2023) +## Preview 10 (July 13, 2023) {#preview-10-july-13-2023} -### Software +### Software {#software-10} | Software | Version | | --- | --- | @@ -1172,9 +1172,9 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te | Soroban Mint Token dapp | `1.1.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog +### Changelog {#changelog-6} -#### XDR +#### XDR {#xdr-3} - Remove TransactionResultV2 - Regenerate for overhaul of error codes @@ -1197,7 +1197,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Generate rename - Update crate-git-revision -#### Soroban Environment +#### Soroban Environment {#soroban-environment-3} - Move a bunch of code out of host, reorg modules slightly. - Remove temp storage, fixes #758 @@ -1250,22 +1250,22 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Change `[IU]256` `[from,to]_bytes` functions to work with Val - Bump wasmi version -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-9} - Fix storage comment - Noop in instance bump for tests -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-4} - Update js-soroban-client dependency from 0.9.0 to 0.9.1 -#### Soroban CLI +#### Soroban CLI {#soroban-cli-4} - Update js-soroban-client dependency from 0.9.0 to 0.9.1 -## Preview 9 (May 24th, 2023) +## Preview 9 (May 24th, 2023) {#preview-9-may-24th-2023} -### Software +### Software {#software-11} | Software | Version | | --- | --- | @@ -1285,31 +1285,31 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te | Laboratory | `2.10.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog +### Changelog {#changelog-7} -#### XDR +#### XDR {#xdr-4} See https://github.com/stellar/rs-stellar-xdr/releases v0.0.16 for more details. -#### Soroban Environment +#### Soroban Environment {#soroban-environment-4} See https://github.com/stellar/rs-soroban-env/releases v0.0.16 for more details. -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-10} See https://github.com/stellar/rs-soroban-sdk/releases v0.8.4 for more details. -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-5} See https://github.com/stellar/soroban-tools/releases v0.8.0 for more details. -#### Soroban CLI +#### Soroban CLI {#soroban-cli-5} See https://github.com/stellar/soroban-tools/releases v0.8.0 for more details. -## Preview 8 (April 4th, 2023) +## Preview 8 (April 4th, 2023) {#preview-8-april-4th-2023} -### Software +### Software {#software-12} | Software | Version | | --- | --- | @@ -1329,7 +1329,7 @@ See https://github.com/stellar/soroban-tools/releases v0.8.0 for more details. | Laboratory | `v2.8.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Breaking changes note +### Breaking changes note {#breaking-changes-note} This release includes a major overhaul of the value representation at the XDR level, which potentially breaks contracts that rely on the old type definitions, here is a summary of the changes: @@ -1342,9 +1342,9 @@ This release includes a major overhaul of the value representation at the XDR le SDK support has also been added/updated for these types. See [xdr](https://github.com/stellar/stellar-xdr/pull/70), [env](https://github.com/stellar/rs-soroban-env/pull/682) and [sdk](https://github.com/stellar/rs-soroban-sdk/pull/879) changes for more details. -### Changelog +### Changelog {#changelog-8} -#### XDR +#### XDR {#xdr-5} - Make types wrapping Strings no longer aliases - Value representation overhaul @@ -1352,7 +1352,7 @@ SDK support has also been added/updated for these types. See [xdr](https://githu See https://github.com/stellar/rs-stellar-xdr/releases v0.0.15 for more details. -#### Soroban Environment +#### Soroban Environment {#soroban-environment-5} - Remove the unnecessary error events that appeared in non-error scenarios. - Reform metering for value cloning and memory allocation. @@ -1375,7 +1375,7 @@ See https://github.com/stellar/rs-stellar-xdr/releases v0.0.15 for more details. See https://github.com/stellar/rs-soroban-env/releases v0.0.15 for more details. -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-11} - Add docs in specs for types. - Rename Serialize/Deserialize to To/FromXdr. @@ -1397,7 +1397,7 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.15 for more details. See https://github.com/stellar/rs-soroban-sdk/releases v0.7.0 for more details. -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-6} - Set a maximum ledger latency in /health method. - Add resultMetaXdr and envelopeXdr back to getTransaction() response. @@ -1412,7 +1412,7 @@ See https://github.com/stellar/rs-soroban-sdk/releases v0.7.0 for more details. See https://github.com/stellar/soroban-tools/releases v0.7.0 for more details. -#### Soroban CLI +#### Soroban CLI {#soroban-cli-6} - Improved documentation, and `--help` text - feat: auto-generate comprehensive CLI docs. @@ -1432,9 +1432,9 @@ See https://github.com/stellar/soroban-tools/releases v0.7.0 for more details. See https://github.com/stellar/soroban-tools/releases v0.7.0 for more details. -## Preview 7 (February 16th, 2023) +## Preview 7 (February 16th, 2023) {#preview-7-february-16th-2023} -### Software +### Software {#software-13} | Software | Version | | --- | --- | @@ -1454,19 +1454,19 @@ See https://github.com/stellar/soroban-tools/releases v0.7.0 for more details. | Laboratory | `v2.7.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Breaking changes note +### Breaking changes note {#breaking-changes-note-1} This release comes with a revamp of authorization approach that is breaking for most of the contracts that did any sort of auth logic or used tokens. [example](../build/smart-contracts/example-contracts/auth.mdx) and [authorization overview](../learn/encyclopedia/security/authorization.mdx) for more details. -### Changelog +### Changelog {#changelog-9} -#### XDR +#### XDR {#xdr-6} - Update Rust XDR for Auth Next. See https://github.com/stellar/rs-stellar-xdr/releases v0.0.13 and v0.0.14 for more details. -#### Soroban Environment +#### Soroban Environment {#soroban-environment-6} - Allow for a custom budget outside tests - Restructure Event to be cheap to clone and allow it to be rolled back @@ -1484,7 +1484,7 @@ See https://github.com/stellar/rs-stellar-xdr/releases v0.0.13 and v0.0.14 for m See https://github.com/stellar/rs-soroban-env/releases v0.0.13 and v0.0.14 for more details. -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-12} - Support variants with multiple fields in UDTs - Error on UDT enums with 0-element tuple variants @@ -1504,7 +1504,7 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.13 and v0.0.14 for m See https://github.com/stellar/rs-soroban-sdk/releases v0.5.0 and v0.6.0 for more details. -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-7} - Configure default limit, update cursor / startLedger validation, and include latest ledger for getEvents - Add support for AuthNext @@ -1518,7 +1518,7 @@ See https://github.com/stellar/rs-soroban-sdk/releases v0.5.0 and v0.6.0 for mor See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more details. -#### Soroban CLI +#### Soroban CLI {#soroban-cli-7} - Add option for running contract with unlimited budget - Add support for AuthNext @@ -1528,9 +1528,9 @@ See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more det See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more details. -## Preview 6 (January 9th, 2023) +## Preview 6 (January 9th, 2023) {#preview-6-january-9th-2023} -### Software +### Software {#software-14} | Software | Version | | --- | --- | @@ -1549,9 +1549,9 @@ See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more det | Stellar JS Soroban Client | `v0.3.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog +### Changelog {#changelog-10} -#### Soroban Environment +#### Soroban Environment {#soroban-environment-7} - Wasm instruction level calibration - Replace `im` containers with `Vec` @@ -1566,7 +1566,7 @@ See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more det See https://github.com/stellar/rs-soroban-env/releases v0.0.12 for more details. -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-13} - Fix contractimpl for empty impl blocks - bump env and fix token interface @@ -1584,13 +1584,13 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.12 for more details. See https://github.com/stellar/rs-soroban-sdk/releases v0.4.0, v0.4.1, v0.4.2 for more details. -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-8} - Add GitHub linting for GO code See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. -#### Soroban CLI +#### Soroban CLI {#soroban-cli-8} - Update rust version - StrValError --> Error and implemented using thiserror @@ -1601,9 +1601,9 @@ See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. -## Preview 5 (December 8th, 2022) +## Preview 5 (December 8th, 2022) {#preview-5-december-8th-2022} -### Software +### Software {#software-15} | Software | Version | | --- | --- | @@ -1621,9 +1621,9 @@ See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. | Stellar JS Soroban Client | `v0.2.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog +### Changelog {#changelog-11} -#### XDR +#### XDR {#xdr-7} - Remove BigInt from ScVal - Add u128 and i128 to ScVal @@ -1632,7 +1632,7 @@ See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. See https://github.com/stellar/stellar-xdr/compare/48d5e17ae63bba0aa9725cd9d18d7438f44c07b1...026c9cd074bdb28ddde8ee52f2a4502d9e518a09 for more details. -#### Soroban Environment +#### Soroban Environment {#soroban-environment-8} - Upgrade crate-git-revision to 0.0.4 (contribution by [@brson]) - Add Host::with_artificial_test_contract_frame @@ -1643,7 +1643,7 @@ See https://github.com/stellar/stellar-xdr/compare/48d5e17ae63bba0aa9725cd9d18d7 See https://github.com/stellar/rs-soroban-env/releases v0.0.10, v0.0.11 for more details. -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-14} - Rename data to storage by @leighmcculloch in #786 - Add ability to get current Budget from env in tests by @leighmcculloch in #789 @@ -1657,7 +1657,7 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.10, v0.0.11 for more See https://github.com/stellar/rs-soroban-sdk/releases v0.3.0, v0.3.1, v0.3.2 for more details. -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-9} - Add soroban-rpc version subcommand - Add a new getLedgerEntry jsonrpc method, deprecating and replacing getContractData allowing an application to fetch any ledger entry @@ -1665,7 +1665,7 @@ See https://github.com/stellar/rs-soroban-sdk/releases v0.3.0, v0.3.1, v0.3.2 fo See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1 for more details. -#### Soroban CLI +#### Soroban CLI {#soroban-cli-9} - Fix apt-get install in publish workflow - Added type description to errors when using --arg (contribution by [@waldmatias]) @@ -1677,9 +1677,9 @@ See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1 for more de See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1, 0.3.3 for more details. -## Preview 4 (November 15th, 2022) +## Preview 4 (November 15th, 2022) {#preview-4-november-15th-2022} -### Software +### Software {#software-16} | Software | Version | | --- | --- | @@ -1694,13 +1694,13 @@ See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1, 0.3.3 for | Stellar Quickstart | `stellar/quickstart:soroban-dev@sha256:0993d3350148af6ffeab5dc8f0b835236b28dade6dcae77ff8a09317162f768d` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog +### Changelog {#changelog-12} -#### XDR +#### XDR {#xdr-8} - Trivial whitespace changes -#### Soroban Environment +#### Soroban Environment {#soroban-environment-9} - Vm tuning - Add token events @@ -1712,7 +1712,7 @@ See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1, 0.3.3 for See https://github.com/stellar/rs-soroban-env/releases v0.0.7, v0.0.8, v0.0.9 for more details. -#### Soroban Rust SDK +#### Soroban Rust SDK {#soroban-rust-sdk-15} - Add Logger::print in testutils - Add conversion from Address to Identifier @@ -1724,11 +1724,11 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.7, v0.0.8, v0.0.9 fo See https://github.com/stellar/rs-soroban-sdk/releases v0.2.0, v0.2.1 for more details. -#### Soroban RPC +#### Soroban RPC {#soroban-rpc-10} - Initial Release -#### Soroban CLI +#### Soroban CLI {#soroban-cli-10} - Strings and symbols are rendered as text in JSON output - Bytes are rendered as hex in JSON output @@ -1739,9 +1739,9 @@ See https://github.com/stellar/rs-soroban-sdk/releases v0.2.0, v0.2.1 for more d See https://github.com/stellar/soroban-cli/releases v0.2.0, v0.2.1 for more details. -## Preview 3 (October 11th, 2022) +## Preview 3 (October 11th, 2022) {#preview-3-october-11th-2022} -### Software +### Software {#software-17} | Software | Version | | --- | --- | @@ -1756,15 +1756,15 @@ See https://github.com/stellar/soroban-cli/releases v0.2.0, v0.2.1 for more deta | Stellar Quickstart | `stellar/quickstart:soroban-dev@sha256:e58d83f92a61f43406087f488dd1cba110a92646dca85f14b3a416163609e853` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog +### Changelog {#changelog-13} See https://www.stellar.org/blog/soroban-a-new-smart-contract-standard. -## Preview 2 (September 13th, 2022) +## Preview 2 (September 13th, 2022) {#preview-2-september-13th-2022} See https://www.stellar.org/developers-blog/soroban-preview-release-2. -## Preview 1 (August 1st, 2022) +## Preview 1 (August 1st, 2022) {#preview-1-august-1st-2022} See https://www.stellar.org/blog/project-jump-cannon-soroban-preview-release. diff --git a/docs/tokens/README.mdx b/docs/tokens/README.mdx index f55a3aaa3..a850a049f 100644 --- a/docs/tokens/README.mdx +++ b/docs/tokens/README.mdx @@ -12,11 +12,11 @@ Several factors can help you determine whether to issue an asset on Stellar or c However: -### TL;DR +### TL;DR {#tldr} If possible, we recommend issuing a Stellar asset and using the SAC to interact with that asset in smart contracts or to send to contract addresses. More on why below. -## Issuing assets on Stellar +## Issuing assets on Stellar {#issuing-assets-on-stellar} Stellar has first-class support for asset tokenization — issuing an asset can be done using a [built-in transaction](./quickstart.mdx) without the development of a smart contract. @@ -36,7 +36,7 @@ Note that while these items are also possible with custom smart contract tokens, Assets issued on the Stellar network are accessible to smart contracts with the use of that asset’s Stellar Asset Contract (SAC). -### Stellar Asset Contract +### Stellar Asset Contract {#stellar-asset-contract} The Stellar Asset Contract (SAC) is compiled into the protocol layer and allows smart contracts to interact with assets issued on Stellar. An instance of the SAC can be deployed for every Stellar asset by anyone who wants to interact with the asset from a contract. The SAC has access to all account balances (for XLM) and trustline balances (for all other assets) as well as smart contract token balances. @@ -55,7 +55,7 @@ Learn how to deploy a Stellar Asset Contract for an asset in [this How-To Guide] - Other than the customization noted above, it is not possible to modify the behavior of Stellar assets or their SAC. If you’re looking to use assets in a way not supported by Stellar assets, you can create your own custom smart contract token using the token interface and all applications that interact with tokens using the token interface will be able to interact with the custom token. -## Custom tokens +## Custom tokens {#custom-tokens} If you have a unique use case where the capabilities Stellar Assets are not sufficient, you can create a custom token that implements the [token interface][ti]. The token interface specifies the functions and events a contract must implement to be compatible with applications that use tokens. @@ -72,7 +72,7 @@ Smart contracts cannot use Stellar assets unless that Stellar asset has a deploy - As the creator of a new token, you decide to implement a feature within your custom token smart contract that enables you to receive a 1% fee from every transaction involving your token. Whenever someone transfers your token to another user, 1% of the transferred amount is automatically deducted and sent to a designated wallet address that you control. - You want to develop a factory contract that automates the creation of instances of a specific token. This contract serves as a centralized and standardized way to deploy new token contracts on demand without manual intervention each time a new instance is needed. -## Helpful links +## Helpful links {#helpful-links} - [Issue an asset tutorial][how-to-issue] - [Stellar Asset Contract][sac] diff --git a/docs/tokens/anatomy-of-an-asset.mdx b/docs/tokens/anatomy-of-an-asset.mdx index a1569f1b6..cf36371d9 100644 --- a/docs/tokens/anatomy-of-an-asset.mdx +++ b/docs/tokens/anatomy-of-an-asset.mdx @@ -11,7 +11,7 @@ Issuing an asset on Stellar is easy and only takes a few operations. However, th Assets issued on the Stellar network are accessible to smart contracts. Every Stellar asset has reserved a [Stellar Asset Contract](./stellar-asset-contract.mdx) that can be deployed by anyone who wants to be able to interact with the asset from a contract. -## Stablecoins +## Stablecoins {#stablecoins} One major category of assets is the stablecoin. A stablecoin is a blockchain-based token whose value is tied to another asset, such as the US dollar, other fiat currencies, commodities like gold, or even cryptocurrencies. There are two types of stablecoin: 1) reserve-backed stablecoins that must have a mechanism for redeeming the asset backing them, and 2) algorithmic stablecoins that don’t have assets backing them and instead rely on an algorithm to control the stablecoin supply. When discussing stablecoins, our documentation will focus on reserve-backed stablecoins. @@ -19,11 +19,11 @@ Reserve-backed stablecoins are pegged to a real-world asset at a 1:1 ratio. Beca Currently, one of Stellar's most significant use cases is the tokenization of fiat currency for processes like cross-border payments. With anchors, users can connect Stellar tokens to existing rails that allow for the deposit of real-world assets in exchange for digital currency and vice versa. Learn more about anchors in our [Anchors section](../learn/fundamentals/anchors.mdx). -### Treasury management +### Treasury management {#treasury-management} When issuing a reserve-backed stablecoin, you must set up its off-chain reserve, which securely stores the asset backing the stablecoin. When users wish to redeem their stablecoin, they can receive an equivalent amount of the underlying reserve asset from the issuer. -## Compliance +## Compliance {#compliance} As an asset issuer, you may need to comply with regulatory requirements that vary based on jurisdiction. Stellar has built-in features that can help meet these requirements, such as: diff --git a/docs/tokens/control-asset-access.mdx b/docs/tokens/control-asset-access.mdx index 537b8e941..4ac48de84 100644 --- a/docs/tokens/control-asset-access.mdx +++ b/docs/tokens/control-asset-access.mdx @@ -6,7 +6,7 @@ sidebar_position: 40 import { CodeExample } from "@site/src/components/CodeExample"; import { Alert } from "@site/src/components/Alert"; -## Issuing and distribution accounts +## Issuing and distribution accounts {#issuing-and-distribution-accounts} It is best practice on the Stellar network to create two accounts when issuing an asset: 1) the issuing account and 2) the distribution account. @@ -18,17 +18,17 @@ Note that you can also issue an asset by creating an offer or liquidity pool dep It is best practice to issue an asset by sending it from the issuing account to a distribution account for two main reasons: security and auditing. -### Security +### Security {#security} The distribution account will be a hot account, meaning that some web service out there has direct access to sign its transactions. For example, if the account you're distributing from is also the issuing account and it is compromised by a malicious actor, the actor can now issue as much of the asset as they want. If the malicious actor redeems the newly issued tokens with an anchor service, the anchor may not have the liquidity to support the customer withdrawals. Stakes are lower if you use a distribution account- if the distribution account is compromised, you can freeze the account’s asset balance and start with a new distribution account without changing the issuing account. -### Auditing +### Auditing {#auditing} Using a distribution account is better for auditing because an issuing account can’t actually hold a balance of its own asset. Sending an asset back to its issuing account burns (deletes) the asset. If you have a standing inventory of the issued asset in a separate account, it’s easier to track and can help with bookkeeping. -## Naming an asset +## Naming an asset {#naming-an-asset} One thing you must decide when issuing an asset is what to call it. An asset code is the asset’s identifying code. There are three possible formats: Alphanumeric 4, Alphanumeric 12, and liquidity pool shares. @@ -40,17 +40,17 @@ Learn about liquidity pool shares in the [Liquidity Pool Encyclopedia Entry](../ Provided it falls into one of these buckets, you can choose any asset code you like. That said, if you’re issuing a currency, you should use the appropriate ISO 4217 code, and if you’re issuing a stock or bond, the appropriate ISIN number. Doing so makes it easier for Stellar interfaces to properly display and sort your token in their listings and allows potential token holders to understand what your token represents. -## Controlling access to an asset with flags +## Controlling access to an asset with flags {#controlling-access-to-an-asset-with-flags} When you issue an asset on Stellar, anyone can hold it by default. In general, that’s a good thing: easy access means better reach and better liquidity. However, if you need to control access to an asset to comply with regulations (or for any other reason), you can easily do so by enabling flags on your issuing account. Flags are created on the account level using a `set_options` operation. They can be set at any time in the life cycle of an asset, not just when you issue it. -### Flag types +### Flag types {#flag-types} The (0xn) next to each flag type denotes the bit settings for each flag. -#### Authorization Required (0x1) +#### Authorization Required (0x1) {#authorization-required-0x1} When `AUTH_REQUIRED_FLAG` is enabled, an issuer must approve an account before that account can hold its asset. This setting allows issuers to vet potential token holders and to approve trustlines. @@ -61,7 +61,7 @@ There are two levels of authorization an asset issuer can grant using the `Set_T - `AUTHORIZED_FLAG`: signifies complete authorization allowing an account to transact freely with the asset to make and receive payments, place orders, and deposit into a liquidity pool. - `AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG`: denotes limited authorization that allows an account to maintain current orders, withdraw from a liquidity pool, or cancel current orders - but not to otherwise transact with the asset. -#### Authorization Revocable (0x2) +#### Authorization Revocable (0x2) {#authorization-revocable-0x2} When `AUTH_REVOCABLE_FLAG` is enabled, an issuer can revoke an existing trustline’s authorization, thereby freezing the asset held by an account. Doing so prevents that account from transferring or trading the asset and cancels the account’s open orders for the asset. @@ -75,21 +75,21 @@ There are three levels of authorization an asset issuer can remove using the `Se - `AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG`: denotes limited authorization that allows an account to maintain current orders but not to otherwise transact with the asset. - `CLAWBACK_ENABLED`: enables the issuing account to take back (burning) all of the asset. See our [section on Clawbacks](../learn/encyclopedia/transactions-specialized/clawbacks.mdx) for more information. -#### Clawback Enabled (0x8) +#### Clawback Enabled (0x8) {#clawback-enabled-0x8} With the `AUTH_CLAWBACK_ENABLED_FLAG` flag set, any _subsequent_ trustlines established with this account will have clawbacks enabled. You can read more about clawbacks (and selectively controlling them on a per-trustline basis) [here](../learn/encyclopedia/transactions-specialized/clawbacks.mdx). Note that this flag requires that revocable is also set. -#### Authorization Immutable (0x4) +#### Authorization Immutable (0x4) {#authorization-immutable-0x4} With this setting, none of the other authorization flags (`AUTH_REQUIRED_FLAG`, `AUTH_REVOCABLE_FLAG`) can be set, and the issuing account can’t be merged. You set this flag to signal to potential token holders that your issuing account and its assets will persist on the ledger in an open and accessible state. -### Set Trustline Flag operation +### Set Trustline Flag operation {#set-trustline-flag-operation} The issuing account can configure various authorization and trustline flags for individual trustlines to an asset. The asset parameter is of the TrustLineAsset type. If you are modifying a trustline to a regular asset (i.e. one in a Code:Issuer format), this is equivalent to the asset type. If you are modifying a trustline to a pool share, this is the liquidity pool’s unique ID. -### Example flow +### Example flow {#example-flow} Let’s look at how an issuer of a regulated asset might use the `AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG` flag. @@ -107,7 +107,7 @@ Here’s a payment from A to B sandwiched between `set_trust_line_flags` operati The authorization sandwich allows the issuer to inspect the specific payment and to grant authorization for it and it alone. Since operations bundled in a transaction are simultaneous, A and B are only authorized for the specific, pre-approved payment operation. Complete authorization does not extend beyond the specific transaction. -### Sample code +### Sample code {#sample-code} In the following code samples, proper error checking is omitted. However, you should always validate your results, as there are many ways that requests can fail. Refer to the [Error Handling](/data/horizon/api-reference/errors/error-handling.mdx) page for tips on error management strategies. @@ -214,7 +214,7 @@ except BaseHorizonError as e: -## Limiting the supply of an asset +## Limiting the supply of an asset {#limiting-the-supply-of-an-asset} :::danger Warning diff --git a/docs/tokens/how-to-issue-an-asset.mdx b/docs/tokens/how-to-issue-an-asset.mdx index e3c073416..c7ea3edd7 100644 --- a/docs/tokens/how-to-issue-an-asset.mdx +++ b/docs/tokens/how-to-issue-an-asset.mdx @@ -14,7 +14,7 @@ If you'd like to interact with an asset issued on the Stellar network in smart c ::: -## Prerequisites +## Prerequisites {#prerequisites} You must ensure you have the required amount of XLM to create your issuing and distribution accounts and cover the minimum balance and transaction fees. If you’re issuing an asset on the testnet, you can fund your account by getting test XLM from friendbot. If you’re issuing an asset in production, you will need to acquire XLM from another wallet or exchange. @@ -24,9 +24,9 @@ Learn about the testnet and mainnet in our [Networks section](../learn/fundament Learn more about fees in our [Fees, Resource Limits, and Metering section](../learn/fundamentals/fees-resource-limits-metering.mdx). -## Foundational tools +## Foundational tools {#foundational-tools} -### Issuer account keypair +### Issuer account keypair {#issuer-account-keypair} First, you must generate a unique keypair. The public key will act as your [issuing identity](../learn/fundamentals/stellar-data-structures/assets.mdx#issuer) on the network, while you use the secret key to sign transactions. @@ -81,13 +81,13 @@ Many users secure their issuing account with cold storage techniques, such as a ::: -### Distribution account keypair +### Distribution account keypair {#distribution-account-keypair} Your asset can be issued and transferred between accounts through a payment, contract, or claimable balance. Although it is not required to create a distribution account, it is best practice, so we will do so in this example. Read more in our [Issuing and Distribution Accounts section](./control-asset-access.mdx#issuing-and-distribution-accounts). -#### Three Operations +#### Three Operations {#three-operations} -##### Generate a new keypair +##### Generate a new keypair {#generate-a-new-keypair} @@ -109,7 +109,7 @@ distributorKeypair := keypair.MustRandom() -##### Import an existing keypair +##### Import an existing keypair {#import-an-existing-keypair} @@ -131,7 +131,7 @@ distributorKeypair := keypair.MustParseFull("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U -##### Employ [multiple signatures](../learn/encyclopedia/security/signatures-multisig.mdx) +##### Employ [multiple signatures](../learn/encyclopedia/security/signatures-multisig.mdx) {#employ-multiple-signatures} :::danger @@ -139,7 +139,7 @@ Be careful when working with raw secret keys. If you don't have issuer trustline ::: -### Local asset object +### Local asset object {#local-asset-object} The asset object is a combination of your [code](./control-asset-access.mdx#naming-an-asset) and your issuing public key. After your issuance, anyone can search the network for your unique asset. @@ -185,9 +185,9 @@ You’ll want to make sure you publish information about your asset to establish ::: -## Network transactions +## Network transactions {#network-transactions} -### Establish distributor trustline +### Establish distributor trustline {#establish-distributor-trustline} Accounts must establish a [trustline](../learn/fundamentals/stellar-data-structures/accounts.mdx#trustlines) with the issuing account to hold that issuer’s asset. This is true for all assets except for the network’s native token, [Lumens](../learn/fundamentals/lumens.mdx). @@ -284,7 +284,7 @@ transaction, _ := txnbuild.NewTransaction( -### Issuer payment to distributor +### Issuer payment to distributor {#issuer-payment-to-distributor} Payments are the most popular operation to actually issue (or mint) your asset, compared to [other issuances](../learn/fundamentals/transactions/list-of-operations.mdx#path-payment-strict-send). A payment creates the amount of an asset specified, up to [the maximum 64-bit integer](../learn/fundamentals/stellar-data-structures/assets.mdx#amount-precision). Relevantly, you do not need to scale up the issuing amount of your asset by the XDR [minimum increment](../learn/fundamentals/stellar-data-structures/assets.mdx#amount-precision). @@ -359,9 +359,9 @@ You can also create a market directly from the issuing account and issue tokens ::: -### Optional transactions +### Optional transactions {#optional-transactions} -#### Configure maximum supply +#### Configure maximum supply {#configure-maximum-supply} :::danger @@ -416,7 +416,7 @@ lockAccountTransaction, _ := txnbuild.NewTransaction( -#### Approve distributor trustline +#### Approve distributor trustline {#approve-distributor-trustline} If you enable the [authorization flag](./control-asset-access.mdx#authorization-required-0x1), the issuing account also needs to approve the distributor account's trustline request before the issuing payment. You will need to do this for all new accounts when set for your asset. @@ -490,7 +490,7 @@ transaction, _ := txnbuild.NewTransaction( -## Full Code Sample +## Full Code Sample {#full-code-sample} diff --git a/docs/tokens/publishing-asset-info.mdx b/docs/tokens/publishing-asset-info.mdx index 0466e224a..ea4d226ee 100644 --- a/docs/tokens/publishing-asset-info.mdx +++ b/docs/tokens/publishing-asset-info.mdx @@ -12,7 +12,7 @@ The most successful asset issuers give exchanges, wallets, and potential buyers Completing your Stellar info file is not a step you can skip. -## What is a Stellar info file? +## What is a Stellar info file? {#what-is-a-stellar-info-file} A Stellar info file is a common place where the Internet can find information about your organization’s Stellar integration. You write it in TOML, a simple and widely used configuration file format designed to be readable by both humans and machines, and publish it at `https://YOUR_DOMAIN/.well-known/stellar.toml`. @@ -20,7 +20,7 @@ That way, everyone knows where to find it, anyone can look it up, and it proves Using a `set_options` operation, you can link your Stellar account to the domain that hosts your Stellar info file, thereby creating a definitive on-chain connection between this information and that account. -## Completing your `stellar.toml` +## Completing your `stellar.toml` {#completing-your-stellartoml} The first Stellar Ecosystem Proposal (SEP) is [SEP-0001: Stellar Info File](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md) and specifies everything you would ever need to include in your Stellar info file. This section will walk through the sections of SEP-0001 that relate to asset issuers. Use this section in conjunction with the SEP to ensure you complete your `stellar.toml` correctly. @@ -35,7 +35,7 @@ For each of those sections, we’ll let you know which fields are required, mean **Note:** it's a good idea to keep the sections in the order presented in SEP-0001: Stellar Info File, which is also the order they're presented here. TOML requires arrays to be at the end, so if you scramble the order, you may cause errors for TOML parsers. -### 1. General Information +### 1. General Information {#1-general-information} Required field for all asset issuers: @@ -45,7 +45,7 @@ Listing your public keys lets users confirm that you own them. For example, when There are several fields where you list information about your Stellar integration to aid in discoverability. If you are an anchor service, and you have set up infrastructure to interoperate with wallets and allow for in-app deposit and withdrawal of assets, make sure to include the locations of your servers on your `stellar.toml` file so those wallets know where to find relevant endpoints to query. In particular, list these: -#### Suggested fields for asset issuers: +#### Suggested fields for asset issuers: {#suggested-fields-for-asset-issuers} - `TRANSFER_SERVER` if you support [SEP-0006: Deposit and Withdrawal API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) - `TRANSFER_SERVER_SEP0024` if you support [SEP-0024: Interactive Deposit and Withdrawal](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md) @@ -55,11 +55,11 @@ There are several fields where you list information about your Stellar integrati If you support other Stellar Ecosystem Proposals — such as federation or delegated signing — or host a public Horizon instance that other people can use to query the ledger, you should also add the location of those resources to [General Information](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md#general-information) so they're discoverable. -### 2. Organization Documentation +### 2. Organization Documentation {#2-organization-documentation} Basic information about your organization goes into a TOML table called [`DOCUMENTATION`]. Organization Documentation is your chance to inform exchanges and buyers about your business and to demonstrate that your business is legitimate and trustworthy. -#### Required field for all asset issuers: +#### Required field for all asset issuers: {#required-field-for-all-asset-issuers} - `ORG_NAME` The legal name of your organization, and if your business has one, its official ORG_DBA. - `ORG_URL` The HTTPS URL of your organization's official website. In order to prove the website is yours, you must host your `stellar.toml` on the same domain you list here. That way, exchanges and buyers can view the SSL certificate on your website and feel reasonably confident that you are who you say you are. @@ -68,7 +68,7 @@ Basic information about your organization goes into a TOML table called [`DOCUME - `ORG_OFFICIAL_EMAIL` The best business email address for your organization. This should be hosted at the same domain as your official website. - `ORG_SUPPORT_EMAIL` The best email for support requests. -#### Suggested fields for asset issuers: +#### Suggested fields for asset issuers: {#suggested-fields-for-asset-issuers-1} - `ORG_GITHUB` Your organization's official Github account. - `ORG_KEYBASE` Your organization's official Keybase account. Your Keybase account should contain proof of ownership of any public online accounts you list here, including your organization's domain. @@ -77,28 +77,28 @@ Basic information about your organization goes into a TOML table called [`DOCUME Issuers that list verified information including phone/address attestations and Keybase verifications are prioritized by Stellar clients. -### 3. Point of Contact Documentation +### 3. Point of Contact Documentation {#3-point-of-contact-documentation} Information about the primary point(s) of contact for your organization goes into a TOML [array of tables](https://github.com/toml-lang/toml#array-of-tables) called `[[PRINCIPALS]]`. You need to put contact information for at least one person in your organization. If you don't, exchanges can't verify your offering, and it is unlikely that buyers will be interested. Multiple principals can be added with additional `[[PRINCIPALS]]` entries. -#### Required field for all asset issuers: +#### Required field for all asset issuers: {#required-field-for-all-asset-issuers-1} - `name` The name of the primary contact. - `email` The primary contact's official email address. This should be hosted at the same domain as your organization's official website. -#### Suggested fields for asset issuers: +#### Suggested fields for asset issuers: {#suggested-fields-for-asset-issuers-2} - `github` The personal Github account of the point of contact. - `twitter` The personal Twitter handle of the point of contact. - `keybase` The personal Keybase account for the point of contact. This account should contain proof of ownership of any public online accounts listed here and may contain proof of ownership of your organization's domain. -### 4. Currency Documentation +### 4. Currency Documentation {#4-currency-documentation} Information about the asset(s) you issue goes into a TOML [array of tables](https://github.com/toml-lang/toml#array-of-tables) called `[[CURRENCIES]]`. If you issue multiple assets, you can include them all in one `stellar.toml`. Each asset should have its own `[[CURRENCIES]]` entry. (These entries are also used for assets you support but don’t issue, but as this section focuses on issuing assets the language will reflect that.) -#### Required field for all asset issuers: +#### Required field for all asset issuers: {#required-field-for-all-asset-issuers-2} - `code` The asset code. This is one of two key pieces of information that identify your token. Without it, your token cannot be listed anywhere. - `issuer` The Stellar public key of the issuing account. This is the second key piece of information that identifies your token. Without it, your token cannot be listed anywhere. @@ -111,13 +111,13 @@ If you're issuing anchored (tethered, stablecoin, asset-backed) tokens, there ar - `redemption_instructions` Instructions to redeem your token for the underlying asset. - `attestation_of_reserve` A URL to attestation or other proof, evidence, or verification of reserves, such as third-party audits, which all issuers of stablecoins should offer to adhere to best practices. -#### Suggested fields for asset issuers: +#### Suggested fields for asset issuers: {#suggested-fields-for-asset-issuers-3} - `desc` A description of your token and what it represents. This is a good place to clarify what your token does and why someone might want to own it. - `conditions` Any conditions you place on the redemption of your token. - `image` A URL to a PNG or GIF image with a transparent background representing your token. Without it, your token will appear blank on many exchanges. -## How to publish your Stellar info file +## How to publish your Stellar info file {#how-to-publish-your-stellar-info-file} After you've followed the steps above to complete your Stellar info file, post it at the following location: `https://YOUR_DOMAIN/.well-known/stellar.toml` @@ -158,7 +158,7 @@ server { } ``` -## Sample code to set the home domain of your issuing account +## Sample code to set the home domain of your issuing account {#sample-code-to-set-the-home-domain-of-your-issuing-account} @@ -298,7 +298,7 @@ func main() { -## Sample `stellar.toml` +## Sample `stellar.toml` {#sample-stellartoml} diff --git a/docs/tokens/stellar-asset-contract.mdx b/docs/tokens/stellar-asset-contract.mdx index 73d6874dc..61af1795e 100644 --- a/docs/tokens/stellar-asset-contract.mdx +++ b/docs/tokens/stellar-asset-contract.mdx @@ -18,7 +18,7 @@ The Stellar Asset Contract (SAC) is an implementation of [CAP-46-6 Smart Contrac See examples of how to use the SAC in the [Tokens How-To Guides](../build/guides/tokens/README.mdx). -## Overview +## Overview {#overview} :::note @@ -48,7 +48,7 @@ The SAC implements the [SEP-41 Token Interface], which is similar to the widely Some functionality available on the Stellar network in transaction operations, such as the order book, do not have any functions exposed on the Stellar Asset Contract in the current protocol. -## Deployment +## Deployment {#deployment} Every Stellar asset on Stellar has reserved a contract address that the Stellar Asset Contract can be deployed to. Anyone can initiate the deploy and the Stellar asset issuer does not need to be involved. @@ -62,7 +62,7 @@ Anyone can deploy the instances of Stellar Asset Contract. Note, that the initia [stellar cli]: ../tools/developer-tools/cli/stellar-cli.mdx [stellar sdk]: ../tools/sdks/library.mdx -## Interacting with classic Stellar assets +## Interacting with classic Stellar assets {#interacting-with-classic-stellar-assets} The Stellar Asset Contract is the only way for contracts to interact with Stellar assets, either the native XLM asset, or those issued by Stellar accounts. @@ -82,15 +82,15 @@ After the contract has been deployed, users can use their classic account (for l - Balances are stored in a 128-bit signed integer. - A balance can only be clawed back if the issuer account had the `AUTH_CLAWBACK_ENABLED_FLAG` set when the balance was created. A balance is created when either an `Address::Contract` is on the receiving end of a successful transfer, or if the admin sets the authorization state. Read more about `AUTH_CLAWBACK_ENABLED_FLAG` [here](./control-asset-access.mdx#clawback-enabled-0x8). -### Balance Authorization Required +### Balance Authorization Required {#balance-authorization-required} In the `Address::Contract` case, if the issuer has `AUTH_REQUIRED_FLAG` set, then the specified `Address::Contract` will need to be explicitly authorized with `set_auth` before it can receive a balance. This logic lines up with how trustlines interact with the `AUTH_REQUIRED_FLAG` issuer flag, allowing asset issuers to have the same control in Soroban as they do in Stellar classic. Read more about `AUTH_REQUIRED_FLAG` [here](./control-asset-access.mdx#authorization-required-0x1). -### Revoking Authorization +### Revoking Authorization {#revoking-authorization} The admin can only revoke authorization from an `Address`, if the issuer of the asset has `AUTH_REVOCABLE_FLAG` set. The deauthorization will fail if the issuer is missing. This requirement is true for both the trustline balances of `Address::Account` and contract balances of `Address:Contract`. Note that when a trustline is deauthorized from Soroban, `AUTHORIZED_FLAG` is cleared and `AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG` is set to avoid having to pull offers and redeeming pool shares. -## Authorization semantics +## Authorization semantics {#authorization-semantics} See the [authorization overview](../learn/encyclopedia/security/authorization.mdx) and [auth example](../build/smart-contracts/example-contracts/auth.mdx) for general information about authorization in Soroban. @@ -106,7 +106,7 @@ Unprivileged mutators require authorization from the `Address` that spends or al Priviliged mutators require authorization from a specific privileged identity, known as the "administrator". For example, only the administrator can `mint` more of the token. Similarly, only the administrator can appoint a new administrator. -## Contract Interface +## Contract Interface {#contract-interface} This interface can be found in the [SDK]. It extends the common [SEP-41 Token Interface]. diff --git a/docs/tokens/token-interface.mdx b/docs/tokens/token-interface.mdx index 08c673937..c1a13ff39 100644 --- a/docs/tokens/token-interface.mdx +++ b/docs/tokens/token-interface.mdx @@ -10,7 +10,7 @@ Tokens deployed on Soroban can implement any interface they choose, however, the Note, that in the specific cases the interface doesn't have to be fully implemented. For example, the custom token may not implement the administrative interface compatible with the Stellar Asset Contract - it won't stop it from being usable in the contracts that only perform the regular user operations (transfers, allowances, balances etc.). -### Compatibility Requirements +### Compatibility Requirements {#compatibility-requirements} For any given contract function, there are 3 requirements that should be consistent with the interface described here: @@ -18,7 +18,7 @@ For any given contract function, there are 3 requirements that should be consist - Authorization - the users have to authorize the token function calls with all the arguments of the invocation (see the interface comments). If this is inconsistent, then the custom token may have issues with getting the correct signatures from the users and may also confuse the wallet software. - Events - the token has to emit the events in the specified format. If inconsistent, then the token may not be handled correctly by the downstream systems such as block explorers. -### Code +### Code {#code} The interface below uses the Rust [soroban-sdk](../tools/sdks/library.mdx#soroban-rust-sdk) to declare a trait that complies with the [SEP-41](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0041.md) token interface. @@ -152,11 +152,11 @@ The `approve` function overwrites the previous value with `amount`, so it is pos ::: -### Metadata +### Metadata {#metadata} Another requirement for complying with the token interface is to write the standard metadata (`decimal`, `name`, and `symbol`) for the token in a specific format. This format allows users to directly read constant data from the ledger instead of invoking a Wasm function. The [token example](https://github.com/stellar/soroban-examples/blob/main/token/src/metadata.rs) demonstrates how to use the Rust [soroban-token-sdk](https://github.com/stellar/rs-soroban-sdk/blob/main/soroban-token-sdk/src/lib.rs) to write the metadata, and we strongly encourage token implementations to follow this approach. -### Handling Failure Conditions +### Handling Failure Conditions {#handling-failure-conditions} In the token interface, there are several instances where function calls can fail due to various reasons such as lack of proper authorization, insufficient allowance or balance, etc. To handle these failure conditions, it is important to specify the expected behavior when such situations arise. @@ -168,21 +168,21 @@ More details on Authorization can be found [here](../learn/encyclopedia/security For the functions in the token interface, [trapping](https://doc.rust-lang.org/book/ch09-00-error-handling.html) should be used as the standard way to handle failure conditions since the interface is not designed to return error codes. This means that when a function encounters an error, it will halt execution and revert any state changes that occurred during the function call. -### Failure Conditions +### Failure Conditions {#failure-conditions} Here is a list of basic failure conditions and their expected behavior for functions in the token interface: -#### Admin functions: +#### Admin functions: {#admin-functions} - If the admin did not authorize the call, the function should trap. - If the admin attempts to perform an invalid action (e.g., minting a negative amount), the function should trap. -#### Token functions: +#### Token functions: {#token-functions} - If the caller is not authorized to perform the action (e.g., transferring tokens without proper authorization), the function should trap. - If the action would result in an invalid state (e.g., transferring more tokens than available in the balance or allowance), the function should trap. -### Example: Handling Insufficient Allowance in `burn_from` function +### Example: Handling Insufficient Allowance in `burn_from` function {#example-handling-insufficient-allowance-in-burn_from-function} In the `burn_from` function, the token contract should check whether the spender has enough allowance to burn the specified amount of tokens from the `from` address. If the allowance is insufficient, the function should trap, halting execution and reverting any state changes. diff --git a/docs/tools/README.mdx b/docs/tools/README.mdx index 11a228bc5..54480d287 100644 --- a/docs/tools/README.mdx +++ b/docs/tools/README.mdx @@ -5,20 +5,20 @@ sidebar_position: 0 This section of the docs will provide links to the SDKs and developer tools for use when developing on Stellar as well as documentation for various SDF-maintained platforms such as the Anchor Platform and Stellar Disbursement Platform (SDP). -## [SDKs](./sdks/library.mdx) +## [SDKs](./sdks/library.mdx) {#sdks} Stellar’s Software Development Kits (SDKs) provide devs with the tools, libraries, and documentation to interact with and develop on the blockchain. They simplify tasks such as creating and deploying smart contracts and sending transactions while also offering APIs to access data and integrate functionalities into applications. -## [Developer Tools](./developer-tools/README.mdx) +## [Developer Tools](./developer-tools/README.mdx) {#developer-tools} Find SDF and ecosystem-maintained developer tools that help streamline the development process for applications and smart contracts on Stellar. -## SDF Platforms +## SDF Platforms {#sdf-platforms} -### [Anchor Platform](/platforms/anchor-platform) +### [Anchor Platform](/platforms/anchor-platform) {#anchor-platform} The Anchor Platform is a set of tools and APIs that enable developers and businesses to build their own on and off-ramp services for the Stellar network. It provides a standardized interface, including the implementation of several Stellar Ecosystem Proposals (SEPs), to make it easy for businesses to integrate with Stellar-based wallets and exchanges. -### [Stellar Disbursement Platform (SDP)](/platforms/stellar-disbursement-platform) +### [Stellar Disbursement Platform (SDP)](/platforms/stellar-disbursement-platform) {#stellar-disbursement-platform-sdp} The Stellar Disbursement Platform (SDP) is a tool built for organizations to make bulk payments to a group of recipients over the Stellar network. diff --git a/docs/tools/developer-tools/IDEs.mdx b/docs/tools/developer-tools/IDEs.mdx index 07dcf971b..6ac363b1b 100644 --- a/docs/tools/developer-tools/IDEs.mdx +++ b/docs/tools/developer-tools/IDEs.mdx @@ -7,10 +7,10 @@ sidebar_position: 70 # IDEs -### [Okashi](https://okashi.dev) +### [Okashi](https://okashi.dev) {#okashi} A web IDE for building, deploying, and testing contracts. -### [Sorobix](https://sorobix.vercel.app/) +### [Sorobix](https://sorobix.vercel.app/) {#sorobix} An IDE and a web GUI where you can write, deploy, and invoke contracts on the Stellar network using Soroban. diff --git a/docs/tools/developer-tools/analytics-platforms.mdx b/docs/tools/developer-tools/analytics-platforms.mdx index 184ffb81f..b73670370 100644 --- a/docs/tools/developer-tools/analytics-platforms.mdx +++ b/docs/tools/developer-tools/analytics-platforms.mdx @@ -9,10 +9,10 @@ sidebar_position: 65 There's a wide range of analytics platforms that make exploring Stellar network data easy and fun! The following platforms allow you to easily create aggregates, visualizations, and dashboards to figure out exactly the story you want to tell, with Stellar data.. -### [Dune](https://dune.com/) +### [Dune](https://dune.com/) {#dune} Dune is a web-based platform that allows you to query Stellar network data and aggregate it into beautiful dashboards. -### [Ortege](https://www.ortege.ai/) +### [Ortege](https://www.ortege.ai/) {#ortege} Ortege is an AI-powered blockchain analytics & insights tool for Stellar, making complex data simple and accessible. Access for free by signing up [here](https://app.ortege.ai/login/). diff --git a/docs/tools/developer-tools/anchor-tools.mdx b/docs/tools/developer-tools/anchor-tools.mdx index 9df1d8830..79a59a15c 100644 --- a/docs/tools/developer-tools/anchor-tools.mdx +++ b/docs/tools/developer-tools/anchor-tools.mdx @@ -7,14 +7,14 @@ sidebar_position: 20 # Anchor Tools -### [Anchor Directory](https://anchors.stellar.org/?) +### [Anchor Directory](https://anchors.stellar.org/?) {#anchor-directory} View all anchors on Stellar, their currencies, and where they operate. -### [Demo Wallet](https://demo-wallet.stellar.org/) +### [Demo Wallet](https://demo-wallet.stellar.org/) {#demo-wallet} An application for interactively testing anchor services. Lets financial application developers test their integrations and learn how Stellar ecosystem protocols (SEPs) work; use the demo wallet to test Regulated Assets (SEP-8), Hosted Deposit and Withdrawal (SEP-24), and Cross-Border Payments (SEP-31) with any home domain that has a Stellar Info File (also known as SEP-1, or a stellar.toml file). -### [Polaris](https://django-polaris.readthedocs.io/en/stable/) +### [Polaris](https://django-polaris.readthedocs.io/en/stable/) {#polaris} An extendable django app that makes it easy for anchors to facilitate cross-border payments and enable deposits and withdrawals; run a web server supporting any combination of SEP-1, 6, 10, 12, and 24. diff --git a/docs/tools/developer-tools/asset-tools.mdx b/docs/tools/developer-tools/asset-tools.mdx index a25773df0..3120f6e6a 100644 --- a/docs/tools/developer-tools/asset-tools.mdx +++ b/docs/tools/developer-tools/asset-tools.mdx @@ -7,6 +7,6 @@ sidebar_position: 30 # Asset Sandbox -### [Asset Sandbox](https://stellar.cheesecakelabs.com/?utm_source=stellar&utm_medium=landing-page&utm_campaign=stellar-asset-sandbox) +### [Asset Sandbox](https://stellar.cheesecakelabs.com/?utm_source=stellar&utm_medium=landing-page&utm_campaign=stellar-asset-sandbox) {#asset-sandbox} A sandbox supported by SDF and Cheesecake Labs for businesses to experiment with asset issuance on Stellar's test network. diff --git a/docs/tools/developer-tools/block-explorers.mdx b/docs/tools/developer-tools/block-explorers.mdx index 69e9780f8..c7a3d851f 100644 --- a/docs/tools/developer-tools/block-explorers.mdx +++ b/docs/tools/developer-tools/block-explorers.mdx @@ -9,18 +9,18 @@ sidebar_position: 40 Block explorers exist to publicly display blockchain data in an easily digestbible way. They can be browsed with an ordinary web browser, and do not require any special developer skills to use. The block explorers available for Soroban index data related to payments, accounts, deployed contracts, transaction history, and more. -### [StellarExpert](https://stellar.expert/explorer/public) +### [StellarExpert](https://stellar.expert/explorer/public) {#stellarexpert} Explore transactions and network activity with StellarExpert. Check stats specific to an asset code, transaction hash, account address, or ledger sequence number. Not available for Futurenet. -### [StellarChain](https://stellarchain.io/) +### [StellarChain](https://stellarchain.io/) {#stellarchain} Explore transactions and network activity for Stellar’s networks, including Futurenet. -### [Soroban Explorer](https://soroban.nownodes.io/) +### [Soroban Explorer](https://soroban.nownodes.io/) {#soroban-explorer} Built specifically for Soroban, you can explore transactions and network activity for Stellar’s Testnet and Futurenet (Mainnet coming soon). -### [Stellar Explorer](https://steexp.com/) +### [Stellar Explorer](https://steexp.com/) {#stellar-explorer} Check data related to payments, accounts, deployed contracts, and more for Stellar’s Futurenet, Testnet, and Mainnet. diff --git a/docs/tools/developer-tools/cli/README.mdx b/docs/tools/developer-tools/cli/README.mdx index 25b7f9675..17e6f52b6 100644 --- a/docs/tools/developer-tools/cli/README.mdx +++ b/docs/tools/developer-tools/cli/README.mdx @@ -6,7 +6,7 @@ sidebar_position: 50 # CLI -### [Stellar CLI](https://github.com/stellar/stellar-cli) +### [Stellar CLI](https://github.com/stellar/stellar-cli) {#stellar-cli} The command line interface to Soroban smart contracts. It allows you to build, deploy, and interact with smart contracts; configure identities; generate key pairs; manage networks; and more. @@ -14,6 +14,6 @@ Install Stellar CLI as explained in [Setup](../../../build/smart-contracts/getti The auto-generated comprehensive reference documentation is available [here](stellar-cli.mdx). -### [Sora](https://github.com/tolgayayci/sora) +### [Sora](https://github.com/tolgayayci/sora) {#sora} Sora is a cross platform GUI designed to simplify use of Stellar CLI. It offers a user-friendly interface for managing projects, identities, networks, contract methods, events, logs and so more in ease. diff --git a/docs/tools/developer-tools/cli/install-cli.mdx b/docs/tools/developer-tools/cli/install-cli.mdx index 621f0efa4..3d0f06594 100644 --- a/docs/tools/developer-tools/cli/install-cli.mdx +++ b/docs/tools/developer-tools/cli/install-cli.mdx @@ -6,7 +6,7 @@ sidebar_position: 50 # Install the Stellar CLI -### [Stellar CLI](https://github.com/stellar/stellar-cli) +### [Stellar CLI](https://github.com/stellar/stellar-cli) {#stellar-cli} There are a few ways to install the latest released version of Stellar CLI. @@ -22,7 +22,7 @@ Install with cargo from source: cargo install --locked stellar-cli --features opt ``` -## Set up Autocomplete +## Set up Autocomplete {#set-up-autocomplete} The Stellar CLI supports some autocompletion. To set up, run the following commands: @@ -44,6 +44,6 @@ To enable autocomplete permanently, run: echo "source <(stellar completion --shell bash)" >> ~/.bashrc ``` -## See Video Tutorial +## See Video Tutorial {#see-video-tutorial} Video Tutorial: https://developers.stellar.org/meetings/2024/06/27 diff --git a/docs/tools/developer-tools/data-indexers.mdx b/docs/tools/developer-tools/data-indexers.mdx index 40e7a7ee7..26c2ae33a 100644 --- a/docs/tools/developer-tools/data-indexers.mdx +++ b/docs/tools/developer-tools/data-indexers.mdx @@ -9,26 +9,26 @@ sidebar_position: 60 To power your applications, a range of data services will be available from data indexers with query interfaces. These indexers will allow you to easily store and retrieve decoded ledger data, contract event emissions, and more. You can focus more energy on making your project successful, and waste less time figuring out precisely how to get the important data from the network. -### [Ankr](https://www.ankr.com/) +### [Ankr](https://www.ankr.com/) {#ankr} Also offers RPC and Horizon instances. -### [BlockEden](https://blockeden.xyz/stellar-soroban/) +### [BlockEden](https://blockeden.xyz/stellar-soroban/) {#blockeden} An all-in-one Stellar RPC, indexer GraphQL API, and data analytics web portal. -### [Goldsky](https://goldsky.com/) +### [Goldsky](https://goldsky.com/) {#goldsky} Mirror and indexer coming soon. -### [Mercury](https://mercurydata.app/) +### [Mercury](https://mercurydata.app/) {#mercury} A network indexing service that provides a toolkit to help get you started working with Stellar network data. -### [SubQuery](https://subquery.network/) +### [SubQuery](https://subquery.network/) {#subquery} An open-source data indexer for Stellar that enables custom API creation for dapps and smart contracts with clean, indexed data. It supports indexing ledgers, transactions, operations, and effects from Stellar, as well as transactions and events from Soroban into a Postgres database. -### [ZettaBlock](https://zettablock.com/) +### [ZettaBlock](https://zettablock.com/) {#zettablock} ZettaBlock offers real-time enterprise-grade data indexing infrastructure services to blockchain ecosystems through customizable, low latency APIs. diff --git a/docs/tools/developer-tools/jupyter-notebooks.mdx b/docs/tools/developer-tools/jupyter-notebooks.mdx index 932e197a3..a16a3a477 100644 --- a/docs/tools/developer-tools/jupyter-notebooks.mdx +++ b/docs/tools/developer-tools/jupyter-notebooks.mdx @@ -17,7 +17,7 @@ Rust support in Jupyter Notebooks is experimental. You might run into bugs, or u ::: -## Getting Started +## Getting Started {#getting-started} 1. Install [Visual Studio Code] (VSCode) 2. Install the [Jupyter Notebook extension] in VSCode @@ -65,11 +65,11 @@ client.add(&1, &2) Congratulations you have a Jupyter Notebook with contract code that should look something like the screenshot below, ready for hacking and experimenting. -## Screenshot +## Screenshot {#screenshot} ![A running Jupyter notebook](/assets/jupyter-notebooks.png) -## Community +## Community {#community} Have ideas for how to improve Soroban contracts in Jupyter Notebooks? Join the community on [Discord]. diff --git a/docs/tools/developer-tools/lab/README.mdx b/docs/tools/developer-tools/lab/README.mdx index 464b1f58c..27a4e831a 100644 --- a/docs/tools/developer-tools/lab/README.mdx +++ b/docs/tools/developer-tools/lab/README.mdx @@ -7,13 +7,13 @@ sidebar_position: 80 # Lab -### [Stellar Lab](https://lab.stellar.org) +### [Stellar Lab](https://lab.stellar.org) {#stellar-lab} Stellar Lab is our new go-to tool for development, experimenting, and testing, as well as exploring APIs developers use to interact with the Stellar network. Whether you're a developer seeking to test transactions, explore RPC methods or Horizon endpoints, or dive deeper into the ecosystem, Stellar Lab provides a modern and user-friendly interface that makes the process smooth and intuitive. ![Lab: Homepage](/assets/lab/lab.png) -### Features of Stellar Lab +### Features of Stellar Lab {#features-of-stellar-lab} - Easily Create Accounts: Create Accounts on Mainnet, Testnet, and Futurenet using a web UI. You can use Friendbot to fund those accounts directly on Lab for Testnet and Futurenet. - Access RPC Methods and Horizon Endpoints: Leverage powerful Stellar RPC methods and Stellar Horizon endpoints in a web UI to interact with the Stellar network and obtain crucial data. Try RPC methods to get states from the ledger like accounts, trustlines, contract wasm, and more. @@ -26,10 +26,10 @@ Stellar Lab is our new go-to tool for development, experimenting, and testing, a These are the features that are available now. There will be more upcoming features to support smart contracts. We look forward to showing you the future of Stellar Lab. -### What About the Old Lab? +### What About the Old Lab? {#what-about-the-old-lab} In case you need it, the previous version of Stellar Lab is still accessible [here](https://old-lab.stellar.org). However, it will no longer be actively maintained. We encourage you to explore the new Lab and if you think there is anything that’s missing, please reach out to us Stellar Github. -### Help Us Improve! +### Help Us Improve! {#help-us-improve} We’re committed to making Stellar Lab even better. If you have any feature requests, please submit them on [Github](https://github.com/stellar/laboratory/issues). Your feedback is important to us with product iterations and in shaping the future of Stellar Lab. diff --git a/docs/tools/developer-tools/lab/account.mdx b/docs/tools/developer-tools/lab/account.mdx index 86150cbf8..2d43ffe7a 100644 --- a/docs/tools/developer-tools/lab/account.mdx +++ b/docs/tools/developer-tools/lab/account.mdx @@ -1,6 +1,6 @@ # Account -## [Create Account Keypair](https://lab.stellar.org/account/create) +## [Create Account Keypair](https://lab.stellar.org/account/create) {#create-account-keypair} ![Lab: Create Account](/assets/lab/lab-account-create.png) @@ -25,7 +25,7 @@ The Friendbot can be used for new account or accounts with balance under a start 4. Optionally, to save the generated keypair, click the "Save Keypair" button. Enter the name in the pop-up and click the "Save" button to save the keypair in the browser's local storage. Click the "Saved Keypairs" link on the left-side menu to view saved keypairs. The save feature is available only on Testnet and Futurenet networks. -## [Fund Account](https://lab.stellar.org/account/fund) +## [Fund Account](https://lab.stellar.org/account/fund) {#fund-account} ![Lab: Fund Account](/assets/lab/lab-account-fund.png) @@ -42,7 +42,7 @@ You can also create an account using a Stellar SDK. Follow a guide [here](../../ ::: -## [Saved Keypairs](https://lab.stellar.org/account/saved) +## [Saved Keypairs](https://lab.stellar.org/account/saved) {#saved-keypairs} ![Lab: Saved Keypairs](/assets/lab/lab-account-saved.png) diff --git a/docs/tools/developer-tools/lab/quickstart-with-lab.mdx b/docs/tools/developer-tools/lab/quickstart-with-lab.mdx index 9cd587866..480adccfc 100644 --- a/docs/tools/developer-tools/lab/quickstart-with-lab.mdx +++ b/docs/tools/developer-tools/lab/quickstart-with-lab.mdx @@ -1,15 +1,15 @@ # Using Lab with Quickstart -## Overview +## Overview {#overview} [Quickstart](https://github.com/stellar/quickstart) provides an easy way to set up a local Stellar network environment. Specifically, Quickstart docker image bundles Stellar Core with Horizon, RPC, Friendbot, and the necessary PostgreSQL databases. Now it is possible to use Stellar Lab as an interface on Quickstart. -## Prerequisites +## Prerequisites {#prerequisites} - [Stellar CLI](/docs/tools/developer-tools/cli/install-cli) - [Docker](https://www.docker.com/) -## Start Quickstart +## Start Quickstart {#start-quickstart} Quickstart can be started for different networks. In this example, we will start Quickstart for `testnet`. Start Quickstart with the Stellar CLI using the following command: @@ -19,7 +19,7 @@ stellar network container start testnet Quickstart will usually start on `http://localhost:8000`. With this information, we can now configure Stellar Lab to use the local network. -## Configure Stellar Lab to use Local Horizon and Local RPC +## Configure Stellar Lab to use Local Horizon and Local RPC {#configure-stellar-lab-to-use-local-horizon-and-local-rpc} ![Lab: Network selector](/assets/lab/lab-custom-network.png) diff --git a/docs/tools/developer-tools/lab/transactions.mdx b/docs/tools/developer-tools/lab/transactions.mdx index 761b7d3f2..4239ee3a0 100644 --- a/docs/tools/developer-tools/lab/transactions.mdx +++ b/docs/tools/developer-tools/lab/transactions.mdx @@ -1,12 +1,12 @@ # Transactions -## [Build Transaction](https://lab.stellar.org/transaction/build) +## [Build Transaction](https://lab.stellar.org/transaction/build) {#build-transaction} ![Lab: Build Transaction](/assets/lab/lab-transactions-build.png) You can access the "Build Transaction" page by clicking the "Transactions" link in the Lab's top navigation. The transaction builder UI has helpful messages, links, and input validation to make learning how to build transactions on the Stellar network easier. There are three main sections: params, operations, and transaction validation (error or success). -### Params +### Params {#params} A Stellar transaction requires a source account, transaction sequence number, and a base fee. Memo and time bounds are optional. @@ -14,7 +14,7 @@ Once you enter a valid public address in the "Source Account" input, you can aut The base fee is 100 by default, but you may need to increase the fee if the network is congested. -### Operations +### Operations {#operations} ![Lab: Transaction operations](/assets/lab/lab-transactions-ops.png) @@ -28,7 +28,7 @@ You can also save a valid transaction by clicking the save button at the bottom Clicking the share button (right next to the save button) allows you to share a link with all the transaction information provided. You can share any transaction, even if it's invalid or incomplete. -### Transaction Validation +### Transaction Validation {#transaction-validation} ![Lab: Transaction validation success](/assets/lab/lab-transactions-response-success.png) @@ -38,7 +38,7 @@ If there are errors in this transaction, you will see them grouped by section (p ![Lab: Transaction validation error](/assets/lab/lab-transactions-response-error.png) -## [Saved Transactions](https://lab.stellar.org/transaction/saved) +## [Saved Transactions](https://lab.stellar.org/transaction/saved) {#saved-transactions} ![Lab: Saved Transactions](/assets/lab/lab-transactions-saved.png) diff --git a/docs/tools/developer-tools/network-insights.mdx b/docs/tools/developer-tools/network-insights.mdx index 51a2edc5e..d414410e5 100644 --- a/docs/tools/developer-tools/network-insights.mdx +++ b/docs/tools/developer-tools/network-insights.mdx @@ -7,6 +7,6 @@ sidebar_position: 85 # Network Insights -### [StellarFee](https://stellarfee.expert/) +### [StellarFee](https://stellarfee.expert/) {#stellarfee} A GUI tool which is a useful fee estimator, transaction simulator to find the resources consumed and the expected fees for a transaction. diff --git a/docs/tools/developer-tools/network-status.mdx b/docs/tools/developer-tools/network-status.mdx index e2bc57b7b..e30685028 100644 --- a/docs/tools/developer-tools/network-status.mdx +++ b/docs/tools/developer-tools/network-status.mdx @@ -7,14 +7,14 @@ sidebar_position: 90 # Network Status -### [Dashboard](https://dashboard.stellar.org/) +### [Dashboard](https://dashboard.stellar.org/) {#dashboard} Displays the current status of the Testnet and Mainnet. Monitor fee stats, recent operations, lumen supply, and more. -### [Stellarbeat](https://stellarbeat.io/) +### [Stellarbeat](https://stellarbeat.io/) {#stellarbeat} View Stellar network nodes and visualize consensus. -### [Status Page](https://status.stellar.org/) +### [Status Page](https://status.stellar.org/) {#status-page} Tracks network incidents and scheduled maintenance for the Testnet and Mainnet. Subscribe to updates to be notified about important events, including protocol upgrades and Testnet resets. diff --git a/docs/tools/developer-tools/node-operator-tools.mdx b/docs/tools/developer-tools/node-operator-tools.mdx index afba032bb..37ad5ef9a 100644 --- a/docs/tools/developer-tools/node-operator-tools.mdx +++ b/docs/tools/developer-tools/node-operator-tools.mdx @@ -7,6 +7,6 @@ sidebar_position: 100 # Node Operator Tools -### [GitHub Repository](https://github.com/stellar/go/tree/master/tools) +### [GitHub Repository](https://github.com/stellar/go/tree/master/tools) {#github-repository} A GitHub repository with tools like Stellar Archivist (for Stellar Core archive maintenance) and Horizon cmp (compares responses of two Horizon servers). diff --git a/docs/tools/developer-tools/security-tools.mdx b/docs/tools/developer-tools/security-tools.mdx index 307691d48..6254891ef 100644 --- a/docs/tools/developer-tools/security-tools.mdx +++ b/docs/tools/developer-tools/security-tools.mdx @@ -7,6 +7,6 @@ sidebar_position: 115 # Security Tools -### [Scout: Bug Fighter](https://www.coinfabrik.com/products/scout/) +### [Scout: Bug Fighter](https://www.coinfabrik.com/products/scout/) {#scout-bug-fighter} A static code analysis tool built to assist Soroban developers and auditors in identifying potential security threats and applying best practices. diff --git a/docs/tools/developer-tools/smart-contract-resources.mdx b/docs/tools/developer-tools/smart-contract-resources.mdx index d7ee8b36a..728f1b53a 100644 --- a/docs/tools/developer-tools/smart-contract-resources.mdx +++ b/docs/tools/developer-tools/smart-contract-resources.mdx @@ -7,18 +7,18 @@ sidebar_position: 120 # Smart Contract Resources -### [Keizai](https://keizai.dev/) +### [Keizai](https://keizai.dev/) {#keizai} Keizai is an open-source postman-inspired application, designed to simplify and elevate the testing process for developers working with Soroban smart contracts. -### [Soroban Copilot](https://github.com/mootz12/soroban-copilot) +### [Soroban Copilot](https://github.com/mootz12/soroban-copilot) {#soroban-copilot} A collection of no_std Rust packages focused on making Soroban development easier. -### [Soroban React](https://github.com/esteblock/soroban-react) +### [Soroban React](https://github.com/esteblock/soroban-react) {#soroban-react} A simple, powerful framework for building modern Soroban dapps using React. -### [Soroban Dev](https://sorobandev.com/) +### [Soroban Dev](https://sorobandev.com/) {#soroban-dev} A web developer's guide to Soroban. Contains guides for learning Soroban and Rust, developer tools, example applications, and more. diff --git a/docs/tools/developer-tools/wallets.mdx b/docs/tools/developer-tools/wallets.mdx index 3a5392547..f06cab618 100644 --- a/docs/tools/developer-tools/wallets.mdx +++ b/docs/tools/developer-tools/wallets.mdx @@ -7,18 +7,18 @@ sidebar_position: 130 # Wallets -### [Stellar Wallet Kit](https://github.com/Creit-Tech/Stellar-Wallets-Kit/) +### [Stellar Wallet Kit](https://github.com/Creit-Tech/Stellar-Wallets-Kit/) {#stellar-wallet-kit} A wallet kit to handle integration to multiple Stellar ecosystem wallets with a simple API. Learn more about how to integrate this library from [the Stellar Wallet Kit Docs](https://stellarwalletskit.dev/). -### [Account Viewer](https://accountviewer.stellar.org/) +### [Account Viewer](https://accountviewer.stellar.org/) {#account-viewer} A stripped-down wallet where you can check an account’s XLM balance and send simple payments on Testnet and Mainnet. -### [Albedo](https://albedo.link/) +### [Albedo](https://albedo.link/) {#albedo} A web-based wallet for Stellar transaction signing and identity verification. -### [Freighter](https://www.freighter.app/) +### [Freighter](https://www.freighter.app/) {#freighter} SDF’s flagship non-custodial wallet extension that allows users to sign Stellar transactions via their browser. diff --git a/docs/tools/sdks/build-your-own.mdx b/docs/tools/sdks/build-your-own.mdx index 5f5a5a308..41a784166 100644 --- a/docs/tools/sdks/build-your-own.mdx +++ b/docs/tools/sdks/build-your-own.mdx @@ -15,22 +15,22 @@ To build SDKs for other languages a few things need to be included in the SDK to Below is a list of functionality a Soroban SDK needs to support those things, as well as some details on what an SDK can provide in regards to testing capabilities. -## Functionality +## Functionality {#functionality} -### Value Conversions +### Value Conversions {#value-conversions} - [Val] encode/decode - [Object] encode/decode - [Symbol] encode/decode - [Error] encode/decode -### Host Functions +### Host Functions {#host-functions} The host functions defined in [env.json] are functions callable from within the Wasm Guest environment. These need to be available to contracts to call, in some form, ideally wrapped so that contracts have a nicer interface. Host functions have friendly names in the file above, such as `get_ledger_version`, however in the Wasm they are only importable via short names, such as `x.4`. The letter proceeding the dot is the module, and the value after the dot is the function name. The mappins are available in env.rs. -### SDK Types +### SDK Types {#sdk-types} All the types in [soroban-sdk](https://docs.rs/soroban-sdk) should be supported. Notably: @@ -38,43 +38,43 @@ All the types in [soroban-sdk](https://docs.rs/soroban-sdk) should be supported. - [Vec] - [Bytes] -### User Defined Types +### User Defined Types {#user-defined-types} Contracts should be able to create user defined types, such as structs, unions, or enums, and have them be transmitted to the host for storing and transmitted back for loading. SDKs do this by converting objects to and from a `Val`. In the [soroban-sdk] this is referred to as a [Val]. -#### Structs +#### Structs {#structs} Structs with named fields should be translated into a `Map` with keys as `Symbol`s and the values as the field value, i.e. `Map`. Structs with unnamed fields should be translated into a `Vec` with the values as the elements. i.e. `Vec`. -#### Unions +#### Unions {#unions} Unions (or enums in some languages) with named variants and unit or tuple values should be translated into a `Vec` with the first element as a `Symbol` of the name of the variant, and zero or more additional elements representing a value stored with the variant. -#### Enums +#### Enums {#enums} Enums with integer values should be translated into a `u32`. -### User Defined Errors +### User Defined Errors {#user-defined-errors} Errors are `u32` values that are translated into a [Error]. -### Environment Meta Generation +### Environment Meta Generation {#environment-meta-generation} Contracts must contain a Wasm custom section with name `contractenvmetav0` and containing a serialized [`SCEnvMetaEntry`]. The interface version stored within should match the version of the host functions supported. -### Contract Spec Generation +### Contract Spec Generation {#contract-spec-generation} Contracts should contain a Wasm custom section with name `contractspecv0` and containing a serialized stream of [`SCSpecEntry`]. There should be a `SCSpecEntry` for every function, struct, and union exported by the contract. -### Contract Meta Generation +### Contract Meta Generation {#contract-meta-generation} Contracts may optionally contain a Wasm custom section with name `contractmetav0` and containing a serialized [`SCMetaEntry`]. Contracts may store any metadata in the entries that can be used by applications and tooling off-network. -## Testing +## Testing {#testing} Any Soroban SDK ideally provides a test environment for executing contract functions in the context of a Soroban runtime environment. The [soroban-sdk] does this by embedding the Soroban environment Rust library, [soroban-env-host]. diff --git a/docs/tools/sdks/library.mdx b/docs/tools/sdks/library.mdx index f7684fa02..e2b4e50a9 100644 --- a/docs/tools/sdks/library.mdx +++ b/docs/tools/sdks/library.mdx @@ -7,7 +7,7 @@ Interact with the Stellar network using the SDK in your preferred language. The Each SDK has its own source code and documentation. Learn how to use a specific SDK by referring to the documentation- most docs offer practical examples that demonstrate how to construct and submit transactions and interact with Horizon endpoints. -### Soroban Rust SDK +### Soroban Rust SDK {#soroban-rust-sdk} [Rust SDK](https://github.com/stellar/rs-soroban-sdk) | [Docs](https://docs.rs/soroban-sdk) @@ -27,7 +27,7 @@ soroban-sdk = $VERSION soroban-sdk = { version = $VERSION, features = ["testutils"] } ``` -### AssemblyScript SDK +### AssemblyScript SDK {#assemblyscript-sdk} [AssemblyScript SDK](https://github.com/Soneso/as-soroban-sdk) @@ -35,7 +35,7 @@ The `as-soroban-sdk` is an open source SDK that supports writing programs for th The AssemblyScript Soroban SDK is maintained by dedicated community developer, Soneso. Report issues and share feedback [here](https://github.com/Soneso/as-soroban-sdk/issues/new). -### JavaScript SDK +### JavaScript SDK {#javascript-sdk} [JavaScript SDK](https://github.com/stellar/js-stellar-sdk) | [Docs](https://stellar.github.io/js-stellar-sdk/) | [NPM](https://www.npmjs.com/package/@stellar/stellar-sdk) @@ -46,7 +46,7 @@ It provides: - A networking layer API for Stellar RPC methods and the Horizon API. - Facilities for building and signing transactions, for communicating with an RPC instance, for communicating with a Horizon instance, and for submitting transactions or querying network state. -### Python SDK +### Python SDK {#python-sdk} [Python SDK](https://github.com/StellarCN/py-stellar-base) | [Docs](https://stellar-sdk.readthedocs.io/en/latest/) | [Examples](https://github.com/StellarCN/py-stellar-base/tree/master/examples) @@ -59,7 +59,7 @@ It provides: - A networking layer API for Horizon endpoints. - Facilities for building and signing transactions, for communicating with a Stellar Horizon instance, and for submitting transactions or querying network history. -### iOS SDK +### iOS SDK {#ios-sdk} [iOS SDK](https://github.com/Soneso/stellar-ios-mac-sdk) | [Docs](https://github.com/Soneso/stellar-ios-mac-sdk/tree/master/docs) | [Smart Contract Docs](https://github.com/Soneso/stellar-ios-mac-sdk/blob/master/soroban.md) @@ -67,7 +67,7 @@ The `stellar-ios-mac-sdk` is an open source Stellar SDK for iOS & Mac. It provid The iOS SDK is maintained by dedicated community developer, Soneso. -### Flutter SDK +### Flutter SDK {#flutter-sdk} [Flutter SDK](https://github.com/Soneso/stellar_flutter_sdk) | [Docs](https://github.com/Soneso/stellar_flutter_sdk/blob/master/soroban.md) @@ -75,7 +75,7 @@ The `stellar-flutter-sdk` is an open source Stellar SDK for Flutter developers. The Flutter Stellar SDK is maintained by dedicated community developer, Soneso. -### PHP SDK +### PHP SDK {#php-sdk} [PHP SDK](https://github.com/Soneso/stellar-php-sdk) | [Docs](https://github.com/Soneso/stellar-php-sdk/blob/main/soroban.md) @@ -83,37 +83,37 @@ The `stellar-php-sdk` is an open source Stellar SDK for PHP developers. It provi The PHP Stellar SDK is maintained by dedicated community developer, Soneso. -### Elixir SDK +### Elixir SDK {#elixir-sdk} [Soroban Elixir SDK](https://github.com/kommitters/soroban.ex) & [Docs](https://github.com/kommitters/soroban.ex#documentation)| [Stellar Elixir SDK](https://github.com/kommitters/stellar_sdk) & [Docs](https://hexdocs.pm/stellar_sdk/readme.html#documentation) | [Examples](https://github.com/kommitters/stellar_sdk/tree/main/docs) This SDK is maintained by dedicated community developers, kommitters Open Source. -### Java SDK +### Java SDK {#java-sdk} [Java SDK](https://github.com/lightsail-network/java-stellar-sdk) | [Docs](https://lightsail-network.github.io/java-stellar-sdk/) `java-stellar-sdk` provides APIs to build transactions and connect to Horizon and also provides functionality to deploy and invoke Soroban smart contracts and communicates with the Stellar RPC Server. -### Go +### Go {#go} This SDK is split up into separate packages, all of which you can find in the [Go monorepo README](https://github.com/stellar/go/blob/master/docs/reference/readme.md). The two key libraries for interacting with Horizon are `txnbuild`, which enables the construction, signing, and encoding of Stellar transactions, and `horizonclient`, which provides a web client for interfacing with Horizon server REST endpoints to retrieve ledger information and submit transactions built with `txnbuild`. - txnbuild: [SDK](https://github.com/stellar/go/tree/master/txnbuild) | [Docs](https://godoc.org/github.com/stellar/go/txnbuild) - Horizonclient: [SDK](https://github.com/stellar/go/tree/master/clients/horizonclient) | [Docs](https://godoc.org/github.com/stellar/go/clients/horizonclient) -### Ruby +### Ruby {#ruby} [Ruby SDK](https://github.com/astroband/ruby-stellar-sdk) | [Base Source](https://github.com/astroband/ruby-stellar-sdk/blob/master/base/README.md) | [SDK Source](https://github.com/astroband/ruby-stellar-sdk/blob/master/sdk/README.md) | [Docs](https://www.rubydoc.info/gems/stellar-sdk) | [Base Examples](https://github.com/astroband/ruby-stellar-sdk/tree/master/base/examples) | [SDK Examples](https://github.com/astroband/ruby-stellar-sdk/tree/master/sdk/examples) -### C# .NET +### C# .NET {#c-net} [C# .NET SDK](https://github.com/Beans-BV/dotnet-stellar-sdk) | [Docs](https://elucidsoft.github.io/dotnet-stellar-sdk/) -### Scala +### Scala {#scala} [Scala SDK](https://github.com/Synesso/scala-stellar-sdk) | [Docs](https://synesso.github.io/scala-stellar-sdk/) -### Qt/C++ +### Qt/C++ {#qtc} [Qt/C++ SDK](https://github.com/bnogalm/StellarQtSDK) | [Docs](https://github.com/bnogalm/StellarQtSDK/wiki) diff --git a/docs/validators/README.mdx b/docs/validators/README.mdx index 848b0f179..2671c23bb 100644 --- a/docs/validators/README.mdx +++ b/docs/validators/README.mdx @@ -16,11 +16,11 @@ If you are interested in Horizon or RPC nodes, please explore those docs. If you are interested in running a validator node — because you issue an asset that you would like to help secure through transaction validation, because you want to help increase network health and decentralization, or because you want to participate in network governance — then this section of the docs is for you. It explains the technical and operational aspects of installing, configuring, and maintaining a Stellar Core validator node, and should help you figure out the best way to set up your Stellar integration. -## Node Setup Process +## Node Setup Process {#node-setup-process} The basic flow, which you can navigate through using the "Admin Guide" on the left, goes (roughly) like this: -### Initial Setup +### Initial Setup {#initial-setup} 1. Use the information on this _Introduction_ page to determine which [type of node](#types-of-nodes) you want to run. 2. [Prerequisite](./admin-guide/prerequisites.mdx) software must be installed (and configured according to your needs). @@ -30,13 +30,13 @@ The basic flow, which you can navigate through using the "Admin Guide" on the le 6. [Start your node](./admin-guide/running-node.mdx) and join the network. 7. [Logging](./admin-guide/logging.mdx) and [monitoring](./admin-guide/monitoring.mdx) should be appropriately set up and used to meet your needs. -### Ongoing Requirements +### Ongoing Requirements {#ongoing-requirements} 8. [Maintenance](./admin-guide/maintenance.mdx) is required from time to time to keep your node up-to-date and participating in the network. 9. [Network upgrades](./admin-guide/network-upgrades.mdx) require validator consensus, and you will need to consider casting a vote in the event of a protocol upgrade. 10. [Soroban settings](./admin-guide/soroban-settings.mdx) are network-wide, configurable, and changes can be proposed by anyone. Similar to protocol upgrades, changes to these settings will require validator consensus, so you should be prepared to participate. -### Other Information +### Other Information {#other-information} - Stellar Core uses a robust [command line](./admin-guide/commands.mdx) tool to control and operate a node. We've gathered information on some of the most-used commands, and linked to further, more comprehensive CLI documentation. - We've collected some miscellaneous helpful and [advanced](./admin-guide/advanced.mdx) information that could be useful as you understand and implement your core node. @@ -53,17 +53,17 @@ This architecture was **deprecated** as of [Horizon 2.0](https://www.stellar.org -### Basic Validator +### Basic Validator {#basic-validator} -#### Validating, no public archive +#### Validating, no public archive {#validating-no-public-archive} A Basic Validator keeps track of the ledger and submits transactions for possible inclusion, but it is _not_ configured to publish history archives. It does require a secret key, and is [configured to participate in consensus](./admin-guide/configuring.mdx#validating-node) by voting on — and signing off on — changes to the ledger, meaning it supports the network and increases decentralization. The advantage: signatures can serve as official endorsements of specific ledgers in real time. That’s important if, for instance, you issue an asset on Stellar that represents a real-world asset: you can let your customers know that you will only honor transactions and redeem assets from ledgers signed by your validator, and in the unlikely scenario that something happens to the network, you can use your node as the final arbiter of truth. Setting up your node as a validator allows you to resolve any questions _up front and in writing_ about how you plan to deal with disasters and disputes. -### Full Validator +### Full Validator {#full-validator} -#### Validating, offers public archive +#### Validating, offers public archive {#validating-offers-public-archive} A Full Validator is the same as a Basic Validator except that it also publishes a [History Archive](./admin-guide/environment-preparation.mdx) containing snapshots of the ledger, including all transactions and their results. A Full Validator writes to an internet-facing blob store — such as AWS or Azure — so it's a bit more expensive and complex to run, but it also does the most to support the network’s resilience and decentralization. diff --git a/docs/validators/admin-guide/advanced.mdx b/docs/validators/admin-guide/advanced.mdx index a681feb3d..3256fe508 100644 --- a/docs/validators/admin-guide/advanced.mdx +++ b/docs/validators/admin-guide/advanced.mdx @@ -5,11 +5,11 @@ sidebar_position: 130 This page contains information that is useful to know but that should not stop somebody from running a node. -## Creating Your Own Private Network +## Creating Your Own Private Network {#creating-your-own-private-network} The [stellar-core GitHub repository] holds [a `testnet.md` file] which contains a short tutorial demonstrating how to configure and run a short-lived, isolated test network. -## Runtime Information: Start and Stop +## Runtime Information: Start and Stop {#runtime-information-start-and-stop} Stellar-core can be started directly from the command line, or through a supervision system such as `init`, `upstart`, or `systemd`. @@ -17,11 +17,11 @@ Stellar-core can be gracefully exited at any time by delivering `SIGINT` or pres Stellar-core can also be packaged in a container system such as Docker, so long as `BUCKET_DIR_PATH` and the database are stored on persistent volumes. For an example, see [`stellar/quickstart`]. -## In-depth Architecture +## In-depth Architecture {#in-depth-architecture} The [stellar-core GitHub repository] also contains [the `architecture.md` file], which describes how stellar-core is structured internally, how it is intended to be deployed, and the collection of servers and services needed to get the full functionality and performance. -## Reproducible Performance Testing With Stellar Supercluster +## Reproducible Performance Testing With Stellar Supercluster {#reproducible-performance-testing-with-stellar-supercluster} [Stellar Supercluster] is a tool that enables running simulated networks of stellar-core nodes on Kubernetes clusters. One use case for Supercluster is running reproducible performance tests. The Supercluster GitHub repository contains a few documents to help users run theoretical maximum Transaction Per Second (TPS) tests: @@ -29,7 +29,7 @@ The [stellar-core GitHub repository] also contains [the `architecture.md` file], - [`doc/eks.md`] details how to build a supercluster-compatible EKS cluster on AWS. - [`doc/theoretical-max-tps.md`] explains how to run the theoretical max TPS test on an EKS cluster. It also contains a table of results from SDF's own theoretical max TPS runs, as well as the configurations used to achieve those results. -### Other Supercluster Resources +### Other Supercluster Resources {#other-supercluster-resources} Supercluster is useful beyond reproducible performance testing. Some helpful resources to learn more about Supercluster include: diff --git a/docs/validators/admin-guide/commands.mdx b/docs/validators/admin-guide/commands.mdx index ed5eb7b07..d15ba895c 100644 --- a/docs/validators/admin-guide/commands.mdx +++ b/docs/validators/admin-guide/commands.mdx @@ -15,7 +15,7 @@ Additionally, while the commands on this page are _CLI_ commands, there is an ad -## Get `--help` Anywhere +## Get `--help` Anywhere {#get---help-anywhere} The `--help` (aliases: `-h` or `-?`) option can be specified at _any place_ in the command line. It will show you the help message for the relevant command. Some example useage is as follows: @@ -26,23 +26,23 @@ stellar-core --help new-db stellar-core catchup --help ``` -## Essential Commands +## Essential Commands {#essential-commands} For all stellar-core commands, options can _only_ by placed after the command. -### `new-db` +### `new-db` {#new-db} The **`new-db`** command creates or restores the local database to the genesis ledger. -#### `new-db` Options +#### `new-db` Options {#new-db-options} - `--minimal-for-in-memory-mode`: Reset the special database used only for in-memory mode. (see the `--in-memory` flag in [`run` options](#run-options)) -### `run` +### `run` {#run} The **`run`** command will run the `stellar-core` node. -#### `run` Options +#### `run` Options {#run-options} - `--disable-bucket-gc`: Keeps all, even old, buckets on disk. - `--metadata-output-stream `: Filename or file-descriptor number `fd:N` to stream metadata to. @@ -50,11 +50,11 @@ The **`run`** command will run the `stellar-core` node. Certain features, such as `in-memory` mode options, have been deprecated, so they aren't listed here. -### `catchup` +### `catchup` {#catchup} The **`catchup`** command will execute a catchup from history archives without connecting to the network. -#### `catchup` Options +#### `catchup` Options {#catchup-options} - ``: (required) Destination ledger is any valid number or `current` and ledger count is any valid number or `max`. - `--archive `: Archive name to be used for catchup. Use `any` to select randomly. diff --git a/docs/validators/admin-guide/configuring.mdx b/docs/validators/admin-guide/configuring.mdx index af49e996e..580072ec9 100644 --- a/docs/validators/admin-guide/configuring.mdx +++ b/docs/validators/admin-guide/configuring.mdx @@ -11,7 +11,7 @@ Before attempting to configure stellar-core, it is highly recommended to first t -## Configuration Basics +## Configuration Basics {#configuration-basics} After you've [installed](./installation.mdx) Stellar Core, your next step is to complete a configuration file that specifies crucial things about your node — like whether it connects to the Testnet or the Mainnet public network, what database it writes to, and which other nodes are in its [quorum set](#choosing-your-quorum-set). @@ -31,7 +31,7 @@ This page attempts (as strictly as is possible) to focus on the specific fields -### Example Configurations +### Example Configurations {#example-configurations} While we're looking at some of the config basics on this page, we've written this content to work best in conjunction with concrete config examples, so as you read through it, you may want to review the following: @@ -43,7 +43,7 @@ While we're looking at some of the config basics on this page, we've written thi Auditing of the P2P network is enabled by default, see the [overlay topology](./monitoring.mdx#overlay-topology-survey) section for more detail if you'd like to disable it -### Network Passphrase +### Network Passphrase {#network-passphrase} Use the `NETWORK_PASSPHRASE` field to specify whether your node connects to the Testnet or the Mainnet [network](../../learn/fundamentals/networks.mdx). @@ -52,15 +52,15 @@ Use the `NETWORK_PASSPHRASE` field to specify whether your node connects to the For more about the Network Passphrase and how it works, check out the [encyclopedia entry](../../learn/encyclopedia/network-configuration/network-passphrases.mdx). -### Database +### Database {#database} You specify your node's database by using the aptly named `DATABASE` field of your config file, which you can can read more about in the [complete example config][complete-example-database]. It defaults to an in-memory database, but you can specify a path as per the example. -### Buckets +### Buckets {#buckets} The flat XDR files of Stellar Core are placed in a directory specified in the config file as `BUCKET_DIR_PATH`, which defaults to `buckets`. -## Validating Node +## Validating Node {#validating-node} :::note @@ -102,7 +102,7 @@ If you run multiple validators, make sure to set a common `HOME_DOMAIN` for them If you want other validators to add your node to their quorum sets, you should also share your public key (`GDMTUTQ...`) by publishing a `stellar.toml` file on your home domain following specifications laid out by [SEP-20]. -## Choosing Your Quorum Set +## Choosing Your Quorum Set {#choosing-your-quorum-set} To create your quorum set, Stellar Core relies on two arrays of tables: `[[HOME_DOMAINS]]` and `[[VALIDATORS]]`. Check out the example config's [`HOME_DOMAINS` array] and [`VALIDATORS` array] to see them in action. @@ -130,7 +130,7 @@ To generate a quorum set, stellar core: While this does not absolve you of all responsibility — you still need to pick trustworthy validators and keep an eye on them to ensure that they're consistent and reliable — it does make your life easier and reduces the chances for human error. -### Validator Discovery +### Validator Discovery {#validator-discovery} When you add a validating node to your quorum set, it's generally because you trust the _organization_ running the node: you trust SDF, not some anonymous Stellar public key. @@ -140,7 +140,7 @@ As a result of that link, you can look up a node by its Stellar public key and c When you look at that list, you will discover that the most reliable organizations actually run more than one validator, and adding all of an organization's nodes to your quorum set creates the redundancy necessary to sustain arbitrary node failure. When an organization with a trio of nodes takes one down for maintenance, for instance, the remaining two nodes vote on the organization's behalf, and the organization's network presence persists. -### Home Domains Array +### Home Domains Array {#home-domains-array} `[[HOME_DOMAINS]]` defines a superset of validators: when you add nodes hosted by the same organization to your configuration, they share a home domain, and the information in the `[[HOME_DOMAINS]]` table, specifically the quality rating, will automatically apply to every one of those validators. @@ -163,7 +163,7 @@ HOME_DOMAIN="some-other-domain" QUALITY="LOW" ``` -### Validators Array +### Validators Array {#validators-array} For each node you would like to add to your quorum set, complete a `[[VALIDATORS]]` table with the following fields: @@ -209,11 +209,11 @@ Your quorum set is automatically configured based on the information you provide ::: -### Validator Quality +### Validator Quality {#validator-quality} `QUALITY` is a required field for each node you add to your quorum set. Whether you specify it for a suite of nodes in a `[[HOME_DOMAINS]]` table, or for a single node in a `[[VALIDATORS]]` table, it means the same thing, and you have the same three rating options: `HIGH`, `MEDIUM`, or `LOW`. -#### HIGH Quality +#### HIGH Quality {#high-quality} **HIGH** quality validators are given the most weight in automatic quorum set configuration. Before assigning a high quality rating to a node, make sure it has low latency and good uptime, and that the organization running the node is reliable and trustworthy. @@ -224,15 +224,15 @@ A high quality validator: Choosing redundant nodes is good practice. The archive requirement is programmatically enforced. -#### MEDIUM Quality +#### MEDIUM Quality {#medium-quality} **MEDIUM** quality validators are nested below high quality validators, and their combined weight is equivalent to a _single high quality entity_. If a node doesn't publish an archive, but you deem it reliable, or have an organizational interest in including it in your quorum set, give it a medium quality rating. -#### LOW Quality +#### LOW Quality {#low-quality} **LOW** quality validators are nested below medium quality validators, and their combined weight is equivalent to a _single medium quality entity_. Should they prove reliable over time, you can upgrade their rating to medium to give them a bigger role in your quorum set configuration. -### Automatic Quorum Set Generation +### Automatic Quorum Set Generation {#automatic-quorum-set-generation} :::info Important Note @@ -253,7 +253,7 @@ Once you add validators to your configuration, stellar core automatically genera _Diagram: Depiction of the nested quality levels and how they interact._ -### Quorum and Overlay Network +### Quorum and Overlay Network {#quorum-and-overlay-network} In order to get in sync and run consensus, your validator needs to be able to connect to the Stellar Network. In most cases, it is sufficient to simply rely on node's built-in peer discovery. However, your validator can be configured to connect to specific peers via `KNOWN_PEERS` and `PREFERRED_PEERS` in the config file. These can be either domain names or IPs. This can be useful for troubleshooting. @@ -261,7 +261,7 @@ Additionally, configuring `PREFERRED_PEER_KEYS` with the keys from your quorum s Without those settings, your validator depends on other nodes on the network to forward you the right messages, which is typically done as a best effort. -### Impact of Validator Quality on Nomination +### Impact of Validator Quality on Nomination {#impact-of-validator-quality-on-nomination} The Stellar Consensus Protocol uses validator quality levels in determining which validator should nominate the next transaction set for inclusion in a ledger. This process of choosing the validator that will nominate the next transaction set is called _leader election_. To start, the leader election algorithm assigns organizations and validators weights as follows: @@ -278,7 +278,7 @@ The leader election algorithm then assigns each validator a probability of winni 1. Higher quality organizations have a greater chance of winning leader election than lower quality organizations. 2. Organizations of equal quality have an equal chance of winning leader election. -#### Validator Nomination Weight Example +#### Validator Nomination Weight Example {#validator-nomination-weight-example} Let there be 3 `HIGH` quality organizations, 2 `MEDIUM` quality organizations, and 1 `LOW` quality organization. The weight of each organization is as follows: diff --git a/docs/validators/admin-guide/environment-preparation.mdx b/docs/validators/admin-guide/environment-preparation.mdx index 9c0aaa9ab..b3fce1e46 100644 --- a/docs/validators/admin-guide/environment-preparation.mdx +++ b/docs/validators/admin-guide/environment-preparation.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { Alert } from "@site/src/components/Alert"; -## Initialize the Database and Local State +## Initialize the Database and Local State {#initialize-the-database-and-local-state} After configuring your [database](./configuring.mdx#database) and [buckets](./configuring.mdx#buckets) settings, before running Stellar Core for the first time, you must initialize the database: @@ -15,7 +15,7 @@ stellar-core new-db This command will initialize the database, as well as the bucket directory, and then exit. You can also use this command if your database gets corrupted and you want to restart it from scratch. -### Automatic Maintenance +### Automatic Maintenance {#automatic-maintenance} Some tables in stellar-core are used to publish ledger data to history archives. @@ -35,7 +35,7 @@ If this happens, database performance can be restored. The node will require som 1. run the `maintenance` http command manually with a large number of ledgers, and 2. perform a database maintenance operation such as `VACUUM FULL` to reclaim/rebuild the database as needed. -### Metadata Snapshots and Restoration +### Metadata Snapshots and Restoration {#metadata-snapshots-and-restoration} Some deployments of Stellar Core and Horizon will want to retain metadata for the _entire history_ of the network. This metadata can be quite large and computationally expensive to regenerate anew by replaying ledgers in stellar-core from an empty initial database state, as described in the previous section. @@ -51,13 +51,13 @@ Some operators therefore prefer to shut down their stellar-core (and/or Horizon) Any reasonably recent state will do — if such a snapshot is a little old, stellar-core will replay ledgers from whenever the snapshot was taken to the current network state anyways — but this procedure can greatly accelerate restoring validator nodes, or cloning them to create new ones. -## History Archives +## History Archives {#history-archives} Stellar Core normally interacts with one or more history archives, which are configurable facilities where [Full Validators](../README.mdx#full-validator) store flat files containing history checkpoints: bucket files and history logs. History archives are usually off-site commodity storage services such as Amazon S3, Google Cloud Storage, Azure Blob Storage, or custom SCP/SFTP/HTTP servers. Use command templates in the config file to give the specifics of which services you will use and how to access them. The [example config] will demonstrate how to configure a history archive through command templates. -### Configuring to Get Data from an Archive +### Configuring to Get Data from an Archive {#configuring-to-get-data-from-an-archive} No matter what kind of node you're running, you should configure it to `get` history from one or more public archives. You can configure any number of archives to download from: Stellar Core will automatically round-robin between them. @@ -69,7 +69,7 @@ If you notice a lot of errors related to downloading archives, you should ensure ::: -### Configuring to Publish Data to an Archive +### Configuring to Publish Data to an Archive {#configuring-to-publish-data-to-an-archive} Archive sections can also be configured with `put` and `mkdir` commands to cause the instance to publish to that archive (for nodes configured as [full validators](../README.mdx#full-validator)). @@ -89,7 +89,7 @@ More detailed guidance and strategies for publishing history archives can be fou ::: -## Other Preparation +## Other Preparation {#other-preparation} In addition, your should ensure that your operating environment is also functional. This means you will have considered and prepared the following. diff --git a/docs/validators/admin-guide/installation.mdx b/docs/validators/admin-guide/installation.mdx index 3df480a67..c11c4afa7 100644 --- a/docs/validators/admin-guide/installation.mdx +++ b/docs/validators/admin-guide/installation.mdx @@ -13,7 +13,7 @@ There are three common ways to install and run Stellar Core: 3. **Use a [Docker image](#docker-based-installation).** Using a Docker image is the quickest and easiest method, so it's a good choice for a lot of developers. -## Release Version +## Release Version {#release-version} Whichever method you use, you should make sure to install the latest [release](https://github.com/stellar/stellar-core/releases) since these builds are backwards compatible and are cumulative. @@ -23,19 +23,19 @@ The version number scheme that we follow is `protocol_version.release_number.pat - `release_number` is bumped when a set of new features or bug fixes not impacting the protocol are included in the release, and - `patch_number` is used when a critical fix has to be deployed. -## Package-Based Installation +## Package-Based Installation {#package-based-installation} If you are using a recent LTS version of Ubuntu, we provide the latest stable releases of [`stellar-core`](https://github.com/stellar/stellar-core) and [`stellar-horizon`](https://github.com/stellar/go/tree/master/services/horizon) in Debian binary package format. You may choose to install these packages individually, which offers the greatest flexibility, but requires **manual** creation of the relevant configuration files and configuration of a **PostgreSQL** database. -## Installing From Source +## Installing From Source {#installing-from-source} The Stellar Core source code repository contains extensive and thorough instructions to build the software from source. Please [check out `INSTALL.md`](https://github.com/stellar/stellar-core/blob/master/INSTALL.md) for more information. -## Docker-Based Installation +## Docker-Based Installation {#docker-based-installation} -### Development Environments +### Development Environments {#development-environments} SDF maintains a [quickstart image](https://github.com/stellar/quickstart) that bundles Stellar's "Captive Core" with Horizon and the necessary PostgreSQL databases. It's a quick way to set up a default, non-validating, ephemeral configuration that should work for most developers. Additionally, the quickstart image can be spun up pre-configured for use as a Mainnet, Testnet, Futurenet, or Local network node. @@ -45,7 +45,7 @@ The quickstart image is not intended to serve as a production-level instance nod -### Production Environments +### Production Environments {#production-environments} SDF also maintains a Stellar-Core-only standalone image, [`stellar/stellar-core`](https://hub.docker.com/r/stellar/stellar-core). diff --git a/docs/validators/admin-guide/maintenance.mdx b/docs/validators/admin-guide/maintenance.mdx index 135b89934..6f454254d 100644 --- a/docs/validators/admin-guide/maintenance.mdx +++ b/docs/validators/admin-guide/maintenance.mdx @@ -13,7 +13,7 @@ If you are changing some settings that may impact network wide settings such as If you're changing your quorum set configuration, also read the [section on what to do](#special-considerations-during-quorum-set-updates). -## Recommended Steps to Perform as Part of a Maintenance +## Recommended Steps to Perform as Part of a Maintenance {#recommended-steps-to-perform-as-part-of-a-maintenance} We recommend performing the following steps in order (repeat sequentially as needed if you run multiple nodes). @@ -23,7 +23,7 @@ We recommend performing the following steps in order (repeat sequentially as nee 4. When done, start your instance that should rejoin the network 5. The instance will be completely caught up when it's both `Synced` and _there is no backlog in uploading history_. -## Special Considerations During Quorum Set Updates +## Special Considerations During Quorum Set Updates {#special-considerations-during-quorum-set-updates} When you join the ranks of node operators, it's also important to join the conversation. The best way to do that: follow the`#validators` channel on the [Stellar Developer Discord](https://discord.gg/stellardev). If you can't do that for some reason, sign up for the [Stellar Validators Google Group](https://groups.google.com/forum/#!forum/stellar-validators). diff --git a/docs/validators/admin-guide/monitoring.mdx b/docs/validators/admin-guide/monitoring.mdx index 1c063e9be..7867cf715 100644 --- a/docs/validators/admin-guide/monitoring.mdx +++ b/docs/validators/admin-guide/monitoring.mdx @@ -17,7 +17,7 @@ You can access this information using commands and inspecting Stellar Core's out However you decide to monitor, the most important thing is that you have a system in place to ensure that your integration keeps ticking. -## General Node Information +## General Node Information {#general-node-information} If you run `$ stellar-core http-command 'info'`, the output will look something like this: @@ -83,7 +83,7 @@ Some notable fields from this `info` endpoint are: - `state`: the node's synchronization status relative to the network - `quorum`: summary of the state of the SCP protocol participants, which is the same information returned by the `quorum` command ([see below](#quorum-health)). -## Peer Information +## Peer Information {#peer-information} The `peers` command returns information on the peers your node is connected to. @@ -167,7 +167,7 @@ The output will look something like: } ``` -## Overlay Topology Survey +## Overlay Topology Survey {#overlay-topology-survey} There is a survey mechanism in the overlay that allows a validator to request connection information from other nodes on the network. The survey can be triggered from a validator, and will flood through the network like any other message, but will request information from other nodes about which nodes it is connected to and a brief summary of their per-connection traffic volumes. @@ -181,7 +181,7 @@ Additionally, the "stop/start collecting" messages contain a `nonce` field ident During the reporting phase, the surveyor sends `TimeSlicedSurveyRequestMessage`s to individual nodes to gather the information the node recorded during the collecting phase. -### Overlay Survey Script +### Overlay Survey Script {#overlay-survey-script} To simplify running an overlay survey, stellar-core ships with a script [`OverlaySurvey.py`](https://github.com/stellar/stellar-core/blob/master/scripts/OverlaySurvey.py) in the [`scripts` directory](https://github.com/stellar/stellar-core/tree/master/scripts). This script walks the network using the overlay survey HTTP endpoints to build a graph containing the topology of the overlay network. The script outputs this graph both in JSON format, as well as GraphML. You can analyze the GraphML file using a GraphML viewer such as [Gephi](https://gephi.org/). @@ -201,7 +201,7 @@ The arguments this example uses are: Therefore, this example will run a survey from a stellar-core node running on the local machine with a collecting phase duration of 20 minutes and output the results to `sr.json` and `gmlw.graphml`. -#### Attaching to a Running Survey +#### Attaching to a Running Survey {#attaching-to-a-running-survey} Use the `--startPhase` option to attach the script to an already running survey. This may be necessary if something happened during the running of the script that caused the script to terminate early (such as losing connection with the surveyor node). `--startPhase` has three possible values: @@ -209,7 +209,7 @@ Use the `--startPhase` option to attach the script to an already running survey. - `stopCollecting`: Immediately broadcast a `TimeSlicedSurveyStopCollectingMessage` for the currently running survey and begin surveying individual nodes for results. Use this option if your survey is currently in the collecting phase and you'd like to move it to the reporting phase. - `surveyResults`: Begin surveying individual nodes for results. Use this option if your survey is in the reporting phase. -#### More Survey Script Options +#### More Survey Script Options {#more-survey-script-options} The survey script contains additional subcommands and options to further analyze the survey results. You can find a complete list of subcommands by running: @@ -225,7 +225,7 @@ $ python3 OverlaySurvey.py -h for more info about any given subcommand. -### Example Survey Command Using HTTP Endpoints +### Example Survey Command Using HTTP Endpoints {#example-survey-command-using-http-endpoints} This section walks through an example of running an overlay survey by calling the survey HTTP endpoints directly. We highly recommend using the overlay survey script instead. This section may be useful to anyone who wants to modify the survey script, or anyone who is curious about the lower-level details of how the survey works and the data it includes. @@ -339,11 +339,11 @@ Some notable fields from this `getsurveyresult` endpoint are: - `lostSyncCount`: The number of times this node lost sync. - `isValidator`: Is this node a validator? -## Quorum Health +## Quorum Health {#quorum-health} To help node operators monitor their quorum sets and maintain the health of the overall network, Stellar Core also provides metrics on other nodes in your quorum set. You should monitor them to make sure they're up and running, and that your quorum set is maintaining good overlap with the rest of the network. -### Quorum Set Diagnostics +### Quorum Set Diagnostics {#quorum-set-diagnostics} The `quorum` command allows you to diagnose problems with the quorum set of the local node. @@ -402,7 +402,7 @@ The output will look something like: This output has two main sections: `qset` and `transitive`. The former describes the node and its quorum set. The latter describes the transitive closure of the node's quorum set. -### Per-node Quorum-set Information +### Per-node Quorum-set Information {#per-node-quorum-set-information} Entries to watch for in the `qset` section, which describe the node and its quorum set, are: @@ -436,7 +436,7 @@ stellar-core http-command 'quorum?node=@GABCDE' Overall network health can be evaluated by walking through all nodes and looking at their health. Note that this is only an approximation, as remote nodes may not have received the same messages (in particular: `missing` for other nodes is not reliable). -### Transitive Closure Summary Information +### Transitive Closure Summary Information {#transitive-closure-summary-information} When showing quorum-set information about the local node rather than some other node, a summary of the transitive closure of the quorum set is also provided in the `transitive` field. This has several important sub-fields: @@ -447,7 +447,7 @@ When showing quorum-set information about the local node rather than some other - `potential_split`: this will contain a pair of lists of validator IDs, which is a potential pair of disjoint quorums allowed by the current configuration. In other words, a possible split in consensus allowed by the current configuration. This may help narrow down the cause of the misconfiguration: likely it involves too-low a consensus threshold in one of the two potential quorums, and/or the absence of a mandatory trust relationship that would bridge the two. - `critical`: an "advance warning" field that lists nodes that _could cause_ the network to fail to enjoy quorum intersection, if they were misconfigured sufficiently badly. In a healthy transitive network configuration, this field will be `null`. If it is non-`null` then the network is essentially "one misconfiguration" (of the quorum sets of the listed nodes) away from no longer enjoying quorum intersection, and again, corrective action should be taken: careful adjustment to the quorum sets of _nodes that depend on_ the listed nodes, typically to strengthen quorums that depend on them. -### Detailed Transitive Quorum Analysis +### Detailed Transitive Quorum Analysis {#detailed-transitive-quorum-analysis} The quorum endpoint can also retrieve detailed information about the transitive quorum. This is a format that's easier to process than what `scp` returns, as it doesn't contain all SCP messages. @@ -528,17 +528,17 @@ Notable fields contained in this response are: - `value_id`: a unique ID for what the node is voting for (allows you to quickly tell if nodes are voting for the same thing) - `value`: what the node is voting for -## Using Prometheus +## Using Prometheus {#using-prometheus} Monitoring `stellar-core` using Prometheus is by far the simplest solution, especially if you already have a Prometheus server within your infrastructure. Prometheus is a free and open source time-series database with a simple yet incredibly powerful query language `PromQL`. Prometheus is also tightly integrated with Grafana, so you can render complex visualisations with ease. In order for Prometheus to scrape `stellar-core` application metrics, you will need to install the stellar-core-prometheus-exporter (`apt-get install stellar-core-prometheus-exporter`) and configure your Prometheus server to scrape this exporter (default port: `9473`). On top of that grafana can be used to visualize metrics. -### Install a Prometheus Server Within your Infrastructure +### Install a Prometheus Server Within your Infrastructure {#install-a-prometheus-server-within-your-infrastructure} Installing and configuring a Prometheus server is out of scope of this document, however it is a fairly simple process: Prometheus is a single Go binary which you can download from https://prometheus.io/docs/prometheus/latest/installation/. -### Install the `stellar-core-prometheus-exporter` +### Install the `stellar-core-prometheus-exporter` {#install-the-stellar-core-prometheus-exporter} The stellar-core-prometheus-exporter is an exporter that scrapes the `stellar-core` metrics endpoint (`http://localhost:11626/metrics`) and renders these metrics in the Prometheus text-based format available for Prometheus to scrape and store in its time series database. @@ -550,11 +550,11 @@ apt-get install stellar-core-prometheus-exporter You will need to open up port `9473` between your Prometheus server and all your Stellar Core nodes for your Prometheus server to be able to scrape metrics. -### Point Prometheus to stellar-core-prometheus-exporter +### Point Prometheus to stellar-core-prometheus-exporter {#point-prometheus-to-stellar-core-prometheus-exporter} Pointing your Prometheus instance to the exporter can be achieved by manually configuring a scrape job; however, depending on the number of hosts you need to monitor this can quickly become unwieldy. Luckily, the process can also be automated using Prometheus' various "service discovery" plugins. For example with AWS hosted instance you can use the `ec2_sd_config` plugin. -#### Manual +#### Manual {#manual} ```yaml - job_name: "stellar-core" @@ -569,7 +569,7 @@ Pointing your Prometheus instance to the exporter can be achieved by manually co application: "stellar-core" ``` -#### Using Service Discovery (EC2) +#### Using Service Discovery (EC2) {#using-service-discovery-ec2} ```yaml - job_name: stellar-core @@ -601,7 +601,7 @@ Pointing your Prometheus instance to the exporter can be achieved by manually co target_label: application ``` -### Create Alerting Rules +### Create Alerting Rules {#create-alerting-rules} Once Prometheus scrapes metrics we can add alerting rules. Recommended rules are [**here**](https://github.com/stellar/packages/blob/master/docs/stellar-core-alerting.rules) (require Prometheus 2.0 or later). Copy rules to _/etc/prometheus/stellar-core-alerting.rules_ on the Prometheus server and add the following to the prometheus configuration file to include the file: @@ -612,7 +612,7 @@ rule_files: Rules are documented in-line,and we strongly recommend that you review and verify all of them as every environment is different. -### Configure Notifications Using Alertmanager +### Configure Notifications Using Alertmanager {#configure-notifications-using-alertmanager} Alertmanager is responsible for sending notifications. Installing and configuring an Alertmanager server is out of scope of this document, however it is a fairly simple process. Official documentation is [here](https://github.com/prometheus/alertmanager/). @@ -654,14 +654,14 @@ receivers: In the above examples alerts with severity "critical" are sent to pagerduty and warnings are sent to slack. -### Useful Exporters +### Useful Exporters {#useful-exporters} You may find the below exporters useful for monitoring your infrastructure as they provide incredible insight into your operating system and database metrics. Installing and configuring these exporters is out of the scope of this document but should be relatively straightforward. - [node_exporter](https://prometheus.io/docs/guides/node-exporter/) can be used to track all operating system metrics. - [postgresql_exporter](https://github.com/wrouesnel/postgres_exporter) can be used to monitor the local stellar-core database. -### Visualize Metrics Using Grafana +### Visualize Metrics Using Grafana {#visualize-metrics-using-grafana} Once you've configured Prometheus to scrape and store your stellar-core metrics, you will want a nice way to render this data for human consumption. Grafana offers the simplest and most effective way to achieve this. Installing Grafana is out of scope of this document but is a very simple process, especially when using the [prebuilt apt packages](https://grafana.com/docs/installation/debian/#apt-repository) diff --git a/docs/validators/admin-guide/network-upgrades.mdx b/docs/validators/admin-guide/network-upgrades.mdx index 86a3e6556..a7f650c0c 100644 --- a/docs/validators/admin-guide/network-upgrades.mdx +++ b/docs/validators/admin-guide/network-upgrades.mdx @@ -23,7 +23,7 @@ When a validator is armed to change network values, the output of `info` will co For a new value to be adopted, the same level of consensus between nodes needs to be reached as for transaction sets. -## Important Notes on Network Wide Settings +## Important Notes on Network Wide Settings {#important-notes-on-network-wide-settings} Changes to network wide settings have to be orchestrated properly between validators as well as non validating nodes. The general process validators have used to propose and vote on network settings is as follows: @@ -38,7 +38,7 @@ This careful orchestration plays an important part in the Stellar network's func For more information, take a look at how versioning takes into account network upgrades in [the `versioning.md` document](https://github.com/stellar/stellar-core/blob/master/docs/versioning.md) in the stellar-core GitHub repository. -## Upgrading Soroban Settings +## Upgrading Soroban Settings {#upgrading-soroban-settings} The mechanism to update Soroban settings is more complex than updating something like the `baseReserve`. The `upgrades` endpoint in stellar-core will require validators to vote on a serialized `ConfigUpgradeSetKey`, which contains a contractID and the SHA-256 hash of the `ConfigUpgradeSet` that will be applied to the existing settings. The serialized `ConfigUpgradeSet` must exist in the ledger as `Temporary` `ContractData` under the contractID specified earlier and with the `SCVal` `Bytes` key that contains the SHA-256 hash of the `ConfigUpgradeSet`. @@ -46,7 +46,7 @@ This means that someone wishing to propose a setting upgrade will need to create We have much more detail on the [next page](./soroban-settings.mdx) about _how_ to craft an upgrade proposal for these settings. Be sure to read and understand that. -## Example Upgrade Command +## Example Upgrade Command {#example-upgrade-command} By way of example, here is the `upgrades` command used to upgrade the protocol version to version 9 on January-31-2018. diff --git a/docs/validators/admin-guide/prerequisites.mdx b/docs/validators/admin-guide/prerequisites.mdx index abaab5d32..81a82a171 100644 --- a/docs/validators/admin-guide/prerequisites.mdx +++ b/docs/validators/admin-guide/prerequisites.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 You can install Stellar Core a [number of different ways](./installation.mdx), and once you do, you can [configure](./configuring.mdx) it to participate in the network on a several [different levels](../README.mdx#types-of-nodes): it can be either a Basic Validator or a Full Validator. No matter how you install Stellar Core or what kind of node you run, however, you need to set up and connect to the peer-to-peer network and store the state of the ledger in a SQL [database](./configuring.mdx#database). -## Hardware Requirements +## Hardware Requirements {#hardware-requirements} :::info @@ -23,23 +23,23 @@ Stellar Core is designed to run on relatively modest hardware so that a whole ra _\* Assuming a 30-day retention window for data storage._ -## Network Access +## Network Access {#network-access} Stellar Core interacts with the peer-to-peer network to keep a distributed ledger in sync, which means that your node needs to make certain [TCP ports](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_ports) available for inbound and outbound communication. -### Inbound +### Inbound {#inbound} A Stellar Core node needs to allow all IPs to connect to its `PEER_PORT` over TCP. You can specify a port when you [configure] Stellar Core, but most people use the default, which is **11625**. -### Outbound +### Outbound {#outbound} A Stellar Core node needs to connect to other nodes on the internet via their `PEER_PORT` over TCP. You can find information about other nodes' `PEER_PORT`s on a network explorer like [Stellarbeat](https://stellarbeat.io/), but most use the default port for this as well, which is (again) **11625**. -## Internal System Access +## Internal System Access {#internal-system-access} Stellar Core also needs to connect to certain internal systems, though exactly how this is accomplished can vary based on your setup. -### Inbound +### Inbound {#inbound-1} - Stellar Core exposes an _unauthenticated_ HTTP endpoint on its `HTTP_PORT`. You can specify a port when you [configure] Stellar Core, but most people use the default, which is **11626**. - The `HTTP_PORT` is used by other systems (such as Horizon) to submit transactions, so this port may have to be exposed to the rest of your internal IP addresses. @@ -53,16 +53,16 @@ If you need to expose this endpoint to other hosts in your local network, we str ::: -### Outbound +### Outbound {#outbound-1} - Stellar Core requires access to a database (PostgreSQL, for example). If that database resides on a different machine on your network, you'll need to allow that connection. You'll specify the database when you [configure] Stellar Core. - You can safely block all other connections. -## Storage +## Storage {#storage} Most storage needs come from stellar-core's database backend, which needs to store the entire ledger state. For the most part, the contents of both the database and related directories (such as `buckets`) can be ignored, since they are completely managed by Stellar Core. In terms of storage space, 100 GB is enough (as of April 2024). -### Database +### Database {#database} The database is consulted during consensus, and modified atomically when a transaction set is applied to the ledger. It's random access, fine-grained, and fast. @@ -78,7 +78,7 @@ If you're using PostgreSQL, we recommend you configure your local database to be # max_connections = 150 ``` -### Buckets +### Buckets {#buckets} Stellar-core stores ledger state in the form of flat XDR files called "buckets." The bucket files are used for hashing and transmission of ledger differences to history archives. If BucketListDB is used, the `buckets` directory is also used as a primary database backend. If SQL is used, the `buckets` directory is only used for hashing and history archives, and simply represents a copy of the ledger state stored in SQL. diff --git a/docs/validators/admin-guide/publishing-history-archives.mdx b/docs/validators/admin-guide/publishing-history-archives.mdx index 69770bd28..18a93864a 100644 --- a/docs/validators/admin-guide/publishing-history-archives.mdx +++ b/docs/validators/admin-guide/publishing-history-archives.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 If you want to run a [Full Validator](../README.mdx#full-validator), you need to set up your node to publish a history archive. You can host an archive using a blob store such as Amazon's S3 or Digital Ocean's spaces, or you can simply serve a local archive directly via an HTTP server such as Nginx or Apache. If you're setting up a [Basic Validator](../README.mdx#basic-validator), you can skip this section. No matter what kind of node you're planning to run, make sure to set it up to `get` history, which is covered in [Environment Preparation](./environment-preparation.mdx). -## Caching and History Archives +## Caching and History Archives {#caching-and-history-archives} The _primary_ cost of running a validator will very likely be egress bandwidth. A crucial part of your strategy to manage those costs should be caching. You can significantly reduce these data transfer costs by using common caching techniques or a CDN. Three simple rules apply to caching the History archives: @@ -13,7 +13,7 @@ The _primary_ cost of running a validator will very likely be egress bandwidth. 2. Do not cache HTTP 4xx responses (`Cache-Control: no-cache`) 3. Cache everything else for as long as possible (**> 1 day**) -## Local History Archive Using nginx +## Local History Archive Using nginx {#local-history-archive-using-nginx} Here, we'll demonstrate how you can configure your node to store its history files in the local filesystem, and then publish that history using nginx for our webserver software. @@ -78,7 +78,7 @@ server { } ``` -## Amazon S3 History Archive +## Amazon S3 History Archive {#amazon-s3-history-archive} Now, let's demonstrate a configuration where your node stores its history files using Amazon's S3 service. You can then publish that history using an Amazon S3 static site, or again use nginx for your webserver software. This time, using nginx, we'll include some proxy and CDN configuration, as well. @@ -150,7 +150,7 @@ server { } ``` -## Backfilling a History Archive +## Backfilling a History Archive {#backfilling-a-history-archive} Given the choice, it's best to configure your history archive _prior to_ your node's initial sync with an existing network. That way your validator's history publishes as you join, and subsequently sync with, the network. @@ -189,7 +189,7 @@ As you allow your node to join the network again, you can watch it start publish At this stage your validator is successfully publishing its history, which enables other users to join the network using your archive. -## Complete History Archive +## Complete History Archive {#complete-history-archive} The [stellar-archivist](https://github.com/stellar/go/tree/master/tools/stellar-archivist) command line tool can be used to mirror, scan, and repair existing archives. Using the [SDF package repositories](https://github.com/stellar/packages), you can install `stellar-archivist` by running: diff --git a/docs/validators/admin-guide/running-node.mdx b/docs/validators/admin-guide/running-node.mdx index 8d5145df0..0d02e8579 100644 --- a/docs/validators/admin-guide/running-node.mdx +++ b/docs/validators/admin-guide/running-node.mdx @@ -3,7 +3,7 @@ title: Running sidebar_position: 60 --- -## Starting Your Node +## Starting Your Node {#starting-your-node} Once you've [set up your environment](./prerequisites.mdx), [configured your node](./configuring.mdx), set up your [quorum set](./configuring.mdx#choosing-your-quorum-set), and selected archives to `get` [history from](./environment-preparation.mdx#history-archives), you're ready to start Stellar Core. @@ -17,7 +17,7 @@ At this point, you're ready to observe your core node's activity as it joins the You may want to skip ahead and review the [Logging](./logging.mdx) page to familiarize yourself with Stellar Core's output. -## Interacting With Your Instance +## Interacting With Your Instance {#interacting-with-your-instance} When your node is running, you can interact with Stellar Core via an administrative HTTP endpoint. Commands can be issued using command-line HTTP tools such as `curl`, or by running a CLI command such as @@ -29,11 +29,11 @@ The HTTP endpoint is [not intended to be exposed to the public internet](./prere Details of available _HTTP_ endpoint commands can be found in the [stellar-core-GitHub repo](https://github.com/stellar/stellar-core/blob/master/docs/software/commands.md#http-commands). Additionally, [the commands page](./commands.mdx) contains an overview of some of the most useful _CLI_ commands (non-HTTP commands) for managing a running core node. -## Joining the Network +## Joining the Network {#joining-the-network} Your node will go through the following phases as it joins the network, and you can query for the output below by using the info endpoint mentioned [here](./monitoring.mdx#general-node-information) : -### Establish Connection to Other Peers. +### Establish Connection to Other Peers. {#establish-connection-to-other-peers} You should see `authenticated_count` increase. @@ -44,7 +44,7 @@ You should see `authenticated_count` increase. }, ``` -### Observing Consensus +### Observing Consensus {#observing-consensus} Until the node sees a quorum, it will say: @@ -77,7 +77,7 @@ After observing consensus, a new field `quorum` will display information about n "state" : "Catching up", ``` -### Catching up +### Catching up {#catching-up} This is a phase where the node downloads data from any configured archives. This phase begins with something like: @@ -101,7 +101,7 @@ The `CATCHUP_COMPLETE` and `CATCHUP_RECENT` config fields are mutually exclusive ::: -### Synced +### Synced {#synced} When the node is done catching up, its state will change to: diff --git a/docs/validators/admin-guide/soroban-settings.mdx b/docs/validators/admin-guide/soroban-settings.mdx index 3ff065f85..d433ee175 100644 --- a/docs/validators/admin-guide/soroban-settings.mdx +++ b/docs/validators/admin-guide/soroban-settings.mdx @@ -7,7 +7,7 @@ import { Alert } from "@site/src/components/Alert"; Soroban has a large collection of settings stored on-ledger that can be modified through a validator vote. Here you can find out how to propose a new settings upgrade as well as how to examine a proposed upgrade. You can also look at the [Commands page](./commands.mdx) for more details on the stellar-core commands used below. -## Propose a Settings Upgrade +## Propose a Settings Upgrade {#propose-a-settings-upgrade} This section will describe how to propose a settings upgrade, but take a look at the [Upgrading the Network page](./network-upgrades.mdx#upgrading-soroban-settings) for more information on how the settings upgrade mechanism works internally. @@ -17,11 +17,11 @@ If you are being asked to vote for an upgrade, please move on to the [Examine a -## Helper Script +## Helper Script {#helper-script} A script to help you create the transactions below is available [in the stellar-core GitHub repo](https://github.com/stellar/stellar-core/blob/master/scripts/settings-helper.sh), with usage details [also available](https://github.com/stellar/stellar-core/blob/master/scripts/README.md). We've saved the information below for now, because it's important to be aware of how the underlying process to generate the transactions works in case the script has some issues. -### 1. Create an Upgrade Set +### 1. Create an Upgrade Set {#1-create-an-upgrade-set} The `stellar` CLI tool allows for the use of a JSON input file to encode a collection of Soroban settings into an base64-encoded string representing the XDR type `ConfigUpgradeSet`. You can use the [`pubnet_phase1.json`] and [`pubnet_phase2.json`] files as a starting point to formulate your upgrade proposal. You can also pull directly from a running core node using `http-command 'sorobaninfo?format=upgrade_xdr' | stellar-xdr decode --type ConfigUpgradeSet --output json-formatted`. This will allow you to get the exact settings running on that core node in JSON format, making it easier to change only the value you want to. Once you have your JSON file with updated values, use the following command to create the required upgrade set XDR: @@ -49,7 +49,7 @@ You can also download a [precompiled binary] of the latest release for your syst -### 2. Generate Settings Upgrade Transactions +### 2. Generate Settings Upgrade Transactions {#2-generate-settings-upgrade-transactions} You can use stellar-core's `get-settings-upgrade-txs` command to create a series of transactions that will: @@ -100,7 +100,7 @@ AAAAAgAAAABi/B0L0JGythwN1lY0aypo19NHxvLCyO5tBEc...F9wX14QAAAAARAAAAAwAAAAAAAAAAA nfyIVkHBNlHcyKH+8oKgrgJmA/MnLCW3E4Fhg4XYTkqZa2MyqzRdB2+mN3DOKUFKtZIAXp6o3DHrkgR0mo7rUw== ``` -### 3. Submit Settings Upgrade Transactions +### 3. Submit Settings Upgrade Transactions {#3-submit-settings-upgrade-transactions} These four transactions can then be submitted to the network through your node. Replace the blob placeholders below with the `TransactionEnvelope`s in lines 1, 3, 5, and 7. @@ -117,7 +117,7 @@ http-command 'tx?blob=' http-command 'tx?blob=' ``` -### 4. Verify Proposed Upgrades +### 4. Verify Proposed Upgrades {#4-verify-proposed-upgrades} You can verify that the proposed upgrades have been set up using stellar-core's `dumpproposedsettings` command, providing the `ConfigUpgradeSetKey` XDR string from line 9 above: @@ -125,7 +125,7 @@ You can verify that the proposed upgrades have been set up using stellar-core's http-command 'dumpproposedsettings?blob=' ``` -### 5. Schedule the Upgrades +### 5. Schedule the Upgrades {#5-schedule-the-upgrades} Now you can schedule the upgrade on all the required validators using stellar-core's `upgrades` command, providing the `ConfigUpgradeSetKey` output from line 9 above and an agreed upon time in the future: @@ -133,13 +133,13 @@ Now you can schedule the upgrade on all the required validators using stellar-co http-command 'upgrades?mode=set&upgradetime=YYYY-MM-DDTHH:MM:SSZ&configupgradesetkey=' ``` -### 6. Update Stellar Expert +### 6. Update Stellar Expert {#6-update-stellar-expert} One of the most-used methods of "watching" an upgrade take place for the network's Soroban settings is the [Protocol History page] on [stellar.expert]. In order to make sure that page gets updated with the proposed upgrades, please fill out a PR against [this repository]. -### Debugging +### Debugging {#debugging} Once the four transactions are run, you should see the proposed upgrade when running the `dumpproposedsettings` command ([see step 4 above](#4-verify-proposed-upgrades)). If you don't, then either one or more of the transactions above failed during application, or the upgrade is invalid. @@ -153,7 +153,7 @@ You should confirm what caused the failure by looking at the `TransactionResult` If the transactions succeeded but the `dumpproposedsettings` command still returns an error, then the upgrade is invalid. The error reporting here needs to be improved, but the validity checks happen [here](https://github.com/stellar/stellar-core/blob/3007c595c2fe9b53502aa0daf8089d119a9c37cb/src/herder/Upgrades.cpp#L1451). -## Examine a Proposed Upgrade +## Examine a Proposed Upgrade {#examine-a-proposed-upgrade} You can use stellar-core's `dumpproposedsettings` command along with a base64-encoded `ConfigUpgradeSetKey` XDR string to query a proposed upgrade: @@ -161,7 +161,7 @@ You can use stellar-core's `dumpproposedsettings` command along with a base64-en http-command 'dumpproposedsettings?blob=A6MvjFLujnqaZa5hacafWyYwhpk4cgRpyu0z6ilZ0pm1S7fmjSNnsyjGwGodLGiD8ss8S1AHiOBBb6GQbOeMbw==' ``` -## Examine Current Settings +## Examine Current Settings {#examine-current-settings} You can also get the current Soroban settings to compare against by using stellar-core's `sorobaninfo`. diff --git a/docs/validators/tier-1-orgs.mdx b/docs/validators/tier-1-orgs.mdx index 95c27b760..025a1adee 100644 --- a/docs/validators/tier-1-orgs.mdx +++ b/docs/validators/tier-1-orgs.mdx @@ -11,7 +11,7 @@ To become a Tier 1 organization, a team running validators must convince enough As a steward of the Stellar network, the SDF works closely with Tier 1 organizations to ensure the health of the network, maintain robust quorum intersection, and build in redundancy to minimize network disruptions. This guide outlines the minimum requirements recommended by the SDF in order to be a Tier 1 organization. However, in the end, the SDF on its own cannot add or remove a Tier 1 organization; this depends on the quorum sets of many other organizations in the network. -## Why Three Validators +## Why Three Validators {#why-three-validators} The most important recommendation for a Tier 1 organization is to set up and maintain three full validators. Why three? @@ -19,13 +19,13 @@ On Stellar, validators choose to trust organizations when they configure their q Here’s what else Tier 1 organizations should expect of one another: -## Publish History Archives +## Publish History Archives {#publish-history-archives} In addition to participating in the Stellar Consensus Protocol, a full validator publishes an archive of network transactions. To do that, you need to configure Stellar Core to record history to a publicly accessible archive, and add the location of that archive to your stellar.toml. We recommend that, as a Tier 1 organization, you should set each of your nodes to record history to a separate archive. Public archives make the network more resilient: when new nodes come online, or when existing nodes lose synch, they need to consult an archive to figure out what they missed. Sharing snapshots of the ledger, which detail transactions and their results, allows those nodes to catch up, and more archives mean more redundancy and greater decentralization. Plus, sharing history keeps everyone honest. -## Set Up a Safe Quorum Set +## Set Up a Safe Quorum Set {#set-up-a-safe-quorum-set} For simplicity, we’re recommending that every Tier 1 node use the same quorum set configuration, which is made up of inner quorum sets representing each Tier 1 organization. @@ -33,13 +33,13 @@ To configure a quorum set for your validator, we recommend including several Tie To see what the current recommended quorum set looks like, check out the [example Full Validator config file](https://github.com/stellar/packages/blob/master/docs/examples/pubnet-validator-full/stellar-core.cfg). -## Declare Your Node +## Declare Your Node {#declare-your-node} [SEP-20](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0020.md) is an open spec that explains how self-verification of validator nodes works. The fields it specifies are pretty simple: you set the home domain of your validator’s Stellar account to your website, where you publish information about your node and your organization in a stellar.toml file. It’s an easy way to propagate information, and it harnesses the network to allow other participants to discover your node and add it to their quorum sets without the need for a centralized database. -## Keep Your Nodes Up To Date +## Keep Your Nodes Up To Date {#keep-your-nodes-up-to-date} Running a validator requires vigilance. You need to keep an eye on your nodes, keep them up to date with the latest version of Stellar Core, and check in on public channels for information about what’s currently happening with other validators. As organizations join or leave the network, you might need to update the quorum set configuration of your validators to ensure that your validators have robust quorum intersection with Tier 1 and robust quorum availability. @@ -52,7 +52,7 @@ We always announce new Stellar Core releases in those channels. You can also fin It’s also critical that you pay attention to information about what those updates mean: often, you’ll need to set your validators to vote on something timely, such as when to vote to upgrade to a new protocol version, or how high to set the operations-per-ledger limit. -## Coordinate With Other Validators +## Coordinate With Other Validators {#coordinate-with-other-validators} Whether you run a trio of validators or a single node, it’s important that you coordinate with other validators when you make a significant change or notice something wrong. You should let them know when you plan to: @@ -63,7 +63,7 @@ Letting other validators know when you plan to take your node down for maintenan Letting other validators know when you plan to change your quorum set allows them to respond, adjust, and think through the implications of the change. For the Stellar network to expand safely, the SDF recommends that validators coordinate off-chain to maintain good quorum intersection. -## Monitor your quorum set +## Monitor your quorum set {#monitor-your-quorum-set} We recommend using Prometheus to scrape and store your stellar-core metrics, and Grafana to render that data for human consumption. You can find step-by-step instructions for setting up monitoring and alerts in [Monitoring and Diagnostics](./admin-guide/monitoring.mdx), along with links to Grafana dashboards we’ve created to make things easier. @@ -71,7 +71,7 @@ You can also use [Stellarbeat](https://stellarbeat.io) to view validators’ quo You should do regular check-ins on your quorum set. If nodes have bad uptime or prove otherwise unreliable, you may need to remove them from your quorum set so that you don’t get stuck and so that the network doesn’t halt. You may also want to add new organizations that come online and prove reliable. If you plan to do either of those things, remember to communicate and coordinate with other validators. -## Get in touch +## Get in touch {#get-in-touch} If you think you can be a Tier 1 organization, let us know on the `#validators` channel on the [Stellar Developers' Discord](https://discord.gg/stellardev). Community members can help you through the process, and once you’re up and running, SDF team members will help you join Tier 1, so that you can take your rightful place as a pillar of the network. Once you’ve proven that you are responsive, reliable, and maintain good uptime, the SDF may recommend that other validators adjust their quorum set to include your validators. diff --git a/platforms/anchor-platform/CONTRIBUTING.md b/platforms/anchor-platform/CONTRIBUTING.md index f246fd3bc..c274105f3 100644 --- a/platforms/anchor-platform/CONTRIBUTING.md +++ b/platforms/anchor-platform/CONTRIBUTING.md @@ -11,7 +11,7 @@ We're super glad to have you here, and hopefully this document will help you understand how (and more importantly _where_) to make the needed changes to our documentation. Let's start off with a bit of Docusaurus vocabulary, shall we? -## TL;DR +## TL;DR {#tldr} - For _unreleased_ versions of Anchor Platform: - Add and edit docs in `/platforms/anchor-platform` @@ -38,7 +38,7 @@ want to be judicious about which files you add to your commit. yarn ap:versions:regen ``` -## Table of Contents +## Table of Contents {#table-of-contents----omit-in-toc---} - [TL;DR](#tldr) - [More About Docusaurus than You Ever Wanted to Know](#more-about-docusaurus-than-you-ever-wanted-to-know) @@ -59,12 +59,12 @@ yarn ap:versions:regen - [Update Documentation Pages](#update-documentation-pages) - [Update API Specification](#update-api-specification) -## More About Docusaurus than You Ever Wanted to Know +## More About Docusaurus than You Ever Wanted to Know {#more-about-docusaurus-than-you-ever-wanted-to-know} I know it can feel a bit mysterious, but here's some knowledge and context to help your understanding of what's ahead. -### Versions Nomenclature +### Versions Nomenclature {#versions-nomenclature} This is how Docusaurus defines these terms, so that's what I'll use in this document, as well. @@ -79,7 +79,7 @@ document, as well. available at the `/platforms/anchor-platform` URL. This is the "stable" set of docs. -### Plugins +### Plugins {#plugins} There are two Docusaurus plugins at play here: @@ -95,7 +95,7 @@ Both of these plugin configurations have been broken out into a `/config/anchorPlatform.config.ts` file, to ease management of them and de-clutter somewhat the main `docusaurus.config.ts` file. -### Instances +### Instances {#instances} This is where it gets a bit more "in the weeds," but I promise this part is helpful to know. Both of the [plugins](#plugins) I mentioned above are really @@ -104,7 +104,7 @@ elsewhere in our docs site for Horizon, SDP, and just "regular" docs. It's not _generally_ important to consider different plugin instances, but it _is_ **quite relevant** when we discuss links. So... -### Links +### Links {#links} Most often, **especially in versioned docs**, it's important to [link to other docs by _relative_ file paths](https://docusaurus.io/docs/versioning#link-docs-by-file-paths). @@ -120,7 +120,7 @@ So, in practical terms: convention, we use _absolute_ paths for this, too, to make it a little more obvious when this behavior is taking place. -#### Examples +#### Examples {#examples} This should help to make it a bit clearer. @@ -167,12 +167,12 @@ This should help to make it a bit clearer. Read more about links [here](https://docusaurus.io/docs/markdown-features/links) (especially toward the bottom of the page). -## Directories to Know +## Directories to Know {#directories-to-know} There are a few directories that _all_ feed into the end product that is our versioned AP documentation. -### Directories You Already Know About +### Directories You Already Know About {#directories-you-already-know-about} - `/platforms/anchor-platform` This is where you are now, and traditionally has been the place to modify any of the markdown content that becomes our AP docs @@ -219,7 +219,7 @@ versioned AP documentation. "old" versions will likely just need to be made in those versioned specfiles for now (more on that in the next section). -### New Shiny Directories +### New Shiny Directories {#new-shiny-directories} - `/ap_versioned_sidebars` We can pretty well breeze right past this one. When you make a new version of the docs, Docusaurus stores a copy of the sidebar at @@ -235,13 +235,13 @@ versioned AP documentation. or update in a released version of the docs, you'll need to update accordingly here. -## Making New Versions +## Making New Versions {#making-new-versions} As noted in the [TL;DR](#tldr), this process is automated with the `VERSION=3.0.0 yarn ap:versions:new` script. However, here's what's happening under the hood of that script. -### Use Docusaurus to "Tag" a New Release +### Use Docusaurus to "Tag" a New Release {#use-docusaurus-to-tag-a-new-release} It's actually pretty simple! Use the Docusaurus CLI to make a new release: @@ -255,13 +255,13 @@ well "work" to get the new version displayed on the site. Any future changes to the 3.0.0 version of the docs should be made within the `/ap_versioned_docs` directory. -### Configure the OpenAPI plugin +### Configure the OpenAPI plugin {#configure-the-openapi-plugin} We'll also want to be able to modify/update/re-generate the API documentation if the need arises. So, we'll need to configure that `docusaurus-plugin-openapi-docs` plugin instance accordingly. -#### Copy the (bundled) OpenAPI Specfiles to the Versioned Directory +#### Copy the (bundled) OpenAPI Specfiles to the Versioned Directory {#copy-the-bundled-openapi-specfiles-to-the-versioned-directory} At the moment, it's just as simple as copying the files: @@ -274,7 +274,7 @@ cp openapi/anchor-platform/bundled-custody.yaml openapi/anchor-platform/versions > Notice how we're copying the _bundled_ file, not the _main_ file. This makes > sure the versioned file contains everything it needs. -#### Add Configuration to the OpenAPI Plugin Instance +#### Add Configuration to the OpenAPI Plugin Instance {#add-configuration-to-the-openapi-plugin-instance} > _Note_: These `versions` parts of the configuration are now generated > dynamically, using a `makeVersions()` function, so these manual config steps @@ -308,9 +308,9 @@ ap_platform: { } ``` -## Updating Old Versions +## Updating Old Versions {#updating-old-versions} -### Update Documentation Pages +### Update Documentation Pages {#update-documentation-pages} Let's say I find a misspelling in the `v2.8.4` Admin Guide documentation. Find the relevant file in the `/ap_versioned_docs/version-2.8.4` directory, fix it @@ -321,7 +321,7 @@ and commit. Content updates are pretty easy here. > here: > `/ap_versioned_docs/version-2.8.4/api-reference/platform/rpc/anchor-platform.openrpc.json` -### Update API Specification +### Update API Specification {#update-api-specification} This is a little more involved, but not much. Find and change the relevant part(s) of the diff --git a/platforms/anchor-platform/admin-guide/architecture.mdx b/platforms/anchor-platform/admin-guide/architecture.mdx index d9abf6435..7e1fd14b7 100644 --- a/platforms/anchor-platform/admin-guide/architecture.mdx +++ b/platforms/anchor-platform/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture +## Architecture {#architecture} Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture +### Fundamental Architecture {#fundamental-architecture} The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client +#### Client {#client} The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server +#### SEP Server {#sep-server} The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server +#### Business Server {#business-server} The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server +#### Platform Server {#platform-server} The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database +#### Database {#database} The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture +### Complete Architecture {#complete-architecture} In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service +#### Event Service {#event-service} The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server +#### Custody Server {#custody-server} The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer +#### Stellar Observer {#stellar-observer} The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/platforms/anchor-platform/admin-guide/custody-services/configuration.mdx b/platforms/anchor-platform/admin-guide/custody-services/configuration.mdx index 05483f0f6..4a45bf803 100644 --- a/platforms/anchor-platform/admin-guide/custody-services/configuration.mdx +++ b/platforms/anchor-platform/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration +## Custody Server Configuration {#custody-server-configuration} If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:latest --custody-server -## Anchor Platform Configuration +## Anchor Platform Configuration {#anchor-platform-configuration} Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration +## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/platforms/anchor-platform/admin-guide/custody-services/fireblocks/example.mdx b/platforms/anchor-platform/admin-guide/custody-services/fireblocks/example.mdx index 613d31bca..9b3b8bf30 100644 --- a/platforms/anchor-platform/admin-guide/custody-services/fireblocks/example.mdx +++ b/platforms/anchor-platform/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: +### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: +### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: +### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: +### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: +### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: +### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/platforms/anchor-platform/admin-guide/events/delivery.mdx b/platforms/anchor-platform/admin-guide/events/delivery.mdx index cd6d3148e..3c5f30142 100644 --- a/platforms/anchor-platform/admin-guide/events/delivery.mdx +++ b/platforms/anchor-platform/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees +## Delivery Guarantees {#delivery-guarantees} Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees +### Client Delivery Guarantees {#client-delivery-guarantees} For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees +### Business Server Delivery Guarantees {#business-server-delivery-guarantees} The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/platforms/anchor-platform/admin-guide/events/integration.mdx b/platforms/anchor-platform/admin-guide/events/integration.mdx index 98c919e72..10c0951f6 100644 --- a/platforms/anchor-platform/admin-guide/events/integration.mdx +++ b/platforms/anchor-platform/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements +## Requirements {#requirements} Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration +## Configuration {#configuration} First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events +## Receiving Events {#receiving-events} The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application +### As a Client Application {#as-a-client-application} Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing +#### Callback Signing {#callback-signing} Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server +### As a Business Server {#as-a-business-server} In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration +#### Configuration {#configuration-1} The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/platforms/anchor-platform/admin-guide/getting-started.mdx b/platforms/anchor-platform/admin-guide/getting-started.mdx index baf963cda..b2bbcc22e 100644 --- a/platforms/anchor-platform/admin-guide/getting-started.mdx +++ b/platforms/anchor-platform/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation +## Installation {#installation} import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:latest
-## Set Up the Development Environment +## Set Up the Development Environment {#set-up-the-development-environment} In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration +## Configuration {#configuration} The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server +### Changing Port of the Platform Server {#changing-port-of-the-platform-server} For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets +### Specify Your Service's Assets {#specify-your-services-assets} Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence +### Add Data Persistence {#add-data-persistence} The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication +### Configure Platform API Authentication {#configure-platform-api-authentication} To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags +### Passing JVM flags {#passing-jvm-flags} Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/platforms/anchor-platform/admin-guide/sep10/README.mdx b/platforms/anchor-platform/admin-guide/sep10/README.mdx index 9d30c9f53..d0acf0529 100644 --- a/platforms/anchor-platform/admin-guide/sep10/README.mdx +++ b/platforms/anchor-platform/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication +## Enable Stellar Authentication {#enable-stellar-authentication} Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution +## Config With Client Attribution {#config-with-client-attribution} `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -127,7 +127,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/platforms/anchor-platform/admin-guide/sep24/configuration.mdx b/platforms/anchor-platform/admin-guide/sep24/configuration.mdx index 41ea33561..b8d012f90 100644 --- a/platforms/anchor-platform/admin-guide/sep24/configuration.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals +## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -115,7 +115,7 @@ SEP24_INITIAL_USER_DEADLINE_SECONDS=1209600 `SEP24_INITIAL_USER_DEADLINE_SECONDS` is an optional param that defines the time in seconds a user has to act before the transaction moves to the next status. It determines the `user_action_required_by` field, which indicates the deadline. Check [JSON-RPC Methods][json-rpc-methods] for usage examples. -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/platforms/anchor-platform/admin-guide/sep24/example.mdx b/platforms/anchor-platform/admin-guide/sep24/example.mdx index 303368354..eeb212f6a 100644 --- a/platforms/anchor-platform/admin-guide/sep24/example.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience +## Building a Web-Based User Experience {#building-a-web-based-user-experience} The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication +### Authentication {#authentication} If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform +## Providing Updates to the Platform {#providing-updates-to-the-platform} Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform +## Fetching Updates from the Platform {#fetching-updates-from-the-platform} If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation +## Full Example Implementation {#full-example-implementation} Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/platforms/anchor-platform/admin-guide/sep24/faq.mdx b/platforms/anchor-platform/admin-guide/sep24/faq.mdx index 5972a06cf..ee5eb71da 100644 --- a/platforms/anchor-platform/admin-guide/sep24/faq.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? +### How To Use JWTs? {#how-to-use-jwts} As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? +### How To Provide Fees? {#how-to-provide-fees} Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? +### How to identify the user account? {#how-to-identify-the-user-account} You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? +### How to identify the wallet? {#how-to-identify-the-wallet} Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/platforms/anchor-platform/admin-guide/sep24/getting-started.mdx b/platforms/anchor-platform/admin-guide/sep24/getting-started.mdx index ce1d1dbf4..e77894428 100644 --- a/platforms/anchor-platform/admin-guide/sep24/getting-started.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience a deposit and withdrawal goes something like this: diff --git a/platforms/anchor-platform/admin-guide/sep24/integration.mdx b/platforms/anchor-platform/admin-guide/sep24/integration.mdx index 4fae1b17e..e41a3c5ed 100644 --- a/platforms/anchor-platform/admin-guide/sep24/integration.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit Transaction Via JSON-RPC +## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information} :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to handle abandoned transactions by expiring those have remained inactive for a certain period. To achieve this, check the transaction status using the `GET /transactions` endpoint and sort the results by the `user_action_required_by` timestamp. If the timestamp has passed, manually execute the appropriate logic, such as expiring the transaction or initiating an auto-refund, based on the transaction's current status. For example, to expire transaction business should change the transaction status to `expired`: @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction} In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC +## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information +### Processing KYC Information {#processing-kyc-information-1} This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `fee_details` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `fee_details` can be updated using this JSON-RPC request, ::: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction +### On-Hold Transaction {#on-hold-transaction-1} Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/platforms/anchor-platform/admin-guide/sep24/setting-up-production-server.mdx b/platforms/anchor-platform/admin-guide/sep24/setting-up-production-server.mdx index f631e5dbf..68c15d0bb 100644 --- a/platforms/anchor-platform/admin-guide/sep24/setting-up-production-server.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment +## Deploying a Secure Environment {#deploying-a-secure-environment} Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC +## Connecting to Real KYC {#connecting-to-real-kyc} Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form +## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails +## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases +## Testing Edge Cases {#testing-edge-cases} Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests +### General Tests {#general-tests} - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests +### KYC Tests {#kyc-tests} - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test +### Interactive Test {#interactive-test} - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests +### Security Tests {#security-tests} - Make sure platform endpoints are secured -## Polishing and Internationalization +## Polishing and Internationalization {#polishing-and-internationalization} Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets +## Connecting to Wallets {#connecting-to-wallets} All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/platforms/anchor-platform/admin-guide/sep31/configuration.mdx b/platforms/anchor-platform/admin-guide/sep31/configuration.mdx index 177b40c42..d0c9892ee 100644 --- a/platforms/anchor-platform/admin-guide/sep31/configuration.mdx +++ b/platforms/anchor-platform/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File +## Modify a Stellar Info File {#modify-a-stellar-info-file} Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments +## Enable Cross Border Payments {#enable-cross-border-payments} Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API +## Enable the Customer KYC API {#enable-the-customer-kyc-api} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API +## Enable the RFQ API {#enable-the-rfq-api} Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication +## Configure Callback API Authentication {#configure-callback-api-authentication} Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/platforms/anchor-platform/admin-guide/sep31/integration.mdx b/platforms/anchor-platform/admin-guide/sep31/integration.mdx index 41e948f32..b4ce186a5 100644 --- a/platforms/anchor-platform/admin-guide/sep31/integration.mdx +++ b/platforms/anchor-platform/admin-guide/sep31/integration.mdx @@ -16,7 +16,7 @@ The following may also be required depending on your use case: - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server +## Create a Business Server {#create-a-business-server} First, lets create a business server and add it to our docker compose file. @@ -69,11 +69,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints +## Customer Callback Endpoints {#customer-callback-endpoints} The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers +### Identifying Customers {#identifying-customers} Customers can be identified using two approaches. @@ -132,13 +132,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types +### Customer Types {#customer-types} Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet +### Test with the Demo Wallet {#test-with-the-demo-wallet} You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -155,33 +155,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint +## Rate Callback Endpoint {#rate-callback-endpoint} Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes +### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID +### Using the Client ID {#using-the-client-id} Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods +### Delivery Methods {#delivery-methods} It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates +## Fetching Transaction Status Updates {#fetching-transaction-status-updates} To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer +### Running the Stellar Observer {#running-the-stellar-observer} The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -201,7 +201,7 @@ services: -### Polling for Received Payments +### Polling for Received Payments {#polling-for-received-payments} The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -217,7 +217,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC +## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -237,7 +237,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} SEP-31 Transactions should initially be in the `pending_receiver` status. To request funds from the Sending Anchor, the Receiving Anchor should change the transaction status to `pending_sender` by making the following RPC request: @@ -275,7 +275,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_sender`. -### Funds Received +### Funds Received {#funds-received} If the Sending Anchor has sent the funds, the Receiving Anchor should change the transaction status to `pending_receiver` by making the following JSON-RPC request: @@ -320,7 +320,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -389,7 +389,7 @@ To execute this, you need to run: -### Verifying Customer Information +### Verifying Customer Information {#verifying-customer-information} In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -426,7 +426,7 @@ To execute this, you need to run: -### Do Stellar Refund +### Do Stellar Refund {#do-stellar-refund} Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -475,7 +475,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent +### Refund Sent {#refund-sent} There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -525,7 +525,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -564,7 +564,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -603,7 +603,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -636,7 +636,7 @@ To execute this, you need to run: -### Configuration +### Configuration {#configuration} You can enable these types of transactions by updating your `assets.yaml` file configuration: diff --git a/platforms/anchor-platform/admin-guide/sep6/configuration.mdx b/platforms/anchor-platform/admin-guide/sep6/configuration.mdx index 69bee9ae5..fb15490cd 100644 --- a/platforms/anchor-platform/admin-guide/sep6/configuration.mdx +++ b/platforms/anchor-platform/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals +## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File +### Modify a Stellar Info File {#modify-a-stellar-info-file} Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File +### Modify the Assets Configuration File {#modify-the-assets-configuration-file} Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts +### Managing Distribution Accounts {#managing-distribution-accounts} Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server +### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -165,7 +165,7 @@ The above tells the Anchor Platform to include a [JWT][how-to-use-jwt], signed w See the [KYC API][platform-api-kyc] and [Rates API][get-rates-api] for details on the endpoints that must be implemented on your business server. -### Additional Optional Configuration +### Additional Optional Configuration {#additional-optional-configuration} `more_info_url` is an optional URL provided by your business server for wallet applications to display information about previously initiated transactions. This URL is typically used by wallets in their transaction history views, and your business can specify the information to be displayed about the transaction. @@ -190,7 +190,7 @@ SEP6_INITIAL_USER_DEADLINE_SECONDS=1209600 -## Test With the Demo Wallet +## Test With the Demo Wallet {#test-with-the-demo-wallet} Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/platforms/anchor-platform/admin-guide/sep6/getting-started.mdx b/platforms/anchor-platform/admin-guide/sep6/getting-started.mdx index 3a1d875e9..fb4e1293c 100644 --- a/platforms/anchor-platform/admin-guide/sep6/getting-started.mdx +++ b/platforms/anchor-platform/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience +## The Basic User Experience {#the-basic-user-experience} The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/platforms/anchor-platform/admin-guide/sep6/integration.mdx b/platforms/anchor-platform/admin-guide/sep6/integration.mdx index 7627af2e8..cc9ea0942 100644 --- a/platforms/anchor-platform/admin-guide/sep6/integration.mdx +++ b/platforms/anchor-platform/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks +## Callbacks {#callbacks} The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information +### Customer Information {#customer-information} The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees +### Quotes and Fees {#quotes-and-fees} To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API +## Securing Platform API {#securing-platform-api} -### Using API Key +### Using API Key {#using-api-key} -### Using JWT +### Using JWT {#using-jwt} -## Making JSON-RPC Requests +## Making JSON-RPC Requests {#making-json-rpc-requests} -### JSON-RPC Request +### JSON-RPC Request {#json-rpc-request} -### JSON-RPC Response +### JSON-RPC Response {#json-rpc-response} -### Error Codes +### Error Codes {#error-codes} -## Updating Deposit (Exchange) Transaction Via JSON-RPC +## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information +### Verifying KYC Information {#verifying-kyc-information} Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -129,7 +129,7 @@ To execute this, you need to run: -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds} After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -201,7 +201,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received +### Funds Received {#funds-received} If offchain funds were received, you'll want to provide updated transaction information. @@ -253,7 +253,7 @@ To execute this, you need to run: -### Waiting For User Funds +### Waiting For User Funds {#waiting-for-user-funds} In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -288,7 +288,7 @@ To execute this, you need to run: -### Sending Onchain Funds +### Sending Onchain Funds {#sending-onchain-funds} Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -326,7 +326,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service +### Sending Payment Via Custody Service {#sending-payment-via-custody-service} The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -369,7 +369,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust +### Pending Trust {#pending-trust} This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -408,7 +408,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set +### Trust Set {#trust-set} This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -450,7 +450,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent +### Refund Sent {#refund-sent} Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -500,11 +500,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending +### Refund Pending {#refund-pending} This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error +### Transaction Error {#transaction-error} If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -543,7 +543,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction +### Expired Transaction {#expired-transaction} Your business may want to handle abandoned transactions by expiring those have remained inactive for a certain period. To achieve this, check the transaction status using the `GET /transactions` endpoint and sort the results by the `user_action_required_by` timestamp. If the timestamp has passed, manually execute the appropriate logic, such as expiring the transaction or initiating an auto-refund, based on the transaction's current status. @@ -582,7 +582,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery +### Transaction Recovery {#transaction-recovery} Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -615,7 +615,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -637,7 +637,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds +### Ready to Receive Funds {#ready-to-receive-funds-1} Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -718,7 +718,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received +### Funds Received {#funds-received-1} If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -767,7 +767,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated +### Amount Updated {#amount-updated} If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `fee_details` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -812,7 +812,7 @@ Only `amount_out` and `fee_details` can be updated using this JSON-RPC request, ::: -### Offchain Funds Available +### Offchain Funds Available {#offchain-funds-available} You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -846,7 +846,7 @@ To execute this, you need to run: -### Offchain Funds Pending +### Offchain Funds Pending {#offchain-funds-pending} Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -880,7 +880,7 @@ To execute this, you need to run: -### Offchain Funds Sent +### Offchain Funds Sent {#offchain-funds-sent} To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -915,11 +915,11 @@ To execute this, you need to run: -### Refund Sent +### Refund Sent {#refund-sent-1} The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service +### Sending Refund Via Custody Service {#sending-refund-via-custody-service} Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -968,19 +968,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error +### Transaction Error {#transaction-error-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction +### Expired Transaction {#expired-transaction-1} Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery +### Transaction Recovery {#transaction-recovery-1} Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions +## Tracking Stellar Transactions {#tracking-stellar-transactions} diff --git a/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx b/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx index 7436ecf55..b437d2198 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx @@ -9,13 +9,13 @@ For that reason, there are some connection points between the two instances that Please note that for the default deployment of the Stellar Disbursement Platform, that relies on default Helm values and default Wallets and Assets, no extra configuration is needed. This guide is for those who want to customize the deployment by changing the Wallets and Assets available in their SDP instance. -## Role of the Anchor Platform in SDP +## Role of the Anchor Platform in SDP {#role-of-the-anchor-platform-in-sdp} The Wallet Registration flow kicks off within the recipient's wallet app. This app interacts with the [Anchor Platform] to initiate the [SEP-24] deposit process through the SDP (Stellar Disbursement Platform). The SDP collects the necessary recipient information to ultimately execute the payment to them. The Anchor Platform (AP) is used to handle the implementation of interoperability protocols such as [SEP-1], [SEP-10], and [SEP-24], making their endpoints available to wallet apps. The [Anchor Platform] is pre-configured in both [the repo]'s Helm chart, and in the Docker Compose file available in the `dev` directory. -## Steps for Configuring SDP-AnchorPlatform Integration +## Steps for Configuring SDP-AnchorPlatform Integration {#steps-for-configuring-sdp-anchorplatform-integration} To ensure a seamless integration between the SDP and the [Anchor Platform], make sure to follow these steps: @@ -26,7 +26,7 @@ To ensure a seamless integration between the SDP and the [Anchor Platform], make By following these steps, you'll ensure a secure and efficient integration between your SDP and Anchor Platform systems. -## Manual Synchronization of Custom Assets and Wallets +## Manual Synchronization of Custom Assets and Wallets {#manual-synchronization-of-custom-assets-and-wallets} Currently, some configurations within the Anchor Platform are static and loaded via environment variables. On the other hand, the SDP reads these same configurations from its database and allows an owner user to modify them. This dynamic pertains particularly to the lists of supported assets and wallets. diff --git a/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx b/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx index 7b12f2f3a..67f3e2914 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx @@ -15,7 +15,7 @@ In this section we will discuss the different configuration options available fo - These configurations are valid for version 2.x of the SDP. - All configurations can be passed in as either environment variables or CLI flags. For instance, the env var `BASE_URL` could be passed in through the `--base-url` flag. CLI flags take priority over env vars, even though env vars are more convenient. -## SDP Core Service +## SDP Core Service {#sdp-core-service} For the most up-to-date configuration, you can run the following command in the [stellar-disbursement-platform-backend git repository](https://github.com/stellar/stellar-disbursement-platform-backend): @@ -27,7 +27,7 @@ For the most up-to-date configuration, you can run the following command in the -### Operational Configuration +### Operational Configuration {#operational-configuration} Operational Configuration allows controlling metrics, logging, and other operational aspects of the SDP Core Service. @@ -42,14 +42,14 @@ Operational Configuration allows controlling metrics, logging, and other operati - `BASE_URL` - The SDP backend server's base URL. Default: "http://localhost:8000". Tenant-specific URLs will be configured during the [tenant provisioning process](tenant-provisioning#creating-tenants). - `SDP_UI_BASE_URL` - The SDP UI/dashboard Base URL used to send the invitation link when a new user is created. Tenant-specific URLs will be configured during the [tenant provisioning process](tenant-provisioning#creating-tenants). -### Messaging Configuration +### Messaging Configuration {#messaging-configuration} Messaging Configuration allows configuring the messaging service used to send messages to recipients and sdp dashboard users. The default configuration is set to "DRY_RUN" which means no messages will be sent and the messages will be logged to the console. This is recommended for testing purposes only. - `EMAIL_SENDER_TYPE`: The messenger type used to send invitations to new dashboard users. Options: "DRY_RUN", "TWILIO_EMAIL", "AWS_EMAIL". Default: "DRY_RUN". - `SMS_SENDER_TYPE`: The messenger type used to send SMS messages to recipients. Options: "DRY_RUN", "TWILIO_SMS", "AWS_SMS". Default: "DRY_RUN". -#### AWS Configuration +#### AWS Configuration {#aws-configuration} The following configurations are required when using AWS SES or SNS to send emails or SMS messages. @@ -59,7 +59,7 @@ The following configurations are required when using AWS SES or SNS to send emai - `AWS_SES_SENDER_ID` - The email that AWS SES will use as the sender when sending emails. Required when `EMAIL_SENDER_TYPE` is set to "AWS_EMAIL". - `AWS_SNS_SENDER_ID` - The sender ID to use when sending SMS messages using AWS SNS. Required when `SMS_SENDER_TYPE` is set to "AWS_SMS". -#### Twilio Configuration +#### Twilio Configuration {#twilio-configuration} The following configurations are required when `SMS_SENDER_TYPE=TWILIO_SMS`. @@ -72,11 +72,11 @@ The following configurations are required when `EMAIL_SENDER_TYPE=TWILIO_EMAIL`. - `TWILIO_SENDGRID_API_KEY` - 🔑 The API key for the Twilio SendGrid (email) service. - `TWILIO_SENDGRID_SENDER_ADDRESS` - The email address used to send emails via Twilio SendGrid. -#### General Messaging Configuration +#### General Messaging Configuration {#general-messaging-configuration} - `MAX_INVITATION_RESEND_ATTEMPTS` - The maximum number of attempts to (auto) resend the invitation to the Receiver Wallets. Default: 3. -### Stellar Configuration +### Stellar Configuration {#stellar-configuration} Stellar Configuration allows configuring accounts, transactions, and other Stellar-related settings. @@ -88,14 +88,14 @@ Stellar Configuration allows configuring accounts, transactions, and other Stell The remaining configurations related to distribution accounts are detailed in the `Stellar accounts configuration` section of [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). -### Security Configuration +### Security Configuration {#security-configuration} Security Configuration allows configuring the security aspects of the SDP Core Service. - `CORS_ALLOWED_ORIGINS` - Specifies the domains allowed to make cross-origin requests. "_" means all domains are allowed. Domains can contain wildcards, e.g., "https://_.example.com". - `SEP24_JWT_SECRET` - 🔑 The secret used to sign the JWT token for SEP-24 transactions. This secret is used during the receiver wallet registration flow. -#### Dashboard Authentication Configuration +#### Dashboard Authentication Configuration {#dashboard-authentication-configuration} The following configurations are related to dashboard user authentication and authorization. @@ -105,14 +105,14 @@ The following configurations are related to dashboard user authentication and au - `DISABLE_MFA` - Disables Multi-Factor Authentication (MFA) for the SDP dashboard users. - `DISABLE_RECAPTCHA` - Disables Google reCAPTCHA v2 for the SDP dashboard users. This flag doesn't affect the reCAPTCHA used during the SEP-24 flow. -#### Recaptcha Configuration +#### Recaptcha Configuration {#recaptcha-configuration} The following configurations are required when using Google reCAPTCHA v2 to protect the SDP Core Service from bots. ReCaptcha is used both for dashboard users and receivers of funds during the SEP-24 flow. - `RECAPTCHA_SITE_KEY` - The Google reCAPTCHA v2 - I'm not a robot site key. - `RECAPTCHA_SITE_SECRET_KEY` - 🔑 The reCAPTCHA site secret key used to validate reCAPTCHA responses. -### Anchor Platform Configuration +### Anchor Platform Configuration {#anchor-platform-configuration} Anchor Platform Configuration allows configuring the anchor platform used by the SDP Core Service. @@ -120,17 +120,17 @@ Anchor Platform Configuration allows configuring the anchor platform used by the - `ANCHOR_PLATFORM_BASE_SEP_URL` - The base URL of the anchor platform's SEP-24 implementation. - `ANCHOR_PLATFORM_OUTGOING_JWT_SECRET` - 🔑 The JWT secret used to create a JWT token used to send requests to the anchor platform. -### Event Broker and Scheduled Jobs Configuration +### Event Broker and Scheduled Jobs Configuration {#event-broker-and-scheduled-jobs-configuration} For asynchronous processing, the SDP Core Service gives user the choice to use either the Event Broker or Scheduled Jobs. The configurations for this section are detailed in the `Event Broker and Scheduler Configurations` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). -### Multi-tenancy Configuration +### Multi-tenancy Configuration {#multi-tenancy-configuration} The configurations for this section are detailed in `General Environment Variables` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). -## Transaction Submission Service (TSS) +## Transaction Submission Service (TSS) {#transaction-submission-service-tss} For the most up-to-date configuration, you can run the following command in the [stellar-disbursement-platform-backend git repository](https://github.com/stellar/stellar-disbursement-platform-backend): @@ -142,11 +142,11 @@ For the most up-to-date configuration, you can run the following command in the -### General Configuration +### General Configuration {#general-configuration} - `QUEUE_POLLING_INTERVAL` - Polling interval (seconds) to query the database for pending transactions to process. Default: 6. -### Operational Configuration +### Operational Configuration {#operational-configuration-1} Operational Configuration allows controlling metrics, logging, and other operational aspects of the Transaction Submission Servic (TSS) @@ -158,7 +158,7 @@ Operational Configuration allows controlling metrics, logging, and other operati - `ENVIRONMENT` - The environment where the application is running. Example: "development", "staging", "production". Default: "development". - `DATABASE_URL` - 🔑 The connection string for the PostgreSQL database. Format is `postgres://username:password@host:port/database?sslmode=disable`. Default: "postgres://localhost:5432/sdp?sslmode=disable". -### Stellar Configuration +### Stellar Configuration {#stellar-configuration-1} Stellar Configuration allows configuring accounts, transactions, and other Stellar-related settings. @@ -166,14 +166,14 @@ Stellar Configuration allows configuring accounts, transactions, and other Stell - `HORIZON_URL` - The URL of the Horizon server to use for submitting transactions. Default "https://horizon-testnet.stellar.org/". - `MAX_BASE_FEE` - The max base fee for submitting a Stellar transaction. Default: 10000. -#### Channel Accounts Configuration +#### Channel Accounts Configuration {#channel-accounts-configuration} The following configurations are required for using channel accounts to submit transactions to the Stellar network. - `NUM_CHANNEL_ACCOUNTS` - Number of channel accounts to utilize for transaction submission. Default: 2. - `CHANNEL_ACCOUNT_ENCRYPTION_PASSPHRASE` - 🔑 A Stellar-compliant ed25519 private key used to encrypt/decrypt the channel accounts' private keys. When not set, it will default to the value of the 'DISTRIBUTION_SEED' option. -#### Distribution Accounts Configuration +#### Distribution Accounts Configuration {#distribution-accounts-configuration} The following configurations are related to the distribution accounts used to send funds to recipients. This configuration should match the configuration in the SDP Core Service. For more details, refer to the `Stellar accounts configuration` section of [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). @@ -181,7 +181,7 @@ The following configurations are related to the distribution accounts used to se - `DISTRIBUTION_PUBLIC_KEY` - The public key of the HOST's Stellar distribution account, used to create channel accounts. - `DISTRIBUTION_SEED` - 🔑 The private key of the HOST's Stellar distribution account, used to create channel accounts. -### Event Broker Configuration +### Event Broker Configuration {#event-broker-configuration} If an Event Broker is used for asynchronous processing, the TSS will need to be configured to use it. For more details, refer to the `Event Broker and Scheduler Configurations` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). @@ -194,11 +194,11 @@ If an Event Broker is used for asynchronous processing, the TSS will need to be - `KAFKA_SSL_ACCESS_CERTIFICATE` - 🔑 Kafka SSL Access Certificate in PEM format that matches with the Kafka Access Key. - `KAFKA_SSL_ACCESS_KEY` - 🔑 The Kafka Access Key (keystore) in PEM format. -## Dashboard +## Dashboard {#dashboard} The SDP Dashboard is a web application that allows users to manage their accounts, view transaction history, and more. Environment variables can be set either on a global `window._env_` object or as `process.env` variables. All environment variables used in this repo are in `src/constants/envVariables.ts` file, including types. The default location of the `window._env_` object is `public/settings/env-config.js`. -### General Configuration +### General Configuration {#general-configuration-1} - `API_URL` - The base URL of the SDP Core Service. Default: "http://localhost:8000". - `STELLAR_EXPERT_URL` - The base URL of the Stellar Expert explorer. Default: "https://stellar.expert/explorer/testnet". diff --git a/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx b/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx index 065ed096f..91c421803 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx @@ -9,15 +9,15 @@ This option is recommended for persistent deployments of production or staging i Please note that configuring deployment details like ingress, TLS, resource limits, and so on are out of scope for this guide. This guide assumes that you have a Kubernetes cluster with a Postgres database deployed in the same cluster and that you have the necessary permissions to deploy the SDP. It also assumes that you have the operational knowledge to manage the cluster and the database. -## Prerequisites +## Prerequisites {#prerequisites} - Kubernetes 1.19+ - Helm 3.2.0+ - Postgres 14.0+ -## Installing the Chart +## Installing the Chart {#installing-the-chart} -### Add the Helm repository +### Add the Helm repository {#add-the-helm-repository} Before you can install the chart, you need to add the Stellar Helm repository. @@ -26,7 +26,7 @@ helm repo add stellar https://helm.stellar.org/charts helm repo update ``` -### Customize the values +### Customize the values {#customize-the-values} The SDP Helm chart has a number of configurable values. You can customize these values by creating a values file and passing it to the `helm install` command. @@ -40,13 +40,13 @@ You can find the full list of configurable values in the [SDP GitHub repository] There is a more detailed explanation of how to configure the SDP in the [Configuring the SDP Guide](configuring-sdp). -### Multi-tenant considerations +### Multi-tenant considerations {#multi-tenant-considerations} When running the SDP in a multi-tenant configuration, you will need to acquire wildcard TLS certificates to facilitate tenant provisioning as the SDP relies on subdomains to differentiate between tenants. This will allow you to provision tenants without having to manually configure TLS certificates for each tenant. You can use a service like [Let's Encrypt](https://letsencrypt.org/) or [Namecheap](https://www.namecheap.com/security/ssl-certificates/) to acquire these certificates. For more information about multi-tenancy in the SDP, see the [Design and Architecture Guide](design-and-architecture#multi-tenancy). -### Install the chart +### Install the chart {#install-the-chart} To install the chart with the release name `sdp` and the values file `myvalues.yaml`: diff --git a/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx b/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx index 458303421..631c144a7 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx @@ -24,7 +24,7 @@ The Stellar Disbursement Platform consists of four services deployed together: - Distribution Account: the SDP requires access to at least one funded Stellar account to make payments to the recipient - SEP-10 Auth Account: the SDP requires a Stellar account for the mutual authentication protocol [SEP-10: Stellar Web Authentication](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) used to connect to wallet applications -## Architecture Diagram +## Architecture Diagram {#architecture-diagram} ![Architecture Diagram](/assets/SDP/SDP2.png) diff --git a/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx b/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx index a9c999634..bbdd95ea9 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx @@ -19,7 +19,7 @@ By the end of this guide, you'll have a clear understanding of the Stellar Disbu Note that while we'll be using USDC and the [Demo Wallet][demo-wallet] in this guide, other Stellar assets and wallets can be used in development or production. -## Create and Fund a Host Distribution Account +## Create and Fund a Host Distribution Account {#create-and-fund-a-host-distribution-account} You'll need a minimum of two accounts when using the Stellar Disbursement Platform, a distribution and receiver account. We'll create the distribution account now and will create the receiver account while making our first disbursment. @@ -53,15 +53,15 @@ You can also acquire USDC through the [Stellar Lab](https://lab.stellar.org) if USDC will arrive in your demo wallet account within seconds! Refresh the account on the demo wallet page to see the new balance. -## Run the SDP Locally +## Run the SDP Locally {#run-the-sdp-locally} -### Prerequisites +### Prerequisites {#prerequisites} -#### Docker +#### Docker {#docker} Make sure you have Docker installed on your system. If not, you can download it from [here](https://docs.docker.com/get-docker/). -#### Stellar Accounts +#### Stellar Accounts {#stellar-accounts} We will need two Stellar accounts to set up the SDP, one of which you already created above. @@ -70,7 +70,7 @@ We will need two Stellar accounts to set up the SDP, one of which you already cr The public and private key of these two accounts will be used to configure the SDP in the next step. -### Run the SDP +### Run the SDP {#run-the-sdp} First you'll need to clone the project. @@ -126,7 +126,7 @@ This will bring up the following services: - `kafka-init`: Initial workflow to exec into the Kafka container and create topics. - `demo-wallet`: The demo wallet client that will be used as a receiver wallet, running on port 4000. -## New Tenant Provisioning Process +## New Tenant Provisioning Process {#new-tenant-provisioning-process} When you ran `main.sh` file, you've already created new tenants: `tenants=("redcorp" "bluecorp")`. To add more tenants, simply append them separated by spaces to that variable like so: `tenants=("redcorp" "bluecorp" "greencorp")` and run main.sh again. @@ -137,7 +137,7 @@ Be sure that the added tenant hosts are included in the host configuration file. 127.0.0.1 redcorp.sdp.local ``` -## Setup Owner User Password for each tenant +## Setup Owner User Password for each tenant {#setup-owner-user-password-for-each-tenant} Go through the forgot password flow to be able to login as an owner user. @@ -145,13 +145,13 @@ Go to Forgot Password page on `http://${tenant}.stellar.local:3000/forgot-passwo A token will be generated, and it's possible to check it on `sdp-api` logs. This token will be needed to Reset Password on `http://${tenant}.stellar.local:3000/reset-password`. -## Log In +## Log In {#log-in} Once the password for your target org user has been reset to one of your choice, navigate to the dashboard by opening a browser to localhost:3000 and login with the user account. ![Login](/assets/SDP/SDP26.png) Click the Sign in button and the SDP Dashboard will open. You will have no disbursements data at this point. ![Dashboard](/assets/SDP/SDP27.png) -## Create Your First Disbursement +## Create Your First Disbursement {#create-your-first-disbursement} Navigate to the frontend service by opening a browser and going to http://bluecorp.stellar.local:3000. @@ -164,7 +164,7 @@ Navigate to the frontend service by opening a browser and going to http://blueco You also have the option of modifying the message in the receiver invite. ![Disbursment Details 2](/assets/SDP/SDP29.png) -## Deposit Money +## Deposit Money {#deposit-money} To deposit money into your account: @@ -179,9 +179,9 @@ To deposit money into your account: - Enter the birthday that matches the phone number in the CSV. - Keep an eye on the dashboard until the payment status reaches `Success`. If everything was set up correctly, your money should be disbursed successfully. -## Troubleshooting +## Troubleshooting {#troubleshooting} -### Distribution account out of funds +### Distribution account out of funds {#distribution-account-out-of-funds} Payments will start failing if the distribution account runs out of funds. To fix this, you can either write a script that funds the distribution account or use the tools available to add more funds to the distribution account by following these steps: @@ -193,7 +193,7 @@ Payments will start failing if the distribution account runs out of funds. To fi - Click on `Send` and enter the distribution account public key and the amount you want to send. - Using Freighter or [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=testnet&label=Testnet&horizonUrl=https:////horizon-testnet.stellar.org&rpcUrl=https:////soroban-testnet.stellar.org&passphrase=Test%20SDF%20Network%20/;%20September%202015;;), swap the XLM for USDC if you wish to test with USDC. -## Verify Your Identity +## Verify Your Identity {#verify-your-identity} When a disbursement is created, the SDP attempts to send a message to receivers using either Twilio/AWS for SMS or email, according to the contact type associated with the user. This message includes a link to the wallet application selected when creating the disbursement, and should direct the receiver to install the wallet app, go through the wallet's onboarding flow, and finally register with the SDP. @@ -207,11 +207,11 @@ Check out the [Email and SMS Messages](#email-and-sms-messages) section to learn ::: -## Create a Receiver Account +## Create a Receiver Account {#create-a-receiver-account} Clicking on initation message link will take the receiver to the [demo-wallet], where they'll need to create an account to be used to receive the USDC payment. Follow the same process described earlier to create the account and add a USDC trustline. -## Initiate SEP-24 Webflow +## Initiate SEP-24 Webflow {#initiate-sep-24-webflow} Now we'll need to connect the demo wallet to the SDP instance running locally. To do that, select the pencil icon next to "centre.io" below your USDC balance and enter "localhost:8080". @@ -235,7 +235,7 @@ The webflow provides a message indicating your successful registration, which is ![Message](/assets/SDP/SDP16.png) -## Check Your Balance +## Check Your Balance {#check-your-balance} Refresh your account. The Demo Wallet should now show a balance of 2 USDC sent from the SDP (or however much was defined in the CSV file). @@ -245,17 +245,17 @@ Keep an eye on the dashboard until the payment status reaches Success. If everyt ![Disbursement](/assets/SDP/SDP18.png) -## Next Up: Updating Application Secrets +## Next Up: Updating Application Secrets {#next-up-updating-application-secrets} Now that you've been able to make a disbursement, let's go back to our docker compose files and update some values. **This is an important step before going to production. We'll be updating encryption keys and application secrets.** -### Email and SMS Messages +### Email and SMS Messages {#email-and-sms-messages} The Stellar Disbursement Platform sends emails to users and SMS/emails to receivers. For SMS messages, the Stellar Disbursement Platform supports Twilio, AWS SNS, and a dry run mode that just logs the messages. For emails, it supports AWS SES, Twilio SendGrid, and dry run. These services can be selected through the `SMS_SENDER_TYPE` and `EMAIL_SENDER_TYPE` configurations. When selecting Twilio or AWS services, you'll need to fill their service-specific configuration as well. Below there are some example configurations, and you can mix and match the services as you see fit. -#### Dry Run Configuration +#### Dry Run Configuration {#dry-run-configuration} Dry run mode is useful for testing the SDP without sending real messages. It will log the messages to the console instead of sending them to the receiver. This is the default configuration and it works for both SMS and Email. @@ -268,7 +268,7 @@ SMS_SENDER_TYPE: DRY_RUN -#### Twilio SMS Configuration +#### Twilio SMS Configuration {#twilio-sms-configuration} @@ -283,7 +283,7 @@ TWILIO_SERVICE_SID: -#### Twilio Email (Send Grid) Configuration +#### Twilio Email (Send Grid) Configuration {#twilio-email-send-grid-configuration} @@ -297,7 +297,7 @@ TWILIO_SENDGRID_SENDER_ADDRESS: -#### AWS SMS Configuration +#### AWS SMS Configuration {#aws-sms-configuration} @@ -316,7 +316,7 @@ AWS_SNS_SENDER_ID: -#### AWS Email Configuration +#### AWS Email Configuration {#aws-email-configuration} @@ -335,7 +335,7 @@ AWS_SES_SENDER_ID: -### Authentication +### Authentication {#authentication} Wallets authenticate with the Stellar Disbursement Platform using a mutual authentication protocol, where both the SDP and wallet prove they are in possession of their Stellar accounts by signing a payload exchanged between themselves. Once this process is complete, a JWT is provided to the wallet to use in future requests. Additionally, the SDP's microservices uses authentication tokens to communicate between themselves, and to encrypt user passwords. We need to provide updated values for all these use cases. @@ -385,13 +385,13 @@ EC256_PRIVATE_KEY: There are many other configuration values to update when moving to a production environment, such as database credentials, URLs, and more. -## Level Up +## Level Up {#level-up} -### Custom Assets and Wallets +### Custom Assets and Wallets {#custom-assets-and-wallets} The SDP contains a list of assets and wallets available for disbursements out-of-the-box. You might want to customize these, either to limit/expand options or to prepare for going live in production. Now that you've made a disbursement and added application secrets, let's look at how to customize the new disbursement options. -#### Assets +#### Assets {#assets} You can add and remove assets easily in the SDP dashboard. The SDP backend handles the request seamlessly, including checking for outstanding balance and adding/removing trustlines on the Stellar network. When assets are removed, the record is still retained in the database to preserve a full history. However, the asset will no longer be available for disbursements or holding a balance in the distribution account. @@ -403,11 +403,11 @@ Please make sure to update the appropriate configuration on the Anchor Platform ::: -#### Wallets +#### Wallets {#wallets} For a full overview on how to add wallets and how to make a wallet SDP-compatible, check out the [Making Your Wallet SDP-Ready](making-your-wallet-sdp-ready) guide. -### Wallet Address Registration +### Wallet Address Registration {#wallet-address-registration} Since version [`3.0.0`](https://github.com/stellar/stellar-disbursement-platform-backend/releases/tag/3.0.0), the SDP can pay directly to Stellar wallet addresses rather than directing the receivers through the registration flow. This is useful for organizations that are paying receivers who already have Stellar wallets and don't need to create a new one. diff --git a/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx b/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx index 5fe6ab80b..47a8347e0 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx @@ -9,7 +9,7 @@ Remember that any SDP instance will need an agreement with a wallet provider bef In this page, we will cover the technical aspects of the SDP-Wallet integration, including how to add a Wallet in the SDP database, how to validate and support the registration links using mobile app's [deep linking], how to start the user registration flow in the wallet using [SEP-24], and a recommended approach for handling [deferred deep linking]. -## Adding a Wallet to an SDP +## Adding a Wallet to an SDP {#adding-a-wallet-to-an-sdp} The default list of SDP wallets depends on which network is being used (testnet or pubnet). The network is passed as an environment variable and then the list of wallets can be seeded appropriately on SDP startup through the CLI command `./stellar-disbursement-platform db setup-for-network`, according with a hardcoded list of known wallets. Alternatively, wallets can be inserted directly into the SDP database through a SQL command. Both methods require adding the wallet name, homepage, SEP-10 client domain, and deep link schema. @@ -63,7 +63,7 @@ Please make sure to update the appropriate configuration on the Anchor Platform ::: -## Recipient Registration Experience +## Recipient Registration Experience {#recipient-registration-experience} The recipient registration experience is paramount to make this application smooth and easy to use. this requires the wallet to support [deferred deep linking], which will be discussed in a later section. A good description of the registration experience is as follows: @@ -75,7 +75,7 @@ The recipient registration experience is paramount to make this application smoo 1. The user receives the payment within seconds -## Registration Deep Link +## Registration Deep Link {#registration-deep-link} Once the user has installed the wallet application, the wallet should be able to interpret a [deep link] that follows the format registered in the SDP in order to kick off the [Wallet Registration Procedure](#wallet-registration-procedure). The deep link format supported by the SDP follows this format: @@ -138,7 +138,7 @@ console.log( ); ``` -### Wallet Registration Procedure +### Wallet Registration Procedure {#wallet-registration-procedure} When opening registration [deep link], these are the steps the wallet should follow in order to enforce the security and privacy measures expected in this flow, and to allow the user to input their information directly with the SDP: @@ -163,7 +163,7 @@ Additionally, the wallet should save the link and/or link attributes and associa 1. Saving the data is useful for reporting and troubleshooting, especially if the wallet needs to justify the source of funds for regulatory or tax purposes. 1. If the payer org wants to pay any cashout fees charged by the wallet or offramp, the wallet will need to know which users and transactions should be invoiced upstream. -### Deferred Deep Links +### Deferred Deep Links {#deferred-deep-links} Most likely, the intended recipient will not have the necessary wallet application installed on their device. For this reason, wallets should support the concept of [deferred deep linking], which enables the following flow: diff --git a/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx b/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx index ac7029ce6..41c66bee4 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx @@ -7,7 +7,7 @@ This manual outlines the security measures implemented in the Stellar Disburseme Security is a critical aspect of the SDP. The measures outlined in this document are designed to mitigate risks and enhance the security of the platform. Users are strongly encouraged to follow these guidelines to protect their accounts and operations. -### Implementation of reCAPTCHA +### Implementation of reCAPTCHA {#implementation-of-recaptcha} Google's reCAPTCHA has been integrated into the SDP to prevent automated attacks and ensure that interactions are performed by humans, not bots. @@ -15,7 +15,7 @@ ReCAPTCHA is enabled by default and can be disabled in the development environme **Note:** Disabling reCAPTCHA is not supported for production environments due to security risks. -### Enforcement of Multi-Factor Authentication +### Enforcement of Multi-Factor Authentication {#enforcement-of-multi-factor-authentication} Multi-Factor Authentication (MFA) provides an additional layer of security to user accounts. It is enforced by default on the SDP and it relies on OTPs sent to the account's email. @@ -23,21 +23,21 @@ MFA is enabled by default and can be disabled in the development environment by **Note:** Disabling MFA is not supported for production environments due to security risks. -### Best Practices for Wallet Management +### Best Practices for Wallet Management {#best-practices-for-wallet-management} The SDP wallet should be used primarily as a hot wallet with a limited amount of funds to minimize potential losses. -#### Hot and Cold Wallets +#### Hot and Cold Wallets {#hot-and-cold-wallets} - A hot wallet is connected to the internet and allows for quick transactions. - A cold wallet is offline and used for storing funds securely. - Learn more about these concepts at [Investopedia](https://www.investopedia.com/hot-wallet-vs-cold-wallet-7098461). -### Distribution of Disbursement Responsibilities +### Distribution of Disbursement Responsibilities {#distribution-of-disbursement-responsibilities} To enhance security, disbursement responsibilities should be distributed among multiple financial controller users. -#### Recommended Configuration +#### Recommended Configuration {#recommended-configuration} 1. **Approval Flow**: Enable the approval flow on the organization page to require two users for the disbursement process. The owner can do that at _Profile > Organization > ... > Edit details > Approval flow > Confirm_. 2. **Financial Controller Role**: Create two users with the _Financial Controller_ role on the organization page to enforce separation of duties. The owner can do hat at _Settings > Team Members_. diff --git a/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx b/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx index a5c5e5d53..be072bc81 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx @@ -10,7 +10,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Here you will find the required steps to migrate an existing single-tenant (`1.x`) Stellar Disbursement Platform application (SDP) to a multi-tenant (`2.x+`) version. -## Why Migrate? +## Why Migrate? {#why-migrate} Starting with version `2.x`, the SDP provides a multi-tenant architecture, where multiple organizations can manage disbursements under a unified infrastructure while maintaining separate datasets and funds management. @@ -26,13 +26,13 @@ You have the option of using the `2.1.0` version to perform this migration, and ::: -## Preparing for the Migrations +## Preparing for the Migrations {#preparing-for-the-migrations} -### Halt the Single-Tenant Version 🚧 +### Halt the Single-Tenant Version 🚧 {#halt-the-single-tenant-version-} Before proceeding with the migration, ensure that the single-tenant version of the SDP is not running. This is crucial to prevent any data inconsistencies or conflicts during the migration process. -### Double-Spending Prevention 🚨 +### Double-Spending Prevention 🚨 {#double-spending-prevention-} To avoid double-spending, ensure that no payment is in the `PENDING` state, otherwise this could result in having the same payment submitted independently by both single-tenant and multi-tenant instances. You can do that by checking the `payments` table for any payment in the `PENDING` state: @@ -56,7 +56,7 @@ SELECT * FROM public.submitter_transactions WHERE status = ANY(array['PROCESSING If there are any payments in the `PENDING` state or transactions in the `PROCESSING` state, you should wait for them to be processed and transitioned to either `SUCCESS` or `FAILED` before proceeding with the migration. -### Remove Channel Accounts 🧹 +### Remove Channel Accounts 🧹 {#remove-channel-accounts-} In version `2.x`, the channel accounts are encrypted using the `CHANNEL_ACCOUNT_ENCRYPTION_PASSPHRASE`, which is a different env from the one used in the single-tenant version (`DISTRIBUTION_SEED`). To avoid any issues, let's remove all existing channel accounts in the single-tenant version priot to the migration: @@ -68,7 +68,7 @@ In version `2.x`, the channel accounts are encrypted using the `CHANNEL_ACCOUNT_ -### Database Backup & Setup 💾 +### Database Backup & Setup 💾 {#database-backup--setup-} Backup your single-tenant database before proceeding with the migration. At this point, the single-tenant instance should be halted, and there shouldn't be any `PENDING` payments nor `PROCESSING` submitter_transactions. @@ -86,7 +86,7 @@ psql --dbname=$multiTenantDB < sdp-singleTenant.sql -## Changes Explained +## Changes Explained {#changes-explained} Among the changes introduced in the multi-tenant version, the most significant ones are: @@ -96,19 +96,19 @@ Among the changes introduced in the multi-tenant version, the most significant o 1. **CLI Commands**: some CLI commands have been revised to be tenant-aware, while others have been included to support new multi-tenant features. 1. **Database Structure**: the database structure has been revised to accommodate multi-tenancy and the tables are now distributed across multiple schemas, providing isolation between tenants. -### Infrastructure +### Infrastructure {#infrastructure} For the infrastructure setup, SDP Multi-tenant offers flexible operational modes. -#### Event Broker vs Scheduled Jobs +#### Event Broker vs Scheduled Jobs {#event-broker-vs-scheduled-jobs} Administrators can choose between using an event broker for event-driven operations, or scheduled jobs for periodic operations. Event brokers are recommended for multi-tenant setups, as they provide a scalable and reliable way to handle events, while scheduled jobs are recommended for local setups or single-tenant SDPs. Also, event-brokers provide faster communication between services. -#### Anchor Platform Version +#### Anchor Platform Version {#anchor-platform-version} While the single-tenant used [`stellar/anchor-platform:2.1.3`](https://hub.docker.com/layers/stellar/anchor-platform/2.1.3/images/sha256-e6ef4b17a8d3e5d1455fa3d8f5f7e2a2b9534ad749584ff5446d685eb07837e9?context=explore), the multi-tenant version requires [`stellar/anchor-platform:2.6.0`](https://hub.docker.com/layers/stellar/anchor-platform/2.6.0/images/sha256-913fa2461d36d5150724a172ca46f8c76284a3890b60a9d5709fe0c606af78b9) or later. -### Environment Variables +### Environment Variables {#environment-variables} Below are the environment variables that have been added or modified in the multi-tenant version. @@ -149,17 +149,17 @@ On the Anchor Platform side, we must set the following envs: - `SEP10_HOME_DOMAIN=""`: this should be an empty string for the Multi-tenant version. - `SEP10_WEB_AUTH_DOMAIN=`: the home domain of the anchor platform instance. -### Seggregation of Funds +### Seggregation of Funds {#seggregation-of-funds} In the multi-tenant version, tenants funds are isolated from each other **unless the tenant is created with `"distribution_account_type": "DISTRIBUTION_ACCOUNT.STELLAR.ENV"`**. For more information on the distribution account types, please refer to the [Tenant Provisioning](./tenant-provisioning.mdx#creating-tenants) section. The channel accounts on the other hand are shared between tenants, and they are created by the HOST distribution account, set in the `DISTRIBUTION_SEED` environment variable. The channel accounts are encrypted using the `CHANNEL_ACCOUNT_ENCRYPTION_PASSPHRASE` environment variable, or the `DISTRIBUTION_SEED` if the former is not set. In the single-tenant version, the channel accounts were encrypted by the `DISTRIBUTION_SEED`. -### CLI Commands +### CLI Commands {#cli-commands} The following CLI commands were updated to become tenant-aware: -#### Database Migrations & Population +#### Database Migrations & Population {#database-migrations--population} The single-tenant commands for DB migration and pre-population used to be: @@ -192,7 +192,7 @@ Please notice that some commands require a tenant-aware flag, that can be either - `--all`: to execute these migrations in all tenants. - `--tenant-id`: to specify the tenant ID to execute the migrations. -#### Channel Accounts +#### Channel Accounts {#channel-accounts} The ensure command was updated from using the `--num-channel-accounts-ensure` flag to using a positional argument: @@ -205,7 +205,7 @@ The ensure command was updated from using the `--num-channel-accounts-ensure` fl -### Database Structure +### Database Structure {#database-structure} In the updated version, the database structure has been revised to accommodate multi-tenancy. As a result, the tables are now distributed across multiple schemas, and new tables have been introduced to support the multi-tenant architecture. The following schemas are used in the multi-tenant version: @@ -215,7 +215,7 @@ In the updated version, the database structure has been revised to accommodate m These changes allow for the isolation of tenant data per schema, ensuring that each tenant's data is kept separate from other tenants. -## Step-by-Step Migration Guide +## Step-by-Step Migration Guide {#step-by-step-migration-guide} :::tip @@ -225,11 +225,11 @@ The project has a [script](https://github.com/stellar/stellar-disbursement-platf Using the new database created from the single-tenant database dump as a starting point (as described in the [Database Backup & Setup](#database-backup--setup-) section), we can now proceed with the migration steps below. -### Deploy the New Version +### Deploy the New Version {#deploy-the-new-version} To transaction to a multi-tenant setup, deploy the latest version of the SDP `2+` version. If you're using helm charts, you can get the helm chart from the [SDP Helm Chart repository](https://github.com/stellar/helm-charts/pull/80). -### Executing Initial Database Migrations +### Executing Initial Database Migrations {#executing-initial-database-migrations} Following the deployment of the multi-tenant SDP, the next step is to perform the initial **database migrations**. It does not include the tenant-specific tables yet, they will be created later. @@ -246,13 +246,13 @@ Migration Commands: These commands will create the tenant admin tables on the **admin** schema and the Transaction Submitter Service tables on the **tss** schema, respectively. -### New Tenant Provisioning Process +### New Tenant Provisioning Process {#new-tenant-provisioning-process} After successfully applying the database migrations, the next step is to provision a new tenant. This is achieved by making an HTTP request to the **Admin API**. Be aware that it will provision the tenants with all the per-tenant migrations included. -#### Starting the SDP API server +#### Starting the SDP API server {#starting-the-sdp-api-server} To facilitate tenant provisioning, initiate the SDP Server using the command: @@ -264,7 +264,7 @@ To facilitate tenant provisioning, initiate the SDP Server using the command: -#### Posting to the Admin API +#### Posting to the Admin API {#posting-to-the-admin-api} - **API port**: The Admin API is accessible on port `8003` by default. This port setting can be adjusted by altering the `ADMIN_PORT` environment variable. - **Authentication**: Admin API employs Basic Authentication for securing access. To authenticate, populate the request "Authorization" header with `"Authorization: Basic ${Base64(ADMIN_ACCOUNT:ADMIN_API_KEY)}"`. @@ -307,7 +307,7 @@ In the SDP Multi-tenant, certain configurations previously managed through envir The field **name** is important because it's the tenant identifier. The other fields can be set to the same values used on the environment variables used on the non-tenant version. -### Importing your data +### Importing your data {#importing-your-data} Now that we've provisioned a new tenant, we can import our data into it. We need to copy our old tables' data to the new tenant schema. @@ -329,7 +329,7 @@ To help with the import process, we added a function to the `admin` schema that This concludes the migration of the SDP data to the multi-tenant version. The next step is to drop the old tables that are no longer needed. -### Drop Old Tables +### Drop Old Tables {#drop-old-tables} Now, the only missing step is to drop the single-tenant tables that should not be in the multi-tenant database: @@ -361,7 +361,7 @@ COMMIT; -### Conclusion 🎉 +### Conclusion 🎉 {#conclusion-} This should conclude the data migration from the single-tenant version to the multi-tenant version of the SDP. Please, make sure to run an e2e test to ensure that everything is working as expected. diff --git a/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx b/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx index 5c0ad4e4f..c771dd584 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx @@ -10,13 +10,13 @@ This section covers the steps to provision a new tenant in the Stellar Disbursem The endpoints needed to manage tenants can be found in the [Admin (Tenant Management)](../api-reference/admin.tag.mdx) docs. -## Creating Tenants +## Creating Tenants {#creating-tenants} Tenants can be created through the [POST /tenants](../api-reference/create-tenant.api.mdx) endpoint. As a quickstart, you can execute the [main.sh](https://github.com/stellar/stellar-disbursement-platform-backend/blob/develop/dev/main.sh) script from our repository and make sure to replace it with the desired values. The following sections detail how each field is used on the provisioning process and, so you can ensure the tenants are provisioned as expected: -### `distribution_account_type` +### `distribution_account_type` {#distribution_account_type} This is by far the most important field, as it determines the source of funds (distribution account) for the tenant, as well as how the secret for this distribution account is stored. The possible values are described below: @@ -51,29 +51,29 @@ Once a tenant is created, the `distribution_account_type` cannot be changed. If ::: -### `name` +### `name` {#name} This is the name of the tenant in the admin database. It is used to generate the per-tenant database schema, and is also used in the dashboard to identify the tenant. It cannot be changed once the tenant is created. -### `base_url`, and `sdp_ui_base_url` +### `base_url`, and `sdp_ui_base_url` {#base_url-and-sdp_ui_base_url} These are the URLs that the tenant will use to access the API and the dashboard, respectively. They are used to generate the tenant-specific URLs that are used in the dashboard and the user-targeted or receiver-targeted messages. They are important to allow the SDP backend to route the unauthenticated requests to the correct tenant, and to generate the correct URLs in the dashboard. -### `owner_email`, `owner_first_name`, and `owner_last_name` +### `owner_email`, `owner_first_name`, and `owner_last_name` {#owner_email-owner_first_name-and-owner_last_name} This is the information of the first user in the tenant organization. This user will have the `OWNER` role, which grants them full access & control to the tenant. The email, first name, and last name can be updated by the user themselvses once they sign up and access the dashboard. -### `organization_name` +### `organization_name` {#organization_name} This fields is used to populate the tenant's name in the dashboard. It can be updated by the owner user through the dashboard. -## Single-tenant Mode +## Single-tenant Mode {#single-tenant-mode} The platform is designed for multi-tenant mode, but it can also be used in single-tenant mode. This is the only case when setting `DISTRIBUTION_ACCOUNT.STELLAR.ENV` is acceptable, while the other modes are still advised. @@ -88,15 +88,15 @@ Once this `SINGLE_TENANT_MODE` env is enabled, all tenant-related requests will ::: -## Fetching Tenants +## Fetching Tenants {#fetching-tenants} The tenants can be fetched through the [GET /tenants](../api-reference/get-all-tenants.api.mdx) and [GET /tenants/:id-or-name](../api-reference/retrieve-a-tenant.api.mdx) endpoints. -## Deleting Tenants +## Deleting Tenants {#deleting-tenants} Tenants can be deleted through the [DELETE /tenants/:id](../api-reference/soft-delete-a-tenant.api.mdx) endpoint. This is a soft deletion though and despite the system not providing a way to ubdelete it, the tenant information won't be deleted from the database with the current implementation. -## Updating Tenants +## Updating Tenants {#updating-tenants} Some fields of a tenant can be updated through the [PATCH /tenants/:id](../api-reference/update-a-tenant.api.mdx) endpoint. The API documentation provides more details on which fields can be updated. diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx index 28c9e8599..21c4f94ae 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx @@ -14,6 +14,6 @@ The Wallets page includes the following: - USDC, EUROC, etc: This is the current balance available for making payments within a disbursement. - XLM: This is the balance of Stellar Lumens. This is used to fund the distribution account (base reserve) and transaction fees associated with making payments. This is for informational purposes and is not the source of funds for disbursements. In general, you do not need to worry about maintaining this, as Stellar network fees are very low. -### Adding Funds +### Adding Funds {#adding-funds} Add funds to your distribution account: You can deposit Stellar-based digital assets into your distribution account by sending them to the provided public key. Make sure your account has a trustline to the asset before you send funds. As a general principle, do not use your distribution account as a long-term holding place for money. It is meant to be a pass-through wallet to fund disbursements. diff --git a/src/pages/docs/learn/interactive/dapps/challenges/challenge-0-crowdfund.mdx b/src/pages/docs/learn/interactive/dapps/challenges/challenge-0-crowdfund.mdx index fbdb33ad9..7690b72dc 100644 --- a/src/pages/docs/learn/interactive/dapps/challenges/challenge-0-crowdfund.mdx +++ b/src/pages/docs/learn/interactive/dapps/challenges/challenge-0-crowdfund.mdx @@ -30,7 +30,7 @@ This challenge will guide you through the process of building and shipping a cro In this challenge, you will learn how to deploy smart contracts to Futurenet, and how to interact with them through a web frontend. In this context, the term "ship" refers to finalizing the development process of your dapp, ensuring that it functions as expected, and is accessible for user interaction and testing through a hosted frontend. However, it's crucial to clarify that despite its functionality, the dapp is not promoted nor intended for deployment in a production-level setting on Futurenet. The challenge is designed for educational purposes, helping you understand how a dapp can be built and interacted with, with further customization and development, it has the potential to evolve into a full-fledged, ready-to-use crowdfunding solution. -## Checkpoint 0: 📦 Install 📚 +## Checkpoint 0: 📦 Install 📚 {#checkpoint-0--install-} Start by installing the required dependencies. You'll also want to be sure you have the most updated version of Rust installed. @@ -56,7 +56,7 @@ cargo install_soroban Soroban CLI is the command line interface to Soroban. It allows you to build, deploy, and interact with smart contracts, configure identities, generate key pairs, manage networks, and more. The soroban-cli (alias) that is used in this challenge is a pinned version of the soroban-cli that is used in the Soroban Dapps Challenge. This ensures that the challenge is reproducible and that all participants are using the same version of Soroban. -## Checkpoint 1: 🎬 Deploy Smart Contracts +## Checkpoint 1: 🎬 Deploy Smart Contracts {#checkpoint-1--deploy-smart-contracts} Now that you have the Crowdfund branch checked out, it's time to deploy the smart contracts to a Sandbox environment. Deploying a smart contract in a production setting involves submitting the contract code to the blockchain's main network ( Mainnet ), where it becomes part of the chain's immutable ledger. Deploying smart contracts to a Sandbox environment simulates that process without actually affecting Mainnet. When you deploy the smart contracts, you'll instead deploy to Futurenet, a test network with more cutting-edge features that have not yet been implemented in the Mainnet. @@ -92,7 +92,7 @@ Please, save your deployed contract ID. You will need it to complete the challen {/* */} -## Checkpoint 2: 🤝 Connect the Frontend to the Backend +## Checkpoint 2: 🤝 Connect the Frontend to the Backend {#checkpoint-2--connect-the-frontend-to-the-backend} Now that you have deployed the smart contract, it's time to check out the frontend of your dapp. The frontend is the browser interface where contributors to your crowdfund campaign will connect their digital wallets and pledge assets to the campaign's cause. @@ -110,7 +110,7 @@ Now that you have the frontend running, it's time to connect it with the backend You will need to add some Futurenet network lumens to your wallet to interact with the dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create and or fund an account on Futurenet. Remember, these are test lumens for use on Futurenet and cannot be used on Mainnet. -## Checkpoint 3: 🌟 Powering the Campaign +## Checkpoint 3: 🌟 Powering the Campaign {#checkpoint-3--powering-the-campaign} Fuel the vision! In this step, you will learn how to mint tokens and fund the crowdfunding campaign. Minting tokens in a crowdfund dapp, while not always required, serves as a bootstrapping mechanism for the campaign, allowing the campaign to be funded with the minted tokens. @@ -129,7 +129,7 @@ Fuel the vision! In this step, you will learn how to mint tokens and fund the cr -#### Open Dapp and Mint +#### Open Dapp and Mint {#open-dapp-and-mint} Open the dapp frontend and click on the "Mint 100 ABND" button. @@ -139,7 +139,7 @@ Open the dapp frontend and click on the "Mint 100 ABND" button. -#### Approve Transaction +#### Approve Transaction {#approve-transaction} You should see a popup from Freighter asking you to sign the transaction. Click on "Approve" and wait for the transaction to be confirmed. @@ -149,7 +149,7 @@ You should see a popup from Freighter asking you to sign the transaction. Click -#### Check Updated Balance +#### Check Updated Balance {#check-updated-balance} You should see an updated balance in the pledge component. @@ -171,7 +171,7 @@ You should see an updated balance in the pledge component. -#### Fund the Campaign +#### Fund the Campaign {#fund-the-campaign} Now that you have your wallet set up, let's fund the crowdfunding campaign. Open the frontend and click on the "Back this project" button. You should see a popup from Freighter asking you to sign the transaction. @@ -181,7 +181,7 @@ Now that you have your wallet set up, let's fund the crowdfunding campaign. Open -#### Approve Transaction +#### Approve Transaction {#approve-transaction-1} Click on "Approve" and wait for the transaction to be confirmed. Once the transaction is confirmed, you should see a success message. @@ -191,7 +191,7 @@ Click on "Approve" and wait for the transaction to be confirmed. Once the transa -#### Check Updated Pledged Amount +#### Check Updated Pledged Amount {#check-updated-pledged-amount} You should see an updated balance reflecting the amount you have pledged in the pledge component. @@ -209,7 +209,7 @@ You should see an updated balance reflecting the amount you have pledged in the {/* Funding completed */} -## Checkpoint 4: 🚢 Ship it! 🚁 +## Checkpoint 4: 🚢 Ship it! 🚁 {#checkpoint-4--ship-it-} Now that your dapp is fully functional, its time to deploy it to a production environment. In this step, you will learn how to deploy your dapp to Vercel, a cloud platform for static sites that offers a quick and effective way to deploy the frontend of your dapp. This section requires that you have a [Vercel account] and the Vercel cli installed. @@ -271,7 +271,7 @@ You can now visit the preview link to see your deployed dapp! 🎉 Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create your Freighter account on Futurenet. -## Checkpoint 5: 💪 Pass the Challenge! +## Checkpoint 5: 💪 Pass the Challenge! {#checkpoint-5--pass-the-challenge} Now it's time to submit your work! @@ -285,7 +285,7 @@ Join [our Community in Discord](https://discord.gg/stellardev) in case you have ::: -## Checkpoint 6: ✅ Check your work! +## Checkpoint 6: ✅ Check your work! {#checkpoint-6--check-your-work} In order to successfully complete this challenge, your work needs to be checked. Please, follow the steps below: @@ -308,7 +308,7 @@ Public Key: GBSXUXZSA2VEXN5VGOWE5ODAJLC575JCMWRJ4FFRDWSTRCJ123456789 Invite a friend to try out your dapp and ask them to provide feedback! -## ⚔️ Side Quests +## ⚔️ Side Quests {#️-side-quests} 🌐 Explore [Stellar Lab] to inspect your account assets on Futurenet. @@ -333,7 +333,7 @@ You should see something like this: [stellar lab]: https://lab.stellar.org/?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;; -## 📚 User Workflows Checklist +## 📚 User Workflows Checklist {#-user-workflows-checklist} During this exercise you should be able to: @@ -352,6 +352,6 @@ Then via the web UI, you should be able to: - See your deposit(s) appear on the page as the transactions are confirmed. - "Live"-Update the page with the total amount with the new amount -## 🛡️🗡️ Take On More Challenges +## 🛡️🗡️ Take On More Challenges {#️️-take-on-more-challenges} View your progress and take on more challenges by visiting your [User Dashboard!](../dashboard) diff --git a/src/pages/docs/learn/interactive/dapps/challenges/challenge-1-payment.mdx b/src/pages/docs/learn/interactive/dapps/challenges/challenge-1-payment.mdx index ed8e2634b..d6128db8e 100644 --- a/src/pages/docs/learn/interactive/dapps/challenges/challenge-1-payment.mdx +++ b/src/pages/docs/learn/interactive/dapps/challenges/challenge-1-payment.mdx @@ -37,7 +37,7 @@ import "./styles.css"; This challenge will guide you through the process of setting up, customizing, and deploying a Soroban Payment dapp, a blockchain-powered payment application designed to work with the Freighter wallet. Payment dapps are powerful because they offer users equitable and accessible means to send and receive payments. Transactions via a payment dapp are peer-to-peer, which means that no central authority, third-party, or bank oversees or controls the payment. This decentralization reduces payment fees, which are comparatively minimal on a blockchain, and transaction time, which is, via a payment dapp, almost instantaneous. What's more, the wallet integration in a payment dapp, like Freighter in this case, means that anyone with a smartphone and the wallet installed can use the payment dapp, no matter where they are in the world. -## Checkpoint 0: 📦 Install Dependencies +## Checkpoint 0: 📦 Install Dependencies {#checkpoint-0--install-dependencies} Before you begin, ensure you have the following installed on your system. You'll also want to be sure you have the most updated versions of Rust and Soroban installed. @@ -48,7 +48,7 @@ Before you begin, ensure you have the following installed on your system. You'll Node and Yarn are package managers that let you install and manage dependencies during the dapp development process. Freighter is the wallet you will integrate into your payment dapp. -## Checkpoint 1: 🚀 Clone the Repository +## Checkpoint 1: 🚀 Clone the Repository {#checkpoint-1--clone-the-repository} Clone and set up the Soroban Dapps Challenge repository, which contains the Soroban Payment Dapp files. Then run yarn to install the dependencies. @@ -59,7 +59,7 @@ git checkout payment yarn ``` -## Checkpoint 2: 🎬 Deploy Smart Contracts +## Checkpoint 2: 🎬 Deploy Smart Contracts {#checkpoint-2--deploy-smart-contracts} For this step you will need to clone and deploy the Soroban token smart contract from the [Soroban Examples repository](https://github.com/stellar/soroban-examples/tree/v21.6.0/token). This Soroban token smart contract, broken into several smaller modules (as is the custom for complex smart contracts like this one), enables you to create and manage tokens on Soroban. @@ -145,7 +145,7 @@ soroban contract invoke \ {/* */} -## Checkpoint 3: 🖥️ Launch the Frontend +## Checkpoint 3: 🖥️ Launch the Frontend {#checkpoint-3-️-launch-the-frontend} In this checkpoint, you will make sure that the frontend of the Payment Dapp successfully communicates with the backend, allowing transactions to be created, signed, and submitted to the network. @@ -170,7 +170,7 @@ Now open your browser and navigate to [`http://localhost:9000`](http://localhost connect -## Checkpoint 4: 🚀 Token Transfer Odyssey +## Checkpoint 4: 🚀 Token Transfer Odyssey {#checkpoint-4--token-transfer-odyssey} Strap in and get ready to send some tokens! In this step, you will use the Payment Dapp to send Soroban tokens to another account. @@ -188,7 +188,7 @@ Strap in and get ready to send some tokens! In this step, you will use the Payme -#### Add Soroban Token +#### Add Soroban Token {#add-soroban-token} To add the newly minted DT token type to your wallet, open your Freighter wallet and click on the `Manage Assets` button at the bottom of the screen. @@ -204,7 +204,7 @@ Then click on the `Add Soroban token ` button and enter the token contract ID th -#### Check Token Addition +#### Check Token Addition {#check-token-addition} You should now see the Soroban token in your Freighter wallet. @@ -223,7 +223,7 @@ You should now see the Soroban token in your Freighter wallet. -#### Connect Freighter and Select Account +#### Connect Freighter and Select Account {#connect-freighter-and-select-account} Back on your dapp's frontend webpage, make sure Freighter is connected and then select the account that will be used to send Soroban tokens. Click "next" to continue. @@ -232,7 +232,7 @@ Back on your dapp's frontend webpage, make sure Freighter is connected and then -#### Provide Token Transfer Details +#### Provide Token Transfer Details {#provide-token-transfer-details} To send DT tokens via the Payment dapp, provide the public key of the account that will receive the Soroban tokens. (This could be another of your own Freighter accounts.) @@ -253,7 +253,7 @@ Confirm the payment settings, which include the option to add a memo and show th -#### Confirm and Submit Transaction +#### Confirm and Submit Transaction {#confirm-and-submit-transaction} Review the transaction details to ensure accuracy and then click "Sign with Freighter". Freighter will prompt you to sign the transaction with your wallet's private key. @@ -297,7 +297,7 @@ Output: {/* Tokens Sent */} -## Checkpoint 5: 🚢 Ship it! 🚁 +## Checkpoint 5: 🚢 Ship it! 🚁 {#checkpoint-5--ship-it-} In this step, you will deploy your dapp to a hosting platform so that it can be accessed by anyone with an internet connection. You can use any hosting platform you like, but for demonstration purposes, this section will use [Vercel](https://vercel.com/). Vercel is a cloud platform for static sites and serverless functions that offers a free tier for developers. It also has a built-in integration with GitHub, which makes it easy to deploy your dapp directly from your GitHub repository. @@ -418,7 +418,7 @@ You can now visit the preview link to see your deployed dapp! 🎉 Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create your Freighter account on Futurenet. -## Checkpoint 6: ✅ Complete the Challenge! +## Checkpoint 6: ✅ Complete the Challenge! {#checkpoint-6--complete-the-challenge} Now it's time to submit your work! @@ -432,11 +432,11 @@ Join [our Community in Discord](https://discord.gg/stellardev) in case you have ::: -## Checkpoint 7: 💪 Share Your Accomplishment with the Community +## Checkpoint 7: 💪 Share Your Accomplishment with the Community {#checkpoint-7--share-your-accomplishment-with-the-community} Don't forget to share your work with the community. Let others see what you've accomplished, receive feedback, and inspire others! -## ⚔️ Side Quests +## ⚔️ Side Quests {#️-side-quests} 🍴[Fork the Example Soroban Payment Dapp repo] and make your own changes to your Dapp. @@ -444,7 +444,7 @@ Consider customizing the code and submitting a pull request for the challenge. Y [fork the example soroban payment dapp repo]: https://github.com/stellar/soroban-react-payment -## 📚 User Workflows Checklist +## 📚 User Workflows Checklist {#-user-workflows-checklist} To ensure that you've covered all the key user actions during the challenge, follow this checklist: @@ -459,6 +459,6 @@ To ensure that you've covered all the key user actions during the challenge, fol - Deploy the site with Vercel - Submit your public key and URL -## 🛡️🗡️ Take On More Challenges +## 🛡️🗡️ Take On More Challenges {#️️-take-on-more-challenges} View your progress and take on more challenges by visiting your [User Dashboard!](../dashboard) diff --git a/src/pages/docs/learn/interactive/dapps/challenges/challenge-2-liquidity-pool.mdx b/src/pages/docs/learn/interactive/dapps/challenges/challenge-2-liquidity-pool.mdx index 8a7ea90ad..115865495 100644 --- a/src/pages/docs/learn/interactive/dapps/challenges/challenge-2-liquidity-pool.mdx +++ b/src/pages/docs/learn/interactive/dapps/challenges/challenge-2-liquidity-pool.mdx @@ -32,7 +32,7 @@ A liquidity pool is a collection of tokens or digital assets deposited by users The functionality of this liquidity pool dapp will allow users to mint tokens, deposit liquidity, swap between asset types, and withdraw funds from the liquidity pool. This dapp challenge will walk you through the step-by-step process of creating and launching a liquidity pool dapp on Stellar using Soroban smart contracts. You will learn how to deploy smart contracts to a sandbox environment and interact with them through a web frontend. In this context, the term "ship" refers to finalizing the development process of your dapp, ensuring that it functions as expected and is accessible for user interaction and testing through a hosted frontend. Despite the end-to-end functionality of this challenge, this dapp is not promoted nor intended for deployment in a production-level setting on Futurenet, but rather is designed for educational purposes. -## Checkpoint 0: 📦 Install 📚 +## Checkpoint 0: 📦 Install 📚 {#checkpoint-0--install-} Start by installing the required dependencies. You'll also want to be sure you have the most updated version of Rust installed. @@ -58,7 +58,7 @@ cargo install_soroban Soroban CLI is the command line interface to Soroban. It allows you to build, deploy, and interact with smart contracts, configure identities, generate key pairs, manage networks, and more. The soroban-cli alias that is used in this challenge is a pinned version of the soroban-cli that is used in the Soroban Dapps Challenge. Using the soroban-cli alias ensures that the challenge is reproducible and that all participants are using the same version of Soroban. -## Checkpoint 1: 🎬 Deploy Smart Contracts +## Checkpoint 1: 🎬 Deploy Smart Contracts {#checkpoint-1--deploy-smart-contracts} Deploying a smart contract in a production setting involves submitting the contract code to the blockchain's main network (Mainnet), where it becomes part of the chain's immutable ledger. When you deploy the smart contracts in this challenge, you'll instead deploy to Futurenet, a test network with more cutting-edge features that have not yet been implemented in the Mainnet. Deploying smart contracts to a sandbox environment simulates the production-level deployment process without actually affecting Mainnet. @@ -94,7 +94,7 @@ Please, save your deployed contract ID. You will need it to complete the challen {/* */} -## Checkpoint 2: 🤝 Connect the Frontend to the Backend +## Checkpoint 2: 🤝 Connect the Frontend to the Backend {#checkpoint-2--connect-the-frontend-to-the-backend} Now that you have deployed the smart contract, it's time to check out the frontend of your dapp. The frontend is the browser interface where users will connect their digital wallets to make deposits into and withdrawals from the liquidity pool. The frontend is also where users will be able to see their balances and swap tokens. @@ -116,7 +116,7 @@ Now that you have the frontend running, it's time to connect it with the backend You will need to add some Futurenet network lumens to your wallet to interact with the dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create), and follow the instructions to create and or fund an account on Futurenet. Remember, these are test lumens for use on Futurenet and cannot be used on Mainnet. -## Checkpoint 3: 🌊 Dive into the Liquidity Pool +## Checkpoint 3: 🌊 Dive into the Liquidity Pool {#checkpoint-3--dive-into-the-liquidity-pool} Embark on a tidal journey! In this step you will mint, deposit, swap, and withdraw tokens from the liquidity pool. Minting tokens, depositing liquidity, swapping between asset types, and withdrawing funds from the liquidity pool constitute the basic lifecycle of interacting with a DeFi protocol. @@ -139,7 +139,7 @@ In the context of liquidity pools, depositing and withdrawing assets involve con -#### Mint USDC and BTC +#### Mint USDC and BTC {#mint-usdc-and-btc} In order to use this liquidity pool dapp, you will need to mint test tokens which can then be used to make deposits and swaps via the frontend of the dapp. To mint USDC and BTC test tokens, open the dapp frontend and click the "MINT" button for USDC and BTC. @@ -148,7 +148,7 @@ In order to use this liquidity pool dapp, you will need to mint test tokens whic -#### Approve Transaction +#### Approve Transaction {#approve-transaction} You should see a popup from Freighter asking you to sign the transactions. Click on "Approve" and wait for the transaction to be confirmed. @@ -157,7 +157,7 @@ You should see a popup from Freighter asking you to sign the transactions. Click -#### Check Updated Balance +#### Check Updated Balance {#check-updated-balance} You should see an updated balance in the account balance component. @@ -178,7 +178,7 @@ You should see an updated balance in the account balance component. -#### Deposit into the Liquidity Pool +#### Deposit into the Liquidity Pool {#deposit-into-the-liquidity-pool} Depositing assets into the liquidity pool involves users submitting deposit transactions via the frontend to deposit tokens from their wallet into the liquidity pool. In this dapp you will make a deposit of two asset types in order to swap between those asset types. In other DeFi protocols, users may also deposit liquidity into a liquidity pool in order to earn yields on their deposits. The intial deposit of liquidity into a liquidity pool is what sets the initial price of the tokens in the pool. For example, if a user deposits 37000 USDC and 1 BTC, the price of each BTC token will be 37000 USDC. @@ -189,7 +189,7 @@ Open the frontend, enter the desired token amounts, and click the "Deposit" butt -#### Approve Transaction +#### Approve Transaction {#approve-transaction-1} Click on "Approve" and wait for the transaction to be confirmed. Once the transaction is confirmed, you should see your balances updated. @@ -197,7 +197,7 @@ Click on "Approve" and wait for the transaction to be confirmed. Once the transa -#### Check Updated Balance +#### Check Updated Balance {#check-updated-balance-1} You should see an updated balance in the amounts you have deposited in the account and reserve balance components, respectively. Following the example, you should see 50 USDC, 50 BTC, and 50 POOL. @@ -219,7 +219,7 @@ You should see an updated balance in the amounts you have deposited in the accou -#### Swap Tokens +#### Swap Tokens {#swap-tokens} Now that you have funded the liquidity pool, you can make a swap to easily exchange one token for another. Swaps in a liquidity pool usually depend on the relationship between two or more different tokens that can be exchanged with each other. Typical liquidity pools rely on a mathematical formula that determines the price of the tokens within the pool. With every deposit and withdraw transaction to or from the pool, the formula adjusts the token price of each token based on this formula. When a swap occurs, the liquidity pool uses the formula and the balances of each token with the pool to determine the swap value of each token relative to the others within the pool. @@ -237,7 +237,7 @@ To complete a swap between USDC and BTC test tokens, open the swap tab of the fr -#### Approve Transaction +#### Approve Transaction {#approve-transaction-2} Click on "Approve" and wait for the transaction to be confirmed. @@ -245,7 +245,7 @@ Click on "Approve" and wait for the transaction to be confirmed. -#### Check Updated Balance +#### Check Updated Balance {#check-updated-balance-2} Once the transaction is confirmed, you should see updated balances on the frontend. @@ -267,7 +267,7 @@ Once the transaction is confirmed, you should see updated balances on the fronte -#### Withdraw Tokens from the Liquidity Pool +#### Withdraw Tokens from the Liquidity Pool {#withdraw-tokens-from-the-liquidity-pool} Now that you have swapped tokens through the liquidity pool, you can make a withdrawal of your funds. @@ -281,7 +281,7 @@ Open the withdraw tab, select how much liquidity you want to remove with the sli -#### Approve Transaction +#### Approve Transaction {#approve-transaction-3} Click on "Approve" and wait for the transaction to be confirmed. @@ -289,7 +289,7 @@ Click on "Approve" and wait for the transaction to be confirmed. -#### Check Updated Balance +#### Check Updated Balance {#check-updated-balance-3} Once the transaction is confirmed, you should see updated balances on the frontend. @@ -305,7 +305,7 @@ Once the transaction is confirmed, you should see updated balances on the fronte {/* Transactions completed */} -## Checkpoint 4: 🚢 Ship It! 🚁 +## Checkpoint 4: 🚢 Ship It! 🚁 {#checkpoint-4--ship-it-} Now that your dapp is fully functional, its time to deploy it to a production environment. In this step, you will learn how to deploy your dapp to Vercel, a cloud platform for static sites that offers a quick and effective way to deploy the frontend of your dapp. This section requires that you have a [Vercel account] and install the Vercel CLI. @@ -421,7 +421,7 @@ You can now visit the preview link to see your deployed dapp! 🎉 Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create your Freighter account on Futurenet. -## Checkpoint 5: ✅ Complete the Challenge! +## Checkpoint 5: ✅ Complete the Challenge! {#checkpoint-5--complete-the-challenge} Now it's time to submit your work! @@ -429,7 +429,7 @@ Submit your `Production` URL from the previous step into the challenge form to p {/* */} -## Checkpoint 6: 💪 Flex! +## Checkpoint 6: 💪 Flex! {#checkpoint-6--flex} 🍴 [Fork the Soroban Dapps Challenge repo] and make your own changes to the Liquidity Pool branch. @@ -440,7 +440,7 @@ Take this opportunity to showcase your skills and make your mark on the Liquidit [stellar lab]: https://lab.stellar.org/?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;; [fork the soroban dapps challenge repo]: https://github.com/stellar/soroban-dapps-challenge/fork -## 📚 User Workflows Checklist +## 📚 User Workflows Checklist {#-user-workflows-checklist} During this exercise, you should be able to: @@ -458,6 +458,6 @@ Then, via the web UI, you should be able to: - Withdraw assets - See your transaction(s) appear on the page as the transactions are confirmed -## 🛡️🗡️ Take On More Challenges +## 🛡️🗡️ Take On More Challenges {#️️-take-on-more-challenges} View your progress and take on more challenges by visiting your [User Dashboard!](../dashboard) diff --git a/src/pages/docs/learn/interactive/dapps/challenges/challenge-3-oracle.mdx b/src/pages/docs/learn/interactive/dapps/challenges/challenge-3-oracle.mdx index 197100c21..a33e132b8 100644 --- a/src/pages/docs/learn/interactive/dapps/challenges/challenge-3-oracle.mdx +++ b/src/pages/docs/learn/interactive/dapps/challenges/challenge-3-oracle.mdx @@ -32,7 +32,7 @@ This challenge will guide you through the process of building and shipping an or In this challenge, you will learn how to deploy smart contracts to Futurenet, and how to interact with them through a web frontend. In this context, the term "ship" refers to finalizing the development process of your dapp, ensuring that it functions as expected, and is accessible for user interaction and testing through a hosted frontend. However, it's crucial to clarify that despite its functionality, the dapp is not promoted nor intended for deployment in a production-level setting on Mainnet. The challenge is designed for educational purposes only, helping you understand how a dapp can be built and interacted with, with further customization and development, it has the potential to evolve into a full-fledged, ready-to-use oracle solution. -## Checkpoint 0: 📦 Install 📚 +## Checkpoint 0: 📦 Install 📚 {#checkpoint-0--install-} Start by installing the required dependencies. @@ -60,7 +60,7 @@ cargo install --locked --version 20.0.0-rc.4.1 soroban-cli Soroban CLI is the command line interface to Soroban. It allows you to build, deploy, and interact with smart contracts; configure identities; generate key pairs; manage networks; and more. -## Checkpoint 1: 📝 Setup the `initialize.sh` Script +## Checkpoint 1: 📝 Setup the `initialize.sh` Script {#checkpoint-1--setup-the-initializesh-script} The `initialize.sh` script is a shell script that will help you initialize the contracts and install dependencies. It is located in the top level directory. @@ -115,7 +115,7 @@ Here is a description of each parameter: - `` - frequency (in seconds) of price updates - `` - address of the wallet that will update the price (in the backend, in the CRON task). It is suggested to create a dedicated wallet for this ([be sure to fund with test Lumens](https://lab.stellar.org/?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;)) -## Checkpoint 2: 🎬 Deploy Smart Contracts +## Checkpoint 2: 🎬 Deploy Smart Contracts {#checkpoint-2--deploy-smart-contracts} Now that the initialization script is set up it's time to deploy the smart contracts to a Sandbox environment. Deploying a smart contract in a production setting involves submitting the contract code to the blockchain's main network ( Mainnet ), where it becomes part of the chain's immutable ledger. Deploying smart contracts to a Sandbox environment simulates that process without actually affecting Mainnet. When you deploy the smart contracts, you'll instead deploy to Futurenet, a test network with more cutting-edge features that have not yet been implemented in the Mainnet. @@ -162,7 +162,7 @@ Please, save your deployed contract ID, you will need it to complete the challen {/* */} -## Checkpoint 3: ⏯️ Create a CRON task +## Checkpoint 3: ⏯️ Create a CRON task {#checkpoint-3-️-create-a-cron-task} A CRON task is a scheduled operation performed at specified intervals, functioning as a customizable backend service. Here, you will run a CRON task to update the BTC price within the Oracle contract. Data can be fetched from an API and set to the contract using the `set_price` function, in this case, the tutorial will use the [CryptoPrice API](https://api-ninjas.com/api/cryptoprice). This is a free API that provides real-time cryptocurrency prices, and it is used in this tutorial for demonstration purposes only. You are free to use any price feed API of your choice. @@ -220,7 +220,7 @@ cron.schedule("*/5 * * * *", async () => { It's important to note that since the price feed is dependent on the CRON task, the price will not update until the CRON task has run at least once. Furthermore, the CRON task will need to keep running in order to keep the price feed updated. You can host the task on your localhost or on a server such as [Vercel](https://vercel.com/docs/cron-jobs). For this example, the CRON task is hosted on a local host. -## Checkpoint 4: 🤝 Connect the Frontend to the Backend +## Checkpoint 4: 🤝 Connect the Frontend to the Backend {#checkpoint-4--connect-the-frontend-to-the-backend} Now that you have the smart contracts deployed, and the cron job running, it's time to check out the frontend of your dapp. @@ -240,7 +240,7 @@ You will need to add some Futurenet network lumens to your wallet to interact wi > Note: These are test lumens for use with Futurenet and cannot be used on Mainnet -## Checkpoint 5: 🧿 Oracle Insights +## Checkpoint 5: 🧿 Oracle Insights {#checkpoint-5--oracle-insights} Gaze into the crystal ball of APIs and retrive the price feed from the all connected internet. Data at your fingertips, at one time an abyss but pioneers have paved the way for many to cross. Here you will reach into the realm of off-chain data and pull out the price of BTC. In this section, you will mint tokens and deposit Bitcoin (BTC) into the donation contract. The conversion to USD will utilize the oracle price feed to ensure your donation is aligned with the current BTC to USD conversion rate. @@ -260,7 +260,7 @@ Gaze into the crystal ball of APIs and retrive the price feed from the all conne -#### Connect a Wallet +#### Connect a Wallet {#connect-a-wallet} Open the dapp frontend and click the "connect" and choose the wallet you want to use. For this example, you will use Freighter. @@ -271,7 +271,7 @@ Open the dapp frontend and click the "connect" and choose the wallet you want to -#### Mint USDC and BTC +#### Mint USDC and BTC {#mint-usdc-and-btc} Open the `Mint BTC Tokens` tab, enter the desired token amount, and click the "Mint" button. @@ -280,7 +280,7 @@ Open the `Mint BTC Tokens` tab, enter the desired token amount, and click the "M -#### Approve Transaction +#### Approve Transaction {#approve-transaction} You should see a popup from Freighter asking you to sign the transactions. Click on "Approve" and wait for the transaction to be confirmed. @@ -289,7 +289,7 @@ You should see a popup from Freighter asking you to sign the transactions. Click -#### Check Updated Balance +#### Check Updated Balance {#check-updated-balance} You should see an updated balance in the account balance component. @@ -310,7 +310,7 @@ You should see an updated balance in the account balance component. -#### Deposit into the Donation Contract +#### Deposit into the Donation Contract {#deposit-into-the-donation-contract} Open the frontend, enter the amount of BTC in USD that you would like to donate, then click the "Calculate" button. You should see the amount of BTC that you need to deposit in order to donate the specified amount in USD. For example, if you enter 35923.82 USD, you should see 1 BTC. @@ -319,7 +319,7 @@ Open the frontend, enter the amount of BTC in USD that you would like to donate, -#### Approve Transaction +#### Approve Transaction {#approve-transaction-1} Click on "Approve" and wait for the transaction to be confirmed. @@ -327,7 +327,7 @@ Click on "Approve" and wait for the transaction to be confirmed. -#### Check Updated Balance +#### Check Updated Balance {#check-updated-balance-1} Once the transaction is confirmed, you should see the contract and your wallet balances update in the `Donate` and `Mint BTC Tokens` tabs, respectively. @@ -346,7 +346,7 @@ Once the transaction is confirmed, you should see the contract and your wallet b {/* Funding completed */} -## Checkpoint 6: 🚢 Ship it! 🚁 +## Checkpoint 6: 🚢 Ship it! 🚁 {#checkpoint-6--ship-it-} In this step, you will deploy your dapp to a hosting platform so that it can be accessed by anyone with an internet connection. Note that it's on futurenet, the network used for testing, not mainnet for production use. You can use any hosting platform you like, but for demonstration purposes, this section will use [Vercel](https://vercel.com/). Vercel is a cloud platform for static sites and serverless functions that offers a free tier for developers. It also has a built-in integration with GitHub, which makes it easy to deploy your dapp directly from your GitHub repository. @@ -471,7 +471,7 @@ You can now visit the preview link to see your deployed dapp! 🎉 Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create your Freighter account on Futurenet. -## Checkpoint 7: 💪 Pass the Challenge! +## Checkpoint 7: 💪 Pass the Challenge! {#checkpoint-7--pass-the-challenge} Now it's time to submit your work! @@ -485,7 +485,7 @@ Join [our Community in Discord](https://discord.gg/stellardev) in case you have ::: -## Checkpoint 8: ✅ Check your work! +## Checkpoint 8: ✅ Check your work! {#checkpoint-8--check-your-work} In order to successfully complete this challenge, your work needs to be checked. Please, follow this steps: @@ -508,7 +508,7 @@ Public Key: GBSXUXZSA2VEXN5VGOWE5ODAJLC575JCMWRJ4FFRDWSTRCJ123456789 Invite a friend to try out your dapp and ask them to provide feedback! -## ⚔️ Side Quests +## ⚔️ Side Quests {#️-side-quests} 🪬 Add a new feature to your dapp (e.g. add a new price feed, add a new token, etc.) @@ -516,7 +516,7 @@ Invite a friend to try out your dapp and ask them to provide feedback! 💡 Develop a function to respond to a significant BTC price change. -## 📚 User Workflows Checklist +## 📚 User Workflows Checklist {#-user-workflows-checklist} During this exercise you should be able to: @@ -535,6 +535,6 @@ Then via the web UI, you should be able to: - Deposit an asset - See your deposit(s) appear on the page as the transactions are confirmed -## 🛡️🗡️ Take On More Challenges +## 🛡️🗡️ Take On More Challenges {#️️-take-on-more-challenges} View your progress and take on more challenges by visiting your [User Dashboard!](../dashboard) diff --git a/src/pages/index.mdx b/src/pages/index.mdx index 4260348ad..0e2df57a8 100644 --- a/src/pages/index.mdx +++ b/src/pages/index.mdx @@ -14,43 +14,43 @@ If you can’t find answers to your questions in the docs, search for your answe -## Navigating the docs +## Navigating the docs {#navigating-the-docs} -### [Build](/docs/build) +### [Build](/docs/build) {#build} Contains tutorials and how-to guides for writing smart contracts, building applications, interacting with the network, and more. -### [Learn](/docs/learn/fundamentals) +### [Learn](/docs/learn/fundamentals) {#learn} Find all informational and conceptual content here. Learn about Stellar fundamentals like how accounts and transactions function, dive deeper into the functionality of each operation, discover how fees work, and more. -### [Tokens](/docs/tokens) +### [Tokens](/docs/tokens) {#tokens} Information on how to issue assets on the Stellar network and create custom smart contract tokens. -### [Data](/docs/data) +### [Data](/docs/data) {#data} Discover various data availability options: RPC, Hubble, and Horizon. -### [Tools](/docs/tools) +### [Tools](/docs/tools) {#tools} Learn about all the available tools at your disposal for building on, interacting with, or just watching the Stellar network. Also, find information on how to use the Anchor Platform or Stellar Disbursement Platform. -### [Networks](/docs/networks) +### [Networks](/docs/networks) {#networks} Information about delpoyed networks (Mainnet, Testnet, and Futurenet), current software versions, and resource limitations and fees. -### [Validators](/docs/validators) +### [Validators](/docs/validators) {#validators} Everything you'll need to know if you want to run, operate, and maintain a core validator node on the Stellar network. -## Contribute to the docs and leave feedback +## Contribute to the docs and leave feedback {#contribute-to-the-docs-and-leave-feedback} Stellar’s Developer Documentation is open-source, and contributions to the docs are encouraged. You can file an issue or pull request to add new content, suggest revisions to existing content, submit suggestions, report bugs, and more in the [Stellar Docs GitHub Repo](https://github.com/stellar/stellar-docs). Also, feel free to leave any additional feedback by filing issues in the various other [Stellar repos](https://github.com/stellar). -## Developer resources +## Developer resources {#developer-resources} Interact with other Stellar developers, keep up with ecosystem standards and protocol upgrades, and learn about upcoming events. diff --git a/src/pages/platforms.mdx b/src/pages/platforms.mdx index 2fac6fdb1..5d4dc9b5b 100644 --- a/src/pages/platforms.mdx +++ b/src/pages/platforms.mdx @@ -2,13 +2,13 @@ SDF has open-sourced some "platforms" that make it easier to accomplish certain things on the network. -## Anchor Platform +## Anchor Platform {#anchor-platform} The Anchor Platform is a set of tools and APIs that enable developers and businesses to build their own on and off-ramp services for the Stellar network. It provides a standardized interface, including the implementation of several Stellar Ecosystem Proposals (SEPs), to make it easy for businesses to integrate with Stellar-based wallets and exchanges. [Learn more about the Anchor Platform API here!](/platforms/anchor-platform) -## Stellar Disbursement Platform +## Stellar Disbursement Platform {#stellar-disbursement-platform} The Stellar Disbursement Platform (SDP) enables organizations to disburse bulk payments to recipients using Stellar. From 1de14cfa4ff5aaf8ad47a5f631b348d0e1db1e6d Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 9 Dec 2024 11:04:52 -0600 Subject: [PATCH 40/60] Revert "write explicit heading ids for markdown docs" This reverts commit 5b420a173084a25332e19f023b7078fa47e15fc1. --- .../version-2.10/admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../version-2.10/admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../admin-guide/sep24/example.mdx | 10 +- .../version-2.10/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 52 ++-- .../admin-guide/sep6/configuration.mdx | 12 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- .../version-2.11/admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../version-2.11/admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../admin-guide/sep24/example.mdx | 10 +- .../version-2.11/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 52 ++-- .../admin-guide/sep6/configuration.mdx | 12 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- .../version-2.8/admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../version-2.8/admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../version-2.8/admin-guide/sep24/example.mdx | 10 +- .../version-2.8/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 54 ++-- .../admin-guide/sep6/configuration.mdx | 12 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- .../version-2.9/admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../version-2.9/admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../version-2.9/admin-guide/sep24/example.mdx | 10 +- .../version-2.9/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 52 ++-- .../admin-guide/sep6/configuration.mdx | 12 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- docs/README.mdx | 16 +- docs/build/README.mdx | 6 +- .../application-design-considerations.mdx | 20 +- docs/build/apps/dapp-frontend.mdx | 32 +-- .../account-creation.mdx | 10 +- .../anchor-integration/sep10.mdx | 8 +- .../anchor-integration/sep24.mdx | 14 +- .../anchor-integration/sep6.mdx | 20 +- .../anchor-integration/setup.mdx | 2 +- .../confirmation-modal.mdx | 12 +- .../contacts-list.mdx | 12 +- .../manage-trust.mdx | 8 +- .../example-application-tutorial/overview.mdx | 12 +- .../path-payment.mdx | 8 +- .../example-application-tutorial/payment.mdx | 8 +- .../querying-data.mdx | 18 +- .../ingest-sdk/ingestion-pipeline-code.mdx | 8 +- docs/build/apps/ingest-sdk/overview.mdx | 22 +- .../moneygram-access-integration-guide.mdx | 42 +-- docs/build/apps/overview.mdx | 4 +- docs/build/apps/smart-wallets.mdx | 22 +- docs/build/apps/wallet/README.md | 14 +- .../wallet/component/dart/configClient.mdx | 2 +- .../apps/wallet/component/kt/configClient.mdx | 4 +- .../apps/wallet/component/ts/configClient.mdx | 2 +- docs/build/apps/wallet/intro.mdx | 8 +- docs/build/apps/wallet/sep10.mdx | 12 +- docs/build/apps/wallet/sep24.mdx | 18 +- docs/build/apps/wallet/sep30.mdx | 6 +- docs/build/apps/wallet/sep38.mdx | 14 +- docs/build/apps/wallet/sep6.mdx | 22 +- docs/build/apps/wallet/sep7.mdx | 4 +- docs/build/apps/wallet/stellar.mdx | 42 +-- .../create-restoration-footprint-js.mdx | 2 +- .../guides/archival/test-ttl-extension.mdx | 4 +- .../guides/basics/automate-reset-data.mdx | 16 +- docs/build/guides/basics/create-account.mdx | 4 +- .../basics/follow-received-payments.mdx | 12 +- .../basics/send-and-receive-payments.mdx | 8 +- .../conventions/check-auth-tutorials.mdx | 52 ++-- .../guides/conventions/cross-contract.mdx | 12 +- .../guides/conventions/deploy-contract.mdx | 18 +- .../conventions/deploy-sac-with-code.mdx | 8 +- .../guides/conventions/extending-wasm-ttl.mdx | 8 +- .../conventions/upgrading-contracts.mdx | 16 +- .../conversions/address-conversions.mdx | 4 +- .../guides/conversions/bytes-conversions.mdx | 6 +- .../guides/conversions/scval-conversions.mdx | 6 +- .../guides/conversions/string-conversions.mdx | 6 +- docs/build/guides/dapps/docker.mdx | 8 +- docs/build/guides/dapps/frontend-guide.mdx | 68 ++--- docs/build/guides/dapps/initialization.mdx | 8 +- docs/build/guides/dapps/react.mdx | 10 +- .../dapps/soroban-contract-init-template.mdx | 34 +-- docs/build/guides/dapps/state-archival.mdx | 24 +- .../dapps/working-with-contract-specs.mdx | 40 +-- docs/build/guides/events/consume.mdx | 12 +- docs/build/guides/events/ingest.mdx | 10 +- .../fees/analyzing-smart-contract-cost.mdx | 72 +++--- .../freighter/integrate-freighter-react.mdx | 2 +- .../storage/choosing-the-right-storage.mdx | 10 +- .../detecting-changes-with-test-snapshots.mdx | 4 +- docs/build/guides/tokens/deploying-a-sac.mdx | 14 +- .../guides/tokens/stellar-asset-contract.mdx | 6 +- .../install-deploy-contract-with-code.mdx | 20 +- .../transactions/install-wasm-bytecode.mdx | 8 +- .../simulateTransaction-Deep-Dive.mdx | 30 +-- .../example-contracts/TEMPLATE.mdx | 16 +- .../example-contracts/alloc.mdx | 8 +- .../example-contracts/atomic-swap.mdx | 12 +- .../example-contracts/auth.mdx | 18 +- .../example-contracts/cross-contract-call.mdx | 16 +- .../example-contracts/custom-account.mdx | 16 +- .../example-contracts/custom-types.mdx | 18 +- .../example-contracts/deployer.mdx | 24 +- .../example-contracts/errors.mdx | 22 +- .../example-contracts/events.mdx | 18 +- .../example-contracts/fuzzing.mdx | 18 +- .../example-contracts/liquidity-pool.mdx | 22 +- .../example-contracts/logging.mdx | 20 +- .../example-contracts/tokens.mdx | 16 +- .../example-contracts/workspace.mdx | 18 +- .../deploy-increment-contract.mdx | 6 +- .../getting-started/deploy-to-testnet.mdx | 6 +- .../getting-started/hello-world.mdx | 26 +- .../smart-contracts/getting-started/setup.mdx | 18 +- .../getting-started/storing-data.mdx | 18 +- docs/build/smart-contracts/overview.mdx | 8 +- docs/data/README.mdx | 12 +- docs/data/galexie/README.mdx | 10 +- docs/data/galexie/admin_guide/configuring.mdx | 2 +- docs/data/galexie/admin_guide/monitoring.mdx | 4 +- .../galexie/admin_guide/prerequisites.mdx | 8 +- docs/data/galexie/admin_guide/running.mdx | 8 +- docs/data/galexie/admin_guide/setup.mdx | 4 +- docs/data/horizon/README.mdx | 4 +- docs/data/horizon/admin-guide/configuring.mdx | 34 +-- .../admin-guide/ingestion-filtering.mdx | 14 +- docs/data/horizon/admin-guide/ingestion.mdx | 18 +- docs/data/horizon/admin-guide/installing.mdx | 16 +- docs/data/horizon/admin-guide/monitoring.mdx | 16 +- docs/data/horizon/admin-guide/overview.mdx | 2 +- .../horizon/admin-guide/prerequisites.mdx | 12 +- docs/data/horizon/admin-guide/running.mdx | 8 +- docs/data/horizon/admin-guide/scaling.mdx | 8 +- docs/data/horizon/admin-guide/upgrading.mdx | 12 +- .../api-reference/errors/error-handling.mdx | 24 +- .../api-reference/resources/effects/types.mdx | 18 +- docs/data/horizon/horizon-providers.mdx | 4 +- docs/data/hubble/README.mdx | 6 +- .../data-curation/architecture.mdx | 2 +- .../data-curation/getting-started.mdx | 16 +- .../admin-guide/data-curation/overview.mdx | 2 +- .../architecture.mdx | 2 +- .../getting-started.mdx | 20 +- .../scheduling-and-orchestration/overview.mdx | 2 +- .../source-system-ingestion/architecture.mdx | 2 +- .../getting-started.mdx | 30 +-- .../source-system-ingestion/overview.mdx | 2 +- .../visualization/getting-started.mdx | 6 +- docs/data/hubble/analyst-guide/connecting.mdx | 8 +- .../analyst-guide/creating-visualizations.mdx | 12 +- .../analyst-guide/optimizing-queries.mdx | 18 +- .../queries-for-horizon-like-data.mdx | 106 ++++---- .../hubble/analyst-guide/viewing-metadata.mdx | 4 +- docs/data/hubble/analytics-platforms.mdx | 6 +- .../data-catalog/data-dictionary/accounts.mdx | 4 +- .../data-dictionary/claimable-balances.mdx | 4 +- .../data-dictionary/contract-code.mdx | 4 +- .../data-dictionary/contract-data.mdx | 4 +- .../enriched-history-operations.mdx | 4 +- .../data-dictionary/history-assets.mdx | 4 +- .../data-dictionary/history-effects.mdx | 4 +- .../data-dictionary/history-ledgers.mdx | 4 +- .../data-dictionary/history-operations.mdx | 4 +- .../data-dictionary/history-trades.mdx | 4 +- .../data-dictionary/history-transactions.mdx | 4 +- .../data-dictionary/liquidity-pools.mdx | 4 +- .../data-catalog/data-dictionary/offers.mdx | 4 +- .../data-dictionary/trustlines.mdx | 4 +- .../data-catalog/data-dictionary/ttl.mdx | 4 +- docs/data/rpc/README.mdx | 2 +- docs/data/rpc/admin-guide.mdx | 30 +-- docs/data/rpc/api-reference/json-rpc.mdx | 2 +- .../methods/getLedgerEntries.mdx | 24 +- .../api-reference/methods/getTransaction.mdx | 2 +- .../api-reference/methods/sendTransaction.mdx | 2 +- docs/data/rpc/rpc-providers.mdx | 6 +- .../stellar-transaction.mdx | 20 +- .../contract-interactions/tests.mdx | 2 +- .../transaction-simulation.mdx | 4 +- .../contract-lifecycle.mdx | 10 +- .../environment-concepts.mdx | 10 +- .../contract-development/events.mdx | 18 +- .../contract-development/rust-dialect.mdx | 12 +- .../types/built-in-types.mdx | 26 +- .../types/custom-types.mdx | 8 +- .../types/fully-typed-contracts.mdx | 6 +- docs/learn/encyclopedia/data-format/xdr.mdx | 10 +- .../errors-and-debugging/debugging-errors.mdx | 12 +- .../errors-and-debugging/debugging.mdx | 4 +- .../errors-and-debugging/errors.mdx | 2 +- .../network-configuration/federation.mdx | 12 +- .../network-configuration/ledger-headers.mdx | 36 +-- ...uidity-on-stellar-sdex-liquidity-pools.mdx | 44 ++-- .../encyclopedia/security/authorization.mdx | 36 +-- .../security/securing-web-based-projects.mdx | 22 +- .../security/signatures-multisig.mdx | 22 +- .../encyclopedia/storage/persisting-data.mdx | 16 +- .../encyclopedia/storage/state-archival.mdx | 46 ++-- .../claimable-balances.mdx | 12 +- .../transactions-specialized/clawbacks.mdx | 20 +- .../fee-bump-transactions.mdx | 20 +- .../transactions-specialized/memos.mdx | 2 +- .../path-payments.mdx | 8 +- .../pooled-accounts-muxed-accounts-memos.mdx | 28 +- .../sponsored-reserves.mdx | 26 +- docs/learn/fundamentals/anchors.mdx | 2 +- .../fees-resource-limits-metering.mdx | 34 +-- docs/learn/fundamentals/lumens.mdx | 14 +- docs/learn/fundamentals/networks.mdx | 22 +- .../stellar-consensus-protocol.mdx | 20 +- .../stellar-data-structures/accounts.mdx | 8 +- .../stellar-data-structures/assets.mdx | 18 +- .../stellar-data-structures/contracts.mdx | 12 +- .../stellar-ecosystem-proposals.mdx | 22 +- docs/learn/fundamentals/stellar-stack.mdx | 10 +- .../transactions/list-of-operations.mdx | 52 ++-- .../operations-and-transactions.mdx | 46 ++-- .../transactions/transaction-lifecycle.mdx | 22 +- docs/learn/glossary.mdx | 150 +++++------ docs/learn/interactive/dapps/introduction.mdx | 6 +- .../interactive/dapps/scaffold-soroban.mdx | 18 +- .../evm/introduction-to-solidity-and-rust.mdx | 8 +- .../migrate/evm/smart-contract-deployment.mdx | 40 +-- .../solidity-and-rust-advanced-concepts.mdx | 72 +++--- .../migrate/evm/solidity-and-rust-basics.mdx | 42 +-- docs/networks/resource-limits-fees.mdx | 6 +- docs/networks/software-versions.mdx | 244 +++++++++--------- docs/tokens/README.mdx | 10 +- docs/tokens/anatomy-of-an-asset.mdx | 6 +- docs/tokens/control-asset-access.mdx | 28 +- docs/tokens/how-to-issue-an-asset.mdx | 32 +-- docs/tokens/publishing-asset-info.mdx | 32 +-- docs/tokens/stellar-asset-contract.mdx | 14 +- docs/tokens/token-interface.mdx | 16 +- docs/tools/README.mdx | 10 +- docs/tools/developer-tools/IDEs.mdx | 4 +- .../developer-tools/analytics-platforms.mdx | 4 +- docs/tools/developer-tools/anchor-tools.mdx | 6 +- docs/tools/developer-tools/asset-tools.mdx | 2 +- .../tools/developer-tools/block-explorers.mdx | 8 +- docs/tools/developer-tools/cli/README.mdx | 4 +- .../tools/developer-tools/cli/install-cli.mdx | 6 +- docs/tools/developer-tools/data-indexers.mdx | 12 +- .../developer-tools/jupyter-notebooks.mdx | 6 +- docs/tools/developer-tools/lab/README.mdx | 8 +- docs/tools/developer-tools/lab/account.mdx | 6 +- .../lab/quickstart-with-lab.mdx | 8 +- .../developer-tools/lab/transactions.mdx | 10 +- .../developer-tools/network-insights.mdx | 2 +- docs/tools/developer-tools/network-status.mdx | 6 +- .../developer-tools/node-operator-tools.mdx | 2 +- docs/tools/developer-tools/security-tools.mdx | 2 +- .../smart-contract-resources.mdx | 8 +- docs/tools/developer-tools/wallets.mdx | 8 +- docs/tools/sdks/build-your-own.mdx | 26 +- docs/tools/sdks/library.mdx | 28 +- docs/validators/README.mdx | 16 +- docs/validators/admin-guide/advanced.mdx | 10 +- docs/validators/admin-guide/commands.mdx | 16 +- docs/validators/admin-guide/configuring.mdx | 36 +-- .../admin-guide/environment-preparation.mdx | 14 +- docs/validators/admin-guide/installation.mdx | 12 +- docs/validators/admin-guide/maintenance.mdx | 4 +- docs/validators/admin-guide/monitoring.mdx | 44 ++-- .../admin-guide/network-upgrades.mdx | 6 +- docs/validators/admin-guide/prerequisites.mdx | 20 +- .../publishing-history-archives.mdx | 10 +- docs/validators/admin-guide/running-node.mdx | 14 +- .../admin-guide/soroban-settings.mdx | 22 +- docs/validators/tier-1-orgs.mdx | 16 +- platforms/anchor-platform/CONTRIBUTING.md | 38 +-- .../admin-guide/architecture.mdx | 22 +- .../custody-services/configuration.mdx | 6 +- .../custody-services/fireblocks/example.mdx | 12 +- .../admin-guide/events/delivery.mdx | 6 +- .../admin-guide/events/integration.mdx | 14 +- .../admin-guide/getting-started.mdx | 16 +- .../admin-guide/sep10/README.mdx | 6 +- .../admin-guide/sep24/configuration.mdx | 6 +- .../admin-guide/sep24/example.mdx | 10 +- .../anchor-platform/admin-guide/sep24/faq.mdx | 8 +- .../admin-guide/sep24/getting-started.mdx | 2 +- .../admin-guide/sep24/integration.mdx | 78 +++--- .../sep24/setting-up-production-server.mdx | 22 +- .../admin-guide/sep31/configuration.mdx | 10 +- .../admin-guide/sep31/integration.mdx | 48 ++-- .../admin-guide/sep6/configuration.mdx | 14 +- .../admin-guide/sep6/getting-started.mdx | 2 +- .../admin-guide/sep6/integration.mdx | 74 +++--- .../anchor-platform-integration-points.mdx | 6 +- .../admin-guide/configuring-sdp.mdx | 44 ++-- .../admin-guide/deploy-the-sdp.mdx | 12 +- .../admin-guide/design-and-architecture.mdx | 2 +- .../admin-guide/getting-started.mdx | 60 ++--- .../making-your-wallet-sdp-ready.mdx | 10 +- .../admin-guide/secure-operation-manual.mdx | 12 +- ...ingle-tenant-to-multi-tenant-migration.mdx | 50 ++-- .../admin-guide/tenant-provisioning.mdx | 20 +- .../admin-guide/user-interface/wallets.mdx | 2 +- .../challenges/challenge-0-crowdfund.mdx | 32 +-- .../dapps/challenges/challenge-1-payment.mdx | 32 +-- .../challenges/challenge-2-liquidity-pool.mdx | 42 +-- .../dapps/challenges/challenge-3-oracle.mdx | 38 +-- src/pages/index.mdx | 20 +- src/pages/platforms.mdx | 4 +- 349 files changed, 3049 insertions(+), 3049 deletions(-) diff --git a/ap_versioned_docs/version-2.10/admin-guide/architecture.mdx b/ap_versioned_docs/version-2.10/admin-guide/architecture.mdx index 7e1fd14b7..d9abf6435 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/architecture.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture {#architecture} +## Architecture Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture {#fundamental-architecture} +### Fundamental Architecture The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client {#client} +#### Client The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server {#sep-server} +#### SEP Server The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server {#business-server} +#### Business Server The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server {#platform-server} +#### Platform Server The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database {#database} +#### Database The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture {#complete-architecture} +### Complete Architecture In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service {#event-service} +#### Event Service The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server {#custody-server} +#### Custody Server The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer {#stellar-observer} +#### Stellar Observer The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/ap_versioned_docs/version-2.10/admin-guide/custody-services/configuration.mdx b/ap_versioned_docs/version-2.10/admin-guide/custody-services/configuration.mdx index e33184b64..c6dd3abfb 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/custody-services/configuration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration {#custody-server-configuration} +## Custody Server Configuration If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:2.10.0 --custody-server -## Anchor Platform Configuration {#anchor-platform-configuration} +## Anchor Platform Configuration Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} +## Kotlin Reference Server Configuration Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/ap_versioned_docs/version-2.10/admin-guide/custody-services/fireblocks/example.mdx b/ap_versioned_docs/version-2.10/admin-guide/custody-services/fireblocks/example.mdx index 9b3b8bf30..613d31bca 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/custody-services/fireblocks/example.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} +### SEP-24 deposit flow with webhook: - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} +### SEP-24 deposit flow with reconciliation job: - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} +### SEP-24 withdrawal flow with webhook: - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} +### SEP-24 withdrawal flow with reconciliation job: - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} +### SEP-31 receive flow with webhook: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} +### SEP-31 receive flow with reconciliation job: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/ap_versioned_docs/version-2.10/admin-guide/events/delivery.mdx b/ap_versioned_docs/version-2.10/admin-guide/events/delivery.mdx index 3c5f30142..cd6d3148e 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/events/delivery.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees {#delivery-guarantees} +## Delivery Guarantees Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees {#client-delivery-guarantees} +### Client Delivery Guarantees For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees {#business-server-delivery-guarantees} +### Business Server Delivery Guarantees The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/ap_versioned_docs/version-2.10/admin-guide/events/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/events/integration.mdx index 15582d435..b2638a348 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/events/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements {#requirements} +## Requirements Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration {#configuration} +## Configuration First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events {#receiving-events} +## Receiving Events The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application {#as-a-client-application} +### As a Client Application Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing {#callback-signing} +#### Callback Signing Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server {#as-a-business-server} +### As a Business Server In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration {#configuration-1} +#### Configuration The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/ap_versioned_docs/version-2.10/admin-guide/getting-started.mdx b/ap_versioned_docs/version-2.10/admin-guide/getting-started.mdx index 89d0fa0ba..ebaccada2 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/getting-started.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation {#installation} +## Installation import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:2.10.0 -## Set Up the Development Environment {#set-up-the-development-environment} +## Set Up the Development Environment In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration {#configuration} +## Configuration The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server {#changing-port-of-the-platform-server} +### Changing Port of the Platform Server For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets {#specify-your-services-assets} +### Specify Your Service's Assets Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence {#add-data-persistence} +### Add Data Persistence The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication {#configure-platform-api-authentication} +### Configure Platform API Authentication To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags {#passing-jvm-flags} +### Passing JVM flags Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep10/README.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep10/README.mdx index fbd4a2a22..1db24083f 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep10/README.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication {#enable-stellar-authentication} +## Enable Stellar Authentication Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution {#config-with-client-attribution} +## Config With Client Attribution `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -131,7 +131,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/configuration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/configuration.mdx index 906850f4f..09c8dc709 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/configuration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} +## Enable Hosted Deposits & Withdrawals Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -109,7 +109,7 @@ SECRET_SEP24_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busi `SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET` and `SECRET_SEP24_MORE_INFO_URL_JWT_SECRET` are encryption keys that the Anchor Platform will use to generate short-lived tokens it will add to the URLs provided to the wallet. Your business server must also have these keys in its environment so it can verify the token's signature. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/example.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/example.mdx index b1ddfa8d6..3ec5be0e1 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/example.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience {#building-a-web-based-user-experience} +## Building a Web-Based User Experience The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication {#authentication} +### Authentication If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform {#providing-updates-to-the-platform} +## Providing Updates to the Platform Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform {#fetching-updates-from-the-platform} +## Fetching Updates from the Platform If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation {#full-example-implementation} +## Full Example Implementation Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/faq.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/faq.mdx index ee5eb71da..5972a06cf 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/faq.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? {#how-to-use-jwts} +### How To Use JWTs? As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? {#how-to-provide-fees} +### How To Provide Fees? Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? {#how-to-identify-the-user-account} +### How to identify the user account? You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? {#how-to-identify-the-wallet} +### How to identify the wallet? Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/getting-started.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/getting-started.mdx index e77894428..ce1d1dbf4 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/getting-started.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience a deposit and withdrawal goes something like this: diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx index bf3573895..865922840 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} +## Updating Deposit Transaction Via JSON-RPC SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information {#processing-kyc-information} +### Processing KYC Information :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction status to `expired`. @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction {#on-hold-transaction} +### On-Hold Transaction In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} +## Updating Withdrawal Transaction Via JSON-RPC This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information {#processing-kyc-information-1} +### Processing KYC Information This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction {#on-hold-transaction-1} +### On-Hold Transaction Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/setting-up-production-server.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/setting-up-production-server.mdx index 68c15d0bb..f631e5dbf 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/setting-up-production-server.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment {#deploying-a-secure-environment} +## Deploying a Secure Environment Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC {#connecting-to-real-kyc} +## Connecting to Real KYC Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} +## Pre-Filling the KYC Form Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} +## Connecting to Real Banking Rails Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases {#testing-edge-cases} +## Testing Edge Cases Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests {#general-tests} +### General Tests - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests {#kyc-tests} +### KYC Tests - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test {#interactive-test} +### Interactive Test - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests {#security-tests} +### Security Tests - Make sure platform endpoints are secured -## Polishing and Internationalization {#polishing-and-internationalization} +## Polishing and Internationalization Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets {#connecting-to-wallets} +## Connecting to Wallets All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep31/configuration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep31/configuration.mdx index 7df1dde9b..d68d781de 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep31/configuration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments {#enable-cross-border-payments} +## Enable Cross Border Payments Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API {#enable-the-customer-kyc-api} +## Enable the Customer KYC API Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API {#enable-the-rfq-api} +## Enable the RFQ API Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication {#configure-callback-api-authentication} +## Configure Callback API Authentication Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep31/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep31/integration.mdx index 5fcaceb04..12407473b 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep31/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep31/integration.mdx @@ -18,7 +18,7 @@ The following may also be required depending on your use case: - [`GET /unique_address`][get-unique-address] if your business uses a custody service for on-chain assets - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server {#create-a-business-server} +## Create a Business Server First, lets create a business server and add it to our docker compose file. @@ -71,11 +71,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints {#customer-callback-endpoints} +## Customer Callback Endpoints The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers {#identifying-customers} +### Identifying Customers Customers can be identified using two approaches. @@ -134,13 +134,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types {#customer-types} +### Customer Types Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet {#test-with-the-demo-wallet} +### Test with the Demo Wallet You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -157,33 +157,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint {#rate-callback-endpoint} +## Rate Callback Endpoint Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} +### Firm vs. Indicative Quotes Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID {#using-the-client-id} +### Using the Client ID Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods {#delivery-methods} +### Delivery Methods It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates {#fetching-transaction-status-updates} +## Fetching Transaction Status Updates To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer {#running-the-stellar-observer} +### Running the Stellar Observer The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -203,7 +203,7 @@ services: -### Polling for Received Payments {#polling-for-received-payments} +### Polling for Received Payments The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -219,7 +219,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} +## Updating Transaction Via JSON-RPC SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -239,7 +239,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds SEP-31 Transactions should initially be in the `pending_sender` status. The Receiving Anchor waits to receive the payment identified by the stellar_memo included in the POST /transactions response. @@ -286,7 +286,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -321,7 +321,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Verifying Customer Information {#verifying-customer-information} +### Verifying Customer Information In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -392,7 +392,7 @@ To execute this, you need to run: -### Do Stellar Refund {#do-stellar-refund} +### Do Stellar Refund Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -441,7 +441,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent {#refund-sent} +### Refund Sent There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -491,7 +491,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -530,7 +530,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -569,7 +569,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -602,11 +602,11 @@ To execute this, you need to run: -## Fee Callback Endpoint {#fee-callback-endpoint} +## Fee Callback Endpoint Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time the funds are paid out to the recipient. In this case, the Anchor Platform will not make a `GET /rate` request, but you will still need to provide the fee your business will charge for these types of transactions using the [`GET /fee`][get-fee] endpoint. -### Configuration {#configuration} +### Configuration You can enable these types of transactions by updating your `assets.yaml` file configuration: @@ -621,11 +621,11 @@ assets: -## Unique Address Callback Endpoint {#unique-address-callback-endpoint} +## Unique Address Callback Endpoint Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so that the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments. In this case, the business must request the custodian to generate the Stellar account & memo. This is done by using the [`GET /unique_address` endpoint][get-unique-address]. -### Configuration {#configuration-1} +### Configuration To configure the Anchor Platform to make these requests, add the following to your configuration: diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep6/configuration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep6/configuration.mdx index 8996dc626..dea786738 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep6/configuration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} +## Enable Programmatic Deposits & Withdrawals Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File {#modify-a-stellar-info-file} +### Modify a Stellar Info File Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File {#modify-the-assets-configuration-file} +### Modify the Assets Configuration File Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts {#managing-distribution-accounts} +### Managing Distribution Accounts Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} +### Enable Callbacks to the Business Server Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -177,7 +177,7 @@ SECRET_SEP6_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busin See the [KYC API][platform-api-kyc] and [Rates API][sep38] for details on the endpoints that must be implemented on your business server. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep6/getting-started.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep6/getting-started.mdx index fb4e1293c..3a1d875e9 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep6/getting-started.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx index c358c8798..87a6919b9 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information {#customer-information} +### Customer Information The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} +## Updating Deposit (Exchange) Transaction Via JSON-RPC SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information {#verifying-kyc-information} +### Verifying KYC Information Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -129,7 +129,7 @@ To execute this, you need to run: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -201,7 +201,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide updated transaction information. @@ -253,7 +253,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -288,7 +288,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -326,7 +326,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -369,7 +369,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -408,7 +408,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -450,7 +450,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent {#refund-sent} +### Refund Sent Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -500,11 +500,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -543,7 +543,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire transactions that have been abandoned by the user after some time. It's good practice to clean up inactive transactions in the `incomplete` status. To do so, make the following JSON-RPC request to expire a transaction. @@ -582,7 +582,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -615,7 +615,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -637,7 +637,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -718,7 +718,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -767,7 +767,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -812,7 +812,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -846,7 +846,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -880,7 +880,7 @@ To execute this, you need to run: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -915,11 +915,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent-1} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -968,19 +968,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/ap_versioned_docs/version-2.11/admin-guide/architecture.mdx b/ap_versioned_docs/version-2.11/admin-guide/architecture.mdx index 7e1fd14b7..d9abf6435 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/architecture.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture {#architecture} +## Architecture Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture {#fundamental-architecture} +### Fundamental Architecture The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client {#client} +#### Client The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server {#sep-server} +#### SEP Server The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server {#business-server} +#### Business Server The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server {#platform-server} +#### Platform Server The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database {#database} +#### Database The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture {#complete-architecture} +### Complete Architecture In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service {#event-service} +#### Event Service The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server {#custody-server} +#### Custody Server The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer {#stellar-observer} +#### Stellar Observer The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/ap_versioned_docs/version-2.11/admin-guide/custody-services/configuration.mdx b/ap_versioned_docs/version-2.11/admin-guide/custody-services/configuration.mdx index db8a2a3b0..d202cb386 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/custody-services/configuration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration {#custody-server-configuration} +## Custody Server Configuration If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:2.11.0 --custody-server -## Anchor Platform Configuration {#anchor-platform-configuration} +## Anchor Platform Configuration Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} +## Kotlin Reference Server Configuration Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/ap_versioned_docs/version-2.11/admin-guide/custody-services/fireblocks/example.mdx b/ap_versioned_docs/version-2.11/admin-guide/custody-services/fireblocks/example.mdx index 9b3b8bf30..613d31bca 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/custody-services/fireblocks/example.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} +### SEP-24 deposit flow with webhook: - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} +### SEP-24 deposit flow with reconciliation job: - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} +### SEP-24 withdrawal flow with webhook: - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} +### SEP-24 withdrawal flow with reconciliation job: - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} +### SEP-31 receive flow with webhook: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} +### SEP-31 receive flow with reconciliation job: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/ap_versioned_docs/version-2.11/admin-guide/events/delivery.mdx b/ap_versioned_docs/version-2.11/admin-guide/events/delivery.mdx index 3c5f30142..cd6d3148e 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/events/delivery.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees {#delivery-guarantees} +## Delivery Guarantees Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees {#client-delivery-guarantees} +### Client Delivery Guarantees For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees {#business-server-delivery-guarantees} +### Business Server Delivery Guarantees The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/ap_versioned_docs/version-2.11/admin-guide/events/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/events/integration.mdx index 15582d435..b2638a348 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/events/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements {#requirements} +## Requirements Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration {#configuration} +## Configuration First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events {#receiving-events} +## Receiving Events The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application {#as-a-client-application} +### As a Client Application Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing {#callback-signing} +#### Callback Signing Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server {#as-a-business-server} +### As a Business Server In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration {#configuration-1} +#### Configuration The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/ap_versioned_docs/version-2.11/admin-guide/getting-started.mdx b/ap_versioned_docs/version-2.11/admin-guide/getting-started.mdx index 48a5d93a6..992e614b2 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/getting-started.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation {#installation} +## Installation import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:2.11.0 -## Set Up the Development Environment {#set-up-the-development-environment} +## Set Up the Development Environment In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration {#configuration} +## Configuration The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server {#changing-port-of-the-platform-server} +### Changing Port of the Platform Server For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets {#specify-your-services-assets} +### Specify Your Service's Assets Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence {#add-data-persistence} +### Add Data Persistence The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication {#configure-platform-api-authentication} +### Configure Platform API Authentication To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags {#passing-jvm-flags} +### Passing JVM flags Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep10/README.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep10/README.mdx index fbd4a2a22..1db24083f 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep10/README.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication {#enable-stellar-authentication} +## Enable Stellar Authentication Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution {#config-with-client-attribution} +## Config With Client Attribution `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -131,7 +131,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/configuration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/configuration.mdx index 906850f4f..09c8dc709 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/configuration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} +## Enable Hosted Deposits & Withdrawals Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -109,7 +109,7 @@ SECRET_SEP24_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busi `SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET` and `SECRET_SEP24_MORE_INFO_URL_JWT_SECRET` are encryption keys that the Anchor Platform will use to generate short-lived tokens it will add to the URLs provided to the wallet. Your business server must also have these keys in its environment so it can verify the token's signature. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/example.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/example.mdx index 762a16973..1013eb596 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/example.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience {#building-a-web-based-user-experience} +## Building a Web-Based User Experience The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication {#authentication} +### Authentication If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform {#providing-updates-to-the-platform} +## Providing Updates to the Platform Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform {#fetching-updates-from-the-platform} +## Fetching Updates from the Platform If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation {#full-example-implementation} +## Full Example Implementation Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/faq.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/faq.mdx index ee5eb71da..5972a06cf 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/faq.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? {#how-to-use-jwts} +### How To Use JWTs? As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? {#how-to-provide-fees} +### How To Provide Fees? Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? {#how-to-identify-the-user-account} +### How to identify the user account? You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? {#how-to-identify-the-wallet} +### How to identify the wallet? Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/getting-started.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/getting-started.mdx index e77894428..ce1d1dbf4 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/getting-started.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience a deposit and withdrawal goes something like this: diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx index 57db2d794..bb3a9f759 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} +## Updating Deposit Transaction Via JSON-RPC SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information {#processing-kyc-information} +### Processing KYC Information :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction status to `expired`. @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction {#on-hold-transaction} +### On-Hold Transaction In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} +## Updating Withdrawal Transaction Via JSON-RPC This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information {#processing-kyc-information-1} +### Processing KYC Information This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction {#on-hold-transaction-1} +### On-Hold Transaction Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/setting-up-production-server.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/setting-up-production-server.mdx index 68c15d0bb..f631e5dbf 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/setting-up-production-server.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment {#deploying-a-secure-environment} +## Deploying a Secure Environment Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC {#connecting-to-real-kyc} +## Connecting to Real KYC Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} +## Pre-Filling the KYC Form Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} +## Connecting to Real Banking Rails Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases {#testing-edge-cases} +## Testing Edge Cases Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests {#general-tests} +### General Tests - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests {#kyc-tests} +### KYC Tests - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test {#interactive-test} +### Interactive Test - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests {#security-tests} +### Security Tests - Make sure platform endpoints are secured -## Polishing and Internationalization {#polishing-and-internationalization} +## Polishing and Internationalization Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets {#connecting-to-wallets} +## Connecting to Wallets All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep31/configuration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep31/configuration.mdx index 7df1dde9b..d68d781de 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep31/configuration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments {#enable-cross-border-payments} +## Enable Cross Border Payments Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API {#enable-the-customer-kyc-api} +## Enable the Customer KYC API Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API {#enable-the-rfq-api} +## Enable the RFQ API Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication {#configure-callback-api-authentication} +## Configure Callback API Authentication Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep31/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep31/integration.mdx index 9811571c5..b8fda8408 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep31/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep31/integration.mdx @@ -18,7 +18,7 @@ The following may also be required depending on your use case: - [`GET /unique_address`][get-unique-address] if your business uses a custody service for on-chain assets - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server {#create-a-business-server} +## Create a Business Server First, lets create a business server and add it to our docker compose file. @@ -71,11 +71,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints {#customer-callback-endpoints} +## Customer Callback Endpoints The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers {#identifying-customers} +### Identifying Customers Customers can be identified using two approaches. @@ -134,13 +134,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types {#customer-types} +### Customer Types Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet {#test-with-the-demo-wallet} +### Test with the Demo Wallet You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -157,33 +157,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint {#rate-callback-endpoint} +## Rate Callback Endpoint Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} +### Firm vs. Indicative Quotes Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID {#using-the-client-id} +### Using the Client ID Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods {#delivery-methods} +### Delivery Methods It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates {#fetching-transaction-status-updates} +## Fetching Transaction Status Updates To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer {#running-the-stellar-observer} +### Running the Stellar Observer The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -203,7 +203,7 @@ services: -### Polling for Received Payments {#polling-for-received-payments} +### Polling for Received Payments The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -219,7 +219,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} +## Updating Transaction Via JSON-RPC SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -239,7 +239,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds SEP-31 Transactions should initially be in the `pending_sender` status. The Receiving Anchor waits to receive the payment identified by the stellar_memo included in the POST /transactions response. @@ -286,7 +286,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -321,7 +321,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Verifying Customer Information {#verifying-customer-information} +### Verifying Customer Information In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -392,7 +392,7 @@ To execute this, you need to run: -### Do Stellar Refund {#do-stellar-refund} +### Do Stellar Refund Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -441,7 +441,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent {#refund-sent} +### Refund Sent There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -491,7 +491,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -530,7 +530,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -569,7 +569,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -602,11 +602,11 @@ To execute this, you need to run: -## Fee Callback Endpoint {#fee-callback-endpoint} +## Fee Callback Endpoint Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time the funds are paid out to the recipient. In this case, the Anchor Platform will not make a `GET /rate` request, but you will still need to provide the fee your business will charge for these types of transactions using the [`GET /fee`][get-fee] endpoint. -### Configuration {#configuration} +### Configuration You can enable these types of transactions by updating your `assets.yaml` file configuration: @@ -621,11 +621,11 @@ assets: -## Unique Address Callback Endpoint {#unique-address-callback-endpoint} +## Unique Address Callback Endpoint Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so that the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments. In this case, the business must request the custodian to generate the Stellar account & memo. This is done by using the [`GET /unique_address` endpoint][get-unique-address]. -### Configuration {#configuration-1} +### Configuration To configure the Anchor Platform to make these requests, add the following to your configuration: diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep6/configuration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep6/configuration.mdx index 8996dc626..dea786738 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep6/configuration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} +## Enable Programmatic Deposits & Withdrawals Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File {#modify-a-stellar-info-file} +### Modify a Stellar Info File Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File {#modify-the-assets-configuration-file} +### Modify the Assets Configuration File Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts {#managing-distribution-accounts} +### Managing Distribution Accounts Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} +### Enable Callbacks to the Business Server Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -177,7 +177,7 @@ SECRET_SEP6_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busin See the [KYC API][platform-api-kyc] and [Rates API][sep38] for details on the endpoints that must be implemented on your business server. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep6/getting-started.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep6/getting-started.mdx index fb4e1293c..3a1d875e9 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep6/getting-started.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx index 42c276825..5b4d53d58 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information {#customer-information} +### Customer Information The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} +## Updating Deposit (Exchange) Transaction Via JSON-RPC SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information {#verifying-kyc-information} +### Verifying KYC Information Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -129,7 +129,7 @@ To execute this, you need to run: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -201,7 +201,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide updated transaction information. @@ -253,7 +253,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -288,7 +288,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -326,7 +326,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -369,7 +369,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -408,7 +408,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -450,7 +450,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent {#refund-sent} +### Refund Sent Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -500,11 +500,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -543,7 +543,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire transactions that have been abandoned by the user after some time. It's good practice to clean up inactive transactions in the `incomplete` status. To do so, make the following JSON-RPC request to expire a transaction. @@ -582,7 +582,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -615,7 +615,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -637,7 +637,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -718,7 +718,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -767,7 +767,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -812,7 +812,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -846,7 +846,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -880,7 +880,7 @@ To execute this, you need to run: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -915,11 +915,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent-1} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -968,19 +968,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/ap_versioned_docs/version-2.8/admin-guide/architecture.mdx b/ap_versioned_docs/version-2.8/admin-guide/architecture.mdx index 7e1fd14b7..d9abf6435 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/architecture.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture {#architecture} +## Architecture Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture {#fundamental-architecture} +### Fundamental Architecture The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client {#client} +#### Client The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server {#sep-server} +#### SEP Server The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server {#business-server} +#### Business Server The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server {#platform-server} +#### Platform Server The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database {#database} +#### Database The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture {#complete-architecture} +### Complete Architecture In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service {#event-service} +#### Event Service The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server {#custody-server} +#### Custody Server The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer {#stellar-observer} +#### Stellar Observer The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/ap_versioned_docs/version-2.8/admin-guide/custody-services/configuration.mdx b/ap_versioned_docs/version-2.8/admin-guide/custody-services/configuration.mdx index 8abcb8312..a068caab1 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/custody-services/configuration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration {#custody-server-configuration} +## Custody Server Configuration If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:2.8.4 --custody-server -## Anchor Platform Configuration {#anchor-platform-configuration} +## Anchor Platform Configuration Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} +## Kotlin Reference Server Configuration Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/ap_versioned_docs/version-2.8/admin-guide/custody-services/fireblocks/example.mdx b/ap_versioned_docs/version-2.8/admin-guide/custody-services/fireblocks/example.mdx index 9b3b8bf30..613d31bca 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/custody-services/fireblocks/example.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} +### SEP-24 deposit flow with webhook: - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} +### SEP-24 deposit flow with reconciliation job: - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} +### SEP-24 withdrawal flow with webhook: - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} +### SEP-24 withdrawal flow with reconciliation job: - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} +### SEP-31 receive flow with webhook: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} +### SEP-31 receive flow with reconciliation job: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/ap_versioned_docs/version-2.8/admin-guide/events/delivery.mdx b/ap_versioned_docs/version-2.8/admin-guide/events/delivery.mdx index 3c5f30142..cd6d3148e 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/events/delivery.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees {#delivery-guarantees} +## Delivery Guarantees Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees {#client-delivery-guarantees} +### Client Delivery Guarantees For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees {#business-server-delivery-guarantees} +### Business Server Delivery Guarantees The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/ap_versioned_docs/version-2.8/admin-guide/events/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/events/integration.mdx index 15582d435..b2638a348 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/events/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements {#requirements} +## Requirements Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration {#configuration} +## Configuration First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events {#receiving-events} +## Receiving Events The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application {#as-a-client-application} +### As a Client Application Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing {#callback-signing} +#### Callback Signing Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server {#as-a-business-server} +### As a Business Server In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration {#configuration-1} +#### Configuration The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/ap_versioned_docs/version-2.8/admin-guide/getting-started.mdx b/ap_versioned_docs/version-2.8/admin-guide/getting-started.mdx index 5ca422da4..c434ee9a4 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/getting-started.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation {#installation} +## Installation import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:2.8.4 -## Set Up the Development Environment {#set-up-the-development-environment} +## Set Up the Development Environment In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration {#configuration} +## Configuration The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server {#changing-port-of-the-platform-server} +### Changing Port of the Platform Server For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets {#specify-your-services-assets} +### Specify Your Service's Assets Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence {#add-data-persistence} +### Add Data Persistence The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication {#configure-platform-api-authentication} +### Configure Platform API Authentication To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags {#passing-jvm-flags} +### Passing JVM flags Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep10/README.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep10/README.mdx index 14cbfc8a4..485e404be 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep10/README.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication {#enable-stellar-authentication} +## Enable Stellar Authentication Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution {#config-with-client-attribution} +## Config With Client Attribution `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -118,7 +118,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/configuration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/configuration.mdx index 6fe6c5501..3c6d294c8 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/configuration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} +## Enable Hosted Deposits & Withdrawals Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -109,7 +109,7 @@ SECRET_SEP24_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busi `SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET` and `SECRET_SEP24_MORE_INFO_URL_JWT_SECRET` are encryption keys that the Anchor Platform will use to generate short-lived tokens it will add to the URLs provided to the wallet. Your business server must also have these keys in its environment so it can verify the token's signature. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/example.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/example.mdx index bf906b32d..7c424f535 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/example.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience {#building-a-web-based-user-experience} +## Building a Web-Based User Experience The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication {#authentication} +### Authentication If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform {#providing-updates-to-the-platform} +## Providing Updates to the Platform Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform {#fetching-updates-from-the-platform} +## Fetching Updates from the Platform If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation {#full-example-implementation} +## Full Example Implementation Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/faq.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/faq.mdx index ee5eb71da..5972a06cf 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/faq.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? {#how-to-use-jwts} +### How To Use JWTs? As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? {#how-to-provide-fees} +### How To Provide Fees? Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? {#how-to-identify-the-user-account} +### How to identify the user account? You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? {#how-to-identify-the-wallet} +### How to identify the wallet? Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/getting-started.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/getting-started.mdx index e77894428..ce1d1dbf4 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/getting-started.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience a deposit and withdrawal goes something like this: diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx index 6e2e6e081..099bd817d 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} +## Updating Deposit Transaction Via JSON-RPC SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information {#processing-kyc-information} +### Processing KYC Information :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction status to `expired`. @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction {#on-hold-transaction} +### On-Hold Transaction In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} +## Updating Withdrawal Transaction Via JSON-RPC This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information {#processing-kyc-information-1} +### Processing KYC Information This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction {#on-hold-transaction-1} +### On-Hold Transaction Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/setting-up-production-server.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/setting-up-production-server.mdx index 68c15d0bb..f631e5dbf 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/setting-up-production-server.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment {#deploying-a-secure-environment} +## Deploying a Secure Environment Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC {#connecting-to-real-kyc} +## Connecting to Real KYC Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} +## Pre-Filling the KYC Form Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} +## Connecting to Real Banking Rails Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases {#testing-edge-cases} +## Testing Edge Cases Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests {#general-tests} +### General Tests - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests {#kyc-tests} +### KYC Tests - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test {#interactive-test} +### Interactive Test - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests {#security-tests} +### Security Tests - Make sure platform endpoints are secured -## Polishing and Internationalization {#polishing-and-internationalization} +## Polishing and Internationalization Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets {#connecting-to-wallets} +## Connecting to Wallets All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep31/configuration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep31/configuration.mdx index 7df1dde9b..d68d781de 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep31/configuration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments {#enable-cross-border-payments} +## Enable Cross Border Payments Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API {#enable-the-customer-kyc-api} +## Enable the Customer KYC API Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API {#enable-the-rfq-api} +## Enable the RFQ API Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication {#configure-callback-api-authentication} +## Configure Callback API Authentication Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep31/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep31/integration.mdx index c564b7db9..eb7f83f05 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep31/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep31/integration.mdx @@ -18,7 +18,7 @@ The following may also be required depending on your use case: - [`GET /unique_address`][get-unique-address] if your business uses a custody service for on-chain assets - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server {#create-a-business-server} +## Create a Business Server First, lets create a business server and add it to our docker compose file. @@ -71,11 +71,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints {#customer-callback-endpoints} +## Customer Callback Endpoints The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers {#identifying-customers} +### Identifying Customers Customers can be identified using two approaches. @@ -134,13 +134,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types {#customer-types} +### Customer Types Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet {#test-with-the-demo-wallet} +### Test with the Demo Wallet You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -157,33 +157,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint {#rate-callback-endpoint} +## Rate Callback Endpoint Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} +### Firm vs. Indicative Quotes Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID {#using-the-client-id} +### Using the Client ID Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods {#delivery-methods} +### Delivery Methods It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates {#fetching-transaction-status-updates} +## Fetching Transaction Status Updates To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer {#running-the-stellar-observer} +### Running the Stellar Observer The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -203,7 +203,7 @@ services: -### Polling for Received Payments {#polling-for-received-payments} +### Polling for Received Payments The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -219,7 +219,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} +## Updating Transaction Via JSON-RPC SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -239,7 +239,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds SEP-31 Transactions should initially be in the `pending_sender` status. The Receiving Anchor waits to receive the payment identified by the stellar_memo included in the POST /transactions response. @@ -286,7 +286,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -321,7 +321,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Customer Info Needed {#customer-info-needed} +### Customer Info Needed In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -388,7 +388,7 @@ To execute this, you need to run: -### Customer Info Updated {#customer-info-updated} +### Customer Info Updated After the Sending Anchor has made another SEP-12 `PUT /customer` request to update customer info, the Receiving Anchor should change the status of the transaction to `pending_receiver`. @@ -421,7 +421,7 @@ To execute this, you need to run: -### Do Stellar Refund {#do-stellar-refund} +### Do Stellar Refund Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -470,7 +470,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent {#refund-sent} +### Refund Sent There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -520,7 +520,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -559,7 +559,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -598,7 +598,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -631,11 +631,11 @@ To execute this, you need to run: -## Fee Callback Endpoint {#fee-callback-endpoint} +## Fee Callback Endpoint Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time the funds are paid out to the recipient. In this case, the Anchor Platform will not make a `GET /rate` request, but you will still need to provide the fee your business will charge for these types of transactions using the [`GET /fee`][get-fee] endpoint. -### Configuration {#configuration} +### Configuration You can enable these types of transactions by updating your `assets.yaml` file configuration: @@ -650,11 +650,11 @@ assets: -## Unique Address Callback Endpoint {#unique-address-callback-endpoint} +## Unique Address Callback Endpoint Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so that the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments. In this case, the business must request the custodian to generate the Stellar account & memo. This is done by using the [`GET /unique_address` endpoint][get-unique-address]. -### Configuration {#configuration-1} +### Configuration To configure the Anchor Platform to make these requests, add the following to your configuration: diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep6/configuration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep6/configuration.mdx index 8996dc626..dea786738 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep6/configuration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} +## Enable Programmatic Deposits & Withdrawals Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File {#modify-a-stellar-info-file} +### Modify a Stellar Info File Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File {#modify-the-assets-configuration-file} +### Modify the Assets Configuration File Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts {#managing-distribution-accounts} +### Managing Distribution Accounts Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} +### Enable Callbacks to the Business Server Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -177,7 +177,7 @@ SECRET_SEP6_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busin See the [KYC API][platform-api-kyc] and [Rates API][sep38] for details on the endpoints that must be implemented on your business server. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep6/getting-started.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep6/getting-started.mdx index fb4e1293c..3a1d875e9 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep6/getting-started.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx index ff79f84b5..7e19260cc 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information {#customer-information} +### Customer Information The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} +## Updating Deposit (Exchange) Transaction Via JSON-RPC SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information {#verifying-kyc-information} +### Verifying KYC Information Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -125,7 +125,7 @@ To execute this, you need to run: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -197,7 +197,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide updated transaction information. @@ -249,7 +249,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -284,7 +284,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -322,7 +322,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -365,7 +365,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -404,7 +404,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -446,7 +446,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent {#refund-sent} +### Refund Sent Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -496,11 +496,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -539,7 +539,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire transactions that have been abandoned by the user after some time. It's good practice to clean up inactive transactions in the `incomplete` status. To do so, make the following JSON-RPC request to expire a transaction. @@ -578,7 +578,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -611,7 +611,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -633,7 +633,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -714,7 +714,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -763,7 +763,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -808,7 +808,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -842,7 +842,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -876,7 +876,7 @@ To execute this, you need to run: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -911,11 +911,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent-1} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -964,19 +964,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/ap_versioned_docs/version-2.9/admin-guide/architecture.mdx b/ap_versioned_docs/version-2.9/admin-guide/architecture.mdx index 7e1fd14b7..d9abf6435 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/architecture.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture {#architecture} +## Architecture Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture {#fundamental-architecture} +### Fundamental Architecture The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client {#client} +#### Client The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server {#sep-server} +#### SEP Server The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server {#business-server} +#### Business Server The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server {#platform-server} +#### Platform Server The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database {#database} +#### Database The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture {#complete-architecture} +### Complete Architecture In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service {#event-service} +#### Event Service The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server {#custody-server} +#### Custody Server The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer {#stellar-observer} +#### Stellar Observer The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/ap_versioned_docs/version-2.9/admin-guide/custody-services/configuration.mdx b/ap_versioned_docs/version-2.9/admin-guide/custody-services/configuration.mdx index 3f21b7b8b..611d9dfa5 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/custody-services/configuration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration {#custody-server-configuration} +## Custody Server Configuration If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:2.9.0 --custody-server -## Anchor Platform Configuration {#anchor-platform-configuration} +## Anchor Platform Configuration Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} +## Kotlin Reference Server Configuration Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/ap_versioned_docs/version-2.9/admin-guide/custody-services/fireblocks/example.mdx b/ap_versioned_docs/version-2.9/admin-guide/custody-services/fireblocks/example.mdx index 9b3b8bf30..613d31bca 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/custody-services/fireblocks/example.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} +### SEP-24 deposit flow with webhook: - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} +### SEP-24 deposit flow with reconciliation job: - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} +### SEP-24 withdrawal flow with webhook: - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} +### SEP-24 withdrawal flow with reconciliation job: - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} +### SEP-31 receive flow with webhook: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} +### SEP-31 receive flow with reconciliation job: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/ap_versioned_docs/version-2.9/admin-guide/events/delivery.mdx b/ap_versioned_docs/version-2.9/admin-guide/events/delivery.mdx index 3c5f30142..cd6d3148e 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/events/delivery.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees {#delivery-guarantees} +## Delivery Guarantees Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees {#client-delivery-guarantees} +### Client Delivery Guarantees For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees {#business-server-delivery-guarantees} +### Business Server Delivery Guarantees The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/ap_versioned_docs/version-2.9/admin-guide/events/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/events/integration.mdx index 15582d435..b2638a348 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/events/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements {#requirements} +## Requirements Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration {#configuration} +## Configuration First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events {#receiving-events} +## Receiving Events The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application {#as-a-client-application} +### As a Client Application Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing {#callback-signing} +#### Callback Signing Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server {#as-a-business-server} +### As a Business Server In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration {#configuration-1} +#### Configuration The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/ap_versioned_docs/version-2.9/admin-guide/getting-started.mdx b/ap_versioned_docs/version-2.9/admin-guide/getting-started.mdx index 650698e14..d373ecaaa 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/getting-started.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation {#installation} +## Installation import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:2.9.0 -## Set Up the Development Environment {#set-up-the-development-environment} +## Set Up the Development Environment In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration {#configuration} +## Configuration The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server {#changing-port-of-the-platform-server} +### Changing Port of the Platform Server For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets {#specify-your-services-assets} +### Specify Your Service's Assets Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence {#add-data-persistence} +### Add Data Persistence The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication {#configure-platform-api-authentication} +### Configure Platform API Authentication To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags {#passing-jvm-flags} +### Passing JVM flags Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep10/README.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep10/README.mdx index fbd4a2a22..1db24083f 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep10/README.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication {#enable-stellar-authentication} +## Enable Stellar Authentication Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution {#config-with-client-attribution} +## Config With Client Attribution `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -131,7 +131,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/configuration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/configuration.mdx index 906850f4f..09c8dc709 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/configuration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} +## Enable Hosted Deposits & Withdrawals Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -109,7 +109,7 @@ SECRET_SEP24_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busi `SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET` and `SECRET_SEP24_MORE_INFO_URL_JWT_SECRET` are encryption keys that the Anchor Platform will use to generate short-lived tokens it will add to the URLs provided to the wallet. Your business server must also have these keys in its environment so it can verify the token's signature. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/example.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/example.mdx index cf4dab925..77fb8b995 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/example.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience {#building-a-web-based-user-experience} +## Building a Web-Based User Experience The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication {#authentication} +### Authentication If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform {#providing-updates-to-the-platform} +## Providing Updates to the Platform Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform {#fetching-updates-from-the-platform} +## Fetching Updates from the Platform If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation {#full-example-implementation} +## Full Example Implementation Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/faq.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/faq.mdx index ee5eb71da..5972a06cf 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/faq.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? {#how-to-use-jwts} +### How To Use JWTs? As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? {#how-to-provide-fees} +### How To Provide Fees? Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? {#how-to-identify-the-user-account} +### How to identify the user account? You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? {#how-to-identify-the-wallet} +### How to identify the wallet? Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/getting-started.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/getting-started.mdx index e77894428..ce1d1dbf4 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/getting-started.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience a deposit and withdrawal goes something like this: diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx index 7f0c43bb6..f07b332a6 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} +## Updating Deposit Transaction Via JSON-RPC SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information {#processing-kyc-information} +### Processing KYC Information :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction status to `expired`. @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction {#on-hold-transaction} +### On-Hold Transaction In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} +## Updating Withdrawal Transaction Via JSON-RPC This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information {#processing-kyc-information-1} +### Processing KYC Information This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction {#on-hold-transaction-1} +### On-Hold Transaction Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/setting-up-production-server.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/setting-up-production-server.mdx index 68c15d0bb..f631e5dbf 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/setting-up-production-server.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment {#deploying-a-secure-environment} +## Deploying a Secure Environment Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC {#connecting-to-real-kyc} +## Connecting to Real KYC Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} +## Pre-Filling the KYC Form Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} +## Connecting to Real Banking Rails Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases {#testing-edge-cases} +## Testing Edge Cases Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests {#general-tests} +### General Tests - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests {#kyc-tests} +### KYC Tests - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test {#interactive-test} +### Interactive Test - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests {#security-tests} +### Security Tests - Make sure platform endpoints are secured -## Polishing and Internationalization {#polishing-and-internationalization} +## Polishing and Internationalization Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets {#connecting-to-wallets} +## Connecting to Wallets All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep31/configuration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep31/configuration.mdx index 7df1dde9b..d68d781de 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep31/configuration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments {#enable-cross-border-payments} +## Enable Cross Border Payments Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API {#enable-the-customer-kyc-api} +## Enable the Customer KYC API Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API {#enable-the-rfq-api} +## Enable the RFQ API Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication {#configure-callback-api-authentication} +## Configure Callback API Authentication Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep31/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep31/integration.mdx index eb14cf5f5..7eb844390 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep31/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep31/integration.mdx @@ -18,7 +18,7 @@ The following may also be required depending on your use case: - [`GET /unique_address`][get-unique-address] if your business uses a custody service for on-chain assets - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server {#create-a-business-server} +## Create a Business Server First, lets create a business server and add it to our docker compose file. @@ -71,11 +71,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints {#customer-callback-endpoints} +## Customer Callback Endpoints The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers {#identifying-customers} +### Identifying Customers Customers can be identified using two approaches. @@ -134,13 +134,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types {#customer-types} +### Customer Types Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet {#test-with-the-demo-wallet} +### Test with the Demo Wallet You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -157,33 +157,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint {#rate-callback-endpoint} +## Rate Callback Endpoint Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} +### Firm vs. Indicative Quotes Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID {#using-the-client-id} +### Using the Client ID Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods {#delivery-methods} +### Delivery Methods It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates {#fetching-transaction-status-updates} +## Fetching Transaction Status Updates To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer {#running-the-stellar-observer} +### Running the Stellar Observer The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -203,7 +203,7 @@ services: -### Polling for Received Payments {#polling-for-received-payments} +### Polling for Received Payments The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -219,7 +219,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} +## Updating Transaction Via JSON-RPC SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -239,7 +239,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds SEP-31 Transactions should initially be in the `pending_sender` status. The Receiving Anchor waits to receive the payment identified by the stellar_memo included in the POST /transactions response. @@ -286,7 +286,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -321,7 +321,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Verifying Customer Information {#verifying-customer-information} +### Verifying Customer Information In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -392,7 +392,7 @@ To execute this, you need to run: -### Do Stellar Refund {#do-stellar-refund} +### Do Stellar Refund Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -441,7 +441,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent {#refund-sent} +### Refund Sent There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -491,7 +491,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -530,7 +530,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -569,7 +569,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -602,11 +602,11 @@ To execute this, you need to run: -## Fee Callback Endpoint {#fee-callback-endpoint} +## Fee Callback Endpoint Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time the funds are paid out to the recipient. In this case, the Anchor Platform will not make a `GET /rate` request, but you will still need to provide the fee your business will charge for these types of transactions using the [`GET /fee`][get-fee] endpoint. -### Configuration {#configuration} +### Configuration You can enable these types of transactions by updating your `assets.yaml` file configuration: @@ -621,11 +621,11 @@ assets: -## Unique Address Callback Endpoint {#unique-address-callback-endpoint} +## Unique Address Callback Endpoint Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so that the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments. In this case, the business must request the custodian to generate the Stellar account & memo. This is done by using the [`GET /unique_address` endpoint][get-unique-address]. -### Configuration {#configuration-1} +### Configuration To configure the Anchor Platform to make these requests, add the following to your configuration: diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep6/configuration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep6/configuration.mdx index 8996dc626..dea786738 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep6/configuration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} +## Enable Programmatic Deposits & Withdrawals Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File {#modify-a-stellar-info-file} +### Modify a Stellar Info File Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File {#modify-the-assets-configuration-file} +### Modify the Assets Configuration File Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts {#managing-distribution-accounts} +### Managing Distribution Accounts Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} +### Enable Callbacks to the Business Server Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -177,7 +177,7 @@ SECRET_SEP6_MORE_INFO_URL_JWT_SECRET="your encryption key shared with your busin See the [KYC API][platform-api-kyc] and [Rates API][sep38] for details on the endpoints that must be implemented on your business server. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep6/getting-started.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep6/getting-started.mdx index fb4e1293c..3a1d875e9 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep6/getting-started.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx index 3faf043f5..c1836b071 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information {#customer-information} +### Customer Information The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} +## Updating Deposit (Exchange) Transaction Via JSON-RPC SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information {#verifying-kyc-information} +### Verifying KYC Information Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -129,7 +129,7 @@ To execute this, you need to run: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -201,7 +201,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide updated transaction information. @@ -253,7 +253,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -288,7 +288,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -326,7 +326,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -369,7 +369,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -408,7 +408,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -450,7 +450,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent {#refund-sent} +### Refund Sent Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -500,11 +500,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -543,7 +543,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire transactions that have been abandoned by the user after some time. It's good practice to clean up inactive transactions in the `incomplete` status. To do so, make the following JSON-RPC request to expire a transaction. @@ -582,7 +582,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -615,7 +615,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -637,7 +637,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -718,7 +718,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -767,7 +767,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `amount_fee` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -812,7 +812,7 @@ Only `amount_out` and `amount_fee` can be updated using this JSON-RPC request, a ::: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -846,7 +846,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -880,7 +880,7 @@ To execute this, you need to run: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -915,11 +915,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent-1} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -968,19 +968,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/docs/README.mdx b/docs/README.mdx index 26cb4ec8f..5444a4dda 100644 --- a/docs/README.mdx +++ b/docs/README.mdx @@ -4,32 +4,32 @@ displayed_sidebar: build hide_table_of_contents: true --- -## Navigating the docs {#navigating-the-docs} +## Navigating the docs -### [Build](./build/README.mdx) {#build} +### [Build](./build/README.mdx) Contains tutorials and how-to guides for writing smart contracts, building applications, interacting with the network, and more. -### [Learn](./learn/fundamentals/README.mdx) {#learn} +### [Learn](./learn/fundamentals/README.mdx) Find all informational and conceptual content here. Learn about Stellar fundamentals like how accounts and transactions function, dive deeper into the functionality of each operation, discover how fees work, and more. -### [Tokens](./tokens/README.mdx) {#tokens} +### [Tokens](./tokens/README.mdx) Information on how to issue assets on the Stellar network and create custom smart contract tokens. -### [Data](./data/README.mdx) {#data} +### [Data](./data/README.mdx) Discover various data availability options: RPC, Hubble, Horizon, and Galexie. -### [Tools](./tools/README.mdx) {#tools} +### [Tools](./tools/README.mdx) Learn about all the available tools at your disposal for building on, interacting with, or just watching the Stellar network. Also, find information on how to use the Anchor Platform or Stellar Disbursement Platform. -### [Networks](./networks/README.mdx) {#networks} +### [Networks](./networks/README.mdx) Information about deployed networks (Mainnet, Testnet, and Futurenet), current software versions, and resource limitations and fees. -### [Validators](./validators/README.mdx) {#validators} +### [Validators](./validators/README.mdx) Everything you'll need to know if you want to run, operate, and maintain a core validator node on the Stellar network. diff --git a/docs/build/README.mdx b/docs/build/README.mdx index 863310c96..473f1e882 100644 --- a/docs/build/README.mdx +++ b/docs/build/README.mdx @@ -8,13 +8,13 @@ The Build section is split into three parts: 1) writing smart contracts, 2) buil Find explanations on what each section contains below. -## Smart contracts {#smart-contracts} +## Smart contracts Smart contracts are self-executing programs with the terms of an agreement written directly into the code. They automatically enforce and execute the terms of the contract when predefined conditions are met. Developers must define the rules and logic of the contract while also ensuring security. Once written and tested, smart contracts are deployed to the blockchain, where they become immutable and publicly accessible. This section will walk you through how to get set up to write smart contracts on Stellar, plus an introduction to testing, storing data, and deploying your contracts. It also provides an array of example contracts for use. -## Applications {#applications} +## Applications Applications interact with the blockchain and can use smart contracts as the backend. They provide user interfaces, manage user interactions, and can integrate with smart contracts to operate. Users can interact with the blockchain using the application interface. Writing smart contracts focuses on the backend logic and rules enforced on the blockchain while building applications involves creating the front end and integrating it with these smart contracts to provide a complete user experience. @@ -26,7 +26,7 @@ You can create applications on Stellar without using smart contracts, as demonst This section walks you through design considerations for applications and tutorials for building applications with or without smart contracts. -## How-To Guides {#how-to-guides} +## How-To Guides This section provides step-by-step instructions to help users complete specific tasks associated with developing on Stellar. These tasks can include instructions for aspects of writing contracts, interacting with contracts, building applications, using Stellar operations, setting up infrastructure, and more. diff --git a/docs/build/apps/application-design-considerations.mdx b/docs/build/apps/application-design-considerations.mdx index 6b5be6608..2ccedc965 100644 --- a/docs/build/apps/application-design-considerations.mdx +++ b/docs/build/apps/application-design-considerations.mdx @@ -3,7 +3,7 @@ title: Application Design Considerations sidebar_position: 10 --- -## Custody models {#custody-models} +## Custody models When building an application, one of the first things you have to decide is how your users’ secret keys will be secured and stored. Stellar applications give users access to their accounts that are stored on the ledger, and access to these accounts is controlled by the account’s secret key. That secret key proves that the user has custody or “owns” the account. @@ -14,23 +14,23 @@ There are four custody options to consider: - Mixture of both - with the use of [multisig](../../learn/encyclopedia/security/signatures-multisig.mdx), this option is useful for maintaining non-custodial status while still allowing for account recovery - Third-party key management services - integrate a third-party custodial service into your application that can store your users’ secret keys -### Non-custodial service {#non-custodial-service} +### Non-custodial service In a non-custodial service, the user of the application stores the secret key for their account and permissions the application to send requests to delegate transaction signing. There are some potential usability issues as the user has to know how to securely store their own account credentials and safely navigate transaction signing on their end. If they lose their secret key, they will also lose access to their account. Typically, non-custodial applications create or import a pre-existing Stellar account for each user. -### Custodial service {#custodial-service} +### Custodial service With a custodial service, the service provider (an application such as a centralized exchange) stores the users’ secret keys and delegates usage rights to the user. Many custodial services choose to use a single pooled Stellar account (called shared, omnibus, or [pooled accounts](../../learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx)) to handle transactions on behalf of their users instead of creating a new Stellar account for each user. To distinguish between individual users in a pooled account, we encourage the implementation of [muxed accounts](../../learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx#muxed-accounts). -### A mixture of non-custodial and custodial {#a-mixture-of-non-custodial-and-custodial} +### A mixture of non-custodial and custodial Building an application with [multi-signature](../../learn/encyclopedia/security/signatures-multisig.mdx) capabilities allows you to have a non-custodial service with account recovery. If the user loses their secret key, they can still sign transactions with other authorized signatures, granted the signature threshold is high enough. -### Third-party key management services​ {#third-party-key-management-services} +### Third-party key management services​ There are several apps and services that specialize in adding additional security layers to users' accounts. Check them out if you're interested in integrating a third-party key management service: @@ -40,26 +40,26 @@ There are several apps and services that specialize in adding additional securit - [StellarGuard](https://stellarguard.me/) - [LobstrVault](https://vault.lobstr.co/) -## Application security {#application-security} +## Application security Even though wallets can operate client-side, they deal with a user’s secret keys, which give direct access to their account, and to any value they hold. That’s why it’s essential to require all web traffic to flow over strong TLS methods. Even when developing locally, use a non-signed localhost certificate to develop secure habits from the very beginning. Stellar is a powerful money-moving software — don’t skimp on security. For more information, check out our guide to [securing web-based products](https://www.stellar.org/developers/guides/walkthroughs/securing-web-projects.html). -## Wallet services {#wallet-services} +## Wallet services A wallet typically has these basic functions: key storage, account creation, transaction signing, and queries to the Stellar database. There are some services that take care of all of these functions for you, so you can build whatever you’d like around it. Check out some of these wallet services below. - [Albedo](https://albedo.link/) - [Freighter](https://www.freighter.app/) -## Account creation strategies {#account-creation-strategies} +## Account creation strategies In this section, we will go over the new user account creation flow between non-custodial wallets and anchors with SEP-24 and/or SEP-6 implementations. A Stellar account is created with a keypair (a public key and private key) and the minimum balance of XLM. When a new customer downloads the wallet application and goes through the deposit flow for the first time, their Stellar account can be created by either the user’s wallet application or the anchor facilitating the first deposit. This section describes each of these strategies. -### Option 1: The anchor creates and funds the Stellar account​ {#option-1-the-anchor-creates-and-funds-the-stellar-account} +### Option 1: The anchor creates and funds the Stellar account​ For this option, the wallet needs to allow users to initiate their first deposit without having to add an asset/establish a trustline. The wallet then prompts the user to add the trustline once funds are received by the anchor. The flow looks like this: @@ -90,7 +90,7 @@ The flow with Claimable Balances looks like this: 6. The anchor creates a Claimable Balance. 7. The wallet detects the Claimable Balance for the account, claims the funds, and posts it in the wallet. -### Option 2: the wallet creates and funds the Stellar account upon user sign-up​ {#option-2-the-wallet-creates-and-funds-the-stellar-account-upon-user-sign-up} +### Option 2: the wallet creates and funds the Stellar account upon user sign-up​ For this option, the wallet creates and funds the Stellar account upon every new user sign-up with the minimum requirement of 1XLM, plus the .5XLM reserve for establishing the first trustline, plus a bit more to cover transaction fees. For more information on minimum balances, check out the [Lumens section](../../learn/fundamentals/lumens.mdx#minimum-balance). diff --git a/docs/build/apps/dapp-frontend.mdx b/docs/build/apps/dapp-frontend.mdx index 4fc37f0db..4479adbbb 100644 --- a/docs/build/apps/dapp-frontend.mdx +++ b/docs/build/apps/dapp-frontend.mdx @@ -9,7 +9,7 @@ This is a continuation of the [Getting Started tutorial](../smart-contracts/gett Let's get started. -## Initialize a frontend toolchain {#initialize-a-frontend-toolchain} +## Initialize a frontend toolchain You can build a Soroban app with any frontend toolchain or integrate it into any existing full-stack app. For this tutorial, we're going to use [Astro](https://astro.build/). Astro works with React, Vue, Svelte, any other UI library, or no UI library at all. In this tutorial, we're not using a UI library. The Soroban-specific parts of this tutorial will be similar no matter what frontend toolchain you use. @@ -49,7 +49,7 @@ This will add the following to your project, which we'll go over in more detail └── tsconfig.json ``` -## Generate an NPM package for the Hello World contract {#generate-an-npm-package-for-the-hello-world-contract} +## Generate an NPM package for the Hello World contract Before we open the new frontend files, let's generate an NPM package for the Hello World contract. This is our suggested way to interact with contracts from frontends. These generated libraries work with any JavaScript project (not a specific UI like React), and make it easy to work with some of the trickiest bits of Soroban, like encoding [XDR](../../learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx). @@ -66,7 +66,7 @@ This project is set up as an NPM Workspace, and so the `hello_world` client libr We attempt to keep the code in these generated libraries readable, so go ahead and look around. Open up the new `packages/hello_world` directory in your editor. If you've built or contributed to Node projects, it will all look familiar. You'll see a `package.json` file, a `src` directory, a `tsconfig.json`, and even a README. -## Generate an NPM package for the Increment contract {#generate-an-npm-package-for-the-increment-contract} +## Generate an NPM package for the Increment contract Though we can run `soroban contract bindings typescript` for each of our contracts individually, the [soroban-template-astro](https://github.com/stellar/soroban-astro-template) that we used as our template includes a very handy `initialize.js` script that will handle this for all of the contracts in our `contracts` directory. @@ -79,7 +79,7 @@ In addition to generating the NPM packages, `initialize.js` will also: We have already taken care of the first three bullet points in earlier steps of this tutorial, so those tasks will be noops when we run `initialize.js`. -### Configure initialize.js {#configure-initializejs} +### Configure initialize.js We need to make sure that `initialize.js` has all of the environment variables it needs before we do anything else. Copy the `.env.example` file over to `.env`. The environment variables set in `.env` are used by the `initialize.js` script. @@ -122,7 +122,7 @@ This `.env` file is used in the `initialize.js` script. When using the CLI, we c ::: -### Run `initialize.js` {#run-initializejs} +### Run `initialize.js` First let's install the Javascript dependencies: @@ -138,7 +138,7 @@ npm run init As mentioned above, this script attempts to build and deploy our contracts, which we have already done. The script is smart enough to check if a step has already been taken care of, and is a no-op in that case, so it is safe to run more than once. -### Call the contract from the frontend {#call-the-contract-from-the-frontend} +### Call the contract from the frontend Now let's open up `src/pages/index.astro` and take a look at how the frontend code integrates with the NPM package we created for our contracts. @@ -174,7 +174,7 @@ When you start up the dev server with `npm run dev`, you will see similar output ::: -### What's happening here? {#whats-happening-here} +### What's happening here? If you inspect the page (right-click, inspect) and refresh, you'll see a couple interesting things: @@ -195,13 +195,13 @@ Then check the `dist` folder. You'll see that it built an HTML and CSS file, but During the build, Astro made a single call to your contract, then injected the static result into the page. This is great for contract methods that don't change, but probably won't work for most contract methods. Let's integrate with the `incrementor` contract to see how to handle interactive methods in Astro. --> -## Call the incrementor contract from the frontend {#call-the-incrementor-contract-from-the-frontend} +## Call the incrementor contract from the frontend While `hello` is a simple view-only/read method, `increment` changes on-chain state. This means that someone needs to sign the transaction. So we'll need to add transaction-signing capabilities to the frontend. The way signing works in a browser is with a _wallet_. Wallets can be web apps, browser extensions, standalone apps, or even separate hardware devices. -### Install Freighter Extension {#install-freighter-extension} +### Install Freighter Extension Right now, the wallet that best supports Soroban is [Freighter](../guides/freighter/README.mdx). It is available as a Firefox Add-on, as well as extensions for Chrome and Brave. Go ahead and [install it now](https://freighter.app). @@ -211,7 +211,7 @@ Go to Settings (the gear icon) → Preferences and toggle the switch to Enable E Now you're all set up to use Freighter as a user, and you can add it to your app. -### Add the StellarWalletsKit and set it up {#add-the-stellarwalletskit-and-set-it-up} +### Add the StellarWalletsKit and set it up Even though we're using Freighter to test our app, there are more wallets that support signing smart contract transactions. To make their integration easier, we are using the `StellarWalletsKit` library which allows us support all Stellar Wallets with a single library. @@ -355,7 +355,7 @@ Then open the page and click the "Connect" button. You should see Freighter pop Now you're ready to sign the call to `increment`! -### Call `increment` {#call-increment} +### Call `increment` Now we can import the `increment` contract client from `soroban_increment_contract` and start using it. We'll again create a new Astro component. Create a new file at `src/components/Counter.astro` with the following contents: @@ -454,7 +454,7 @@ There's obviously some functionality missing, though. For example, that `???` is Before you try to update it, let's streamline the process around building, deploying, and generating clients for contracts. -## Take it further {#take-it-further} +## Take it further If you want to take it a bit further and make sure you understand all the pieces here, try the following: @@ -465,13 +465,13 @@ If you want to take it a bit further and make sure you understand all the pieces - Rather than using NPM scripts for everything, try using a more elegant script runner such as [just](https://github.com/casey/just). The existing npm `scripts` can then call `just`, such as `"setup": "just setup"`. - Update the README to explain what this project is and how to use it to potential collaborators and employers 😉 -## Troubleshooting {#troubleshooting} +## Troubleshooting Sometimes things go wrong. As a first step when troubleshooting, you may want to [clone our tutorial repository](https://github.com/AhaLabs/soroban-tutorial-project) and see if the problem happens there, too. If it happens there, too, then it may be a temporary problem with the Soroban network. Here are some common issues and how to fix them. -### Call to `hello` fails {#call-to-hello-fails} +### Call to `hello` fails Sometimes the call to `hello` can start failing. You can obviously stub out the call and define `result` some other way to troubleshoot. @@ -479,11 +479,11 @@ One of the common problems here is that the contract becomes [archived](../../le If you're still having problems, join our Discord (link above) or [open an issue in GitHub](https://github.com/stellar/stellar-docs/issues/new/choose). -### All contract calls start throwing `403` errors {#all-contract-calls-start-throwing-403-errors} +### All contract calls start throwing `403` errors This means that Testnet is down, and you probably just need to wait a while and try again. -## Wrapping up {#wrapping-up} +## Wrapping up Some of the things we did in this section: diff --git a/docs/build/apps/example-application-tutorial/account-creation.mdx b/docs/build/apps/example-application-tutorial/account-creation.mdx index ca791f5da..43776881e 100644 --- a/docs/build/apps/example-application-tutorial/account-creation.mdx +++ b/docs/build/apps/example-application-tutorial/account-creation.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 Accounts are the central data structure in Stellar and can only exist with a valid keypair (a public and secret key) and the required minimum balance of XLM. Read more in the [Accounts section]. -## User experience {#user-experience} +## User experience To start, we'll have our user create an account. In BasicPay, the signup page will display a randomized public and secret keypair that the user can select with the option to choose a new set if preferred. @@ -25,11 +25,11 @@ With BasicPay, when the user clicks the “Signup” button, they will be asked When you're ready to move the application to Pubnet, accounts will need to be funded with real XLM. This is something the application can cover itself by depositing XLM into the user's account, with the use of [sponsored reserves], or the user can cover the required balance with their own XLM. -## Code implementation {#code-implementation} +## Code implementation We will create a Svelte `store` to interact with our user's randomly generated keypair. The store will take advantage of some of the `js-stellar-wallets` SDK to encrypt/decrypt the keypair, as well as sign transactions. -### Creating the `walletStore` store {#creating-the-walletstore-store} +### Creating the `walletStore` store Our `walletStore` will make a few things possible throughout our application. @@ -170,7 +170,7 @@ const setupKeyManager = () => { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/walletStore.js -### Creating the account on the Stellar network {#creating-the-account-on-the-stellar-network} +### Creating the account on the Stellar network After we've registered the user, we need to fund the account on the Stellar network. As discussed previously, there are multiple ways to accomplish this task, but we are using Friendbot to ensure the user has some Testnet XLM to experiment with. @@ -184,7 +184,7 @@ export async function fundWithFriendbot(publicKey) { Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -### Using the `walletStore` store {#using-the-walletstore-store} +### Using the `walletStore` store Our `walletStore` is used in a ton of places in our application, especially in the confirmation modal when asking a user to input their pincode. Read on to see how we've done that. diff --git a/docs/build/apps/example-application-tutorial/anchor-integration/sep10.mdx b/docs/build/apps/example-application-tutorial/anchor-integration/sep10.mdx index 9a584bb0f..114d853a0 100644 --- a/docs/build/apps/example-application-tutorial/anchor-integration/sep10.mdx +++ b/docs/build/apps/example-application-tutorial/anchor-integration/sep10.mdx @@ -9,7 +9,7 @@ Similar to the SEP-1 information, both SEP-6 and SEP-24 protocols make use of SE Since we have the `stellar.toml` file information already, we can use that to display some interactive elements to the user. -## Prompt for authentication {#prompt-for-authentication} +## Prompt for authentication :::note @@ -54,7 +54,7 @@ The `/src/routes/dashboard/transfers/+page.svelte` is doing **a lot** of work th **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## Requesting a challenge transaction {#requesting-a-challenge-transaction} +## Requesting a challenge transaction Now, when the user clicks the "authenticate" button, it triggers the `auth` function. @@ -192,7 +192,7 @@ function validateChallengeTransaction({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js -## Sign and submit the challenge transaction {#sign-and-submit-the-challenge-transaction} +## Sign and submit the challenge transaction In response, the user signs the transaction. You may have noticed we present this challenge transaction to the user with our regular confirmation modal. Once they've signed the transaction, the application sends it back to the anchor with a `POST` request. If the signature checks out, the success response will contain a [JSON Web Token (JWT)](https://jwt.io/), which BasicPay stores in the `webAuthStore` store to use for future interactions with the anchor. @@ -271,7 +271,7 @@ export async function submitChallengeTransaction({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js -## About the `webAuthStore` store {#about-the-webauthstore-store} +## About the `webAuthStore` store Like so much of our BasicPay application, the various authentication tokens the user may have accumulated over time are stored in the browser's `localStorage`. There's not much special about this particular store, but here's how we put it together: diff --git a/docs/build/apps/example-application-tutorial/anchor-integration/sep24.mdx b/docs/build/apps/example-application-tutorial/anchor-integration/sep24.mdx index e1b7a5c44..d06cf5661 100644 --- a/docs/build/apps/example-application-tutorial/anchor-integration/sep24.mdx +++ b/docs/build/apps/example-application-tutorial/anchor-integration/sep24.mdx @@ -13,7 +13,7 @@ Remember, SEP-24 depends on [SEP-10 authentication]. Everything below assumes th ::: -## Find the anchor's `TRANSFER_SERVER_SEP0024` {#find-the-anchors-transfer_server_sep0024} +## Find the anchor's `TRANSFER_SERVER_SEP0024` Before we can ask anything about _how_ to make a SEP-24 transfer, we have to figure out _where_ to discover that information. Fortunately, the SEP-1 protocol describes standardized fields to find out what we need. @@ -27,7 +27,7 @@ export async function getTransferServerSep24(domain) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js -## Get `/info` {#get-info} +## Get `/info` Our application will request the `/info` endpoint from the anchor's transfer server to understand the supported transfer methods (deposit, withdraw) and available endpoints, as well as additional features that may be available during transfers. @@ -53,7 +53,7 @@ export async function getSep24Info(domain) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep24.js -## The user clicks "deposit" or "withdraw" {#the-user-clicks-deposit-or-withdraw} +## The user clicks "deposit" or "withdraw" Now that we have all the SEP-24 information the anchor has made available to us, it's up to the user to actually begin the initiation process. In BasicPay, they do that by simply clicking a button that will then trigger the `launchTransferWindowSep24` function. @@ -95,7 +95,7 @@ This file was pretty heavily covered in the [SEP-6 section]. We'll be presenting **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## Retrieve the interactive URL {#retrieve-the-interactive-url} +## Retrieve the interactive URL BasicPay then initiates a transfer method by sending a `POST` request to either the “SEP-24 Deposit” or “SEP-24 Withdraw” endpoint. The anchor then sends an interactive URL that BasicPay will open as a popup for the user to complete and confirm the transfer. @@ -135,7 +135,7 @@ export async function initiateTransfer24({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep24.js -## Launch the popup window and listen for a callback {#launch-the-popup-window-and-listen-for-a-callback} +## Launch the popup window and listen for a callback BasicPay doesn't really need (or want) to know everything that's happening between the user and the anchor during a SEP-24 transfer. However, we _do_ want to know when the interaction is over, since we may need to take some action at that point. So, we add a callback to the interactive URL and open the popup window. @@ -175,7 +175,7 @@ Since BasicPay is an entirely client-side application, we can't provide a callba **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## Complete transfer {#complete-transfer} +## Complete transfer Once the user is finished with the interactive window from the anchor, they'll be brought back to BasicPay. We store the details of the transfer in the `transfersStore` store (remember, this is just so we can track which anchors to query for transfers later on). @@ -215,7 +215,7 @@ Once the user is finished with the interactive window from the anchor, they'll b **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## (Sometimes) Send a Stellar payment {#sometimes-send-a-stellar-payment} +## (Sometimes) Send a Stellar payment In a withdrawal transaction, BasicPay will also build and present to the user a Stellar transaction for them to sign with their pincode. diff --git a/docs/build/apps/example-application-tutorial/anchor-integration/sep6.mdx b/docs/build/apps/example-application-tutorial/anchor-integration/sep6.mdx index 7b3eac8f0..7605c70f0 100644 --- a/docs/build/apps/example-application-tutorial/anchor-integration/sep6.mdx +++ b/docs/build/apps/example-application-tutorial/anchor-integration/sep6.mdx @@ -7,7 +7,7 @@ import useBaseUrl from "@docusaurus/useBaseUrl"; SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. In this integration, a user’s KYC information is gathered and handled by the wallet and submitted to the anchor _on behalf of_ the user. -## Find the anchor's `TRANSFER_SERVER` {#find-the-anchors-transfer_server} +## Find the anchor's `TRANSFER_SERVER` Before we can ask anything about _how_ to make a SEP-6 transfer, we have to figure out _where_ to discover that information. Fortunately, the SEP-1 protocol describes standardized fields to find out what we need. @@ -21,7 +21,7 @@ export async function getTransferServerSep6(domain) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js -## Get `/info` {#get-info} +## Get `/info` Now that we know where the transfer server is located, BasicPay needs to fetch the `/info` endpoint from the anchor's transfer server to understand the supported transfer methods ([deposit, withdraw, deposit-exchange, and withdraw-exchange](https://stellar.org/protocol/sep-6#info)) and available endpoints, as well as additional features that may be available during transfers. @@ -45,7 +45,7 @@ export async function getSep6Info(domain) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep6.js -## Display interactive elements {#display-interactive-elements} +## Display interactive elements Since many of the SEP-6 (and SEP-24) endpoints require authentication, we wait until our user is [authenticated with SEP-10](./sep10.mdx) before we display what kinds of transfers are available. When they have a valid authentication token, we can display some buttons the user can use to begin a transfer. @@ -75,13 +75,13 @@ The user can then initiate one of the transfer methods (in BasicPay, only deposi **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -## A special SEP-6 modal component {#a-special-sep-6-modal-component} +## A special SEP-6 modal component If you recall back to our [confirmation modal section](../confirmation-modal.mdx), we designed our modal component to be useful for anything we might require. Well, that's _almost_ true. The fact is that SEP-6 interactions are just plain complex. To facilitate that complexity, we've created a purpose-built SEP-6 transfer modal. There is **so much** to it, that we couldn't possibly cover everything it does here. However, we'll cover the main bits and link to the relevant source files. The modal component itself has been broken into several smaller Svelte components. Check out this source file to start looking through how we've put it together: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferModalSep6.svelte -### Launching the SEP-6 modal {#launching-the-sep-6-modal} +### Launching the SEP-6 modal The above buttons will use the `launchTransferModalSep6` function to display the modal to the user. Here's how it's defined in that same file. @@ -126,7 +126,7 @@ The above buttons will use the `launchTransferModalSep6` function to display the Once launched, the `TransferModalSep6` will walk the user through a "wizard" to gather all the required information and ultimately create the transfer. -### Modal step 1: Transfer details {#modal-step-1-transfer-details} +### Modal step 1: Transfer details BasicPay prompts the user to input additional information such as transfer type, destination, and amount. Some of this is prepopulated based on which button the user clicked. However, the user can change any of the fields if they so choose. @@ -134,7 +134,7 @@ We'll spare the code sample in this section, since it's mostly Svelte things goi -### Modal step 2: Gather KYC information {#modal-step-2-gather-kyc-information} +### Modal step 2: Gather KYC information To find out what infrastructure the anchor has made available for us to use, we need to query the anchor's SEP-1 `stellar.toml` file for the `KYC_SERVER` field. If this is not defined, BasicPay will fallback to using the `TRANSFER_SERVER` for these requests. @@ -178,7 +178,7 @@ export async function getSep12Fields({ authToken, homeDomain }) { Again, the presentation of the fields the user must complete is more on the Svelte side of things, so we won't share those details here. However, the source for this component is available here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCInformation.svelte -### Modal step 3: Put KYC fields and report status {#modal-step-3-put-kyc-fields-and-report-status} +### Modal step 3: Put KYC fields and report status Now that the user has provided the necessary information for the KYC requirements of the anchor, we can submit them to the anchor's KYC server with a `PUT` request. @@ -210,7 +210,7 @@ BasicPay receives back from the anchor a status message for the user to see. Onc This component of the SEP-6 modal, like most of them, is almost entirely Svelte-related. So as to keep this tutorial (somewhat) uncluttered, we'll refer you to the source for the component, which you can find here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCStatus.svelte -### Modal step 4: Submit transfer {#modal-step-4-submit-transfer} +### Modal step 4: Submit transfer BasicPay makes this request by taking all the fields that have been collected during this process and wrapping them into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J&asset_code=SRT&type=bank_account&amount=11) @@ -257,7 +257,7 @@ The only reason we're storing anything about the transfer in BasicPay is to help ::: -### (Sometimes) Modal step 5: Send a Stellar payment {#sometimes-modal-step-5-send-a-stellar-payment} +### (Sometimes) Modal step 5: Send a Stellar payment In a withdrawal transaction, BasicPay will also build and present to the user a Stellar transaction for them to sign with their pincode. Here we will finally get to move back to our "regular" modal that _is_ so good at so many things! diff --git a/docs/build/apps/example-application-tutorial/anchor-integration/setup.mdx b/docs/build/apps/example-application-tutorial/anchor-integration/setup.mdx index 3f31d6e84..0890e73a5 100644 --- a/docs/build/apps/example-application-tutorial/anchor-integration/setup.mdx +++ b/docs/build/apps/example-application-tutorial/anchor-integration/setup.mdx @@ -22,7 +22,7 @@ Our integrations will also use the following SEPs: - [SEP-10: Stellar Web Authentication](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) - defines the standard way for clients to create authenticated web sessions on behalf of a user who holds a Stellar account - [SEP-12: KYC API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md) - defines a standard way for Stellar clients to upload KYC information to anchors -## Finding anchored assets {#finding-anchored-assets} +## Finding anchored assets BasicPay takes care of all the anchor transfer details on the `/dashboard/transfers` page. See it in action here: https://basicpay.pages.dev/dashboard/transfers diff --git a/docs/build/apps/example-application-tutorial/confirmation-modal.mdx b/docs/build/apps/example-application-tutorial/confirmation-modal.mdx index bb99ba49b..84c269eee 100644 --- a/docs/build/apps/example-application-tutorial/confirmation-modal.mdx +++ b/docs/build/apps/example-application-tutorial/confirmation-modal.mdx @@ -5,7 +5,7 @@ sidebar_position: 22 Since the user's keypair is encrypted with a pincode and stored in their browser, we will occasionally need to prompt them for that pincode to sign a transaction or otherwise prove that they should be permitted to perform some action or view some data. -## User Experience {#user-experience} +## User Experience The user should be informed about any actions that may take place, especially when funds are on the line. To ensure this, we will overtly request their confirmation via pincode before anything is done. The application has no way of knowing a user's pincode, so it can't decrypt their keypair without their confirmation. @@ -13,7 +13,7 @@ The modal window we've implemented facilitates this confirmation flow whenever w ![confirmation modal](/assets/confirm-pincode.png) -## Code implementation {#code-implementation} +## Code implementation Our modal function uses the `svelte-simple-modal` package to give us a versatile starting point. If you need to, install it now. @@ -21,7 +21,7 @@ Our modal function uses the `svelte-simple-modal` package to give us a versatile npm install --save-dev svelte-simple-modal ``` -### Wrapping the rest of our app in the modal {#wrapping-the-rest-of-our-app-in-the-modal} +### Wrapping the rest of our app in the modal On the Svelte side, this modal component will be a "wrapper" around the rest of our application, which allows us to trigger the modal from anywhere we need, and it should behave similarly no matter what. @@ -54,7 +54,7 @@ On the Svelte side, this modal component will be a "wrapper" around the rest of **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/+layout.svelte -### Creating a reusable modal Svelte component {#creating-a-reusable-modal-svelte-component} +### Creating a reusable modal Svelte component To avoid reinventing the wheel every time we need a modal, we will create a reusable component that can accomodate most of our needs. Then, when we need the confirmation modal, we can pass an object of props to customize the modal's behavior. @@ -104,7 +104,7 @@ The basic parts of this component look like this: **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/components/ConfirmationModal.svelte -### Trigger the modal component at signup {#trigger-the-modal-component-at-signup} +### Trigger the modal component at signup We can now use this modal component whenever we need to confirm something from the user. For example, here is how the modal is triggered when someone signs up. @@ -146,7 +146,7 @@ We can now use this modal component whenever we need to confirm something from t **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/signup/+page.svelte -### Customizing confirmation and rejection behavior {#customizing-confirmation-and-rejection-behavior} +### Customizing confirmation and rejection behavior Now, as these components have been written so far, they don't actually _do_ anything when the user inputs their pincode or clicks on a button. Let's change that! diff --git a/docs/build/apps/example-application-tutorial/contacts-list.mdx b/docs/build/apps/example-application-tutorial/contacts-list.mdx index 151019ace..3916150d6 100644 --- a/docs/build/apps/example-application-tutorial/contacts-list.mdx +++ b/docs/build/apps/example-application-tutorial/contacts-list.mdx @@ -5,7 +5,7 @@ sidebar_position: 25 One central feature of BasicPay is a list of contacts containing a user's name and associated Stellar addresses. -## User experience {#user-experience} +## User experience There are a few ways for a user to interact with the contact list. One way is that they can add a user and address on the `/dashboard/contacts` page (which also checks for a valid public key!). @@ -13,11 +13,11 @@ There are a few ways for a user to interact with the contact list. One way is th See it in action here: https://basicpay.pages.dev/dashboard/contacts -## Code implementation {#code-implementation} +## Code implementation We will create a Svelte `store` to keep track of a user's contact list. -### Creating the `contacts` store {#creating-the-contacts-store} +### Creating the `contacts` store As with the rest of our user-data, the contacts list will live in the browser's `localStorage`. We are using the [`svelt-local-storage-store` package] to facilitate this. We create a Svelte `store` to hold the data, and add a few custom functions to manage the list: `empty`, `remove`, `add`, `favorite`, and `lookup`. @@ -90,9 +90,9 @@ export const contacts = createContactsStore(); **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/contactsStore.js -### Using the `contacts` store {#using-the-contacts-store} +### Using the `contacts` store -#### On the `/dashboard/contacts` page {#on-the-dashboardcontacts-page} +#### On the `/dashboard/contacts` page We also have a page dedicated to managing contacts. The `/dashboard/contacts` page will allow the user to collect and manage a list of contact entries that stores the contact's name and Stellar address. The contact can also be flagged or unflagged as a "favorite" contact to be displayed on the main `/dashboard` page. @@ -123,7 +123,7 @@ We also have a page dedicated to managing contacts. The `/dashboard/contacts` pa **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/contacts/+page.svelte -#### On the `/dashboard` page {#on-the-dashboard-page} +#### On the `/dashboard` page The `contacts` store is now exported from this file and can be accessed and used inside a Svelte page or component. Here is how we've implemented a "favorite contacts" component for display on the main BasicPay dashboard. diff --git a/docs/build/apps/example-application-tutorial/manage-trust.mdx b/docs/build/apps/example-application-tutorial/manage-trust.mdx index a002c945c..e840fe7e3 100644 --- a/docs/build/apps/example-application-tutorial/manage-trust.mdx +++ b/docs/build/apps/example-application-tutorial/manage-trust.mdx @@ -5,7 +5,7 @@ sidebar_position: 30 For an account to hold and trade assets other than XLM, it must establish a [trustline](../../../learn/fundamentals/stellar-data-structures/accounts.mdx#trustlines) with the issuing account of that particular asset. Each trustline increases the account’s [base reserve](../../../learn/fundamentals/stellar-data-structures/accounts.mdx#base-reserves-and-subentries) by 0.5 XLM, which means the account will have to hold more XLM in its minimum balance. -## User experience {#user-experience} +## User experience First, we’ll have the user create a trustline for an asset by navigating to the Assets page, selecting an asset, and clicking the “Add Asset” button. @@ -33,11 +33,11 @@ Trustlines hold the balances for all of their associated assets (except XLM, whi See it in action here: https://basicpay.pages.dev/dashboard/assets -## Code implementation {#code-implementation} +## Code implementation The trustlines an account holds will be necessary to view in several parts of the BasicPay application. First, we'll discuss how we manage different trustlines for the account. -### The `/dashboard/assets` page {#the-dashboardassets-page} +### The `/dashboard/assets` page The `/dashboard/assets` page allows the user to manage the Stellar assets their account carries trustlines to. On this page, they can select from several pre-suggested or highly ranked assets, or they could specify their own asset to trust using an asset code and issuer public key. They can also remove trustlines that already exist on their account. @@ -136,7 +136,7 @@ The layout of the page is quite similar to our contacts page. It has a table dis **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/assets/+page.svelte -### The `createChangeTrustTransaction` function {#the-createchangetrusttransaction-function} +### The `createChangeTrustTransaction` function In the above page, we've made use of the `createChangeTrustTransaction` function. This function can be used to add, delete, or modify trustlines on a Stellar account. diff --git a/docs/build/apps/example-application-tutorial/overview.mdx b/docs/build/apps/example-application-tutorial/overview.mdx index 348b2b01d..a5c674e35 100644 --- a/docs/build/apps/example-application-tutorial/overview.mdx +++ b/docs/build/apps/example-application-tutorial/overview.mdx @@ -19,9 +19,9 @@ Although BasicPay is a full-fledged application on Stellar's Testnet, it has bee ::: -## Project setup {#project-setup} +## Project setup -### Project requirements {#project-requirements} +### Project requirements To build a basic Stellar application, you'll need: @@ -52,14 +52,14 @@ This tutorial is probably best viewed as "_nearly_ comprehensive." We aren't goi ::: -### Dev helpers {#dev-helpers} +### Dev helpers - [Stellar Lab]: an experimental playground to interact with the Stellar network - Friendbot: a bot that funds accounts with 10,000 fake XLM on Stellar's Testnet; you can fund your account by going to `https://friendbot.stellar.org/?addr=G...` - [Testnet toml file]: an example `stellar.toml` file that demonstrates what information an anchor might publish - [BasicPay dev helpers]: if you're _using_ the BasicPay application, we've created a few helpful tools to help you explore its functionality -## Getting started {#getting-started} +## Getting started Here are the steps we've taken to start building BasicPay. Feel free to be inspired and customize these directions as you see fit. The entire [BasicPay codebase] is freely open and available on GitHub for reference. @@ -69,7 +69,7 @@ This part of the tutorial will need a large helping of "your mileage may vary." ::: -### Install frameworks {#install-frameworks} +### Install frameworks The first thing we'll need to do is create a SvelteKit app, using `npm`, we are using v18.x of nodejs. @@ -188,7 +188,7 @@ Your SvelteKit project is now configured and ready to run! npm run dev ``` -### Stellar dependencies {#stellar-dependencies} +### Stellar dependencies To work with the Stellar network, datastructures, and locally stored keypairs, we're going to install and configure a few more dependencies. diff --git a/docs/build/apps/example-application-tutorial/path-payment.mdx b/docs/build/apps/example-application-tutorial/path-payment.mdx index e1f165687..617f5b219 100644 --- a/docs/build/apps/example-application-tutorial/path-payment.mdx +++ b/docs/build/apps/example-application-tutorial/path-payment.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 A path payment is where the asset sent can be different from the asset received. There are two possible path payment operations: 1) `path_payment_strict_send`, which allows the user to specify the amount of the asset to send, and 2) `path_payment_strict_receive`, which allows the user to specify the amount of the asset received. Read more in the [Path Payments Encyclopedia Entry](../../../learn/encyclopedia/transactions-specialized/path-payments.mdx). -## User experience {#user-experience} +## User experience With BasicPay, the user sends a path payment by navigating to the Payments page, where they can either select a user from their contacts or input the public key of a destination address. They then select the Send and Receive Different Assets toggle and determine whether they want to specify the asset sent or received. Finally they select the asset sent and the asset received and the amounts and select the Preview Transaction button. @@ -13,9 +13,9 @@ With BasicPay, the user sends a path payment by navigating to the Payments page, The user will then preview the transaction, input their pincode, and select the Confirm button to sign and submit the transaction to the network. -## Code implementation {#code-implementation} +## Code implementation -### The `/dashboard/send` page {#the-dashboardsend-page} +### The `/dashboard/send` page Most of this page has been discussed in the [Payment section](./payment.mdx#the-dashboardsend-page). Below, we're highlighting the unique pieces that are added to BasicPay to allow for the path payment feature. @@ -156,7 +156,7 @@ Most of this page has been discussed in the [Payment section](./payment.mdx#the- **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/send/+page.svelte -### The transaction functions {#the-transaction-functions} +### The transaction functions In the above section, we used the `createPathPaymentStrictReceiveTransaction` and `createPathPaymentStrictSendTransaction` functions. These are used to create transactions that contain the actual path payment operation. diff --git a/docs/build/apps/example-application-tutorial/payment.mdx b/docs/build/apps/example-application-tutorial/payment.mdx index 4370e34aa..765d4f450 100644 --- a/docs/build/apps/example-application-tutorial/payment.mdx +++ b/docs/build/apps/example-application-tutorial/payment.mdx @@ -5,7 +5,7 @@ sidebar_position: 40 A payment operation sends an amount in a specific asset (XLM or non-XLM) to a destination account. With a basic payment operation, the asset sent is the same as the asset received. BasicPay also allows for path payments (where the asset sent is different than the asset received), which we’ll talk about in the next section. -## User experience {#user-experience} +## User experience In our BasicPay application, the user will navigate to the Payments page where can either select a user from their contacts or input the public key of a destination address with a specified asset they’d like to send along with the amount of the asset. @@ -21,9 +21,9 @@ In BasicPay, we’ve set it up so that the user always pays a static fee of 100, The user then inputs their pincode and clicks the "Confirm" button, which signs and submits the transaction to the ledger. -## Code implementation {#code-implementation} +## Code implementation -### The `/dashboard/send` page {#the-dashboardsend-page} +### The `/dashboard/send` page The `/dashboard/send` page allows the user to send payments to other Stellar addresses. They can select from a dropdown containing their contact list names, or they can enter their own "Other..." public key. @@ -163,7 +163,7 @@ For now, we'll focus on regular payments, and we'll dig into the path payments i **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/send/+page.svelte -### The transaction functions {#the-transaction-functions} +### The transaction functions In the above section, we used the `createPaymentTransaction` function. This function can be used to send a payment of any asset from one Stellar address to another. diff --git a/docs/build/apps/example-application-tutorial/querying-data.mdx b/docs/build/apps/example-application-tutorial/querying-data.mdx index 5da977a7a..69c939239 100644 --- a/docs/build/apps/example-application-tutorial/querying-data.mdx +++ b/docs/build/apps/example-application-tutorial/querying-data.mdx @@ -13,7 +13,7 @@ In other places in this tutorial, we have omitted the JSDoc descriptions and typ ::: -## Imports and types {#imports-and-types} +## Imports and types ```js title="/src/lib/stellar/horizonQueries.js" import { error } from "@sveltejs/kit"; @@ -49,7 +49,7 @@ const server = new Server(horizonUrl); **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## fetchAccount {#fetchaccount} +## fetchAccount Gives an account's sequence number, asset balances, and trustlines. @@ -87,7 +87,7 @@ export async function fetchAccount(publicKey) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## fetchAccountBalances {#fetchaccountbalances} +## fetchAccountBalances Gets existing balances for a given `publicKey`. @@ -107,7 +107,7 @@ export async function fetchAccountBalances(publicKey) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## fetchRecentPayments {#fetchrecentpayments} +## fetchRecentPayments Finds any payments made to or from the given `publicKey` (includes: payments, path payments, and account merges). @@ -133,7 +133,7 @@ export async function fetchRecentPayments(publicKey, limit = 10) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## submit {#submit} +## submit Submit a signed transaction to the Stellar network. @@ -159,7 +159,7 @@ export async function submit(transaction) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## fetchAssetsWithHomeDomains {#fetchassetswithhomedomains} +## fetchAssetsWithHomeDomains We create a brand new `HomeDomainBalanceLine` type that includes the balance information of a user's trustline, and also adds the `home_domain` of the asset issuer. If you're using something else for type safety (or nothing at all), feel free to adapt or ignore the `@typedef`s we've included here. @@ -205,7 +205,7 @@ export async function fetchAssetsWithHomeDomains(balances) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## findStrictSendPaths {#findstrictsendpaths} +## findStrictSendPaths Find the available strict send paths between a source asset/amount and receiving account. @@ -243,7 +243,7 @@ export async function findStrictSendPaths({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## findStrictReceivePaths {#findstrictreceivepaths} +## findStrictReceivePaths Find the available strict receive paths between a source account and receiving asset/amount. @@ -284,7 +284,7 @@ export async function findStrictReceivePaths({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## Query Stellar Expert {#query-stellar-expert} +## Query Stellar Expert Stellar Expert is a third-party block explorer that is indispensable as a tool for understanding what is happening on the Stellar network. On our `/dashboard/assets` page, we're pre-populating a list of asset trustlines a user might choose to add to their Stellar account. We get this list of assets from the Stellar Expert API. diff --git a/docs/build/apps/ingest-sdk/ingestion-pipeline-code.mdx b/docs/build/apps/ingest-sdk/ingestion-pipeline-code.mdx index 0d082a940..baba56d1f 100644 --- a/docs/build/apps/ingest-sdk/ingestion-pipeline-code.mdx +++ b/docs/build/apps/ingest-sdk/ingestion-pipeline-code.mdx @@ -12,7 +12,7 @@ Steps: #2 - compile and run with `go mod tidy;go build -o pipeline ./.; ./pipeline` #3 - in separate terminal, run `python distributed_payment_subsciber.py`, this will perform distributed pipeline topology, as it receives messages with payment info from the pipeline process and does additional processing(printing it to console). -### `go.mod` {#gomod} +### `go.mod` @@ -31,7 +31,7 @@ require ( -### `main.go` {#maingo} +### `main.go` @@ -244,7 +244,7 @@ func main() { -### `config.toml` {#configtoml} +### `config.toml` The CDP configuration settings, this file defines the data storage which contains the pre-generated Ledger Metadata files. Google Cloud storage is used in this example. @@ -264,7 +264,7 @@ files_per_partition = 64000 -### `distributed_payment_subsciber.py` {#distributed_payment_subsciberpy} +### `distributed_payment_subsciber.py` A Python script demonstrating how we now have distributed processing and event driven architecture by leveraging the MQ Broker to push derived application payment data model out to other microservices. Make sure to `pip install pyzmq` diff --git a/docs/build/apps/ingest-sdk/overview.mdx b/docs/build/apps/ingest-sdk/overview.mdx index f6c369f80..714d8f241 100644 --- a/docs/build/apps/ingest-sdk/overview.mdx +++ b/docs/build/apps/ingest-sdk/overview.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 This tutorial walks through how an application can leverage [CDP architecture](https://stellar.org/blog/developers/composable-data-platform) to create fast, lightweight Stellar Ledger Metada data pipelines using a few select packages from the Stellar Go Repo [github.com/stellar/go](https://github.com/stellar/go/blob/master/) collectively known as the 'Ingestion' SDK: -## The Ingestion SDK packages {#the-ingestion-sdk-packages} +## The Ingestion SDK packages - `github.com/stellar/go/amount` utility package to convert prices from network transaction operations to string - `github.com/stellar/go/historyarchive` `github.com/stellar/go/support/datastore` `github.com/stellar/go/support/storage` utility package with convenient wrappers for accessing history archives, and avoid low-level http aspects @@ -14,9 +14,9 @@ This tutorial walks through how an application can leverage [CDP architecture](h - `github.com/stellar/go/network` provides convenient pre-configured settings for Testnet and Mainnet networks - `github.com/stellar/go/xdr` a complete Golang binding to the Stellar network data model -## Ingestion project setup {#ingestion-project-setup} +## Ingestion project setup -### Project requirements {#project-requirements} +### Project requirements To use this example CDP pipeline for live Stellar network transaction data, you'll need: @@ -49,17 +49,17 @@ The example application will perform both of CDP pipelines. A minimum of two pip ![](/assets/cdp_pipelines.png) -### Ledger Metadata Export Pipeline {#ledger-metadata-export-pipeline} +### Ledger Metadata Export Pipeline This pipeline needs to be initiated first, it is responsible for exporting Stellar Ledger Metadata as files to a [CDP Datastore](https://github.com/stellar/go/blob/master/support/datastore/datastore.go#L17). -#### Determine the Datastore {#determine-the-datastore} +#### Determine the Datastore The Datastore in CDP is an interface, allowing for multiple implementations which represent different physical storage layers that can be 'plugged in' to export and consumer pipelines. Stellar provides the [GCS Datastore] as the first Datastore implementation, and this example chooses to use this existing implementation. There will be open source contributions for implementations on other storage layers to choose from as CDP grows. If you can't find an implementation for a storage layer you would like to use, it is also possible to develop your own [ Datastore](https://github.com/stellar/go/blob/master/support/datastore/datastore.go#L17) implementation, which is beyond scope of this example, as it entails a separate learning exercise of its own, coming soon! -#### Exporting network metadata to Datastore {#exporting-network-metadata-to-datastore} +#### Exporting network metadata to Datastore Use Galexie, a new CDP command line program for exporting network metadata to datastores. @@ -69,24 +69,24 @@ Use Galexie, a new CDP command line program for exporting network metadata to da - For one time export of historical bounded range of ledgers, use `append --start --end ` - For a continuous export of prior ledgers and all new ledgers generated on network, use `append --start `. -### Ledger Metadata Consumer Pipeline {#ledger-metadata-consumer-pipeline} +### Ledger Metadata Consumer Pipeline A consumer pipeline retrieves files from the GCS bucket and uses them as the origin of Ledger Metadata in a data processing pipeline. There can be many separate consumer pipelines all accessing the same Datastore at stame time. Each consumer pipeline will typically perform three distinct stream processor roles: -#### Inbound Adapter {#inbound-adapter} +#### Inbound Adapter The 'source of origin' for the ledger metadata in a pipeline. This processor retrieves [Ledger Metadata](https://github.com/stellar/go/blob/f30d11432e81c7a7cbb739a694520f729bbb31dd/xdr/xdr_generated.go#L18358) files from the GCS Datastore, extracts the `LedgerCloseMeta` for each Ledger and publishes it onto the messaging pipeline. The go sdk provides consumer helper function [ApplyLedgerMetadata](https://github.com/stellar/go/blob/master/ingest/cdp/producer.go#L89) for automated, performant, buffered retrieval of files from the remote datastore, application code can leverage this to acquire pure `LedgerCloseMeta` data from a callback function. -#### Transformer {#transformer} +#### Transformer Subscribes on the pipeline to receive `LedgerCloseMeta`. Uses the Go SDK package [github.com/stellar/go/xdr](https://github.com/stellar/go/tree/master/xdr) to parse the ledger meta data model for payment operations and convert those into a new instance of application data model `AppPayment` instances. Publishes `AppPayment` to the pipeline. -#### Outbound Adapter {#outbound-adapter} +#### Outbound Adapter Acts as the termination of the pipeline, it subscribes to receive `ApplicationPayment` and publishes the data off the pipeline and to an external data store, a ZeroMQ Publisher Socket, which is essentially a message broker. -### Summary {#summary} +### Summary Refer to [Ingestion Pipeline Sample Application](./ingestion-pipeline-code.mdx) for complete consumer code example, demonstrating a live, streaming pipeline against the Stellar network, processing each new ledger's metadata as it is closed on the network. diff --git a/docs/build/apps/moneygram-access-integration-guide.mdx b/docs/build/apps/moneygram-access-integration-guide.mdx index 9a6dd4d7b..bb84dbdfa 100644 --- a/docs/build/apps/moneygram-access-integration-guide.mdx +++ b/docs/build/apps/moneygram-access-integration-guide.mdx @@ -9,7 +9,7 @@ This document guides the reader through the technical requirements for integrati MoneyGram requires businesses to go through an onboarding process in order to get access to their testing and production environments. To get started with this process, reach out to partnerships@stellar.org. -## Resources {#resources} +## Resources - [MoneyGram Access Wallet MVP Implementation] - Use this MVP implementation as a reference for building your own integration. Many of the code snippets shared in this document are pulled from this project. @@ -24,18 +24,18 @@ MoneyGram requires businesses to go through an onboarding process in order to ge - [Stellar Ecosystem Proposal 10 (SEP-10)][sep-10] - The standardized API protocol for Stellar authentication, implemented by MoneyGram -## Asset Information {#asset-information} +## Asset Information Before you get access to MoneyGram's test environment, you should test your implementation with the SDF's [Stellar Test Anchor]. It implements the same APIs as MoneyGram's service but uses a different asset. The information for each asset is below. -### Stellar Reference Token {#stellar-reference-token} +### Stellar Reference Token This token is only on testnet. - **Issuing Account**: [GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B] - **Asset Code**: SRT -### USD Coin {#usd-coin} +### USD Coin Testnet: @@ -47,7 +47,7 @@ Pubnet: - **Issuing Account**: [GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN] - **Asset Code**: USDC -## Introduction {#introduction} +## Introduction Applications seeking to integrate MoneyGram Access must implement the client side of [Stellar Ecosystem Proposal 24 (SEP-24)][sep-24], a standardized protocol defined for applications to connect to businesses such as MoneyGram, more generally called anchors, that offer Stellar deposit & withdrawal services utilizing local payment rails. @@ -55,7 +55,7 @@ This document will walk you through the necessary steps to develop a functional The guide will assume your application is first being developed on Stellar’s test network and using MoneyGram’s testing deployment of Access, but there are no functional differences deploying the application to Stellar’s public network and using MoneyGram’s production deployment. -### Installing the Wallet SDK {#installing-the-wallet-sdk} +### Installing the Wallet SDK We highly recommend using the wallet SDK to facilitate building your integration. Find more info on the [Stellar Wallet SDK Docs]. @@ -69,7 +69,7 @@ yarn add @stellar/typescript-wallet-sdk -## Custodial vs. Non-Custodial Applications {#custodial-vs-non-custodial-applications} +## Custodial vs. Non-Custodial Applications Some applications, such as centralized exchanges, are custodial, meaning the application has access to the private keys of the acccounts holding its users’ funds on Stellar. Typically, custodial applications pool user funds into a smaller set of managed Stellar accounts, called pooled, shared, or omnibus accounts. @@ -77,7 +77,7 @@ Other applications are non-custodial, meaning the application does not have acce These two approaches require minor but concrete differences in how applications integrate with MoneyGram Access. The sub-sections below will describe these differences, but the rest of this tutorial will assume the application is custodial. -### Authentication {#authentication} +### Authentication MoneyGram needs to authenticate both the user and the application being used via Stellar's [SEP-10] protocol. @@ -85,15 +85,15 @@ Custodial applications are identified by the Stellar account public key they reg Because each user of a non-custodial application has their own Stellar account, non-custodial applications are identified by the home domain they register with MoneyGram during the onboarding process. When authenticating, the application must pass _the user's_ public key as the `account` query parameter, and pass their home domain as the `client_domain` query parameter. MoneyGram will look up the `SIGNING_KEY` value at `https:///.well-known/stellar.toml`, and return a Stellar transaction that requires signatures from both the user's private key & the private key of the public `SIGNING_KEY` on the application's [SEP-1] stellar.toml file. An example file can be found at https://vibrantapp.com/.well-known/stellar.toml. -### Transaction Initiation {#transaction-initiation} +### Transaction Initiation Because users of custodial applications don't have individual Stellar accounts, only the application knows how much money a user has to withdraw. Because of this, MoneyGram requires custodial applications to always pass the `amount` field in the request to start a new transaction. Non-custodial applications do not need to do this, although they can if they prefer. -### Source & Destination of Funds {#source--destination-of-funds} +### Source & Destination of Funds MoneyGram requires custodial applications to provide the Stellar accounts that may be used as the source or destination of funds during the onboarding process. For non-custodial applications, MoneyGram requires the source and destination of funds for each transaction to be the same account that was authenticated via [SEP-10]. -## Application Flow & Architecture {#application-flow--architecture} +## Application Flow & Architecture This guide will assume the application has a basic client-server architecture. The application’s client will request resources and initiate actions with the application’s server, which will communicate directly with MoneyGram’s server. @@ -107,7 +107,7 @@ After Step 4, the application should open the URL provided by MoneyGram in a mob The provided reference number would then be taken to any MoneyGram cash agent in order to receive cash in the user’s fiat currency. These steps document the cash-out, or withdrawal flow. The deposit flow is similar and detailed in the steps below. -## Generate Stellar Keypairs {#generate-stellar-keypairs} +## Generate Stellar Keypairs In this section, you will generate at least two Stellar keypairs, one that will be used to prove your application’s identity when authenticating with MoneyGram Access, and another that will hold, send & receive USDC on Stellar. You should always use one keypair for authentication, but application could use many keypairs for sending & receiving payments. In this guide, we'll assume the application uses one keypair for each purpose. @@ -119,7 +119,7 @@ The first keypair will be called the “authentication” keypair (or public / s Provide the public keys (starting with a G) of both the authentication and funds keypairs to MoneyGram. They will add these keys to their known lists of keys, granting them access to their deployment. -## Get XLM & USDC {#get-xlm--usdc} +## Get XLM & USDC Many cryptocurrency exchanges support purchasing XLM or USDC on Stellar. The SDF also maintains an [Anchor Directory] that attempts to list all the on & off-ramps for the Stellar Network. @@ -129,7 +129,7 @@ Some exchanges support XLM but do not support USDC on Stellar. This is not a pro To do this, send your XLM to the funds public key from the exchange, add a USDC trustline, and sell XLM for USDC using a [sell offer]. -## Authenticate {#authenticate} +## Authenticate This section encompasses steps 1 & 2 of the diagram displayed in the Architecture section above. The application’s client should request a MoneyGram transaction URL from the application’s server on user initiation. This should trigger an authentication process between the application’s server and MoneyGram’s server. This process is standardized in [SEP-10][sep-10]. @@ -210,7 +210,7 @@ def get_token() -> str: -## Initiate a Transaction {#initiate-a-transaction} +## Initiate a Transaction This section encompasses steps 3 & 4 of the architecture diagram displayed above. The application’s server will make a deposit or withdrawal initiation request to MoneyGram’s server, and MoneyGram will return a transaction ID, which will be used later to poll the transaction’s status, and a transaction URL, which should be returned to the application’s client and opened for the user. @@ -281,7 +281,7 @@ def initiate_withdraw(token: str, amount: str) -> Tuple[str, str]: The logic for initiating a deposit transaction looks very similar. See the [SEP-24][sep-24] standard specification for detailed information. -## Listen for the Close Notification {#listen-for-the-close-notification} +## Listen for the Close Notification The next step is to open the provided URL in the application’s client using a mobile webview, browser tab, or popup. The user will then go through KYC if they have not before in a prior transaction. In the deposit case, the user may also select a MoneyGram agent location to go to when providing cash. @@ -312,13 +312,13 @@ function closeWebView(e) { -## Send or Receive Funds {#send-or-receive-funds} +## Send or Receive Funds In withdrawal (or cash-out) transactions, applications must send USDC to the Stellar account MoneyGram specifies. In deposit (cash-in) transactions, applications must monitor their Stellar account for a payment from MoneyGram. In each case, the transaction submitted to Stellar must have a memo attached to it. This memo is provided by MoneyGram in the withdrawal case, and provided by the application in the deposit case. The memo is an identifier that allows the parties to tie the on-chain payment to the transaction record in the application’s or MoneyGram’s database. -### Poll Until MoneyGram is Ready {#poll-until-moneygram-is-ready} +### Poll Until MoneyGram is Ready Before the application can send funds or instruct the user to provide cash to a MoneyGram agent, the application should confirm with MoneyGram’s server that the transaction is ready to proceed which is signaled by the `pending_user_transfer_start` status. @@ -457,7 +457,7 @@ def poll_transaction_until_status( -### Sending Funds {#sending-funds} +### Sending Funds Once MoneyGram is ready to receive funds, your application should extract the Stellar account, memo and amount to use in the payment transaction, construct a Stellar transaction, and submit it to the Stellar network. You’ll need: @@ -639,7 +639,7 @@ def submit_payment(destination: str, memo: str, amount: str): -### Receiving Funds {#receiving-funds} +### Receiving Funds Once MoneyGram is ready for the user to drop off cash at an MGI agent (in deposit or cash-in cases), the application’s server should begin monitoring its Stellar account for an inbound USDC payment sent by MoneyGram. @@ -729,7 +729,7 @@ def stream_payments(account: str, cursor: str): -## Fetch the Reference Number {#fetch-the-reference-number} +## Fetch the Reference Number For deposit or cash-in transactions, MoneyGram does not provide reference numbers. All the user needs to do is drop off cash at the agent location chosen in the MoneyGram UI earlier in the flow, and the application should complete the transaction when a matching payment is detected on Stellar. diff --git a/docs/build/apps/overview.mdx b/docs/build/apps/overview.mdx index 869da82eb..2d2ca104f 100644 --- a/docs/build/apps/overview.mdx +++ b/docs/build/apps/overview.mdx @@ -9,7 +9,7 @@ Stellar has built-in logic for key storage, creating accounts, signing transacti This documentation includes sections on how to build applications without smart contracts with the [Wallet SDK](./wallet/overview.mdx) or the [JS SDK](./example-application-tutorial/overview.mdx), building with smart contracts with the [dapp frontend tutorial](./dapp-frontend.mdx), and all information regarding experimentation with [smart wallets](./smart-wallets.mdx). -## Anchors {#anchors} +## Anchors Many Stellar assets connect to real-world currencies, and Stellar has open protocols for integrating deposits and withdrawals of these assets via the [anchor network](https://stellar.org/learn/anchor-basics). Because of this, a Stellar-based application can take advantage of real banking rails and connect to real money. @@ -19,7 +19,7 @@ Set up an anchor using the [Anchor Platform](/platforms/anchor-platform). Integrate MoneyGram Access into an existing application with the [Integrate with MoneyGram Access tutorial](./moneygram-access-integration-guide.mdx). -## Stellar Ecosystem Proposals (SEPs) {#stellar-ecosystem-proposals-seps} +## Stellar Ecosystem Proposals (SEPs) Stellar-based products and services interoperate by implementing various Stellar Ecosystem Proposals (SEPs), which are publicly created, open-source documents that live in a [GitHub repository](https://github.com/stellar/stellar-protocol/tree/master/ecosystem#stellar-ecosystem-proposals-seps) and define how asset issuers, anchors, wallets, and other service providers interact with each other. diff --git a/docs/build/apps/smart-wallets.mdx b/docs/build/apps/smart-wallets.mdx index d8cb77633..690c367d1 100644 --- a/docs/build/apps/smart-wallets.mdx +++ b/docs/build/apps/smart-wallets.mdx @@ -27,7 +27,7 @@ See the work being done on creating a standard for a smart wallet interface in t Join the SEP discussion on the WebAuthn contract interface in [GitHub](https://github.com/stellar/stellar-protocol/discussions/1499). -## Experiment with passkeys on Stellar {#experiment-with-passkeys-on-stellar} +## Experiment with passkeys on Stellar Check out some of the current work being done with passkeys on Stellar! This page will be updated frequently as more projects and standards are created. @@ -39,7 +39,7 @@ These examples are not created or maintained officially by the SDF but by dedica Play around with the various examples linked below, build your own passkey-powered projects, and share your findings in the `#passkeys` channel on [Discord](https://discord.gg/stellardev). -### Soroban by example 🐔 {#soroban-by-example-} +### Soroban by example 🐔 An app that uses passkeys to sign Stellar smart contract transactions. @@ -49,7 +49,7 @@ An app that uses passkeys to sign Stellar smart contract transactions. - Watch the [discussion](https://developers.stellar.org/meetings/2024/05/09) - Read the [blog](https://kalepail.com/blockchain/the-passkey-powered-future-of-web3) -### Super Peach 🍑 {#super-peach-} +### Super Peach 🍑 A passkey-powered multi-signer abstract account contract example. @@ -57,7 +57,7 @@ A passkey-powered multi-signer abstract account contract example. - View the [code](https://github.com/kalepail/superpeach) - Watch the [demo](https://youtu.be/0Agiwso2OMc?si=CHD9U8s-YLyqbXUJ) -### Passkey Kit 📦 {#passkey-kit-} +### Passkey Kit 📦 A client-side SDK tool for managing and using passkeys. @@ -65,16 +65,16 @@ A client-side SDK tool for managing and using passkeys. - View the [code](https://github.com/kalepail/passkey-kit) - Watch the [discussion](https://developers.stellar.org/meetings/2024/06/13) -### Launchtube transaction submission 🧪 {#launchtube-transaction-submission-} +### Launchtube transaction submission 🧪 An API service where developers can send their smart contract transactions to get them funded and submitted to the Stellar Testnet. No classic Stellar G addresses needed! - View the [code](https://github.com/kalepail/launchtube) - Ask in the `#passkeys` channel on [Discord](https://discord.gg/stellardev) for an access token -## What does it all mean? {#what-does-it-all-mean} +## What does it all mean? -### Secp256r1 {#secp256r1} +### Secp256r1 The [secp256r1 signature scheme](https://wiki.hyperledger.org/display/BESU/SECP256R1+Support) is an elliptic curve that is often used with the Elliptic Curve Digital Signature Algorithm (ECDSA), which is a widely used public key signature scheme. @@ -82,19 +82,19 @@ Secp256r1 is a common signature algorithm used in WebAuthn, which is the standar The Stellar blockchain natively uses the Ed25519 elliptic curve, which is extremely fast and secure but is not as widely supported in WebAuthn implementations as secp256r1. -### WebAuthn {#webauthn} +### WebAuthn [WebAuthn (web authentication)](https://www.okta.com/blog/2019/03/what-is-webauthn/) is a web standard for secure, passwordless authentication. It uses public-key cryptography to eliminate the reliance on secret keys and enhances security and usability for dapps. WebAuthn provides decentralized authentication (no central authority manages passwords), enhanced security (secret keys remain on the user’s device), improved user experience (users don’t have to worry about remembering their secret keys), and broader interoperability (WebAuthn is already supported by major browsers and platforms). -### Passkeys {#passkeys} +### Passkeys Passkeys are an implementation of the WebAuthn standard. The ability to use passkeys to sign transactions and access accounts removes the need for users to remember their secret keys or 12- to 24-word seed phrases, something that has been a massive barrier to entry for end-users entering the blockchain space. Secret keys and seed phrases can be overwhelming, hard to remember, entered incorrectly, and prone to security breaches. Passkeys offer a faster, more secure method of identity authentication by using encrypted data stored on a device and performing user verification with hardware tokens (like YubiKeys), biometric data (like fingerprints or facial recognition), or other cryptographic methods. -### Smart wallets {#smart-wallets} +### Smart wallets Smart wallets are digital wallets that leverage smart contract composability to offer enhanced functionality and security for managing digital assets. Unlike traditional cryptocurrency wallets, smart wallets integrate features such as multi-signature support, programmable transactions, and enhanced user experience compatibilities with decentralized applications (dApps). @@ -102,7 +102,7 @@ Smart wallets enable users to interact seamlessly with blockchain ecosystems, pr By utilizing smart contracts, smart wallets can automate transactions and implement advanced security protocols, such as time-locked transfers, spending limits, and fraud detection. These features make smart wallets an ideal choice for users seeking a secure, convenient, and versatile solution for managing their digital assets in the evolving landscape of blockchain technology. -### How they work together {#how-they-work-together} +### How they work together Secp256r1 provides the cryptographic foundation for key generation and digital signatures, WebAuthn offers a standardized framework for passwordless authentication using public-key cryptography, and passkeys implement these technologies to provide a seamless and secure user experience. Bundle all of that together into a Stellar smart contract and you have the foundation for the planet's best smart wallet impelementation! diff --git a/docs/build/apps/wallet/README.md b/docs/build/apps/wallet/README.md index b1add8054..59ecdf3fc 100644 --- a/docs/build/apps/wallet/README.md +++ b/docs/build/apps/wallet/README.md @@ -1,4 +1,4 @@ -## Contributing guide {#contributing-guide} +## Contributing guide Thank you for contributing to the Stellar Wallet documentation! To get started, please first read [main README](../../../README.md) guide. @@ -13,9 +13,9 @@ Generally, text should be applicable to all of supported programming languages, but for differences special `` component can be used (read more below) -### Wallet guide components {#wallet-guide-components} +### Wallet guide components -#### Header {#header} +#### Header Header is a special .mdx file that should be included on all pages. It contains: @@ -30,17 +30,17 @@ of languages that are work in progress:
``` -#### LanguageButtons {#languagebuttons} +#### LanguageButtons This component is a part of the header. It allows to switch between programming languages. Current language is stored as a cookie. -#### WalletGuideWarn {#walletguidewarn} +#### WalletGuideWarn This component puts a warning if language is in progress for this section. Please use `WIPLangs` property to enable it for a language for the page. -#### WalletCodeExample {#walletcodeexample} +#### WalletCodeExample This is improved `CodeExample` component. It currently supports dynamic switching between TypeScript, Kotlin and Flutter code snippets (depending on the @@ -67,7 +67,7 @@ missing. Here's an example on how to use it: For a regular code examples (non Wallet SDK) please use vanilla `CodeExample` component. -#### LanguageSpecific {#languagespecific} +#### LanguageSpecific This component allows to render parts of documentation based on selected code. To get started, crete 2 files in `component` directory: diff --git a/docs/build/apps/wallet/component/dart/configClient.mdx b/docs/build/apps/wallet/component/dart/configClient.mdx index 12884f47b..17963fc43 100644 --- a/docs/build/apps/wallet/component/dart/configClient.mdx +++ b/docs/build/apps/wallet/component/dart/configClient.mdx @@ -1,6 +1,6 @@ import { CodeExample } from "@site/src/components/CodeExample"; -### Configuring the Client {#configuring-the-client} +### Configuring the Client The Flutter Wallet SDK uses the standard Client from the [http package](https://pub.dev/packages/http) for all network requests (excluding Horizon, where the Flutter Stellar SDK's HTTP client is used). diff --git a/docs/build/apps/wallet/component/kt/configClient.mdx b/docs/build/apps/wallet/component/kt/configClient.mdx index 8f8fe0682..c344030ac 100644 --- a/docs/build/apps/wallet/component/kt/configClient.mdx +++ b/docs/build/apps/wallet/component/kt/configClient.mdx @@ -1,6 +1,6 @@ import { CodeExample } from "@site/src/components/CodeExample"; -### Configuring the Client {#configuring-the-client} +### Configuring the Client The Kotlin wallet SDK uses the [ktor client](https://ktor.io/docs/getting-started-ktor-client.html) for all network requests (excluding Horizon, where the Stellar SDK's HTTP client is used). Currently, the okhttp engine is configured to be used with the client. You can read more about how to configure the ktor client [here](https://ktor.io/docs/create-client.html#configure-client). @@ -41,7 +41,7 @@ val anchorCustomClient = -### Closing Resources {#closing-resources} +### Closing Resources After the wallet class is no longer used, it's necessary to close all clients used by it. While in some applications it may not be required (e.g. the wallet lives for the whole lifetime of the application), in other cases it can be required. If your wallet class is short-lived, it's recommended to close client resources using a close function: diff --git a/docs/build/apps/wallet/component/ts/configClient.mdx b/docs/build/apps/wallet/component/ts/configClient.mdx index fa4e67d2c..d1c980d19 100644 --- a/docs/build/apps/wallet/component/ts/configClient.mdx +++ b/docs/build/apps/wallet/component/ts/configClient.mdx @@ -1,6 +1,6 @@ import { CodeExample } from "@site/src/components/CodeExample"; -### Configuring the Client {#configuring-the-client} +### Configuring the Client The Typescript wallet SDK uses the [axios client](https://axios-http.com/docs/intro) for all network requests. You can read more about how to configure the axios client [here](https://axios-http.com/docs/instance). diff --git a/docs/build/apps/wallet/intro.mdx b/docs/build/apps/wallet/intro.mdx index a03417926..94556d89a 100644 --- a/docs/build/apps/wallet/intro.mdx +++ b/docs/build/apps/wallet/intro.mdx @@ -17,7 +17,7 @@ import AllowHttpInfo from "./component/ts/allowHttpInfo.mdx";
-## Installation {#installation} +## Installation First, you need to add the SDK dependency to your project. @@ -27,7 +27,7 @@ First, you need to add the SDK dependency to your project. dart={} /> -## Working with the SDK {#working-with-the-sdk} +## Working with the SDK Let's start with the main class that provides all SDK functionality. It's advised to have a singleton wallet object shared across the application. Creating a wallet with a default configuration connected to Stellar's Testnet is simple: @@ -75,7 +75,7 @@ var wallet = Wallet(StellarConfiguration.publicNet); dart={} /> -## Stellar Basics {#stellar-basics} +## Stellar Basics The wallet SDK provides some extra functionality on top of the existing [Horizon SDK]. For interaction with the Stellar network, the wallet SDK covers only the basics used in a typical wallet flow. For more advanced use cases, the underlying [Horizon SDK] should be used instead. @@ -107,7 +107,7 @@ Default configuration connects to the public Stellar Horizon instance. You can c You can read more about working with the Stellar network in the [respective section](./stellar.mdx). -## Anchor Basics {#anchor-basics} +## Anchor Basics Primary use of the SDK is to provide an easy way to connect to anchors via sets of protocols known as SEPs. Let's look into connecting to the Stellar test anchor: diff --git a/docs/build/apps/wallet/sep10.mdx b/docs/build/apps/wallet/sep10.mdx index b239e5f25..1543f0279 100644 --- a/docs/build/apps/wallet/sep10.mdx +++ b/docs/build/apps/wallet/sep10.mdx @@ -16,7 +16,7 @@ Wallets connect to anchors using a standard way of authentication via the Stella This guide will cover all ways to use SEP-10 to authenticate with an anchor. -## Creating Authentication Key {#creating-authentication-key} +## Creating Authentication Key :::info Custodial wallets only @@ -28,7 +28,7 @@ The authentication key is only used for authentication purposes and doesn't need Go to the [Stellar Lab] and generate a keypair. The secret key must be handled securely, because it will be used for authentication. -## Basic Authentication {#basic-authentication} +## Basic Authentication Let's do a basic authentication. In this example, we will use wallet SDK to create an authentication token. @@ -80,11 +80,11 @@ final authToken = await sep10.authenticate(authKey); For non-custodial wallets, you want to use the user's private key as an `authKey`. -## Home Domain (Optional) {#home-domain-optional} +## Home Domain (Optional) The home domain is the optional parameter for SEP-10 authentication, when a single auth server is shared between multiple domains. Some anchors may require you to provide this argument. The SDK automatically sets the `home_domain` parameter in all SEP-10 requests. -## Client Domain (Optional) {#client-domain-optional} +## Client Domain (Optional) :::info Non-custodial wallets only @@ -100,7 +100,7 @@ Client domain is used by anchors to verify the origin of user's request (which w Supporting `client_domain` comes in two parts, the wallet's client and the wallet's server implementations. In this setup, we will have an extra authentication key. This key will be stored remotely on the server. Using the SEP-1 info file, the anchor will be able to query this key and verify the signature. As such, the anchor would be able to confirm that the request is coming from your wallet, belonging to wallet's `client_domain`. -### Client Side {#client-side} +### Client Side First, let's implement the client side. In this example we will connect to a remote signer that signs transactions on the endpoint `https://demo-wallet-server.stellar.org/sign` for the client domain `demo-wallet-server.stellar.org`. @@ -175,7 +175,7 @@ var signer = DomainSigner("https://demo-wallet-server.stellar.org/sign", } ts={} /> -### Server Side {#server-side} +### Server Side Next, let's implement the server side. diff --git a/docs/build/apps/wallet/sep24.mdx b/docs/build/apps/wallet/sep24.mdx index 675deaf0f..ea263c883 100644 --- a/docs/build/apps/wallet/sep24.mdx +++ b/docs/build/apps/wallet/sep24.mdx @@ -15,7 +15,7 @@ The [SEP-24] standard defines the standard way for anchors and wallets to intera During the flow, a wallet makes several requests to the anchor, and finally receives an interactive URL to open in iframe. This URL is used by the user to provide an input (such as KYC) directly to the anchor. Finally, the wallet can fetch transaction information using query endpoints. -## Get Anchor Information {#get-anchor-information} +## Get Anchor Information Let's start with getting an instance of `Sep24` class, responsible for all SEP-24 interactions: @@ -57,7 +57,7 @@ final servicesInfo = await sep24.getServiceInfo(); -## Interactive Flows {#interactive-flows} +## Interactive Flows Before getting started, make sure you have connected to the anchor and received an authentication token, as described in the [Stellar Authentication] wallet guide. We will use the `authToken` object in the examples below as the [SEP-10] authentication token, obtained earlier. @@ -99,7 +99,7 @@ Before starting with the deposit flow, make sure that the user account has [esta ::: -### Basic Flow {#basic-flow} +### Basic Flow Let's start with a basic deposit: @@ -172,7 +172,7 @@ final id = withdrawal.id; -### Providing KYC Info {#providing-kyc-info} +### Providing KYC Info To improve the user experience, the [SEP-24] standard supports passing user KYC to the anchor via [SEP-9]. In turn, the anchor will pre-fill this information in the interactive popup. @@ -211,7 +211,7 @@ final deposit = await sep24.deposit(asset, authToken, -### Changing Stellar Transfer Account {#changing-stellar-transfer-account} +### Changing Stellar Transfer Account By default, the Stellar transfer will be sent to the authenticated account (with a memo) that initiated the deposit. @@ -274,13 +274,13 @@ final withdrawal = await sep24.withdraw(asset, authToken, withdrawalAccount: ori -## Getting Transaction Info {#getting-transaction-info} +## Getting Transaction Info On the typical flow, the wallet would get transaction data to notify users about status updates. This is done via the [SEP-24] `GET /transaction` and `GET /transactions` endpoint. Alternatively, some anchors support webhooks for notifications. Note that this feature is not widely adopted yet. -### Tracking Transaction {#tracking-transaction} +### Tracking Transaction Let's look into how to use the wallet SDK to track transaction status changes. We will use `Watcher` class for this purpose. First, let's initialize watcher and start tracking a transaction. @@ -340,7 +340,7 @@ final result = watcher.watchAsset(authToken, asset); } /> -### Fetching Transaction {#fetching-transaction} +### Fetching Transaction While `Watcher` class offers powerful tracking capabilities, sometimes it's required to just fetch a transaction (or transactions) once. The `Anchor` class allows you to fetch a transaction by ID, Stellar transaction ID, or external transaction ID: @@ -431,7 +431,7 @@ final transactions = await sep24.getTransactionsForAsset(asset, authToken); -## Submitting Withdrawal Transfer {#submitting-withdrawal-transfer} +## Submitting Withdrawal Transfer Previously, we took a look at starting the withdrawal flow. Now, let's take a look at a full example. diff --git a/docs/build/apps/wallet/sep30.mdx b/docs/build/apps/wallet/sep30.mdx index d6f1a39cd..029d8ada7 100644 --- a/docs/build/apps/wallet/sep30.mdx +++ b/docs/build/apps/wallet/sep30.mdx @@ -10,7 +10,7 @@ import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCod The [Sep-30] standard defines the standard way for an individual (e.g., a user or wallet) to regain access to their Stellar account after losing its private key without providing any third party control of the account. During this flow the wallet communicates with one or more recovery signer servers to register the wallet for a later recovery if it's needed. -## Create Recoverable Account {#create-recoverable-account} +## Create Recoverable Account First, let's create an account key, a device key, and a recovery key that will be attached to the account. @@ -214,7 +214,7 @@ await wallet.stellar().submitTransaction(transaction); -## Get Account Info {#get-account-info} +## Get Account Info You can fetch account info from one or more servers. To do so, first we need to authenticate with a recovery server using the SEP-10 authentication method: @@ -289,7 +289,7 @@ var accountInfo = await recovery.getAccountInfo(accountKp, {second: -## Recover Wallet {#recover-wallet} +## Recover Wallet Let's say we've lost our device key and need to recover our wallet. diff --git a/docs/build/apps/wallet/sep38.mdx b/docs/build/apps/wallet/sep38.mdx index 83a935b21..ef05a8c49 100644 --- a/docs/build/apps/wallet/sep38.mdx +++ b/docs/build/apps/wallet/sep38.mdx @@ -12,7 +12,7 @@ import Header from "./component/header.mdx"; The [SEP-38] standard defines a way for anchors to provide quotes for the exchange of an off-chain asset and a different on-chain asset, and vice versa. Quotes may be [indicative](https://www.investopedia.com/terms/i/indicativequote.asp) or [firm](https://www.investopedia.com/terms/f/firmquote.asp) ones. When either is used is explained in the sections below. -## Creating Sep-38 Object {#creating-sep-38-object} +## Creating Sep-38 Object Let's start with creating a sep38 object, which we'll use for all SEP-38 interactions. Authentication is optional for these requests, and depends on the anchor implementation. For our example we will include it. @@ -38,7 +38,7 @@ var sep38 = anchor.sep38(authToken: authToken); -## Get Anchor Information {#get-anchor-information} +## Get Anchor Information First, let's get information about the anchor's support for [SEP-38]. The response gives what stellar on-chain assets and off-chain assets are available for trading. @@ -72,7 +72,7 @@ For example a response will look like this. The asset identifiers are described } ``` -## Asset Identification Format {#asset-identification-format} +## Asset Identification Format Before calling other endpoints we should understand the scheme used to identify assets in this protocol. The following format is used: @@ -96,7 +96,7 @@ iso4217:USD Further explanation can be found in [SEP-38 specification](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0038.md#asset-identification-format). -## Get Prices {#get-prices} +## Get Prices Now let's get [indicative](https://www.investopedia.com/terms/i/indicativequote.asp) prices from the anchor in exchange for a given asset. This is an indicative price. The actual price will be calculated at conversion time once the Anchor receives the funds from a user. @@ -134,7 +134,7 @@ The response gives the asset prices for exchanging the requested sell asset. For } ``` -## Get Price {#get-price} +## Get Price Next, let's get an [indicative](https://www.investopedia.com/terms/i/indicativequote.asp) price for a certain pair. @@ -172,7 +172,7 @@ The response gives information for exchanging these assets. For example, a respo { price: '1.18', sell_amount: '5.00', buy_amount: '4.24' } ``` -## Post Quote {#post-quote} +## Post Quote Now let's get a [firm](https://www.investopedia.com/terms/f/firmquote.asp) quote from the anchor. As opposed to the earlier endpoints, this quote is stored by the anchor for a certain period of time. We will show how we can grab the quote again later. @@ -218,7 +218,7 @@ An example response looks like this: } ``` -## Get Quote {#get-quote} +## Get Quote Now let's get the previously requested quote. To do that we use the `id` from the `.requestQuote()` response. diff --git a/docs/build/apps/wallet/sep6.mdx b/docs/build/apps/wallet/sep6.mdx index 9eaae23e9..b57404197 100644 --- a/docs/build/apps/wallet/sep6.mdx +++ b/docs/build/apps/wallet/sep6.mdx @@ -14,7 +14,7 @@ The [SEP-6] standard defines a way for anchors and wallets to interact on behalf Please note, this is for _programmatic_ deposits and withdrawals. For hosted deposits and withdrawals, where the anchor interacts with wallets interactively using a popup, please see [Hosted Deposit and Withdrawal](./sep24.mdx). -## Get Anchor Information {#get-anchor-information} +## Get Anchor Information Let's start with creating a sep6 object, which we'll use for all SEP-6 interactions: @@ -44,7 +44,7 @@ var info = await sep6.info(); -## Start a deposit {#start-a-deposit} +## Start a deposit Before getting started, make sure you have connected to the anchor and received an authentication token, as described in the [Stellar Authentication] wallet guide. We will use `authToken` in the examples below as the [SEP-10] authentication token, obtained earlier. @@ -81,11 +81,11 @@ var deposit = await anchor.sep6().deposit( There are several kinds of responses, depending on if the anchor needs more information. All deposits and withdrawals will have these same response types: -### 1. Success response {#1-success-response} +### 1. Success response If the response is successful (HTTP 200), then the anchor is processing the deposit. If it needs additional information, it will communicate it when providing the [transaction info](#getting-transaction-info). -### 2. Still processing, or denied {#2-still-processing-or-denied} +### 2. Still processing, or denied If an HTTP 403 with data: `customer_info_status` is returned, it means the action is still processing, or not accepted. In this case the `more_info_url` field should have a link describing next steps. @@ -99,7 +99,7 @@ An example response: } ``` -### 3. Needs more KYC info {#3-needs-more-kyc-info} +### 3. Needs more KYC info Another common response is an HTTP 403, with the response: `non_interactive_customer_info_needed`. In this case the anchor needs more KYC information via [SEP-12]. @@ -169,7 +169,7 @@ Then, we can re-call the deposit method like before and it should be successful. More information about sending KYC info using [SEP-12] can be found in [Providing KYC info](#providing-kyc-info). -## Providing KYC info {#providing-kyc-info} +## Providing KYC info An anchor may respond to a deposit or withdrawal request saying they need additional KYC info. To faciliate this, [SEP-6] supports adding a customer's KYC info via [SEP-12]. The user can send in the required info using the sep12 object like below. @@ -219,7 +219,7 @@ await sep12.add(sep9Info, sep9Files: sep9Files); -## Start a withdrawal {#start-a-withdrawal} +## Start a withdrawal Starting a withdrawal is similar to deposit, and has the same response types as described earlier. @@ -252,7 +252,7 @@ var resp = await anchor.sep6().withdraw(params, authToken); -## Get exchange info {#get-exchange-info} +## Get exchange info If the anchor supports [SEP-38] quotes, it can support deposits that make a bridge between non-equivalent assets. For example, an anchor recieves BRL via bank transfer and in return sends USDC (of equivalent value minus fees) to the user on Stellar. @@ -320,11 +320,11 @@ var resp = await anchor.sep6().withdrawExchange(params, authToken); The response follows the same types as all the deposits and withdrawals for SEP-6. -## Getting Transaction Info {#getting-transaction-info} +## Getting Transaction Info On the typical flow, the wallet would get transaction data to notify users about status updates. This is done via the [SEP-6] `GET /transaction` and `GET /transactions` endpoint. -### Tracking Transaction {#tracking-transaction} +### Tracking Transaction Let's look into how to use the sdk to track transaction status changes. We will use the `Watcher` class for this purpose. First, let's initialize it and start tracking a transaction. @@ -396,7 +396,7 @@ result.controller.stream.listen( -### Fetching Transaction {#fetching-transaction} +### Fetching Transaction While `Watcher` class offers powerful tracking capabilities, sometimes it's required to just fetch a transaction (or transactions) once. The `Anchor` class allows you to fetch a transaction by ID, Stellar transaction ID, or external transaction ID: diff --git a/docs/build/apps/wallet/sep7.mdx b/docs/build/apps/wallet/sep7.mdx index 9a6048c8b..8199c50ca 100644 --- a/docs/build/apps/wallet/sep7.mdx +++ b/docs/build/apps/wallet/sep7.mdx @@ -10,7 +10,7 @@ import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCod The [Sep-7] standard defines a way for a non-wallet application to construct a URI scheme that represents a specific transaction for an account to sign. The scheme used is `web+stellar`, followed by a colon. Example: `web+stellar:?=&=` -## Tx Operation {#tx-operation} +## Tx Operation The tx operation represents a request to sign a specific transaction envelope, with [some configurable parameters]. @@ -101,7 +101,7 @@ uri.toString(); // encodes everything and converts to a uri string -## Pay Operation {#pay-operation} +## Pay Operation The pay operation represents a request to pay a specific address with a specific asset, regardless of the source asset used by the payer. You can [configure parameters] to build the payment operation. diff --git a/docs/build/apps/wallet/stellar.mdx b/docs/build/apps/wallet/stellar.mdx index 2963b4339..c1a737042 100644 --- a/docs/build/apps/wallet/stellar.mdx +++ b/docs/build/apps/wallet/stellar.mdx @@ -12,7 +12,7 @@ import CreateKeyPairInfo from "./component/ts/createKeypairInfo.mdx"; In the previous section we learned how to create a wallet and a `Stellar` object that provides a connection to Horizon. In this section, we will look at the usages of this class. -## Accounts {#accounts} +## Accounts The most basic entity on the Stellar network is an account. Let's look into AccountService that provides the capability to work with accounts: @@ -52,15 +52,15 @@ var accountKeyPair = account.createKeyPair(); } /> -## Build Transaction {#build-transaction} +## Build Transaction The transaction builder allows you to create various transactions that can be signed and submitted to the Stellar network. Some transactions can be sponsored. -### Building Basic Transactions {#building-basic-transactions} +### Building Basic Transactions First, let's look into building basic transactions. -#### Create Account {#create-account} +#### Create Account The create account transaction activates/creates an account with a starting balance of XLM (1 XLM by default). @@ -86,7 +86,7 @@ var tx = txBuilder.createAccount(destinationAccountKeyPair).build(); -#### Modify Account {#modify-account} +#### Modify Account You can lock the master key of the account by setting its weight to 0. Use caution when locking the account's master key. Make sure you have set the correct signers and weights. Otherwise, you will lock the account irreversibly. @@ -182,7 +182,7 @@ var tx = txBuilder.setThreshold(low: 1, medium: 10, high: 20).build(); -#### Modify Assets (Trustlines) {#modify-assets-trustlines} +#### Modify Assets (Trustlines) Add an asset (trustline) to the account. This allows the account to receive transfers of the asset. @@ -237,7 +237,7 @@ var tx = txBuilder.removeAssetSupport(asset).build(); -#### Swap {#swap} +#### Swap Exchange an account's asset for a different asset. The account must have a trustline for the destination asset. @@ -271,7 +271,7 @@ var txn = txBuilder.swap( -#### Path Pay {#path-pay} +#### Path Pay Send one asset from the source account and receive a different asset in the destination account. @@ -313,7 +313,7 @@ var txn = txBuilder.pathPay( -#### Set Memo {#set-memo} +#### Set Memo Set a memo on the transaction. The memo object can be imported from ["@stellar/stellar-sdk"](https://www.npmjs.com/package/@stellar/stellar-sdk). @@ -334,7 +334,7 @@ var tx = txBuilder.setMemo(memo).build(); -#### Account Merge {#account-merge} +#### Account Merge Merges account into a destination account. @@ -361,7 +361,7 @@ var mergeTxn = txBuilder.accountMerge( -#### Fund Testnet Account {#fund-testnet-account} +#### Fund Testnet Account Fund an account on the Stellar test network @@ -377,7 +377,7 @@ await wallet.stellar().fundTestNetAccount(accountKp.address); -### Building Advanced Transactions {#building-advanced-transactions} +### Building Advanced Transactions In some cases a private key may not be known prior to forming a transaction. For example, a new account must be funded to exist and the wallet may not have the key for the account so may request the create account transaction to be sponsored by a third party. @@ -539,7 +539,7 @@ bool success = await stellar.submitTransaction(modifyAccountTransaction); -#### Adding an Operation {#adding-an-operation} +#### Adding an Operation Add a custom Operation to a transaction. This can be any [Operation](../../../learn/fundamentals/transactions/list-of-operations) supported by the Stellar network. The Operation object can be imported from ["@stellar/stellar-sdk"](https://www.npmjs.com/package/@stellar/stellar-sdk). @@ -581,9 +581,9 @@ var tx = txBuilder.addOperation( -### Sponsoring Transactions {#sponsoring-transactions} +### Sponsoring Transactions -#### Sponsor Operations {#sponsor-operations} +#### Sponsor Operations Some operations, that modify account reserves can be [sponsored](../../../learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx#sponsored-reserves-operations). For sponsored operations, the sponsoring account will be paying for the reserves instead of the account that being sponsored. This allows you to do some operations, even if account doesn't have enough funds to perform such operations. To sponsor a transaction, simply start a sponsoring block:} ts={simply create a building function (describing which operations are to be sponsored) and pass it to the sponsoring method:}/> @@ -633,7 +633,7 @@ Only some operations can be sponsored, and a sponsoring sponsored block} ts={sponsoring method} /> (`newKeyPair` below). If this argument is present, all operations inside the sponsored block will be sourced by this `sponsoredAccount`. (Except account creation, which is always sourced by the sponsor). @@ -754,7 +754,7 @@ stellar.sign(transaction, newKeyPair); -### Fee-Bump Transaction {#fee-bump-transaction} +### Fee-Bump Transaction If you wish to modify a newly created account with a 0 balance, it's also possible to do so via `FeeBump`. It can be combined with a sponsoring block} ts={method} /> to achieve the same result as in the example above. However, with `FeeBump` it's also possible to add more operations (that don't require sponsoring), such as a transfer. @@ -864,7 +864,7 @@ bool success = await stellar.submitTransaction(feeBump); -### Using XDR to Send Transaction Data {#using-xdr-to-send-transaction-data} +### Using XDR to Send Transaction Data Note, that a wallet may not have a signing key for `sponsorKeyPair`. In that case, it's necessary to convert the transaction to XDR, send it to the server, containing `sponsorKey` and return the signed transaction back to the wallet. Let's use the previous example of sponsoring account creation, but this time with the sponsor key being unknown to the wallet. The first step is to define the public key of the sponsor keypair: @@ -996,7 +996,7 @@ bool success = await stellar.submitTransaction(signedTransaction); -## Submit Transaction {#submit-transaction} +## Submit Transaction :::info @@ -1069,7 +1069,7 @@ bool success = await stellar.submitWithFeeIncrease( This will create and sign the transaction that originated from the `sourceAccountKeyPair`. Every 30 seconds this function will re-construct this transaction with a new fee (increased by 100 stroops), repeating signing and submitting. Once the transaction is successful, the function will return the transaction body. Note, that any other error will terminate the retry cycle and an exception will be thrown. -## Accessing Horizon SDK {#accessing-horizon-sdk} +## Accessing Horizon SDK It's very simple to use the Horizon SDK connecting to the same Horizon instance as a `Wallet` class. To do so, simply call: diff --git a/docs/build/guides/archival/create-restoration-footprint-js.mdx b/docs/build/guides/archival/create-restoration-footprint-js.mdx index e112ce266..9703ace49 100644 --- a/docs/build/guides/archival/create-restoration-footprint-js.mdx +++ b/docs/build/guides/archival/create-restoration-footprint-js.mdx @@ -79,7 +79,7 @@ async function createRestorationFootprint( } ``` -## Code walkthrough {#code-walkthrough} +## Code walkthrough As we're making use of [Stellar SDK for JavaScript](https://stellar.github.io/js-stellar-sdk/) `js-stellar-sdk`, first we import the module. diff --git a/docs/build/guides/archival/test-ttl-extension.mdx b/docs/build/guides/archival/test-ttl-extension.mdx index 85e79af2a..8632c108d 100644 --- a/docs/build/guides/archival/test-ttl-extension.mdx +++ b/docs/build/guides/archival/test-ttl-extension.mdx @@ -6,7 +6,7 @@ description: Test contracts that extend contract data time to live (TTL) In order to test contracts that extend the contract data [TTL](../../../learn/encyclopedia/storage/state-archival.mdx#ttl) via `extend_ttl` storage operations, you can use the TTL getter operation (`get_ttl`) in combination with manipulating the ledger sequence number. Note, that `get_ttl` function is only available for tests and only in Soroban SDK v21+. -## Example {#example} +## Example Follow along the [example](https://github.com/stellar/soroban-examples/blob/main/ttl/src/lib.rs) that tests TTL extensions. The example has extensive comments, this document just highlights the most important parts. @@ -167,6 +167,6 @@ fn test_persistent_entry_archival() { } ``` -## Testing TTL extension for other contract instances {#testing-ttl-extension-for-other-contract-instances} +## Testing TTL extension for other contract instances Sometimes a contract may want to extend TTL of another contracts and/or their Wasm entries (usually that would happen in factory contracts). This logic may be covered in a similar fashion to the example above using `env.deployer().get_contract_instance_ttl(&contract)` to get TTL of any contract's instance, and `env.deployer().get_contract_code_ttl(&contract)` to get TTL of any contract's Wasm entry. You can find an example of using these function in the SDK [test suite](https://github.com/stellar/rs-soroban-sdk/blob/ff05c3d4cbed97db50142372e9d7a4fa4a8d1d5d/soroban-sdk/src/tests/storage_testutils.rs#L76). diff --git a/docs/build/guides/basics/automate-reset-data.mdx b/docs/build/guides/basics/automate-reset-data.mdx index 586f1a3db..fbe13b563 100644 --- a/docs/build/guides/basics/automate-reset-data.mdx +++ b/docs/build/guides/basics/automate-reset-data.mdx @@ -16,36 +16,36 @@ description: Learn how to automate Testnet and Futurenet reset data on Stellar /> -## Overview {#overview} +## Overview Stellar operates two primary testing environments: the [Testnet and the Futurenet](../../../learn/fundamentals/networks.mdx). These networks allow developers to experiment with Stellar features without risking real assets. Periodically, these networks are reset to ensure they remain clean and manageable. -## What is the Testnet and Futurenet reset? {#what-is-the-testnet-and-futurenet-reset} +## What is the Testnet and Futurenet reset? Testnet and Futurenet are reset periodically to the genesis ledger to declutter the network, remove spam, reduce the time needed to catch up on the latest ledger, and help maintain the system. These resets take place approximately quarterly. Resets clear all ledger entries (accounts, trustlines, offers, smart contract data, etc.), transactions, and historical data from Stellar Core, Horizon, and the Stellar RPC, which is why developers should not rely on the persistence of accounts or the state of any balances when using Testnet or Futurenet. You can check current reset dates [here](../../../learn/fundamentals/networks.mdx#testnet-and-futurenet-data-reset). -## Why resets are important {#why-resets-are-important} +## Why resets are important 1. **Clean Slate:** Regular resets ensure that both Testnet and Futurenet provide a clean environment for testing. This helps in avoiding complications arising from old data or configurations. 2. **Performance:** Over time, test environments can accumulate a lot of data, which can slow down performance. Resets help in maintaining optimal performance. 3. **Protocol Updates:** Introducing new features or protocol changes often requires a reset to ensure compatibility and stability. 4. **Development Cycles:** Aligning with development cycles allows developers to plan their testing phases and ensures they have a reliable environment for their work. -## Data automation on Testnet and Futurenet {#data-automation-on-testnet-and-futurenet} +## Data automation on Testnet and Futurenet Automating blockchain state on Stellar's Testnet and Futurenet can streamline development workflows, ensuring that you can consistently test and validate your applications in these environments. -### Code walkthrough {#code-walkthrough} +### Code walkthrough -### Prerequisites: {#prerequisites} +### Prerequisites: - [Node.js](https://nodejs.org/en) and `npm` installed. - Stellar SDK for [JavaScript](https://www.npmjs.com/package/@stellar/stellar-sdk) and `fs` installed - An understanding of the rudimentary, retry-enabled transaction polling function `yeetTx` which we outlined in [another guide](../transactions/submit-transaction-wait-js.mdx) -### Code {#code} +### Code ```javascript import { @@ -357,6 +357,6 @@ Initializes the Stellar server connection, Creates two accounts, Issues a custom `yeetTx(feedback, message)`: provides more detailed logging of transaction results. -### Conclusion {#conclusion} +### Conclusion Automating the setup of data on the Stellar Testnet and Futurenet can significantly enhance your development workflow, ensuring that you can quickly return to testing after a network reset. By following the above steps and using the provided code samples, you can streamline your processes and maintain consistency across resets. diff --git a/docs/build/guides/basics/create-account.mdx b/docs/build/guides/basics/create-account.mdx index 6f7e7a579..975e0e56c 100644 --- a/docs/build/guides/basics/create-account.mdx +++ b/docs/build/guides/basics/create-account.mdx @@ -11,7 +11,7 @@ _Before we get started with working with Stellar in code, consider going through [Accounts](../../../learn/fundamentals/stellar-data-structures/accounts.mdx) are a fundamental building block of Stellar: they hold all your balances, allow you to send and receive payments, and let you place offers to buy and sell assets. Since pretty much everything on Stellar is in some way tied to an account, the first thing you generally need to do when you start developing is create one. This beginner-level tutorial will show you how to do that. -## Create a Keypair {#create-a-keypair} +## Create a Keypair Stellar uses public key cryptography to ensure that every transaction is secure: every Stellar account has a keypair consisting of a **public key** and a **secret key**. The public key is always safe to share — other people need it to identify your account and verify that you authorized a transaction. It's like an email address. The secret key, however, is private information that proves you own — and gives you access to — your account. It's like a password, and you should never share it with anyone. @@ -79,7 +79,7 @@ print(f"Public Key: {pair.public_key}") -## Create Account {#create-account} +## Create Account A valid keypair, however, does not make an account: in order to prevent unused accounts from bloating the ledger, Stellar requires accounts to hold a [minimum balance](../../../learn/fundamentals/lumens.mdx#minimum-balance) of 1 XLM before they actually exist. Until it gets a bit of funding, your keypair doesn't warrant space on the ledger. diff --git a/docs/build/guides/basics/follow-received-payments.mdx b/docs/build/guides/basics/follow-received-payments.mdx index 9d739988e..61839947d 100644 --- a/docs/build/guides/basics/follow-received-payments.mdx +++ b/docs/build/guides/basics/follow-received-payments.mdx @@ -21,7 +21,7 @@ In this tutorial we will learn: - How to fund your account using friendbot. - How to follow payments to your account using curl and EventSource. -## Project Skeleton {#project-skeleton} +## Project Skeleton Let's get started by building our project skeleton: @@ -48,7 +48,7 @@ $ node -e "require('stellar-base')" Everything was successful if no output was generated from the above command. Now let's write a script to create a new account. -## Creating an account {#creating-an-account} +## Creating an account Create a new file named `make_account.js` and paste the following text into it: @@ -82,7 +82,7 @@ $ Before our account can do anything it must be funded. Indeed, before an account is funded it does not truly exist! -## Funding your account {#funding-your-account} +## Funding your account The Stellar test network provides the Friendbot, a tool that developers can use to get testnet lumens for testing purposes. To fund your account, simply execute the following curl command: @@ -110,7 +110,7 @@ Don't forget to replace the account id above with your own. If the request succe After a few seconds, the Stellar network will perform consensus, close the ledger, and your account will have been created. Next up we will write a command that watches for new payments to your account and outputs a message to the terminal. -## Following payments using `curl` {#following-payments-using-curl} +## Following payments using `curl` To follow new payments connected to your account you simply need to send the `Accept: text/event-stream` header to the [/payments](../../../data/horizon/api-reference/resources/operations/README.mdx) endpoint. @@ -150,7 +150,7 @@ data: {"_links":{"effects":{"href":"/operations/713226564145153/effects/{?cursor Every time you receive a new payment you will get a new row of data. Payments is not the only endpoint that supports streaming. You can also stream transactions [/transactions](../../../data/horizon/api-reference/resources/transactions/README.mdx) and operations [/operations](../../../data/horizon/api-reference/resources/operations/README.mdx). -## Following payments using `EventStream` {#following-payments-using-eventstream} +## Following payments using `EventStream` > **Warning!** `EventSource` object does not reconnect for certain error types so it can stop working. If you need a reliable streaming connection please use our [SDK](https://github.com/stellar/js-stellar-sdk). @@ -200,7 +200,7 @@ New payment: -## Testing it out {#testing-it-out} +## Testing it out We now know how to get a stream of transactions to an account. Let's check if our solution actually works and if new payments appear. Let's watch as we send a payment ([`create_account` operation](../../../learn/fundamentals/transactions/list-of-operations.mdx#create-account)) from our account to another account. diff --git a/docs/build/guides/basics/send-and-receive-payments.mdx b/docs/build/guides/basics/send-and-receive-payments.mdx index 6607c2261..42be6c52a 100644 --- a/docs/build/guides/basics/send-and-receive-payments.mdx +++ b/docs/build/guides/basics/send-and-receive-payments.mdx @@ -9,7 +9,7 @@ import { Alert } from "@site/src/components/Alert"; Most of the time, you’ll be sending money to someone else who has their own account. For this tutorial, however, you'll need a second account to transact with. So before proceeding, follow the steps outlined in [Create an Account](./create-account.mdx) to make _two_ accounts: one for sending and one for receiving. -## About Operations and Transactions {#about-operations-and-transactions} +## About Operations and Transactions Actions that do things on Stellar — like sending payments or making buy or sell offers — are called [operations](../../../learn/fundamentals/transactions/operations-and-transactions.mdx#operations). To submit an operation to the network, you bundle it into a [transaction](../../../learn/fundamentals/transactions/operations-and-transactions.mdx#transactions), which is a group of anywhere from 1 to 100 operations accompanied by some extra information, like which account is making the transaction and a cryptographic signature to verify that the transaction is authentic. @@ -23,7 +23,7 @@ In the following code samples, proper error checking is omitted for brevity. How -## Send a Payment {#send-a-payment} +## Send a Payment Stellar stores and communicates transaction data in a binary format called [XDR](../../../learn/encyclopedia/data-format/xdr.mdx), which is optimized for network performance but unreadable to the human eye. Luckily, [Horizon](../../../data/horizon/README.mdx), the Stellar API, and the [Stellar SDKs](../../../tools/sdks/library.mdx) convert XDRs into friendlier formats. Here’s how you might send 10 lumens to an account: @@ -474,7 +474,7 @@ server.submit_transaction(transaction) In this example, we're submitting the transaction to the SDF-maintained public testnet instance of Horizon, the Stellar API. When submitting transactions to a Horizon server — which is what most people do — it's possible that you will not receive a response from the server due to a bug, network conditions, etc. In such a situation it's impossible to determine the status of your transaction. That's why you should always save a built transaction (or transaction encoded in XDR format) in a variable or a database and resubmit it if you don't know its status. If the transaction has already been successfully applied to the ledger, Horizon will simply return the saved result and not attempt to submit the transaction again. Only in cases where a transaction’s status is unknown (and thus will have a chance of being included into a ledger) will a resubmission to the network occur. -## Receive a Payment {#receive-a-payment} +## Receive a Payment You don’t actually need to do anything to receive payments into a Stellar account: if a payer makes a successful transaction to send assets to you, those assets will automatically be added to your account. @@ -795,7 +795,7 @@ payments_next = payments.next() -## Transacting in Other Currencies {#transacting-in-other-currencies} +## Transacting in Other Currencies One of the amazing things about the Stellar network is that you can create, hold, send, receive, and trade any type of asset. Many organizations issue assets on Stellar that represent real-world currencies such as US dollars or Nigerian naira or other cryptocurrencies such as bitcoin or ether. diff --git a/docs/build/guides/conventions/check-auth-tutorials.mdx b/docs/build/guides/conventions/check-auth-tutorials.mdx index a709b2eed..f7d9cf6b7 100644 --- a/docs/build/guides/conventions/check-auth-tutorials.mdx +++ b/docs/build/guides/conventions/check-auth-tutorials.mdx @@ -13,23 +13,23 @@ description: Two guides that walk through using __check_auth /> -## Tutorial 1: time based restriction on token transfers {#tutorial-1-time-based-restriction-on-token-transfers} +## Tutorial 1: time based restriction on token transfers Imagine a multi-sig account contract where certain actions, like transferring tokens, need to be controlled by the time elapsed between consecutive transfers. For example, a token transfer should only be allowed if a certain period of time has passed since the last transfer. This can be useful in scenarios where you want to limit the frequency of transactions to prevent misuse or to implement rate limiting. -### Base concepts {#base-concepts} +### Base concepts -#### Time-based restrictions {#time-based-restrictions} +#### Time-based restrictions The idea is to enforce a minimum time interval between consecutive token transfers. Each token can have its own time limit, and the contract will track the last transfer time for each token. -#### Data storage {#data-storage} +#### Data storage The contract will store the time limit and last transfer time for each token in its storage to keep track of these values across transactions. -### Code walkthrough {#code-walkthrough} +### Code walkthrough -#### Contract structure and imports {#contract-structure-and-imports} +#### Contract structure and imports ```rust #![no_std] @@ -73,7 +73,7 @@ const TRANSFER_FN: Symbol = symbol_short!("transfer"); ``` -#### Contract initialization {#contract-initialization} +#### Contract initialization 1. Initializes the contract with a list of signers' public keys 2. Stores the count of signers in the contract's storage @@ -93,7 +93,7 @@ impl AccountContract { } ``` -#### Setting time limits {#setting-time-limits} +#### Setting time limits 1. Allows setting a time limit for a specific token 2. Ensures that only the contract itself can set these limits by requiring the contract's authorization @@ -111,7 +111,7 @@ impl AccountContract { } ``` -#### Custom authentication and authorization {#custom-authentication-and-authorization} +#### Custom authentication and authorization 1. Authenticates the signatures 2. Checks if all required signers have signed @@ -157,7 +157,7 @@ impl CustomAccountInterface for AccountContract { } ``` -#### Authentication logic {#authentication-logic} +#### Authentication logic 1. Verifies that the signatures are in the correct order and that each signer is authorized 2. Uses [ed25519_verify](https://docs.rs/soroban-sdk/latest/soroban_sdk/crypto/struct.Crypto.html#method.ed25519_verify) function to verify each signature @@ -193,7 +193,7 @@ impl CustomAccountInterface for AccountContract { } ``` -#### Authorization policy verification {#authorization-policy-verification} +#### Authorization policy verification 1. Checks if the function being called is a transfer or approve function 2. Enforces the time-based restriction by comparing the current time with the last transfer time @@ -248,11 +248,11 @@ fn verify_authorization_policy( } ``` -#### Summary {#summary} +#### Summary The contract begins by initializing with a set of authorized signers. It allows setting a time limit for token transfers, which controls how frequently a token can be transferred. The \_\_check_auth function is the core of the authorization process, ensuring that all necessary signatures are valid and checking the time-based restriction for token transfers. If the required time has not passed since the last transfer, the contract will deny the operation, enforcing the desired rate limiting. By tracking the last transfer time and enforcing a minimum time interval between transfers, the contract effectively limits the frequency of token transfers, resolving the issue of potential abuse through rapid consecutive transactions. -#### Complete code {#complete-code} +#### Complete code Here are all the snippets stacked together in a single file for convenience: @@ -594,11 +594,11 @@ fn test_token_auth() { } ``` -## Tutorial 2: implementing a smart wallet (WebAuthn) {#tutorial-2-implementing-a-smart-wallet-webauthn} +## Tutorial 2: implementing a smart wallet (WebAuthn) Imagine a world where traditional passwords are obsolete. In this world, WebAuthn (Web Authentication) has become the standard for secure online interactions. Alice, a blockchain enthusiast, wants to create a wallet that leverages WebAuthn technology for enhanced security. She decides to implement a WebAuthn wallet on Stellar, allowing users to manage their digital assets using their device's biometric features or security keys (e.g., YubiKey, Google Titan Security Key, etc.). -### Base concepts {#base-concepts-1} +### Base concepts WebAuthn is a web standard for passwordless authentication. It allows users to authenticate using biometrics (like fingerprints or facial recognition). @@ -615,9 +615,9 @@ This tutorial's code credit goes to [@kalepail's](https://github.com/kalepail) w ::: -### Code walkthrough {#code-walkthrough-1} +### Code walkthrough -#### Contract structure and imports {#contract-structure-and-imports-1} +#### Contract structure and imports This section sets up the contract structure and imports necessary components from the Soroban SDK. @@ -635,7 +635,7 @@ use soroban_sdk::{ pub struct Contract; ``` -#### Error definitions {#error-definitions} +#### Error definitions This enum defines possible errors that can occur during contract execution. @@ -653,7 +653,7 @@ pub enum Error { } ``` -#### Core contract functions {#core-contract-functions} +#### Core contract functions These functions handle adding and removing signers, updating the contract, and managing admin counts. @@ -803,7 +803,7 @@ impl Contract { ``` -#### Signature structure {#signature-structure} +#### Signature structure This structure represents a WebAuthn signature. @@ -817,7 +817,7 @@ pub struct Signature { } ``` -#### CustomAccountInterface implementation {#customaccountinterface-implementation} +#### CustomAccountInterface implementation This implements the core authentication logic for the WebAuthn wallet. @@ -916,7 +916,7 @@ impl CustomAccountInterface for Contract { } ``` -#### Base64 url encoding {#base64-url-encoding} +#### Base64 url encoding This function provides Base64 URL encoding functionality used in the WebAuthn process. @@ -974,11 +974,11 @@ pub fn encode(dst: &mut [u8], src: &[u8]) { ``` -#### Written explanation of code {#written-explanation-of-code} +#### Written explanation of code The WebAuthn wallet contract manages user credentials and authentication. It allows adding and removing signers, distinguishing between admin and regular users. The add function registers new signers, storing admin keys persistently and regular keys temporarily. The remove function deletes signers, and update allows contract upgrades. The core of the wallet's security is the `__check_auth` function, which verifies WebAuthn signatures. It checks the signature against the stored public key, verifies the client data JSON, and ensures the challenge matches the expected value. The contract uses Soroban's storage capabilities to manage keys and admin counts, with different TTLs (Time To Live) for persistent and temporary storage. -#### Test cases {#test-cases} +#### Test cases These are test cases to ensure our WebAuthn wallet is functioning correctly. We'll use the Soroban SDK's testing utilities to create and run these tests. @@ -1067,11 +1067,11 @@ mod test { } ``` -#### Summary {#summary-1} +#### Summary This WebAuthn wallet implementation provides a secure and user-friendly way to manage digital assets on Stellar. It leverages the security benefits of WebAuthn while maintaining the flexibility needed for blockchain interactions. -#### Complete code {#complete-code-1} +#### Complete code Here are all the snippets stacked together in a single file for convenience: diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index 35fc2fc41..4d69293ef 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -12,7 +12,7 @@ There are two kinds of dependencies that can be introduced in a Stellar smart co In the following, we will see how contracts can be leveraged from within another contract. -## Contract as a dependency {#contract-as-a-dependency} +## Contract as a dependency While finding a contract is out of scope for this guide, there are a few place to be on the lookout. Most projects and dApps publicly disclose the address of their Stellar smart contract on their website. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorers also allow you to download the compiled contract as a Wasm file. There are also projects that provide a link to access the code itself. @@ -22,7 +22,7 @@ To depend on a project, we need to know the contract address of the contract to ::: -## Public API {#public-api} +## Public API All public functions of a contract can be called. Using a network explorer can be helpful as some propose to see the Rust interface of a contract. Bindings can also be generated using the CLI: @@ -30,7 +30,7 @@ All public functions of a contract can be called. Using a network explorer can b stellar contract bindings rust --network --contract-id ... --output-dir ... ``` -## Making a cross-contract call {#making-a-cross-contract-call} +## Making a cross-contract call Once we know which function to call and which arguments to use, there are two main ways to make a cross-contract call: we can either load the Wasm or call the contract. @@ -81,7 +81,7 @@ client::ContractAEnum::SomeField ::: -## Handling responses {#handling-responses} +## Handling responses In the examples above, we have used `env.invoke_contract` and `client.some_function`. In both cases, if there is an issue with the underlying contract call, the contract will panic. This might be a valid approach, but in some cases we want to catch errors and handle them depending on the outcome. This is to forward a custom error message, or even triggers an alternative code path. @@ -105,7 +105,7 @@ match client.try_add(&x, &y) { } ``` -## Depending on another contract {#depending-on-another-contract} +## Depending on another contract Congratulations, now you can effectively leverage the whole Soroban ecosystem and its myriad of smart contracts. There is one last point to discuss before closing up: **dependability**. @@ -123,7 +123,7 @@ stellar contract fetch --id C... --network ... > contract.wasm Besides this security consideration, upgrading a contract is an integral part of a contract's lifecycle. New features are added, bugs are fixed, and public API changes are made. Here as well, it is important to observe any development on these contracts to ensure the continuous operation of your own contract. -## Examples {#examples} +## Examples See the following full example with tests: diff --git a/docs/build/guides/conventions/deploy-contract.mdx b/docs/build/guides/conventions/deploy-contract.mdx index 6e355603d..1881143b0 100644 --- a/docs/build/guides/conventions/deploy-contract.mdx +++ b/docs/build/guides/conventions/deploy-contract.mdx @@ -18,17 +18,17 @@ description: Deploy a contract from installed Wasm bytecode using a deployer con /> -## Overview {#overview} +## Overview This guide walks through the process of deploying a smart contract from installed Wasm bytecode using a deployer contract. We will cover setting up your environment, uploading Wasm bytecode, and deploying and initializing a contract atomically. -### Prerequisites: {#prerequisites} +### Prerequisites: - Basic understanding of [Rust programming language](https://www.rust-lang.org/). To brush up on Rust, check out [Rustlings](https://github.com/rust-lang/rustlings) or [The Rust book](https://doc.rust-lang.org/book/). - Familiarity with [Stellar smart contracts](../../smart-contracts/getting-started/hello-world.mdx) - Installed Cargo, [Stellar CLI](../../smart-contracts/getting-started/setup.mdx#install-the-stellar-cli) and Soroban SDK -### Setup environment {#setup-environment} +### Setup environment The [deployer example](https://github.com/stellar/soroban-examples/tree/v21.6.0/deployer) demonstrates how to deploy contracts using a contract. @@ -66,7 +66,7 @@ test test::test_deploy_from_contract ... ok test test::test_deploy_from_address ... ok ``` -### Code overview {#code-overview} +### Code overview ```rust title="deployer/deployer/src/lib.rs" #[contract] @@ -110,11 +110,11 @@ impl Deployer { } ``` -## How it works {#how-it-works} +## How it works The deployer contract provides a mechanism to deploy other contracts in a secure and deterministic manner. It ensures that the deployment is authorized by the specified deployer address and supports atomic initialization of the newly deployed contract. This guarantees that the contract is properly initialized immediately after deployment, preventing any potential issues with uninitialized contracts. -### Function breakdown {#function-breakdown} +### Function breakdown - `env: Env`: The Env object represents the current contract execution environment. It provides methods to interact with the blockchain and other contracts, as well as perform various operations. - `deployer: Address`: The Address of the entity that is requesting the contract deployment. This address will be used to authorize the deployment. @@ -123,7 +123,7 @@ The deployer contract provides a mechanism to deploy other contracts in a secure - `init_fn: Symbol`: The name of the initialization function to be called on the newly deployed contract. - `init_args: Vec`: A vector of arguments, specified as `{type: value}` objects, to be passed to the initialization function of the deployed contract. -### Function steps {#function-steps} +### Function steps ```rust if deployer != env.current_contract_address() { @@ -157,7 +157,7 @@ let res: Val = env.invoke_contract(&deployed_address, &init_fn, init_args); Returns a tuple containing the address of the newly deployed contract and the result of the initialization function. -### Build the contracts {#build-the-contracts} +### Build the contracts To build the contract into a `.wasm` file, use the `stellar contract build` command. This command builds both the deployer contract and the test contract. @@ -175,7 +175,7 @@ target/wasm32-unknown-unknown/release/soroban_deployer_contract.wasm target/wasm32-unknown-unknown/release/soroban_deployer_test_contract.wasm ``` -## Run the contract {#run-the-contract} +## Run the contract Before deploying the test contract with the deployer, install the test contract Wasm using the `install` command. The `install` command will print out the hash derived from the Wasm file which should be used by the deployer. diff --git a/docs/build/guides/conventions/deploy-sac-with-code.mdx b/docs/build/guides/conventions/deploy-sac-with-code.mdx index 058b91e72..814e465f0 100644 --- a/docs/build/guides/conventions/deploy-sac-with-code.mdx +++ b/docs/build/guides/conventions/deploy-sac-with-code.mdx @@ -18,18 +18,18 @@ description: Deploy a SAC for a Stellar asset using Javascript SDK /> -## Overview {#overview} +## Overview In this guide, you'll learn how to deploy a [Stellar Asset Contract (SAC)](../../../tokens/stellar-asset-contract.mdx) for a Stellar asset using the [Stellar SDK](../../../tools/sdks/library.mdx#javascript-sdk). The Stellar SDK is a set of tools and library designed to help developers build applications that interact with the Stellar blockchain network. -### Prerequisites: {#prerequisites} +### Prerequisites: - [Node.js ](https://nodejs.org/en) and npm installed. - Stellar SDK for [JavaScript](https://www.npmjs.com/package/@stellar/stellar-sdk) installed - [Knowledge about Issuing an Asset on Stellar](https://developers.stellar.org/docs/tokens/how-to-issue-an-asset) - An understanding of the rudimentary, retry-enabled transaction polling function `yeetTx` which we outlined in [another guide](../transactions/submit-transaction-wait-js.mdx) -## Code overview {#code-overview} +## Code overview ```javascript title="deployassetcontract.js" import * as StellarSdk from "@stellar/stellar-sdk"; @@ -78,7 +78,7 @@ const deployStellarAssetContract = async () => { await deployStellarAssetContract(); ``` -## Code explanation {#code-explanation} +## Code explanation **Server Setup** diff --git a/docs/build/guides/conventions/extending-wasm-ttl.mdx b/docs/build/guides/conventions/extending-wasm-ttl.mdx index 6aed1fa85..332048cf0 100644 --- a/docs/build/guides/conventions/extending-wasm-ttl.mdx +++ b/docs/build/guides/conventions/extending-wasm-ttl.mdx @@ -11,13 +11,13 @@ The TTL is the number of ledgers between the current ledger and the final ledger This guide will show you how to extend the TTL of a deployed contract's Wasm code using JavaScript. -## Prerequisites {#prerequisites} +## Prerequisites - Stellar SDK: `npm install @stellar/stellar-sdk` - A Stellar RPC endpoint (e.g., `https://soroban-testnet.stellar.org`) - Basic knowledge of Stellar SDK -## Process overview {#process-overview} +## Process overview - Get the contract's footprint, - Set a reasonable resource fee (perhaps start at 10,000 stroops as this is a costly operation), @@ -26,7 +26,7 @@ This guide will show you how to extend the TTL of a deployed contract's Wasm cod - Create an operation `StellarSdk.Operation.extendFootprintTtl`, - Note that a resource fee and base fee are both charged in this operation. -## JavaScript code {#javascript-code} +## JavaScript code The code below uses Nodejs environment but same concept can also be applied in the browser using Freighter wallet or using any other [Stellar SDK](../../../tools/sdks/library.mdx). @@ -86,7 +86,7 @@ extendContractWasmTTL(contractId, sourceKeypair) .catch(console.error); ``` -### Breaking Down the Code {#breaking-down-the-code} +### Breaking Down the Code Let's walk through the key parts of this function: diff --git a/docs/build/guides/conventions/upgrading-contracts.mdx b/docs/build/guides/conventions/upgrading-contracts.mdx index 011efbc1f..baa8a770e 100644 --- a/docs/build/guides/conventions/upgrading-contracts.mdx +++ b/docs/build/guides/conventions/upgrading-contracts.mdx @@ -16,17 +16,17 @@ description: Upgrade Wasm bytecode for a deployed contract /> -## Introduction {#introduction} +## Introduction Upgrading a smart contract allows you to improve or modify your contract without changing its address. This guide will walk you through the process of upgrading a WebAssembly (Wasm) bytecode contract using the Soroban SDK. -### Prerequisites: {#prerequisites} +### Prerequisites: - Basic understanding of [Rust programming language]. To brush up on Rust, check out [Rustlings](https://github.com/rust-lang/rustlings) or [The Rust book](https://doc.rust-lang.org/book/). - Familiarity with [Stellar smart contracts](../../smart-contracts/getting-started/hello-world.mdx) - Installed [Stellar CLI](../../smart-contracts/getting-started/setup.mdx#install-the-stellar-cli) and Soroban SDK -### Download the upgradeable contract example {#download-the-upgradeable-contract-example} +### Download the upgradeable contract example The [upgradeable contract example] demonstrates how to upgrade a Wasm contract. @@ -36,7 +36,7 @@ The [upgradeable contract example] demonstrates how to upgrade a Wasm contract. [upgradeable contract example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/upgradeable_contract [Rust programming language]: https://www.rust-lang.org/ -### Code {#code} +### Code The example contains both an "old" and "new" contract, where we upgrade from "old" to "new". The code below is for the "old" contract. @@ -85,7 +85,7 @@ impl UpgradeableContract { ``` -## How it works {#how-it-works} +## How it works When upgrading a contract, the key function used is `e.deployer().update_current_contract_wasm`, which takes the Wasm hash of the new contract as a parameter. Here’s a step-by-step breakdown of how this process works: @@ -113,7 +113,7 @@ pub fn upgrade(e: Env, new_wasm_hash: BytesN<32>) { [here]: https://docs.rs/soroban-sdk/20.0.2/soroban_sdk/struct.Env.html#method.update_current_contract_wasm [event]: ../../../learn/encyclopedia/contract-development/events.mdx#event-types -## Tests {#tests} +## Tests Open the `upgradeable_contract/old_contract/src/test.rs` file to follow along. @@ -234,7 +234,7 @@ client.upgrade(&new_wasm_hash); assert_eq!(2, client.version()); ``` -## Build the contract {#build-the-contract} +## Build the contract To build the contract `.wasm` files, run `stellar contract build` in both `upgradeable_contract/old_contract` and `upgradeable_contract/new_contract` in that order. @@ -248,7 +248,7 @@ target/wasm32-unknown-unknown/release/soroban_upgradeable_contract_old_contract. target/wasm32-unknown-unknown/release/soroban_upgradeable_contract_new_contract.wasm ``` -## Run the contract {#run-the-contract} +## Run the contract If you have [`stellar-cli`] installed, you can invoke contract functions. Deploy the old contract and install the Wasm for the new contract. diff --git a/docs/build/guides/conversions/address-conversions.mdx b/docs/build/guides/conversions/address-conversions.mdx index 75689aefc..82ef7b281 100644 --- a/docs/build/guides/conversions/address-conversions.mdx +++ b/docs/build/guides/conversions/address-conversions.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; The `Address` is an opaque type that could represent an "account" on the Stellar network (i.e., a keypair), or a "contract." From Soroban's point of view, it doesn't really matter which it is. The "account" variety of these addresses are typically displayed as a `G...` public address, and the "contract" variety is typically displayed as a `C...` address. An address may also be displayed in other formats such as a 32 byte array, a string, or an ScVal type. The Soroban SDKs provide methods that easily convert an address to any of these types. -## Address to bytesN {#address-to-bytesn} +## Address to bytesN Bytes are a more compact and efficient way to store data in terms of storage optimization and data transmission. In situations where you need to store or transmit an address in a fixed-size, such as for cryptographic operations or data serialization, you need to convert the address to a bytesN format @@ -47,7 +47,7 @@ StrKey.decode_ed25519_public_key(stellar_address) -## Address to String {#address-to-string} +## Address to String When transferring data between different systems or over a network, using text-based formats like JSON and XML string formats are often required. Storing addresses as strings in databases can simplify database schema design and queries. Strings are easier to manipulate and are more compatible with user interfaces and APIs. diff --git a/docs/build/guides/conversions/bytes-conversions.mdx b/docs/build/guides/conversions/bytes-conversions.mdx index 7f9c25a41..f04548b7e 100644 --- a/docs/build/guides/conversions/bytes-conversions.mdx +++ b/docs/build/guides/conversions/bytes-conversions.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Bytes is a contiguous growable array type containing u8s. They may represent various types of data including strings, addresses, or other information. Converting any data type to bytes ensures that the data be consistently handled by the Soroban runtime and interacting systems. -## Bytes to Address {#bytes-to-address} +## Bytes to Address When retrieving data stored on the blockchain, addresses might be stored in byte representation for compactness and efficiency. Off-chain systems, such as APIs, databases, or user interfaces, usually expect addresses in a human-readable format. In such cases, you need to convert the bytes to an address format to ensure compatibility. @@ -48,7 +48,7 @@ bytes_to_address = Address.from_raw_account(raw_bytes) -## Bytes to String {#bytes-to-string} +## Bytes to String When dealing with binary data, you may need to convert certain portions of the data to a human-readable format like strings for logging, debugging, processing or display. @@ -85,7 +85,7 @@ bytes_to_string = raw_bytes.decode('utf-8') -## Bytes to ScVal {#bytes-to-scval} +## Bytes to ScVal In a Soroban smart contract that interacts with an external oracle service to provide price data in raw byte format, you would need to convert the bytes to ScVal to process and manipulate the data within your contract. diff --git a/docs/build/guides/conversions/scval-conversions.mdx b/docs/build/guides/conversions/scval-conversions.mdx index f131a0b98..455945503 100644 --- a/docs/build/guides/conversions/scval-conversions.mdx +++ b/docs/build/guides/conversions/scval-conversions.mdx @@ -9,7 +9,7 @@ import TabItem from "@theme/TabItem"; Soroban Contract Value (`ScVal`) is a custom type defined within the Soroban runtime environment that represents other data types such as strings, bytes, and more complex structures used within smart contracts in a format that that the soroban runtime can process, store and retrieve efficiently. -## ScVal to bytesN {#scval-to-bytesn} +## ScVal to bytesN @@ -40,7 +40,7 @@ sc_val_to_bytes = stellar_sdk.scval.from_bytes(sc_val) -## ScVal to address {#scval-to-address} +## ScVal to address @@ -70,7 +70,7 @@ sc_to_address = Address.from_xdr_sc_address(sc_val) -## ScVal to String {#scval-to-string} +## ScVal to String diff --git a/docs/build/guides/conversions/string-conversions.mdx b/docs/build/guides/conversions/string-conversions.mdx index 384a58752..bbe4f9508 100644 --- a/docs/build/guides/conversions/string-conversions.mdx +++ b/docs/build/guides/conversions/string-conversions.mdx @@ -9,7 +9,7 @@ import TabItem from "@theme/TabItem"; Strings are a sequence of characters used to represent readable text. They are used to store and manipulate text-based information such as function names, arguments, key-value data and interfacing with external systems. Strings may often need to be converted to other data types for efficient processing and storage. -## String to bytesN {#string-to-bytesn} +## String to bytesN Some systems use binary formats where data needs to be represented as a fixed-length byte array for storage or processing. For example, fixed-length hashes or identifiers. Converting strings to a fixed byte size ensures that the data fits the required size constraints. @@ -51,7 +51,7 @@ string_value.encode() -## String to address {#string-to-address} +## String to address An address received in a user input may be of string type and you would need to convert it to an address type to perform validations, transactions, or other operations within your smart contract. @@ -81,7 +81,7 @@ const stringToAddress = StellarSdk.Address.fromString(stellarAddress); -## String to ScVal {#string-to-scval} +## String to ScVal When calling functions or methods that expect ScVal types, you need to convert your string data to ScVal to make the call successful. For example, if your smart contract needs to store or manipulate a user input string within its state or use it as part of its logic, you would convert the string to an ScVal type to integrate it with the contract's operations. diff --git a/docs/build/guides/dapps/docker.mdx b/docs/build/guides/dapps/docker.mdx index c91093b39..1002ef49e 100644 --- a/docs/build/guides/dapps/docker.mdx +++ b/docs/build/guides/dapps/docker.mdx @@ -3,7 +3,7 @@ title: Use Docker to build and run dapps description: Understand Docker and use it to build applications --- -## What is Docker? {#what-is-docker} +## What is Docker? Welcome to the world of [Docker](https://www.docker.com/), an essential tool for software development. Docker packages software into units known as containers, ensuring consistency, isolation, portability, and scalability. @@ -11,7 +11,7 @@ Docker is particularly useful in dapp development. It helps manage microservices Understanding Docker begins with understanding Docker images and containers. A Docker image, created from a Dockerfile, is a package that contains everything needed to run the software. A Docker container is a running instance of this image. -## Building and Running a Docker Image {#building-and-running-a-docker-image} +## Building and Running a Docker Image You can create a Docker image using the docker build command with a Dockerfile. Once the image is created, you can run a Docker container using the docker run command. @@ -34,7 +34,7 @@ docker build . \ --rm ``` -### Makefile Overview {#makefile-overview} +### Makefile Overview ```bash docker build . @@ -60,7 +60,7 @@ Ensures Docker removes any intermediate containers after the build process compl Guarantees the removal of the intermediate container, even if the build fails. By using `make build-docker`, you're harnessing the power of Docker to create a consistent, reliable environment for our dapp. -## Container Deployment {#container-deployment} +## Container Deployment You can streamline the deployment process by using a script to run the Docker container. The following script is a wrapper for the [`stellar/quickstart` Docker image], which provides a quick way to run a Stellar network. You can find an example of the `quickstart.sh` script located in the root directory of the [example crowdfund dapp]. diff --git a/docs/build/guides/dapps/frontend-guide.mdx b/docs/build/guides/dapps/frontend-guide.mdx index e1db91554..5e6685c83 100644 --- a/docs/build/guides/dapps/frontend-guide.mdx +++ b/docs/build/guides/dapps/frontend-guide.mdx @@ -3,16 +3,16 @@ title: Comprehensive frontend guide for Stellar dapps description: Learn how to build functional frontend interfaces for Stellar dapps using React, Tailwind CSS, and the Stellar SDK. --- -## Pre-requisites: {#pre-requisites} +## Pre-requisites: - Basic knowledge of React, Tailwind CSS, and related web technologies - Basic understanding of the Stellar blockchain - Node.js and npm installed - Web browser with [Freighter Wallet](https://www.freighter.app) extension installed -## 1. Introduction {#1-introduction} +## 1. Introduction -### The role of frontend in Stellar dapps {#the-role-of-frontend-in-stellar-dapps} +### The role of frontend in Stellar dapps Frontend development plays a crucial role in decentralized applications (dapps) built on the Stellar network. It serves as the primary interface between users and the underlying blockchain technology. A well-designed frontend not only makes your dapp accessible and user-friendly but also helps users interact seamlessly with complex blockchain operations. @@ -24,7 +24,7 @@ In Stellar dapps, the frontend is responsible for: 4. Providing real-time updates on transaction status and account balances 5. Guiding users through complex processes like multi-signature transactions or claimable balance operations -### Importance of user interface and user experience {#importance-of-user-interface-and-user-experience} +### Importance of user interface and user experience The importance of a good user interface (UI) and user experience (UX) in Stellar dapps cannot be overstated. Blockchain technology can be intimidating for many users, and a well-designed UI/UX can make the difference between a successful dapp and one that users find frustrating or confusing. @@ -38,11 +38,11 @@ Key aspects of UI/UX in Stellar dapps include: By focusing on these aspects, you can create Stellar dapps that are not only functional but also enjoyable to use, encouraging wider adoption of your application and the Stellar network as a whole. -## 2. Setting up the development environment {#2-setting-up-the-development-environment} +## 2. Setting up the development environment Before we start building our Stellar dapp, we need to set up our development environment. We'll be using React with Next.js for our frontend framework, Tailwind CSS for styling, and the Stellar SDK for interacting with the Stellar network. -### Installing Node.js and npm {#installing-nodejs-and-npm} +### Installing Node.js and npm First, make sure you have Node.js and npm (Node Package Manager) installed on your system. You can download and install them from the official Node.js website: https://nodejs.org/ @@ -55,7 +55,7 @@ npm --version Both commands should return version numbers if the installation was successful. -### Setting up a Next.js project {#setting-up-a-nextjs-project} +### Setting up a Next.js project Next.js is a React framework that provides features such as server-side rendering and routing out of the box. To create a new Next.js project, run the following commands in your terminal: @@ -73,7 +73,7 @@ When prompted, choose the following options: - Would you like to use App Router? Yes - Would you like to customize the default import alias? No -### Setup HTTPS on Localhost {#setup-https-on-localhost} +### Setup HTTPS on Localhost Freighter wallet requires a secure connection (HTTPS) to interact with your dapp. To enable HTTPS on localhost, you can use a tool like `mkcert`. Fortunately, Next.js provides built-in support for HTTPS. @@ -85,7 +85,7 @@ To enable HTTPS in your Next.js project, open the `package.json` file and edit t } ``` -### Installing Stellar SDK and other dependencies {#installing-stellar-sdk-and-other-dependencies} +### Installing Stellar SDK and other dependencies To interact with the Stellar network, we'll need to install the Stellar SDK and some additional dependencies: @@ -99,11 +99,11 @@ npm install stellar-sdk @stellar/freighter-api bignumber.js Now that we have our development environment set up, we're ready to start building our Stellar dapp! -## 3. Building basic interface elements {#3-building-basic-interface-elements} +## 3. Building basic interface elements In this section, we'll create reusable components for our Stellar dapp and implement forms and inputs using React and Tailwind CSS. -### Creating reusable components {#creating-reusable-components} +### Creating reusable components Let's start by creating a button component that we'll use throughout our application. Create a new file `components/Button.tsx`: @@ -167,7 +167,7 @@ export function ConnectButton({ label }: ConnectButtonProps) { This button component uses the `setAllowed` function from the `@stellar/freighter-api` library to connect the Freighter wallet when clicked. -### Implementing forms and inputs {#implementing-forms-and-inputs} +### Implementing forms and inputs Next, let's create a reusable input component. Create a new file `components/Input.tsx`: @@ -268,7 +268,7 @@ const SendPaymentForm: React.FC = ({ onSubmit }) => { export default SendPaymentForm; ``` -### Designing responsive layouts with Tailwind CSS {#designing-responsive-layouts-with-tailwind-css} +### Designing responsive layouts with Tailwind CSS To create a responsive layout for our dapp, we'll use Tailwind CSS utility classes. Let's create a layout component that we can use across our pages. Edit the file `app/layout.tsx`: @@ -341,27 +341,27 @@ export default function Home() { This setup provides a solid foundation for building the user interface of our Stellar dapp. In the next section, we'll integrate these components with the Stellar SDK to perform actual blockchain operations. -## 4. Basic Concepts of Soroban Contracts {#4-basic-concepts-of-soroban-contracts} +## 4. Basic Concepts of Soroban Contracts Before we start integrating smart contract functionality into our Stellar dapp, let's understand the basic concepts of Soroban contracts. Soroban is a smart contract platform built on the Stellar network. It allows developers to write and deploy smart contracts that run on the Stellar blockchain. Soroban contracts are written in Rust and compiled to [XDR (External Data Representation)](/docs/learn/encyclopedia/data-format/xdr) for execution on the Stellar network. -### Data Types {#data-types} +### Data Types Stellar supports a few data types that can be used in Soroban contracts and we need to do conversions from time to time between those types and the types we have in Javascript. The full list of primitive data types are explained [here](/docs/learn/encyclopedia/contract-development/types/built-in-types). -### XDR {#xdr} +### XDR Values that are passed to contracts and returned from contracts are serialized using XDR. XDR is a standard data serialization format used in Stellar to represent complex data structures. It is used to encode and decode data for transmission over the Stellar network. XDR is mostly represented in Javascript as string and can be converted to other types using the Stellar SDK. -### Fees {#fees} +### Fees Gas fees like they are called in the ethereum network are charged differently here. When submitting different types of transactions, the type of fees paid are different. When submitting a transaction to the network that interacts with the network, a Base fee is paid together with the resource fee for the operation. The base fee is a fixed fee that is paid for every transaction on the network. The resource fee is a fee that is paid for the resources used by the operation and is calculated based on the resources used by the operation and the network's current resource price. Calculating these fees can be cumbersome but the Stellar SDK provides a way to calculate these fees using the `server.prepareTransaction` method which simulates the transaction, gets the appropriate fees and appends the correct fee settings to the transaction. -### ABI or Spec {#abi-or-spec} +### ABI or Spec The ABI or spec is a json file that contains the contract's interface. It defines the functions that can be called on the contract, their parameters, and return types. The ABI is used by clients to interact with the contract and execute its functions. The ABI is generated from the contract's source code and is used to compile the contract into XDR for execution on the Stellar network. @@ -369,7 +369,7 @@ ABI can be genrated for a contract using the [`stellar contract bindings`](/docs This ABI can also be generated as a typescript library to ease development in your DApp and we'll be looking it later in this guide -## 5. Integrating with Stellar blockchain {#5-integrating-with-stellar-blockchain} +## 5. Integrating with Stellar blockchain Now that we have our basic UI components in place, let's integrate them with the Stellar blockchain using the Stellar SDK. It is imperative to know that the Stellar blockchain has three major networks: @@ -379,7 +379,7 @@ Now that we have our basic UI components in place, let's integrate them with the For this guide, we'll be using the Test network to avoid using real lumens during development. Read more about the Stellar networks [here](https://developers.stellar.org/docs/learn/fundamentals/networks). -### Setting up the Stellar SDK {#setting-up-the-stellar-sdk} +### Setting up the Stellar SDK Below is a snippet that shows how to set up the Stellar SDK in your project. We will be using parts of it a lot in this guide so lets try to understand it. @@ -400,7 +400,7 @@ In the above snippet, we import the Stellar SDK and create a server instance for We also create a transaction builder instance with the appropriate network passphrase. The `BASE_FEE` is the minimum fee required for a transaction on the Stellar network. while the `Networks.TESTNET` is the network passphrase for the Stellar Testnet. When using the public network, you can replace `TESTNET` with `PUBLIC` or `FUTURENET` for the Futurenet network. -### Interacting with the Stellar network {#interacting-with-the-stellar-network} +### Interacting with the Stellar network If you are coding along this guide at this point, you should have a minimal web application with a form to send payments. Now, let's integrate this form with the Stellar SDK to send actual payments on the Stellar network. @@ -528,7 +528,7 @@ Hurray! You have successfully integrated your Stellar dapp with the Stellar netw ::: -### Interacting with smart contracts {#interacting-with-smart-contracts} +### Interacting with smart contracts In the above example, we sent a simple payment transaction using the `StellarSdk.Operation.payment` operation. However, Stellar also supports many other operations, one of which is `invokeHostFunction` operation which is used to interact with smart contracts on the Stellar network. @@ -733,7 +733,7 @@ Congratulations! You have successfully interacted with a smart contract on the S ::: -### Reading events from the Stellar network {#reading-events-from-the-stellar-network} +### Reading events from the Stellar network Events on Stellar are values emitted from contracts grouped by topics. These events are emitted when a contract is called and can be read by any client that is interested in the contract. Events are stored in the Stellar ledger and can be read by any client that is interested in the contract. @@ -791,13 +791,13 @@ Source code for this program is available [here](https://github.com/myestery/ste Now, when the page loads, it will query the events from the Stellar network and update the counter value accordingly. -## 6. Using Typescript Bindings {#6-using-typescript-bindings} +## 6. Using Typescript Bindings The Stellar CLI comes with support for exporting a contract spec to a typescript library. This library is optimized for importing as an npm based module to your application. The library generated contains helper methods for calling each contract and also does automatic type conversion of the types for any contract method. -### How to create the bindings library {#how-to-create-the-bindings-library} +### How to create the bindings library To achieve this, you need to @@ -805,39 +805,39 @@ To achieve this, you need to - Have either source code or deployed contract ID of the contract. - Know the network it was deployed to. -#### Scenario 1: I have the Contract ID but no code {#scenario-1-i-have-the-contract-id-but-no-code} +#### Scenario 1: I have the Contract ID but no code In this scenario, we need to use the command [`stellar contract fetch`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-fetch) to fetch the wasm code of the contract -#### Scenario 2: I have the code {#scenario-2-i-have-the-code} +#### Scenario 2: I have the code The next step here is to build it to a wasm file using the [`stellar contract build`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-build) command. -### Generating the Library {#generating-the-library} +### Generating the Library After getting the wasm, we can now run [`stellar contract bindings typescript`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-bindings-typescript) to generate the library which is ready to be published to NPM. The library generated is suited for working with complex contracts. -## 7. Common Pitfalls {#7-common-pitfalls} +## 7. Common Pitfalls Below are a few common pitfalls that soroban DApp developers might run into -### Data Type Conversions {#data-type-conversions} +### Data Type Conversions The data types in Javascript are different from the data types in soroban. When working with soroban contracts, you need to be aware of the data types and how to convert them to the types you are familiar with in Javascript. The Stellar SDK provides helper methods for converting between XDR and Javascript types in the `xdr` namespace. -### Fees {#fees-1} +### Fees Calculating fees for transactions can be tricky. The Stellar SDK provides a way to calculate fees using the `server.prepareTransaction` method, which simulates the transaction and returns the appropriate fees. Fees are calculated in [stroops](/docs/learn/glossary#stroop) -### SendTransaction and GetTransaction {#sendtransaction-and-gettransaction} +### SendTransaction and GetTransaction Results from a smart contract execution or any of the [valid transactions](/docs/learn/fundamentals/transactions/list-of-operations#extend-footprint-ttl) on soroban are not immediate. They are kept in a `PENDING` state until they are confirmed. You need to poll the `getTransaction` method to get the final result of the transaction. -### State Archival {#state-archival} +### State Archival State Archival is a characteristic of soroban contracts where some data stored on the ledger about the contract might be archived. This [guide](/docs/build/guides/archival) helps to understand how to work with state archival in DApps. -### Data Retention {#data-retention} +### Data Retention A few things to note about data retention in soroban contracts: diff --git a/docs/build/guides/dapps/initialization.mdx b/docs/build/guides/dapps/initialization.mdx index 054f44b6a..f72bb9c0b 100644 --- a/docs/build/guides/dapps/initialization.mdx +++ b/docs/build/guides/dapps/initialization.mdx @@ -5,7 +5,7 @@ description: Set up initialization correctly to ensure seamless setup for your d When setting up an example Soroban Dapp, correct initialization is crucial. This process entails several steps, including deploying Docker, cloning and deploying smart contracts, and invoking functions to configure them. In this comprehensive guide, you will walk you through the necessary steps to successfully build and deploy these smart contracts, ensuring a seamless setup for your Soroban Dapp. -## Building and Deploying the Soroban Token Smart Contract {#building-and-deploying-the-soroban-token-smart-contract} +## Building and Deploying the Soroban Token Smart Contract In dapps like the [Example Payment Dapp](https://github.com/stellar/soroban-react-payment/), the [Soroban Token smart contracts](https://github.com/stellar/soroban-examples/tree/main/token) are used to represent the tokenized asset that users can send and receive. Here is an example of how to build and deploy the Soroban Token smart contracts: @@ -41,7 +41,7 @@ stellar contract deploy \ This command deploys the smart contracts to Futurenet using the `stellar contract deploy` function. -## Initializing a Token Contract {#initializing-a-token-contract} +## Initializing a Token Contract With the contracts deployed, it's time to initialize the token contract: @@ -68,7 +68,7 @@ This command requires certain inputs: - Token Symbol: This is the token's symbol, also represented as a hex string. '4454' translates to the symbol "DT". -## Minting Tokens {#minting-tokens} +## Minting Tokens Lastly, you need to mint some tokens to the sender's account: @@ -89,7 +89,7 @@ By following these steps, you ensure that the Soroban token smart contracts are For a deeper dive into Stellar CLI commands, check out the [Stellar CLI repo](https://github.com/stellar/stellar-cli/blob/main/FULL_HELP_DOCS.md). -## Automating Initialization with Scripts {#automating-initialization-with-scripts} +## Automating Initialization with Scripts To streamline the initialization process, you can use a script. This script should automate various tasks such as setting up the network, wrapping Stellar assets, generating token-admin identities, funding the token-admin account, building and deploying the contracts, and initializing them with necessary parameters. diff --git a/docs/build/guides/dapps/react.mdx b/docs/build/guides/dapps/react.mdx index 5490ef23a..a905a085a 100644 --- a/docs/build/guides/dapps/react.mdx +++ b/docs/build/guides/dapps/react.mdx @@ -30,7 +30,7 @@ import { useSorobanReact } from "@soroban-react/core"; These imports include `SorobanReactProvider` from `@soroban-react/core`, which is a context provider used to pass the SorobanReact instance to other components. You also import several types such as `WalletChain`, `ChainMetadata`, and `ChainName`, which help to maintain type safety within our application. -## React Components and Prop Passing {#react-components-and-prop-passing} +## React Components and Prop Passing React thrives on its component-based architecture. Components are reusable pieces of code that return a React element to be rendered on the page. A typical React application consists of multiple components working harmoniously to create a dynamic user interface. @@ -58,7 +58,7 @@ function MintButton({ This functional component takes three properties as arguments: `account`, `decimals`, and `symbol`. It demonstrates the concept of prop passing, a way to pass data from parent to child components in React. The `onComplete` prop even allows you to pass functions to your copmonents as props. We also see React's `useState` hook for local state management, a method to preserve values between function calls. -## State Management and Hooks {#state-management-and-hooks} +## State Management and Hooks State management is another core concept of React, allowing components to create and manage their own data. The `useState` hook is a feature introduced in React 16.8 that allows functional components to have their own state. @@ -70,7 +70,7 @@ const [isSubmitting, setSubmitting] = useState(false); The `useState` hook returns a pair of values: the current state and a function that updates it. In this case, the `isSubmitting` state is initialized to `false` and the `setSubmitting` function is used to update it. React also allows for the creation of custom hooks, like `useNetwork` and `useSendTransaction`, for encapsulating and reusing stateful logic across multiple components. -## Custom Hooks {#custom-hooks} +## Custom Hooks React hooks are functions that let you “hook into” React state and lifecycle features from functional components. Custom hooks allow you to encapsulate complex logic and make it reusable across components. Let's take a look at `useNetwork` and `useSendTransaction`, two custom hooks used in the [example crowdfund dapp]. @@ -86,7 +86,7 @@ const { sendTransaction } = useSendTransaction(); `useNetwork` provides the active chain and the server, and `useSendTransaction` gives us the `sendTransaction` method, which you'll later use to mint tokens. This way, you can keep the component focused on rendering and event handling logic, making it easier to test and maintain. -## Asynchronous Processing and Robust Error Handling {#asynchronous-processing-and-robust-error-handling} +## Asynchronous Processing and Robust Error Handling When dealing with operations that might take an unpredictable amount of time, like network requests or, in our case, minting tokens on the blockchain, React's support for asynchronous operations is crucial. This allows the execution of the rest of the code without being blocked by these operations. @@ -132,7 +132,7 @@ The `sendTransaction` method accepts two arguments: a `TransactionBuilder` insta If the transaction is successful, `paymentResult` contains the result, which you log for debugging purposes. If an error occurs during the transaction, the function throws an error, which you catch and log. -## Conclusion {#conclusion} +## Conclusion React offers a host of high-level concepts that can drastically improve your web development process. By understanding and utilizing these concepts—such as components, prop passing, state management, asynchronous operations, and error handling—you can create scalable, maintainable, and efficient applications. diff --git a/docs/build/guides/dapps/soroban-contract-init-template.mdx b/docs/build/guides/dapps/soroban-contract-init-template.mdx index bac879b21..8b54a100c 100644 --- a/docs/build/guides/dapps/soroban-contract-init-template.mdx +++ b/docs/build/guides/dapps/soroban-contract-init-template.mdx @@ -23,7 +23,7 @@ This guide picks up where [Build a Dapp Frontend](../../apps/dapp-frontend.mdx) Building our own template will be a great way to learn how they work. They're not that complicated! -## Search GitHub for other Soroban templates {#search-github-for-other-soroban-templates} +## Search GitHub for other Soroban templates The official template maintained by Stellar Development Foundation (SDF), as used in [Build a Dapp Frontend](../../apps/dapp-frontend.mdx), lives on GitHub at [stellar/soroban-template-astro](https://github.com/stellar/soroban-astro-template). It uses the [Astro](https://astro.build/) web framework. While Astro works with React, Vue, Svelte, and any other UI library, the template opts not to use them, preferring Astro's own templating language, which uses vanilla JavaScript with no UI library. @@ -48,11 +48,11 @@ How do you know if any of these are any good? Try them. Look at their source cod If none of them suit, then it might be time to... -## Make your own template {#make-your-own-template} +## Make your own template This will be easier than you might imagine. There are a few gotchas, but overall these templates are fairly standard Node projects. -### But first, how are these projects organized? {#but-first-how-are-these-projects-organized} +### But first, how are these projects organized? When you run `stellar contract init`, it _always_ includes a Rust/Cargo project, with a `Cargo.toml` that defines a workspace, and workspace members located in a `contracts` folder. At a minimum, there's one contract, `contracts/hello_world`, but you can get more by using `--with-example`. @@ -60,7 +60,7 @@ Separately, you _may_ include a `--frontend-template`. Frontend templates so far So keep that in mind. We're making a fairly simple Node project, and telling it about our Soroban stuff, like the `contracts` folder. -### 1. Initialize an NPM project {#1-initialize-an-npm-project} +### 1. Initialize an NPM project So let's make a simple Node project! Rather than initializing an Astro project, like the official frontend template, let's try something new. The [State of JS survey](https://2022.stateofjs.com/en-US/libraries/front-end-frameworks/#front_end_frameworks_experience_linechart) tells me that something called "Solid" is fairly new and well-loved. [What does it say to do?](https://www.solidjs.com/) @@ -73,7 +73,7 @@ npm run dev Ok, we have a running Solid template! Now let's turn it into a Soroban template! -### 2. git init {#2-git-init} +### 2. git init Commit early, commit often! You can stop running the dev server (the one you started with `npm run dev` above; stop it with ctrlc, even on a Mac) if you want, or open a new terminal and: @@ -83,7 +83,7 @@ git add . git commit -m "init from solid ts template" ``` -### 3. Copy in the `initialize.js` script {#3-copy-in-the-initializejs-script} +### 3. Copy in the `initialize.js` script The SDF-maintained `soroban-template-astro` has [an `initialize.js` script](https://github.com/stellar/soroban-astro-template/blob/main/initialize.js) in its project root. Copy-paste it into your project. @@ -105,7 +105,7 @@ So this script does that. But it needs a few other things. -#### A. `devDependencies` {#a-devdependencies} +#### A. `devDependencies` The script uses a couple NPM packages. Install them: @@ -113,7 +113,7 @@ The script uses a couple NPM packages. Install them: npm install --save-dev dotenv glob ``` -#### B. `.env` {#b-env} +#### B. `.env` The [`dotenv` package](https://www.npmjs.com/package/dotenv) installed above parses environment variables from a `.env` file. The official template includes [a `.env.example`](https://github.com/stellar/soroban-astro-template/blob/main/.env.example). Go ahead and copy it into your own project. To set you up for testing it all out, you can also copy it to a local `.env`. @@ -121,7 +121,7 @@ The [`dotenv` package](https://www.npmjs.com/package/dotenv) installed above par cp .env.example .env ``` -#### C. `.gitignore` {#c-gitignore} +#### C. `.gitignore` You'll want to ignore the `.env` file you created above, as well as some other build artifacts created by the `initialize.js` script. Paste the bottom of [the official template's `.gitignore`](https://github.com/stellar/soroban-astro-template/blob/main/.gitignore) into your template's `.gitignore`: @@ -140,7 +140,7 @@ src/contracts/* !src/contracts/util.ts ``` -#### C. `package.json` {#c-packagejson} +#### C. `package.json` Make sure users of your template don't forget to run the `initialize.js` script. Modify the `scripts` section as follows: @@ -181,17 +181,17 @@ Also make sure that this project is set up to allow the `import` statements in t While you're here, you can also update the `name` (maybe `"soroban-template-solid"`) and `description`. -#### E. `src/contracts/util.ts` {#e-srccontractsutilts} +#### E. `src/contracts/util.ts` In the `.gitignore` above, you may have noticed that this file is explicitly included. Copy it in from [the official template](https://github.com/stellar/soroban-astro-template/blob/main/src/contracts/util.ts). You'll need to create the `src/contracts` folder. As you can see, it just makes it easy to `import { rpcUrl, networkPassphrase } from 'util'` in the files generated in the `importAll` step. -#### F. README {#f-readme} +#### F. README You might want to start by copying [the official template's README](https://github.com/stellar/soroban-astro-template/blob/main/README.md) to explain how to `cp .env.example .env`. From there, this might also be a good time to explain anything else that makes your template unique! Why might people want to use it? -### 4. `git commit` {#4-git-commit} +### 4. `git commit` Commit changes! @@ -200,7 +200,7 @@ git add . git commit -m "add initialize.js script and supporting changes" ``` -### 5. Try it! {#5-try-it} +### 5. Try it! That's it! You have an NPM project with an `initialize.js` script (and its supporting cast). That's all you really need! @@ -241,7 +241,7 @@ And projects that use yours will want to commit the `Cargo.*` files and `contrac Alright. Go ahead and open the app in your browser. Solid runs its dev server on `http://localhost:3000`. Does it load? It should! We didn't actually use the new `src/contracts/*` stuff in the app itself! -### 6. Wait. Should the template actually use the contracts? {#6-wait-should-the-template-actually-use-the-contracts} +### 6. Wait. Should the template actually use the contracts? Good question! @@ -273,7 +273,7 @@ Here's a way you could demonstrate how to import and use the `hello_world` contr + ``` -### 7. Make it as complex as you want! {#7-make-it-as-complex-as-you-want} +### 7. Make it as complex as you want! This is _your_ template. Go ahead and add helpful dependencies and utility files that you always want, like wallet management or whatever. If you want to add a whole complex stack of UI components, styles, and state-management libraries, go ahead! @@ -281,7 +281,7 @@ The official template strives for simplicity. For shallowness, even. It's meant And templates are cheap to make! If you want to have one `soroban-template-framework-x-basic` for a broader audience, and another `soroban-template-framework-x-opinionated` for your own projects, you can do that! -## Wrapping up {#wrapping-up} +## Wrapping up Some things we did in this section: diff --git a/docs/build/guides/dapps/state-archival.mdx b/docs/build/guides/dapps/state-archival.mdx index ff96db1a0..86b012b96 100644 --- a/docs/build/guides/dapps/state-archival.mdx +++ b/docs/build/guides/dapps/state-archival.mdx @@ -7,7 +7,7 @@ When developing decentralized applications on Stellar, state archival is part of Some state archival terminology we will be using in this guide are described in the [state archival section](/docs/learn/encyclopedia/storage/state-archival#terms-and-semantics). -## Why managing state archival is important for applications {#why-managing-state-archival-is-important-for-applications} +## Why managing state archival is important for applications Managing state archival is crucial for Stellar dapps for several reasons: @@ -16,9 +16,9 @@ Managing state archival is crucial for Stellar dapps for several reasons: - Data lifecycle management: Proper management ensures that important data remains accessible while allowing temporary data to expire. - Application continuity: Ensuring contract instances and Wasm code remain live is essential for uninterrupted dapp operation. It is essential to check for contract availability before attempting to interact with the contract after a long period of inactivity. -## Methods of implementing state archival on the client side {#methods-of-implementing-state-archival-on-the-client-side} +## Methods of implementing state archival on the client side -### 1. Extending TTL from the smart contract {#1-extending-ttl-from-the-smart-contract} +### 1. Extending TTL from the smart contract This method involves invoking the [`extend_ttl()` method](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Instance.html#method.extend_ttl) from your smart contract to extend the TTL of the contract instance and its associated data. This method is useful when you want to keep the data accessible for a longer period. To use this method, your contract must not be archived at the time of calling. @@ -87,7 +87,7 @@ The above contract shows how to extend the TTL of a `Persistent`, `Instance`, an ::: -#### Using the Extend TTL method in your Contract {#using-the-extend-ttl-method-in-your-contract} +#### Using the Extend TTL method in your Contract When we create DApps, we do not typically create buttons to extend the TTL of data entries. Instead, we can create a function that extends the TTL of the data entries when the DApp is used. @@ -123,17 +123,17 @@ impl BiddingContract { } ``` -### 2. Restoring archived data {#2-restoring-archived-data} +### 2. Restoring archived data When developing a dapp on Stellar, you may encounter situations where contract data or the contract instance has been archived due to inactivity. Let's walk through the process of restoring archived data using the JavaScript SDK and Freighter wallet. -#### Prerequisites {#prerequisites} +#### Prerequisites - Stellar SDK: `npm install @stellar/stellar-sdk` - Freighter API: `npm install @stellar/freighter-api` - A Stellar RPC endpoint (e.g., `https://soroban-testnet.stellar.org`) -#### Step 1: Set up the SDK and Freighter {#step-1-set-up-the-sdk-and-freighter} +#### Step 1: Set up the SDK and Freighter First, import the necessary components: @@ -154,7 +154,7 @@ const networkPassphrase = StellarSdk.Networks.TESTNET; // Use PUBLIC for product This setup provides the foundation for interacting with the Stellar network and Freighter wallet. -#### Step 2: Create a helper function for restoration {#step-2-create-a-helper-function-for-restoration} +#### Step 2: Create a helper function for restoration Let's create a helper function that attempts to submit a transaction, and if it fails due to archived data, it will restore the data and retry: @@ -237,7 +237,7 @@ async function submitOrRestoreAndRetry(contractId, method, ...args) { This function now uses Freighter for signing transactions. It first checks if Freighter is connected and authorized, then proceeds with the transaction. If restoration is needed (indicated by a `HostStorageError`), it creates a separate restoration transaction, signs it with Freighter, and submits it before retrying the original transaction. -#### Step 3: Use the helper function in your dapp {#step-3-use-the-helper-function-in-your-dapp} +#### Step 3: Use the helper function in your dapp You can now use this function to make contract calls that automatically handle restoration: @@ -254,7 +254,7 @@ async function performContractAction(contractId, method, ...args) { } ``` -#### Step 4: Handling contract instance restoration {#step-4-handling-contract-instance-restoration} +#### Step 4: Handling contract instance restoration For restoring an entire contract instance, you might need a separate function: @@ -336,12 +336,12 @@ This function specifically restores a contract instance and its associated Wasm ::: -## When to use these functions {#when-to-use-these-functions} +## When to use these functions 1. [`performContractAction`](#step-3-use-the-helper-function-in-your-dapp) helper can be used when trying to invoke a smart contract function. It can help to restore persistent data associated with the call. 2. [`restoreContractInstance`](#step-4-handling-contract-instance-restoration) helper can be used during app initialization after the app has not been used for a long time. Using an indexer to get this info (when last app was used) is a great approach. -## Conclusion {#conclusion} +## Conclusion By implementing these state archival and restoration techniques, your dapp will be able to handle situations where contract data or instances have been archived, ensuring a smoother user experience even after periods of inactivity. The use of wallets like Freighter for transaction signing provides a secure and user-friendly way for users to interact with your dapp. diff --git a/docs/build/guides/dapps/working-with-contract-specs.mdx b/docs/build/guides/dapps/working-with-contract-specs.mdx index ee764476e..c285613c1 100644 --- a/docs/build/guides/dapps/working-with-contract-specs.mdx +++ b/docs/build/guides/dapps/working-with-contract-specs.mdx @@ -5,7 +5,7 @@ description: A guide to understanding and interacting with Soroban smart contrac import { CodeExample } from "@site/src/components/CodeExample"; -## Introduction {#introduction} +## Introduction Soroban smart contracts are powerful tools for building decentralized applications on the Stellar network. To interact with these contracts effectively, it's crucial to understand their specifications and how to use them in your programming language of choice. @@ -17,7 +17,7 @@ A typical contract specification (spec) includes: These details guide how you interact with the contract, regardless of the programming language you're using. -## Prerequisites {#prerequisites} +## Prerequisites Before diving into contract interactions, ensure you have the following: @@ -27,13 +27,13 @@ Before diving into contract interactions, ensure you have the following: For this guide, we will focus on the [Java](/docs/tools/sdks/library#java-sdk), [Python](/docs/tools/sdks/library#python-sdk), and [PHP](/docs/tools/sdks/library#php-sdk) SDKs for reference, but the concepts can also be applied to other languages. -## What are contract specs? {#what-are-contract-specs} +## What are contract specs? A contract spec is just like an ABI (Application Binary Interface) in Ethereum. It is a standardized description of a smart contract's interface, typically in JSON format. It defines the contract's functions, data structures, events, and errors in a way that external applications can understand and use. This specification serves as a crucial bridge between the smart contract and client applications, enabling them to interact without needing to know the contract's internal implementation details. -## Generating contract specs {#generating-contract-specs} +## Generating contract specs The Stellar CLI provides a command to generate a contract spec from a contract's source code. This process is easy but requires you to have the Wasm binary of the contract. @@ -41,19 +41,19 @@ Sometimes, you may not have access to the contract's source code or the ability Finally, we use the [`stellar bindings`](../../../tools/developer-tools/cli/stellar-cli.mdx#stellar-contract-bindings-json) command to generate the contract spec from the Wasm binary. -### Fetching the contract binary {#fetching-the-contract-binary} +### Fetching the contract binary ```bash stellar contract fetch --network-passphrase 'Test SDF Network ; September 2015' --rpc-url https://soroban-testnet.stellar.org --id CONTRACT_ID --out-file contract.wasm ``` -### Generating the contract spec from Wasm {#generating-the-contract-spec-from-wasm} +### Generating the contract spec from Wasm ```bash stellar contract bindings json --wasm contract.wasm > abi.json ``` -## Understanding the contract specification {#understanding-the-contract-specification} +## Understanding the contract specification The ABI (Application Binary Interface) specification for Stellar smart contracts includes several key components that define how to interact with the contract. Let's examine these in detail with examples: @@ -204,7 +204,7 @@ These specifications are crucial for encoding and decoding data when interacting - If a function returns a `ClaimableBalance`, you would expect to receive a struct with an amount (i128), a vector of addresses (claimants), a TimeBound object, and an address (token). - If a function could return an `Error`, it will most likely fail at simulation and you won't need to decode the result. -## Soroban types {#soroban-types} +## Soroban types Before we dive into interacting with Stellar smart contracts, it is important to note that Soroban has its own set of types that are used to interact with the contracts as described in [this guide](../../../learn/encyclopedia/contract-development/types/built-in-types.mdx). Here are some of the common types: @@ -225,7 +225,7 @@ In this guide and the SDKs, these types are represented as `ScU32`, `ScU64`, `Sc Every other complex type can be derived using these basic types but these types do not really map to values in the programming languages. The Stellar SDKs provide helper classes to work with these types. -## Working with native Soroban types {#working-with-native-soroban-types} +## Working with native Soroban types One of the most common tasks when working with Stellar smart contracts is converting between Stellar smart contract types and native types in your programming language. In this guide, we will go over some common conversions and show how they can be used to invoke contracts with the help of the contract spec. @@ -237,7 +237,7 @@ The JSON code block shows the contract spec, while RUST code blocks show the con ::: -### 1. Invoking a contract function with no parameters {#1-invoking-a-contract-function-with-no-parameters} +### 1. Invoking a contract function with no parameters We will be using the `increment` function of the sample [increment contract](https://github.com/stellar/soroban-examples/tree/main/increment) to exemplify this. The `increment` function takes no parameters and increments the counter by 1. @@ -414,7 +414,7 @@ Subsequent examples will show code blocks for using the contract spec only to re ::: -### 2. Invoking a contract function with one or more parameters {#2-invoking-a-contract-function-with-one-or-more-parameters} +### 2. Invoking a contract function with one or more parameters Generally, this involves passing in a native `array` (not a `ScVec`) of parameters to the contract function. @@ -504,7 +504,7 @@ $transaction = (new TransactionBuilder($accountA)) -### 3. Getting responses from contracts {#3-getting-responses-from-contracts} +### 3. Getting responses from contracts Data returned from contracts is also in `ScVal` format and need to be converted to native types in your programming language. @@ -651,7 +651,7 @@ class Test { -## Working with complex data types {#working-with-complex-data-types} +## Working with complex data types As described in [this guide](../../../learn/encyclopedia/contract-development/types/custom-types.mdx), there are some other variants of data structure supported by Soroban. They are @@ -662,7 +662,7 @@ As described in [this guide](../../../learn/encyclopedia/contract-development/ty We would be looking at how these variants translate to the spec and how to construct them in the different SDKs. -### Struct with named fields {#struct-with-named-fields} +### Struct with named fields Structs with named values when converted to ABI or spec are represented as a `ScMap` where each value has the key in `ScSymbol` and the value in the underlying type. @@ -738,7 +738,7 @@ XdrSCVal::forMap( -### Struct with unnamed fields {#struct-with-unnamed-fields} +### Struct with unnamed fields Structs with unnamed values when converted to ABI or spec are represented as a `ScVal` where each value has the underlying type. @@ -809,7 +809,7 @@ XdrSCVal::forVec( -### Enum (unit and tuple variants) {#enum-unit-and-tuple-variants} +### Enum (unit and tuple variants) Enums are generally represented with `ScVec`, their unit types are represented as `ScSymbol` and their tuple variants are represented as the underlying types. @@ -895,7 +895,7 @@ XdrSCVal::forVec( -### Enum (integer variants) {#enum-integer-variants} +### Enum (integer variants) Enums are generally represented with `ScVec`, the integer variant has no keys so it's just a `ScVec` of the underlying type. @@ -968,7 +968,7 @@ XdrSCVal::forVec( -### A complex example {#a-complex-example} +### A complex example Let's use the [timelock contract](https://github.com/stellar/soroban-examples/blob/main/timelock/src/lib.rs) example to show how to interact with a contract that has complex data types. @@ -1142,7 +1142,7 @@ tx = ( -## Reading contract events {#reading-contract-events} +## Reading contract events Reading contract events is similar to reading transaction results. You can use the [`getEvents`](../../../data/rpc/api-reference/methods/getEvents.mdx) RPC method to get the list of events associated with a contract. @@ -1251,7 +1251,7 @@ curl -X POST \ -## Wrapping Up {#wrapping-up} +## Wrapping Up As we've seen, working with Soroban smart contracts across different programming languages isn't rocket science, but it does require some careful attention to detail. The key takeaways: diff --git a/docs/build/guides/events/consume.mdx b/docs/build/guides/events/consume.mdx index d214fe65b..d011b3c51 100644 --- a/docs/build/guides/events/consume.mdx +++ b/docs/build/guides/events/consume.mdx @@ -7,7 +7,7 @@ Once events have been ingested into a database, for instance as done in the [ing Let's get started! -## First, get some events in a DB {#first-get-some-events-in-a-db} +## First, get some events in a DB Continuing right where we left in the [ingest guide], we will use the ORM models to add a few more events. @@ -85,7 +85,7 @@ Here, we are storing XDR encoded values. We could have instead decided to store ::: -## Consuming events {#consuming-events} +## Consuming events Using the same model we used to ingest events into the database, we can query the database to iterate over all events present in the table. @@ -138,7 +138,7 @@ INFO sqlalchemy.engine.Engine [...] (1,) INFO sqlalchemy.engine.Engine ROLLBACK ``` -## Streaming events {#streaming-events} +## Streaming events Depending on our application, we might want to consume events periodically by calling the database to see if there is anything new. Or fetch data as needed by our application. There is another possibility: event listeners! @@ -184,11 +184,11 @@ INFO sqlalchemy.engine.Engine COMMIT Congratulations, you are ready to consume events from Stellar RPC! -## Going further {#going-further} +## Going further Using the techniques we just presented would probably be enough for a lot of use cases. Still, for the readers wanting to go further there are a few things to look into. -### Asynchronous programming {#asynchronous-programming} +### Asynchronous programming So far, we have used SQLAlchemy in a synchronous way. If we were to have an endpoint in the backend calling the database, this endpoint would block during the database call. SQLAlchemy supports asynchronous programming with `async` and `await` keywords. @@ -196,7 +196,7 @@ As a general thought, it's simpler to start with a synchronous logic and then mo SQLAlchemy allows you to simply change from a synchronous session to an asynchronous one without having to change your models nor queries making it a very easy task to use one or the other. -### Idempotency considerations {#idempotency-considerations} +### Idempotency considerations Depending on your application, you might want to look into the concept of idempotency. Or simply put: guarantee that an event is consumed only once. diff --git a/docs/build/guides/events/ingest.mdx b/docs/build/guides/events/ingest.mdx index 2ee85d1d5..f112a4072 100644 --- a/docs/build/guides/events/ingest.mdx +++ b/docs/build/guides/events/ingest.mdx @@ -12,7 +12,7 @@ There are many strategies you can use to ingest and keep the events published by Another approach we'll explore here is using a cron job to query Stellar RPC periodically and store the relevant events in a locally stored SQLite database. We are going to use an Object Relational Mapper (ORM), allowing us to write database query directly in Python or JavaScript. -## Setup {#setup} +## Setup @@ -28,7 +28,7 @@ pip install sqlalchemy stellar-sdk -## Setup the Database Client {#setup-the-database-client} +## Setup the Database Client @@ -125,7 +125,7 @@ Using a database model is very convenient as it allows us to control the databas We'll use this model to create and query for the events stored in our database. -## Query Events from Stellar RPC {#query-events-from-stellar-rpc} +## Query Events from Stellar RPC First, we'll need to query the events from Stellar RPC. This simple example makes an RPC request using the `getEvents` method, filtering for all `transfer` events that are emitted by the native XLM contract. @@ -215,7 +215,7 @@ let events = await server.getEvents({ -## Store Events in the Database {#store-events-in-the-database} +## Store Events in the Database Now, we'll check if the `events` object contains any new events we should store, and we do exactly that. We're storing the event's topics and values as base64-encoded strings here, but you could decode the necessary topics and values into the appropriate data types for your use-case. @@ -283,7 +283,7 @@ if (events.events?.length) { -## Run the Script with Cron {#run-the-script-with-cron} +## Run the Script with Cron A cron entry is an excellent way to automate this script to gather and ingest events every so often. You could configure this script to run as (in)frequently as you want or need. This example would run the script every 24 hours at 1:14 pm: diff --git a/docs/build/guides/fees/analyzing-smart-contract-cost.mdx b/docs/build/guides/fees/analyzing-smart-contract-cost.mdx index dc20a7157..cd88515af 100644 --- a/docs/build/guides/fees/analyzing-smart-contract-cost.mdx +++ b/docs/build/guides/fees/analyzing-smart-contract-cost.mdx @@ -6,15 +6,15 @@ description: Create efficient and cost-effective contracts Several factors influence how quickly and efficiently your smart contracts execute on the Stellar network. This guide will help you understand these factors and provide tips on how to write cost-effective contracts. -## How to optimize smart contract cost: {#how-to-optimize-smart-contract-cost} +## How to optimize smart contract cost: Complex contracts with numerous conditions, loops, and computations require more processing power on Stellar. This can lead to higher gas costs (transaction fees) and slower execution times. -### 1. Efficient loop and storage calls usage {#1-efficient-loop-and-storage-calls-usage} +### 1. Efficient loop and storage calls usage A contract that requires multiple loops and conditions to execute will cost more than a simple contract that executes a single operation. -#### Not Optimal Contract ❎ {#not-optimal-contract-} +#### Not Optimal Contract ❎ ```rust #![no_std] @@ -44,7 +44,7 @@ impl ExampleContract { ::: -#### Optimal Contract ✅ {#optimal-contract-} +#### Optimal Contract ✅ ```rust #![no_std] @@ -75,11 +75,11 @@ In this optimized approach, we'll accumulate the changes outside the loop and pe ::: -### 2. Proper use of batch operations {#2-proper-use-of-batch-operations} +### 2. Proper use of batch operations From the first example, we can see that batch operations are more efficient than individual operations. This is because batch operations reduce the number of external calls to the blockchain, which can be costly. However, there are some scenarios where the use of batch operations can be further optimized. Examples are shown below. -#### Not Optimal Contract ❎ {#not-optimal-contract--1} +#### Not Optimal Contract ❎ ```rust #![no_std] @@ -114,7 +114,7 @@ This function performs individual transfers for each recipient. While straightfo ::: -#### Optimal Contract ✅ {#optimal-contract--1} +#### Optimal Contract ✅ ```rust #![no_std] @@ -159,11 +159,11 @@ Internal distributions are cheaper due to the reduction in the number of costly ::: -### 3. Use of events over storage {#3-use-of-events-over-storage} +### 3. Use of events over storage Events are a cost-effective way to store data that doesn't need to be accessed frequently. Events are cheaper than storage operations and can be used to store data that doesn't need to be accessed frequently. -#### Default Contract {#default-contract} +#### Default Contract ```rust #![no_std] @@ -203,7 +203,7 @@ We cannot store everything in storage like we would do in a traditional database ::: -#### Optimized Using Events {#optimized-using-events} +#### Optimized Using Events ```rust #![no_std] @@ -236,7 +236,7 @@ In this optimized approach, we use events to store data that doesn't need to be ::: -#### Trade-offs: {#trade-offs} +#### Trade-offs: The current approach using events is indeed optimized for gas efficiency, but it comes with its own set of trade-offs. Let's see different approaches and their implications: @@ -269,17 +269,17 @@ This approach offers a balance between accessibility and efficiency. - Slightly higher gas cost than using only events - Temporary storage is cleared after each transaction, so historical data is not permanently accessible on-chain -### 4. Use of efficient data structures {#4-use-of-efficient-data-structures} +### 4. Use of efficient data structures Heap allocated arrays are slow and costly. Prefer fixed-sized arrays or `soroban_sdk::vec!`. This is crucial for large arrays, as exceeding the current linear memory size (a multiple of 64KB) triggers `wasm32::memory_grow`, which is highly computationally intensive. -##### Example (Heap Allocated Array) ❎ {#example-heap-allocated-array-} +##### Example (Heap Allocated Array) ❎ ```rust let mut v1 = alloc::vec![]; ``` -##### Example (Fixed-Sized Array) ✅ {#example-fixed-sized-array-} +##### Example (Fixed-Sized Array) ✅ ```rust let mut v2 = [0; 100]; @@ -287,7 +287,7 @@ let mut v2 = [0; 100]; Storing many items in a `Vec` can be inefficient due to the linear time complexity of membership checks. However, there are some alternatives to having a cumbersome `Vec`: -##### Example (Inefficient Data Storage) ❎ {#example-inefficient-data-storage-} +##### Example (Inefficient Data Storage) ❎ ```rust #![no_std] @@ -380,7 +380,7 @@ impl NonOptimalGameContract { ::: -##### Alternative: using keyed vecs ✅ {#alternative-using-keyed-vecs-} +##### Alternative: using keyed vecs ✅ ```rust #![no_std] @@ -459,64 +459,64 @@ Here's a breakdown of the optimizations and benefits: ::: -### 5. Use of appropriate `env.storage` mechanisms {#5-use-of-appropriate-envstorage-mechanisms} +### 5. Use of appropriate `env.storage` mechanisms There are three types of storage mechanisms in Stellar: -#### [`env.storage().persistent()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.persistent) {#envstoragepersistent} +#### [`env.storage().persistent()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.persistent) Persistent storage is used to store data that needs to be retained across contract invocations. Data stored in persistent storage is maintained between contract invocations and is accessible to all contract functions. Storage for data here is intended to stay in the ledger indefinitely until explicitly deleted. Expired entries can be restored but cannot be recreated. -#### Use cases {#use-cases} +#### Use cases - Data requiring long-term persistence, such as token balances and user properties. - When data needs to be stored indefinitely and must survive even if it expires and needs restoration. - Examples: Token balances, user properties. -#### Cost {#cost} +#### Cost - Highest cost compared to others due to long-term persistence. -#### Lifetime {#lifetime} +#### Lifetime - Data behaves as if it were stored forever but can expire and be restored. -### [`env.storage().temporary()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.temporary) {#envstoragetemporary} +### [`env.storage().temporary()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.temporary) Temporary storage is used to store data that is only needed during the current contract invocation. Data stored in temporary storage is cleared at the end of the contract invocation and is not accessible to other contract functions. Storage for data here is done with a limited lifespan in the ledger. Entries will be removed after their lifetime ends and can be recreated with different values. -#### Use cases {#use-cases-1} +#### Use cases - Data that only needs to exist temporarily, such as oracle data, claimable balances, and offers. - When data only needs to exist for a limited time and can be recreated if needed. - Examples: Oracle data, claimable balances, offers. -#### Cost {#cost-1} +#### Cost - Cheaper than persistent storage due to the limited lifespan of data. (Cheapest cost). -#### Lifetime {#lifetime-1} +#### Lifetime - Data exists for a predefined period and is then removed. -### [`env.storage().instance()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.instance) {#envstorageinstance} +### [`env.storage().instance()`](https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.instance) Storage here is done for a small amount of persistent data tightly coupled with the contract instance. Data is loaded from the ledger every time the contract instance is loaded and it is limited by the ledger entry size, typically in the order of 100 KB serialized. -#### Use cases {#use-cases-2} +#### Use cases - Small data directly associated with the contract, such as admin details, configuration settings, and tokens. For small, frequently used data that is integral to the contract instance and benefits from being loaded every time the contract is used. - Examples: Contract admin details, configuration settings, tokens operated by the contract. -#### Cost {#cost-2} +#### Cost - Likely cheaper than storing data separately in persistent storage. -#### Lifetime {#lifetime-2} +#### Lifetime - Similar lifetime properties to persistent storage but does not appear in the ledger footprint. -### 5. Contract size {#5-contract-size} +### 5. Contract size The size of your smart contract's `wasm` binary influences the cost of running your smart contract on the Stellar network. Larger `wasm` binaries require more processing power and memory to execute, leading to higher gas costs. Larger binaries also cost more gas to deploy and invoke. @@ -526,9 +526,9 @@ To optimize the size of your `wasm` binary, you can: - Minimize the use of external dependencies - Use built-in tools to optimize the size of your `wasm` binary -## Other tips to optimize smart contract cost: {#other-tips-to-optimize-smart-contract-cost} +## Other tips to optimize smart contract cost: -### 1. Use of built-in tools {#1-use-of-built-in-tools} +### 1. Use of built-in tools One way to optimize the size of your `wasm` binary is to use the `soroban optimize` command. This command comes from the [Soroban CLI](https://www.google.com) will optimize the size of your `wasm` binary by removing unnecessary code and reducing the size of the binary. @@ -552,24 +552,24 @@ stellar contract invoke \ Reference: https://sorobandev.com/guides/soroban-cli -### 2. Manual code review {#2-manual-code-review} +### 2. Manual code review Perform a manual code review of your smart contract to identify areas where you can optimize the code. Look for redundant loops, conditions, and storage operations that can be minimized or removed. -### 3. Unit testing with gas measurements {#3-unit-testing-with-gas-measurements} +### 3. Unit testing with gas measurements Use unit tests to measure the gas cost of your smart contract functions. This will help you identify functions that are consuming a lot of gas and optimize them accordingly. Also, using [simulateTransaction](/docs/data/rpc/api-reference/methods/simulateTransaction) rpc helper method can give you an insight of the gas cost of your contract functions. -### 4. Static analysis tools {#4-static-analysis-tools} +### 4. Static analysis tools Tools like [Clippy](https://doc.rust-lang.org/clippy/) (part of the Rust compiler) can identify potential performance issues during the compilation stage. These tools can warn about: - Unnecessary allocations - Redundant code -### 5. Reconsidering storage locations {#5-reconsidering-storage-locations} +### 5. Reconsidering storage locations - #### State Variables: diff --git a/docs/build/guides/freighter/integrate-freighter-react.mdx b/docs/build/guides/freighter/integrate-freighter-react.mdx index ce6ab0879..5d0c1cd09 100644 --- a/docs/build/guides/freighter/integrate-freighter-react.mdx +++ b/docs/build/guides/freighter/integrate-freighter-react.mdx @@ -5,7 +5,7 @@ description: Integrate the Freighter wallet into your React dapps Wallets are an essential part of any dapp. They allow users to interact with the blockchain and sign transactions. In this section, you'll learn how to integrate the Freighter wallet into your React dapps. -### WalletData Component {#walletdata-component} +### WalletData Component In the [example crowdfund dapp](https://github.com/stellar/soroban-example-dapp), the `WalletData` component plays a key role in wallet integration. Let's break down the code and understand its functionality: diff --git a/docs/build/guides/storage/choosing-the-right-storage.mdx b/docs/build/guides/storage/choosing-the-right-storage.mdx index 3b90fac6c..9ffcac1b3 100644 --- a/docs/build/guides/storage/choosing-the-right-storage.mdx +++ b/docs/build/guides/storage/choosing-the-right-storage.mdx @@ -4,7 +4,7 @@ hide_table_of_contents: true description: This guide walks you through choosing the most suitable storage type for your use case and how to implement it --- -## Storage types {#storage-types} +## Storage types Smart contracts can persist data in the Stellar ledger using the storage interface (`env.storage()` in Soroban SDK). There are three types of storage available on the Stellar network: @@ -20,7 +20,7 @@ Every storage 'map' is completely independent from every other storage 'map'. It All the storage types have almost exactly the same functionality, besides the differences highlighted in the table above, specifically cost, behavior when TTL expires, and limit for the number of keys stored per contract. -### A note on TTL {#a-note-on-ttl} +### A note on TTL If you're wondering what 'TTL' means, here is a quick intro on TTLs and state archival in Stellar. @@ -30,7 +30,7 @@ TTL also may be extended however many times is necessary, for a fee. Read more about state archival [here](../../../learn/encyclopedia/storage/state-archival.mdx). -## Persistent storage {#persistent-storage} +## Persistent storage This storage type is used for storing data on the network over an indefinitely long time period. @@ -82,7 +82,7 @@ impl LoyaltyPointsContract { } ``` -## Instance storage {#instance-storage} +## Instance storage Instance storage is a small, limited-size map attached to the contract instance. It is physically stored in the same ledger entry as the contract itself and shares TTL with it. @@ -127,7 +127,7 @@ impl LoyaltyPointsContract { } ``` -## Temporary storage {#temporary-storage} +## Temporary storage As the name implies, temporary storage stores data only for a certain time period, and then discards it automatically when TTL expires. **Temporary entries are gone forever when their TTL expires**. diff --git a/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx b/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx index a8aa6c2e0..f595ae9dd 100644 --- a/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx +++ b/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx @@ -8,13 +8,13 @@ Tests are written to ensure that contracts behave today as expected, and in the However tests are limited, as they only show changes to values that the tests assert on. -## Test Snapshots {#test-snapshots} +## Test Snapshots The Soroban Rust SDK generates test snapshots on every test involving an `Env`. Test snapshots are enabled by default. At the end of the test the `Env` writes a JSON file to the `test_snapshots` directory with a full snapshot of all the events published, logged, and the final ledger storage state. Most tests have a single `Env` and will result in a single test snapshot. Tests that have multiple `Env`s will write multiple test snapshots, one for each `Env`. Test snapshot files are named with a incrementing number on the end to separate the test snapshots for each `Env`. -### How to Use Test Snapshots {#how-to-use-test-snapshots} +### How to Use Test Snapshots 1. Write tests using the default `Env`. For example: diff --git a/docs/build/guides/tokens/deploying-a-sac.mdx b/docs/build/guides/tokens/deploying-a-sac.mdx index b8adb7cb2..feb15e9e2 100644 --- a/docs/build/guides/tokens/deploying-a-sac.mdx +++ b/docs/build/guides/tokens/deploying-a-sac.mdx @@ -19,11 +19,11 @@ description: Deploy a SAC from another smart contract using the Rust SDK /> -## Overview {#overview} +## Overview In this guide, you'll learn how to deploy a [Stellar Asset Contract (SAC)](../../../tokens/stellar-asset-contract.mdx) from within another smart contract using the Soroban Rust SDK. The Soroban Rust SDK provides tools and utilities for working with Stellar smart contracts, allowing you to deploy and interact with SACs directly from your contract logic. -## Prerequisites: {#prerequisites} +## Prerequisites: Before you begin, make sure you have the following: @@ -31,7 +31,7 @@ Before you begin, make sure you have the following: - [Soroban Rust SDK](../../../tools/sdks/library.mdx#soroban-rust-sdk) installed and configured in your development environment. - Basic understanding of the Soroban Rust SDK and familiarity with Soroban's core concepts and Rust programming. -## 1. Define the SacDeployer contract {#1-define-the-sacdeployer-contract} +## 1. Define the SacDeployer contract The SacDeployer contract will be responsible for deploying the Stellar Asset Contract. Here is the code for the SacDeployer contract: @@ -55,14 +55,14 @@ impl SacDeployer { } ``` -### Explanation {#explanation} +### Explanation - `SacDeployer` contract: this contract defines the `deploy_sac` function to handle the deployment of the SAC. - `deploy_sac` function: - `env.deployer().with_stellar_asset(serialized_asset)`: creates a deployer configured to deploy a Stellar Asset Contract using the provided serialized asset. - `deployer.deploy()`: Deploys the SAC and returns the address of the deployed contract. -## 2. Testing the deployment {#2-testing-the-deployment} +## 2. Testing the deployment You need to test the deployment to ensure everything works as expected. The following code demonstrates how to test the SacDeployer contract using the Soroban Rust SDK's test utilities. @@ -77,7 +77,7 @@ fn main() { } ``` -### Explanation {#explanation-1} +### Explanation - `TestEnv::default()`: creates a default testing environment for the deployment. - `SacDeployer::default()`: initializes the SacDeployer contract. @@ -86,7 +86,7 @@ fn main() { - `assert!(sac_address.to_string().len() > 0, "SAC address should be non-empty")`: asserts that the SAC address is non-empty, ensuring a successful deployment. - `serialized_asset`is the Stellar `Asset` XDR serialized to bytes. Refer to `[soroban_sdk::xdr::Asset]` [XDR](https://docs.rs/stellar-xdr/latest/stellar_xdr/curr/enum.Asset.html) -### Conclusion {#conclusion} +### Conclusion By following this guide, you’ve successfully deployed a Stellar Asset Contract from within another contract using the Soroban Rust SDK. This approach enables smart contracts to handle SAC deployments dynamically, providing flexibility for various use cases in the Stellar ecosystem. diff --git a/docs/build/guides/tokens/stellar-asset-contract.mdx b/docs/build/guides/tokens/stellar-asset-contract.mdx index a05956d2c..65b5a07e2 100644 --- a/docs/build/guides/tokens/stellar-asset-contract.mdx +++ b/docs/build/guides/tokens/stellar-asset-contract.mdx @@ -6,7 +6,7 @@ description: Test and use Stellar assets in a Stellar smart contract When interacting with assets in a smart contract, the [Stellar Asset Contract](../../../tokens/stellar-asset-contract.mdx) is not different from any other token that implements the Stellar [SEP-41 Token Interface]. -## Contract Code {#contract-code} +## Contract Code The Rust SDK contains a pre-generated client for any contract that implements the token interface: @@ -55,7 +55,7 @@ client.mint(...); ::: -## Testing {#testing} +## Testing Soroban Rust SDK provides an easy way to instantiate a Stellar Asset Contract tokens using `register_stellar_asset_contract_v2`. This function can be seen as the deployment of a generic token. It also allows you to manipulate flags on the issuer account like `AUTH_REVOCABLE` and `AUTH_REQUIRED`. In the following example, we are following the best practices outlined in the [Issuing and Distribution Accounts section](../../../tokens/control-asset-access.mdx#issuing-and-distribution-accounts): @@ -97,7 +97,7 @@ fn test() { } ``` -## Examples {#examples} +## Examples See the full examples that utilize the token contract in various ways for more details: diff --git a/docs/build/guides/transactions/install-deploy-contract-with-code.mdx b/docs/build/guides/transactions/install-deploy-contract-with-code.mdx index 8a452d645..06847aed6 100644 --- a/docs/build/guides/transactions/install-deploy-contract-with-code.mdx +++ b/docs/build/guides/transactions/install-deploy-contract-with-code.mdx @@ -18,7 +18,7 @@ description: Install and deploy a smart contract with code This guide will walk you through the process of installing and deploying a smart contract using [js-stellar-sdk](https://github.com/stellar/js-stellar-sdk). We will cover the setup of a sample Rust contract, creating a Node.js project to manage the deployment, and finally, installing the Wasm of the contract and deploying it to the network -## Prerequisites {#prerequisites} +## Prerequisites Before you begin, ensure you have the following installed: @@ -26,7 +26,7 @@ Before you begin, ensure you have the following installed: 2. [Node.js](https://nodejs.org/en) and npm (for running JavaScript deployment scripts) 3. [Soroban CLI](../../smart-contracts/getting-started/setup.mdx#install-the-stellar-cli) -## Initialize a sample Rust Contract {#initialize-a-sample-rust-contract} +## Initialize a sample Rust Contract ```bash soroban contract init hello-world @@ -36,7 +36,7 @@ soroban contract build This sequence of commands creates a new directory for your project, initializes a new Soroban smart contract within that directory, and builds the contract. The build generates .wasm file in the path `hello-word/target/wasm32-unknown-unknown/release/hello_world.wasm` -## Create a Node Project {#create-a-node-project} +## Create a Node Project 1. Create a new directory for your Node.js project and navigate into it: @@ -52,9 +52,9 @@ npm init -y npm install @stellar/stellar-sdk fs ``` -## Set Up Deployment Scripts {#set-up-deployment-scripts} +## Set Up Deployment Scripts -### Imports {#imports} +### Imports Import necessary modules in your JavaScript file: @@ -63,7 +63,7 @@ import * as StellarSDK from "@stellar/stellar-sdk"; import fs from "fs"; ``` -### Installing the Wasm on the network {#installing-the-wasm-on-the-network} +### Installing the Wasm on the network Create a function to upload the compiled Wasm file: @@ -78,7 +78,7 @@ async function uploadWasm(filePath) { This function reads the compiled Wasm file, retrieves account details from the network, and installs the bytecode using `uploadContractWasm` Stellar operation, which when wrapped in a transaction is sent to the network. -### Deploy contract {#deploy-contract} +### Deploy contract Deploy the contract by referencing the Wasm hash: @@ -102,7 +102,7 @@ async function deployContract(response) { This function uses the Wasm hash to deploy the contract using the `createCustomContract` stellar operation, which when wrapped in a transaction is sent to the network, generating a contract address. -### Building, Signing and Sending the Transaction {#building-signing-and-sending-the-transaction} +### Building, Signing and Sending the Transaction Handle the building, signing, and sending of transactions: @@ -145,7 +145,7 @@ async function buildAndSendTransaction(account, operations) { This function constructs a transaction, signs it, and submits it to the network, handling any necessary retries for transaction confirmation. -## Running the Script {#running-the-script} +## Running the Script Execute the deployment script: @@ -169,7 +169,7 @@ Replace "Your_Secret_Key" with your actual secret key. This script initiates the This is just demo code, so ensure that you handle secrets and private keys securely in production environments and never expose them in your code repositories. This guide should provide you with a clear path to installing and deploying your smart contracts using Javascript code. -## Complete Script {#complete-script} +## Complete Script Here are all the snippets stacked together in a single file for convenience: diff --git a/docs/build/guides/transactions/install-wasm-bytecode.mdx b/docs/build/guides/transactions/install-wasm-bytecode.mdx index 4a33d4a71..35f8d372a 100644 --- a/docs/build/guides/transactions/install-wasm-bytecode.mdx +++ b/docs/build/guides/transactions/install-wasm-bytecode.mdx @@ -23,14 +23,14 @@ import TabItem from "@theme/TabItem"; This process uploads the contract code to the Stellar Testnet in a transaction, the uploaded Wasm blob is a [contract source](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-02.md#contract-source), which can be thought of as a 'class' of a contract. Multiple [instances of a contract can be deployed](../conventions/deploy-contract.mdx) which share the same source, but have their own state. -## Prerequisites {#prerequisites} +## Prerequisites Before you begin, ensure you have the following installed to compile a smart contract: 1. [Rust](https://www.rust-lang.org/) and Cargo (for compiling smart contracts) 2. The [Stellar CLI](https://github.com/stellar/stellar-cli) -## Initialize and build a sample Rust contract {#initialize-and-build-a-sample-rust-contract} +## Initialize and build a sample Rust contract ```bash soroban contract init hello-world @@ -45,7 +45,7 @@ We are initializing the default `hello_world` contract in [soroban_examples](htt After building the contract for release, the generated .wasm file is at the path `hello-word/target/wasm32-unknown-unknown/release/hello_world.wasm` -## Upload Wasm to the Stellar blockchain {#upload-wasm-to-the-stellar-blockchain} +## Upload Wasm to the Stellar blockchain We can use one of the [SDKs](https://developers.stellar.org/docs/tools/sdks/library), install necessary dependencies for your chosen programming language: @@ -59,7 +59,7 @@ mkdir install-wasm cd install-wasm ``` -### Running the install script {#running-the-install-script} +### Running the install script Different programming languages can be used to upload the `.wasm` file, its SHA256 hash is used for deploying the contract. diff --git a/docs/build/guides/transactions/simulateTransaction-Deep-Dive.mdx b/docs/build/guides/transactions/simulateTransaction-Deep-Dive.mdx index 4906e78b6..1a9972528 100644 --- a/docs/build/guides/transactions/simulateTransaction-Deep-Dive.mdx +++ b/docs/build/guides/transactions/simulateTransaction-Deep-Dive.mdx @@ -3,7 +3,7 @@ title: simulateTransaction RPC method guide description: simulateTransaction examples and tutorials guide --- -## Overview {#overview} +## Overview The `simulateTransaction` endpoint in Stellar RPC allows you to submit a trial contract invocation to simulate how it would be executed by the Stellar network. This simulation calculates the effective transaction data, required authorizations, and minimal resource fee. It provides a way to test and analyze the potential outcomes of a transaction without actually submitting it to the network. It can be a nice way to get contract data as well sometimes. @@ -11,11 +11,11 @@ While calling the method on the rpc server is not the ONLY way to simulate a tra Here we will look at the objects involved and their definitions. -## RPC Services {#rpc-services} +## RPC Services Stellar Development Foundation provides a testnet RPC service at `http://soroban-testnet.stellar.org`. For public network providers please refer to the [Ecosystem RPC Providers](../../../data/rpc/rpc-providers.mdx) list. -### Testnet Endpoint: {#testnet-endpoint} +### Testnet Endpoint: https://soroban-testnet.stellar.org:443 @@ -32,7 +32,7 @@ interface SimulateTransactionParams { **SimulateTransactionResult** is the return result from the call. It includes [many useful things](https://developers.stellar.org/docs/data/rpc/api-reference/methods/simulateTransaction)! -## Things `simulateTransaction` is used for: {#things-simulatetransaction-is-used-for} +## Things `simulateTransaction` is used for: 1. **Preparing `invokeHostFunctionOp` Transactions**: Anytime you need to submit an `invokeHostFunctionOp` transaction to the network. 2. **Footprint Determination**: To determine the ledger footprint, which includes all the data entries the transaction will read or write. @@ -42,9 +42,9 @@ interface SimulateTransactionParams { 6. **Simulating Contract Getter Calls**: To retrieve certain data from the contract without affecting the ledger state. (It's worth noting you could also retrieve certain contract data direct from the ledgerkeys without simulation if it doesn't require any manipulation within the contract logic.) 7. **Resource Calculation**: To calculate the necessary resources (CPU instructions, memory, etc.) that a transaction will consume. -## How to Call `simulateTransaction` {#how-to-call-simulatetransaction} +## How to Call `simulateTransaction` -### Using Fetch {#using-fetch} +### Using Fetch Here's an example of how to call the `simulateTransaction` endpoint directly using `fetch` in JavaScript: @@ -82,7 +82,7 @@ const transactionXDR = simulateTransaction(transactionXDR); ``` -### Using the JavaScript SDK {#using-the-javascript-sdk} +### Using the JavaScript SDK The Stellar SDK provides a convenient method to simulate a transaction: @@ -146,7 +146,7 @@ RpcServer.simulateTransaction(transaction).then((sim) => { }); ``` -#### Running the example {#running-the-example} +#### Running the example To run the above code, you will need to install the Stellar SDK into your project. You can do this by running the following command in your project directory: @@ -156,7 +156,7 @@ Once your project is set up, you can create a new mjs file and paste the code ab `node .mjs` -## Understanding the Footprint {#understanding-the-footprint} +## Understanding the Footprint A footprint is a set of ledger keys that the transaction will read or write. These keys are marked as either read-only or read-write: @@ -165,11 +165,11 @@ A footprint is a set of ledger keys that the transaction will read or write. The The footprint ensures that a transaction is aware of all the ledger entries it will interact with, preventing unexpected errors during execution. -## Assembling a Transaction {#assembling-a-transaction} +## Assembling a Transaction Once you have simulated the transaction and obtained the necessary data, you can assemble the transaction for actual submission. The `assembleTransaction` function in the SDK helps with this process, but you can also call `prepareTransaction` to have it both simulate and assemble the transaction for you in one step. Using the javascript SDK we can call [`assembleTransaction`](https://stellar.github.io/js-stellar-sdk/global.html#assembleTransaction) to easily assemble a transaction. -## Handling Archived Ledger Entries {#handling-archived-ledger-entries} +## Handling Archived Ledger Entries When a ledger entry is archived, it needs to be restored before the transaction can be submitted. This is indicated in the `restorePreamble` field of the result. @@ -362,7 +362,7 @@ export async function handleRestoration( } ``` -## Fees and Resource Usage {#fees-and-resource-usage} +## Fees and Resource Usage Soroban smart contracts on Stellar use a multidimensional resource fee model, charging fees for several resource types: @@ -375,13 +375,13 @@ Soroban smart contracts on Stellar use a multidimensional resource fee model, ch Fees are calculated based on the resource consumption declared in the transaction. Refundable fees are charged before execution and refunded based on actual usage, while non-refundable fees are calculated from CPU instructions, read bytes, write bytes, and transaction size. [Check out this document for a more in depth understanding of fees and metering.](https://developers.stellar.org/docs/learn/fundamentals/fees-resource-limits-metering) -## Preflight Error Handling {#preflight-error-handling} +## Preflight Error Handling The preflight mechanism provides an estimation of CPU and memory consumption in a transaction. It helps identify potential errors and resource limitations before actual submission. Errors returned by the host are propagated through RPC and do not cover network errors or errors in RPC itself. [Common Preflight Errors, and more information can be found here.](https://developers.stellar.org/docs/learn/encyclopedia/errors-and-debugging/debugging-errors#1-preflight) -## Backend Code and Workflow {#backend-code-and-workflow} +## Backend Code and Workflow The `simulateTransaction` endpoint leverages various backend components to simulate the execution of a transaction. Here is a brief explanation of how it works: @@ -407,7 +407,7 @@ The `simulateTransaction` endpoint leverages various backend components to simul These functions are defined in the [`rs-soroban-env`](https://github.com/stellar/rs-soroban-env) and also in a [`soroban-simulation`](https://github.com/stellar/rs-soroban-env/tree/main/soroban-simulation) [crate](https://crates.io/crates/soroban-simulation) and handle the core logic for simulating transactions. -## Further Reading {#further-reading} +## Further Reading For more information and examples, check out the code and other documentation: diff --git a/docs/build/smart-contracts/example-contracts/TEMPLATE.mdx b/docs/build/smart-contracts/example-contracts/TEMPLATE.mdx index 7d561ff15..55cda0312 100644 --- a/docs/build/smart-contracts/example-contracts/TEMPLATE.mdx +++ b/docs/build/smart-contracts/example-contracts/TEMPLATE.mdx @@ -23,7 +23,7 @@ Place each link definition at the bottom of the section it first is used in. [example demonstrates]: https://github.com/stellar/soroban-examples/tree/v21.6.0/hello_world [other example]: ../getting-started/setup.mdx -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -49,7 +49,7 @@ test test::test ... ok [setup]: ../getting-started/setup.mdx -## Code {#code} +## Code ```rust title="hello_world/src/lib.rs" #![no_std] @@ -69,11 +69,11 @@ mod test; Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/hello_world -## How it Works {#how-it-works} +## How it Works This is the written part of each guide. You can call out each thing unique to this contract, sometimes referencing other important concepts from other example contracts, too. -### Major Concepts {#major-concepts} +### Major Concepts You could add sub-headings for highlighting even further important bits or concepts to know. The `events` example guide has the following `h3` headings: @@ -83,7 +83,7 @@ You could add sub-headings for highlighting even further important bits or conce Underneath each of those headings is a brief discussion of how that concept ties into the example contract code. -## Tests {#tests} +## Tests Open the `/hello_world/src/test.rs` file to follow along. @@ -129,7 +129,7 @@ All public functions within an `impl` block that is annotated with the `#[contra Then you can describe the intricacies of what your contract test does uniquely. -## Build the Contract {#build-the-contract} +## Build the Contract To build the contract, use the `cargo build` command. @@ -143,7 +143,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_hello_world_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke contract functions using it. @@ -179,6 +179,6 @@ stellar contract invoke ` [`stellar-cli`]: ../getting-started/setup.mdx#install-the-stellar-cli -## Further Reading {#further-reading} +## Further Reading If you have some further links to share or background knowledge you can link to, this is the place to share it. Or, maybe you want to point out how this example is similar or not when compared with other examples. diff --git a/docs/build/smart-contracts/example-contracts/alloc.mdx b/docs/build/smart-contracts/example-contracts/alloc.mdx index d05d9527b..3784a237e 100644 --- a/docs/build/smart-contracts/example-contracts/alloc.mdx +++ b/docs/build/smart-contracts/example-contracts/alloc.mdx @@ -28,7 +28,7 @@ The [allocator example] demonstrates how to utilize the allocator feature when w The `soroban-sdk` crate provides a lightweight bump-pointer allocator which can be used to emulate heap memory allocation in a Wasm smart contract. -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -54,7 +54,7 @@ running 1 test test test::test ... ok ``` -## Dependencies {#dependencies} +## Dependencies This example depends on the `alloc` feature in `soroban-sdk`. To include it, add "alloc" to the "features" list of `soroban-sdk` in the `Cargo.toml` file: @@ -66,7 +66,7 @@ soroban-sdk = { version = "20.0.0", features = ["alloc"] } soroban-sdk = { version = "20.0.0", features = ["testutils", "alloc"] } ``` -## Code {#code} +## Code ```rust title="alloc/src/lib.rs" #![no_std] @@ -96,7 +96,7 @@ impl AllocContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/alloc -## How it Works {#how-it-works} +## How it Works ```rust extern crate alloc; diff --git a/docs/build/smart-contracts/example-contracts/atomic-swap.mdx b/docs/build/smart-contracts/example-contracts/atomic-swap.mdx index 462975e33..78adef05a 100644 --- a/docs/build/smart-contracts/example-contracts/atomic-swap.mdx +++ b/docs/build/smart-contracts/example-contracts/atomic-swap.mdx @@ -26,7 +26,7 @@ This is example demonstrates advanced usage of Soroban auth framework and assume [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v21.6.0 [atomic swap example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/atomic_swap -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -51,7 +51,7 @@ running 1 test test test::test_atomic_swap ... ok ``` -## Code {#code} +## Code ```rust title="atomic_swap/src/lib.rs" #[contract] @@ -125,13 +125,13 @@ fn move_token( Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/atomic_swap -## How it Works {#how-it-works} +## How it Works The example contract requires two `Address`-es to authorize their parts of the swap operation: one `Address` wants to sell a given amount of token A for token B at a given price and another `Address` wants to sell token B for token A at a given price. The contract swaps the tokens atomically, but only if the requested minimum price is respected for both parties. Open the `atomic_swap/src/lib.rs` file or see the code above to follow along. -### Swap authorization {#swap-authorization} +### Swap authorization ```rust ... @@ -146,7 +146,7 @@ b.require_auth_for_args( Authorization of `swap` function leverages `require_auth_for_args` Soroban host function. Both `a` and `b` need to authorize symmetric arguments: token they sell, token they buy, amount of token they sell, minimum amount of token they want to receive. This means that `a` and `b` can be freely exchanged in the invocation arguments (as long as the respective arguments are changed too). -### Moving the tokens {#moving-the-tokens} +### Moving the tokens ```rust ... @@ -182,7 +182,7 @@ fn move_token( The swap itself is implemented via two token moves: from `a` to `b` and from `b` to `a`. The token move is implemented via allowance: the users don't need to know each other in order to perform the swap, and instead they authorize the swap contract to spend the necessary amount of token on their behalf via `transfer`. Soroban auth framework makes sure that the `transfer` signatures would have the proper context, and they won't be usable outside the `swap` contract invocation. -### Tests {#tests} +### Tests Open the [`atomic_swap/src/test.rs`] file to follow along. diff --git a/docs/build/smart-contracts/example-contracts/auth.mdx b/docs/build/smart-contracts/example-contracts/auth.mdx index 082ed0834..4042b5e7a 100644 --- a/docs/build/smart-contracts/example-contracts/auth.mdx +++ b/docs/build/smart-contracts/example-contracts/auth.mdx @@ -31,7 +31,7 @@ This example is an extension of the [storing data example]. [storing data example]: ../getting-started/storing-data.mdx [auth example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/auth -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -57,7 +57,7 @@ running 1 test test test::test ... ok ``` -## Code {#code} +## Code ```rust title="auth/src/lib.rs" #[contracttype] @@ -112,13 +112,13 @@ impl IncrementContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/auth -## How it Works {#how-it-works} +## How it Works The example contract stores a per-`Address` counter that can only be incremented by the owner of that `Address`. Open the `auth/src/lib.rs` file or see the code above to follow along. -### `Address` {#address} +### `Address` ```rust #[contracttype] @@ -137,7 +137,7 @@ In the example the counter for each address is stored against `DataKey::Counter( ::: -### `require_auth` {#require_auth} +### `require_auth` ```rust impl IncrementContract { @@ -162,7 +162,7 @@ user.require_auth_for_args((&user, value).into_val(&env)); user.require_auth_for_args((value,).into_val(&env)); ``` -### Tests {#tests} +### Tests Open the [`auth/src/test.rs`] file to follow along. @@ -271,7 +271,7 @@ assert_eq!(client.increment(&user_1, &3), 10); assert_eq!(client.increment(&user_2, &4), 5); ``` -## Build the Contract {#build-the-contract} +## Build the Contract To build the contract into a `.wasm` file, use the `stellar contract build` command. @@ -285,7 +285,7 @@ The `.wasm` file should be found in the `target` directory after building: target/wasm32-unknown-unknown/release/soroban_auth_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke functions on the contract. @@ -476,7 +476,7 @@ Contract auth: [{"address_with_nonce":null,"root_invocation":{"contract_id":"000 [`stellar-cli`]: ../getting-started/setup.mdx#install-the-stellar-cli -## Further reading {#further-reading} +## Further reading [Authorization documentation](../../../learn/encyclopedia/security/authorization.mdx) provides more details on how Soroban auth framework works. diff --git a/docs/build/smart-contracts/example-contracts/cross-contract-call.mdx b/docs/build/smart-contracts/example-contracts/cross-contract-call.mdx index d2ad0d88c..81f274274 100644 --- a/docs/build/smart-contracts/example-contracts/cross-contract-call.mdx +++ b/docs/build/smart-contracts/example-contracts/cross-contract-call.mdx @@ -34,7 +34,7 @@ In this example there are two contracts that are compiled separately, deployed s [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v21.6.0 [cross contract call example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/cross_contract -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -60,7 +60,7 @@ running 1 test test test::test ... ok ``` -## Code {#code} +## Code ```rust title="cross_contract/contract_a/src/lib.rs" #[contract] @@ -95,7 +95,7 @@ impl ContractB { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/cross_contract -## How it Works {#how-it-works} +## How it Works Cross contract calls are made by invoking another contract by its contract ID. @@ -112,7 +112,7 @@ The `contractimport!` macro will generate the types in the module it is used, so Open the files above to follow along. -### Contract A: The Contract to be Called {#contract-a-the-contract-to-be-called} +### Contract A: The Contract to be Called The contract to be called is Contract A. It is a simple contract that accepts `x` and `y` parameters, adds them together and returns the result. @@ -134,7 +134,7 @@ The contract uses the `checked_add` method to ensure that there is no overflow, ::: -### Contract B: The Contract doing the Calling {#contract-b-the-contract-doing-the-calling} +### Contract B: The Contract doing the Calling The contract that does the calling is Contract B. It accepts a contract ID that it will call, as well as the same parameters to pass through. In many contracts the contract to call might have been stored as contract data and be retrieved, but in this simple example it is being passed in as a parameter each time. @@ -163,7 +163,7 @@ impl ContractB { } ``` -### Tests {#tests} +### Tests Open the `cross_contract/contract_b/src/test.rs` file to follow along. @@ -223,7 +223,7 @@ The test asserts that the result that is returned is as we expect. assert_eq!(sum, 12); ``` -## Build the Contracts {#build-the-contracts} +## Build the Contracts To build the contract into a `.wasm` file, use the `stellar contract build` command. Both `contract_call/contract_a` and `contract_call/contract_b` must be built, with `contract_a` being built first. @@ -241,7 +241,7 @@ target/wasm32-unknown-unknown/release/soroban_cross_contract_a_contract.wasm target/wasm32-unknown-unknown/release/soroban_cross_contract_b_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke contract functions. Both contracts must be deployed. diff --git a/docs/build/smart-contracts/example-contracts/custom-account.mdx b/docs/build/smart-contracts/example-contracts/custom-account.mdx index e4a08d4bf..a4aa2b7e5 100644 --- a/docs/build/smart-contracts/example-contracts/custom-account.mdx +++ b/docs/build/smart-contracts/example-contracts/custom-account.mdx @@ -41,7 +41,7 @@ While custom accounts are supported by the Stellar protocol and Soroban SDK, the [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v21.6.0 [custom account example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/account -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -66,7 +66,7 @@ running 1 test test test::test_token_auth ... ok ``` -## How it Works {#how-it-works} +## How it Works Open the `account/src/lib.rs` file to follow along. @@ -76,7 +76,7 @@ This example contract uses ed25519 keys for signature verification and supports For example, the user may initialize this contract with 2 keys and introduce 100 USDC spend limit. This way they can use a single key to sign their contract invocations and be sure that even if they sign a malicious transaction they won't spend more than 100 USDC. -### Initialization {#initialization} +### Initialization ```rust #[contracttype] @@ -102,7 +102,7 @@ pub fn init(env: Env, signers: Vec>) { This account contract needs to work with the public keys explicitly. Here we initialize the contract with ed25519 keys. -### Policy modification {#policy-modification} +### Policy modification ```rust // Adds a limit on any token transfers that aren't signed by every signer. @@ -122,7 +122,7 @@ pub fn add_limit(env: Env, token: BytesN<32>, limit: i128) { This function allows users to set and modify the per-token spend limit described above. The neat trick here is that `require_auth` can be used for the `current_contract_address()`, i.e. the account contract may be used to verify authorization for its own administrative functions. This way there is no need to write duplicate authorization and authentication logic. -### `__check_auth` {#\_\_check_auth} +### `__check_auth` ```rust pub fn __check_auth( @@ -168,7 +168,7 @@ Here it is implemented in two steps. First, authentication is performed using th `__check_auth` is a reserved function and can only be called by the Soroban environment in response to a call to `require_auth`. Any direct call to `__check_auth` will fail. This makes it safe to write to the account contract storage from `__check_auth`, as it's guaranteed to not be called in unexpected context. In this example it's possible to persist the spend limits without worrying that they'll be exhausted via a bad actor calling `__check_auth` directly. -### Authentication {#authentication} +### Authentication ```rust fn authenticate( @@ -203,7 +203,7 @@ fn authenticate( Authentication here simply checks that the provided signatures are valid given the payload and also that they belong to the signers of this account contract. -### Authorization policy {#authorization-policy} +### Authorization policy ```rust fn verify_authorization_policy( @@ -274,7 +274,7 @@ Ok(()) Then we check for the standard token function names and verify that for these function we don't exceed the spending limits. -### Tests {#tests} +### Tests Open the [`account/src/test.rs`] file to follow along. diff --git a/docs/build/smart-contracts/example-contracts/custom-types.mdx b/docs/build/smart-contracts/example-contracts/custom-types.mdx index 0bf1c621f..aa485af99 100644 --- a/docs/build/smart-contracts/example-contracts/custom-types.mdx +++ b/docs/build/smart-contracts/example-contracts/custom-types.mdx @@ -29,7 +29,7 @@ The [custom types example] demonstrates how to define your own data structures t [custom types example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/custom_types [storing data example]: ../getting-started/storing-data.mdx -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -55,7 +55,7 @@ running 1 test test test::test ... ok ``` -## Code {#code} +## Code ```rust title="custom_types/src/lib.rs" #[contracttype] @@ -99,13 +99,13 @@ impl IncrementContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/custom_types -## How it Works {#how-it-works} +## How it Works Custom types are defined using the `#[contracttype]` attribute on either a `struct` or an `enum`. Open the `custom_types/src/lib.rs` file to follow along. -### Custom Type: Struct {#custom-type-struct} +### Custom Type: Struct Structs are stored on ledger as a map of key-value pairs, where the key is up to a 32 character string representing the field name, and the value is the value encoded. @@ -120,7 +120,7 @@ pub struct State { } ``` -### Custom Type: Enum {#custom-type-enum} +### Custom Type: Enum The example does not contain enums, but enums may also be contract types. @@ -149,7 +149,7 @@ pub enum Enum { } ``` -### Using Types in Functions {#using-types-in-functions} +### Using Types in Functions Types that have been annotated with `#[contracttype]` can be stored as contract data and retrieved later. @@ -172,7 +172,7 @@ pub fn get_state(env: Env) -> State { } ``` -## Tests {#tests} +## Tests Open the `custom_types/src/test.rs` file to follow along. @@ -232,7 +232,7 @@ assert_eq!( ); ``` -## Build the Contract {#build-the-contract} +## Build the Contract To build the contract, use the `stellar contract build` command. @@ -246,7 +246,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_custom_types_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke contract functions in the Wasm using it. diff --git a/docs/build/smart-contracts/example-contracts/deployer.mdx b/docs/build/smart-contracts/example-contracts/deployer.mdx index d0706877e..3044067da 100644 --- a/docs/build/smart-contracts/example-contracts/deployer.mdx +++ b/docs/build/smart-contracts/example-contracts/deployer.mdx @@ -38,7 +38,7 @@ In this example there are two contracts that are compiled separately, and the te [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v21.6.0 [deployer example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/deployer -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -64,7 +64,7 @@ running 1 test test test::test ... ok ``` -## Code {#code} +## Code ```rust title="deployer/deployer/src/lib.rs" #[contract] @@ -110,7 +110,7 @@ impl Deployer { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/deployer -## How it Works {#how-it-works} +## How it Works Contracts can deploy other contracts using the SDK `deployer()` method. @@ -118,13 +118,13 @@ The contract address of the deployed contract is deterministic and is derived fr Open the `deployer/deployer/src/lib.rs` file to follow along. -### Contract Wasm Upload {#contract-wasm-upload} +### Contract Wasm Upload Before deploying the new contract instances, the Wasm code needs to be uploaded on-chain. Then it can be used to deploy an arbitrary number of contract instances. The upload should typically happen outside of the deployer contract, as it needs to happen just once. However, it is possible to use `env.deployer().upload_contract_wasm()` function to upload Wasm from a contract as well. See the [tests](#tests) for an example of uploading the contract code programmatically. For the actual on-chain installation see the general deployment [tutorial](../../smart-contracts/getting-started/deploy-to-testnet.mdx). -### Authorization {#authorization} +### Authorization :::info @@ -150,7 +150,7 @@ While `deployer().with_address()` performs authorization as well, we want to mak See more details on the actual authorization payloads in [tests](#tests). -### `deployer()` {#deployer} +### `deployer()` The `deployer()` SDK function comes with a few deployment-related utilities. Here we use the most generic deployer kind, `with_address(deployer_address, salt)`. @@ -173,7 +173,7 @@ Only the `wasm_hash` itself is stored per contract ID thus saving the ledger spa When only deploying the contract on behalf of the current contract, i.e. when `deployer` address is always `env.current_contract_address()` it is possible to use `deployer().with_current_contract(salt)` function for brevity. -### Initialization {#initialization} +### Initialization The contract can be called immediately after deployment, which is useful for initialization. @@ -191,7 +191,7 @@ The contract returns the deployed contract's address and the result of executing (deployed_address, res) ``` -### Tests {#tests} +### Tests Open the `deployer/deployer/src/test.rs` file to follow along. @@ -230,7 +230,7 @@ This test contract will be used when testing the deployer. The deployer contract There are two tests: deployment from the current contract without authorization and deployment from an arbitrary address with authorization. Besides authorization, these tests are very similar. -#### Curent contract deployer {#curent-contract-deployer} +#### Curent contract deployer In the first test we deploy contract from the `Deployer` contract instance itself. @@ -308,7 +308,7 @@ let sum = client.value(); assert_eq!(sum, 5); ``` -#### External deployer {#external-deployer} +#### External deployer The second test is very similar to the first one. @@ -432,7 +432,7 @@ let sum = client.value(); assert_eq!(sum, 5); ``` -## Build the Contracts {#build-the-contracts} +## Build the Contracts To build the contract into a `.wasm` file, use the `stellar contract build` command. Build both the deployer contract and the test contract. @@ -450,7 +450,7 @@ target/wasm32-unknown-unknown/release/soroban_deployer_contract.wasm target/wasm32-unknown-unknown/release/soroban_deployer_test_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke the contract function to deploy the test contract. diff --git a/docs/build/smart-contracts/example-contracts/errors.mdx b/docs/build/smart-contracts/example-contracts/errors.mdx index b7436285e..234a34c44 100644 --- a/docs/build/smart-contracts/example-contracts/errors.mdx +++ b/docs/build/smart-contracts/example-contracts/errors.mdx @@ -29,7 +29,7 @@ The [errors example] demonstrates how to define and generate errors in a contrac [errors example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/errors [storing data example]: ../getting-started/storing-data.mdx -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -77,7 +77,7 @@ test test::test_panic - should panic ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.33s ``` -## Code {#code} +## Code ```rust title="errors/src/lib.rs" #[contracterror] @@ -122,11 +122,11 @@ impl IncrementContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/errors -## How it Works {#how-it-works} +## How it Works Open the `errors/src/lib.rs` file to follow along. -### Defining an Error {#defining-an-error} +### Defining an Error Contract errors are Rust u32 enums where every variant of the enum is assigned an integer. The `#[contracterror]` attribute is used to set the error up so it can be used in the return value of contract functions. @@ -153,7 +153,7 @@ If an error is returned from a function anything the function has done is rolled ::: -### Returning an Error {#returning-an-error} +### Returning an Error Errors can be returned from contract functions by returning `Result<_, E>`. @@ -172,7 +172,7 @@ pub fn increment(env: Env) -> Result { } ``` -### Panicking with an Error {#panicking-with-an-error} +### Panicking with an Error Errors can also be panicked instead of being returned from the function. @@ -197,7 +197,7 @@ Functions that do not return a `Result<_, E>` type do not include in their speci ::: -## Tests {#tests} +## Tests Open the `errors/src/test.rs` file to follow along. @@ -255,7 +255,7 @@ let client = IncrementContractClient::new(&env, &contract_id); Two functions are generated for every contract function, one that returns a `Result<>`, and the other that does not handle errors and panicks if an error occurs. -### `try_increment` {#try_increment} +### `try_increment` In the first test the `try_increment` function is called and returns `Result, Result>`. @@ -272,7 +272,7 @@ assert_eq!(client.try_increment(), Err(Ok(Error::LimitReached))); - If the function call is unsuccessful but returns an error code not in the `Error` enum, or returns a system error code, `Err(Err(Status))` is returned and the `Status` can be inspected. -### `increment` {#increment} +### `increment` In the second test the `increment` function is called and returns `u32`. When the last call is made the function panicks. @@ -287,7 +287,7 @@ client.increment(); - If the function call is unsuccessful, a panic occurs. -## Build the Contract {#build-the-contract} +## Build the Contract To build the contract, use the `stellar contract build` command. @@ -301,7 +301,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_errors_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract Let's deploy the contract to Testnet so we can run it. The value provided as `--source` was set up in our Getting Started guide; please change accordingly if you created a different identity. diff --git a/docs/build/smart-contracts/example-contracts/events.mdx b/docs/build/smart-contracts/example-contracts/events.mdx index ea6350722..5c26f69fb 100644 --- a/docs/build/smart-contracts/example-contracts/events.mdx +++ b/docs/build/smart-contracts/example-contracts/events.mdx @@ -26,7 +26,7 @@ The [events example] demonstrates how to publish events from a contract. This ex [events example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/events [storing data example]: ../getting-started/storing-data.mdx -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -52,7 +52,7 @@ running 1 test test test::test ... ok ``` -## Code {#code} +## Code ```rust title="events/src/lib.rs" const COUNTER: Symbol = symbol_short!("COUNTER"); @@ -89,7 +89,7 @@ impl IncrementContract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/events -## How it Works {#how-it-works} +## How it Works This example contract extends the increment example by publishing an event each time the counter is incremented. @@ -101,7 +101,7 @@ Contracts can publish events using the environments events publish function. env.events().publish(topics, data); ``` -### Event Topics {#event-topics} +### Event Topics Topics are conveniently defined using a tuple. In the sample code two topics of `Symbol` type are used. @@ -115,7 +115,7 @@ The topics don't have to be made of the same type. ::: -### Event Data {#event-data} +### Event Data An event also contains a data object of any value or type including types defined by contracts using `#[contracttype]`. In the example the data is the `u32` count. @@ -123,7 +123,7 @@ An event also contains a data object of any value or type including types define env.events().publish(..., count); ``` -### Publishing {#publishing} +### Publishing Publishing an event is done by calling the `publish` function and giving it the topics and data. The function returns nothing on success, and panics on failure. Possible failure reasons can include malformed inputs (e.g. topic count exceeds limit) and running over the resource budget (TBD). Once successfully published, the new event will be available to applications consuming the events. @@ -137,7 +137,7 @@ Published events are discarded if a contract invocation fails due to a panic, bu ::: -## Tests {#tests} +## Tests Open the `events/src/test.rs` file to follow along. @@ -217,7 +217,7 @@ assert_eq!( ); ``` -## Build the Contract {#build-the-contract} +## Build the Contract To build the contract, use the `stellar contract build` command. @@ -231,7 +231,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_events_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke contract functions in the using it. diff --git a/docs/build/smart-contracts/example-contracts/fuzzing.mdx b/docs/build/smart-contracts/example-contracts/fuzzing.mdx index 0febf2789..f927325c4 100644 --- a/docs/build/smart-contracts/example-contracts/fuzzing.mdx +++ b/docs/build/smart-contracts/example-contracts/fuzzing.mdx @@ -31,7 +31,7 @@ The [fuzzing example] demonstrates how to fuzz test Soroban contracts with [`car [`proptest-arbitrary-interop`]: https://docs.rs/proptest-arbitrary-interop [timelock example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/timelock -## Run the Example {#run-the-example} +## Run the Example First go through the [setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -84,7 +84,7 @@ INFO: seed corpus: files: 105 min: 32b max: 61b total: 3558b rss: 86Mb The rest of this tutorial will explain how to set up this fuzz test, interpret this output, and remedy fuzzing failures. -## Background: Fuzz Testing and Rust {#background-fuzz-testing-and-rust} +## Background: Fuzz Testing and Rust Fuzzing is a kind of testing where new inputs are repeatedly fed into a program in hopes of finding unexpected bugs. This style of testing is commonly employed to increase confidence in the correctness of security-sensitive software. @@ -108,7 +108,7 @@ In Rust, multiple fuzzers are maintained by the [`rust-fuzz`] GitHub organizatio [`rust-fuzz`]: https://github.com/rust-fuzz -## About the Example {#about-the-example} +## About the Example The example used for this tutorial is based on the [`timelock`] example program, with some changes to demonstrate fuzzing. @@ -155,7 +155,7 @@ pub enum TimeBoundKind { `deposit` may only be successfully called once, after which `claim` may be called multiple times until the balance is completely drained, at which point the contract becomes dormant and may no longer be used. -## Fuzz Testing Setup {#fuzz-testing-setup} +## Fuzz Testing Setup For these examples, the fuzz tests have been created for you, but normally you would use the `cargo fuzz init` command to create a fuzzing project as a subdirectory of the contract under test. @@ -239,7 +239,7 @@ path = ".." features = ["testutils"] ``` -## A Simple Fuzz Test {#a-simple-fuzz-test} +## A Simple Fuzz Test First let's look at [`fuzz_target_1.rs`]. This fuzz test does two things: it first deposits an arbitrary amount, then it claims an arbitrary amount. @@ -396,7 +396,7 @@ fn assert_invariants( } ``` -## Interpreting `cargo-fuzz` Output {#interpreting-cargo-fuzz-output} +## Interpreting `cargo-fuzz` Output If you run `cargo-fuzz` with `fuzz_target_1`, from inside the `soroban-examples/fuzzing` directory, you will see output similar to: @@ -619,7 +619,7 @@ See the [`libfuzzer` documentation] for more. [`libfuzzer` documentation]: https://llvm.org/docs/LibFuzzer.html#output -## Accepting Soroban Types as Input with the `SorobanArbitrary` Trait {#accepting-soroban-types-as-input-with-the-sorobanarbitrary-trait} +## Accepting Soroban Types as Input with the `SorobanArbitrary` Trait Inputs to the `fuzz_target!` macro must implement the [`Arbitrary`] trait, which accepts bytes from the fuzzer driver and converts them to Rust values. Soroban types though are managed by the host environment, and so must be created from an [`Env`] value, which is not available to the fuzzer driver. The [`SorobanArbitrary`] trait, implemented for all Soroban contract types, exists to bridge this gap: it defines a _prototype_ pattern whereby the `fuzz_target` macro creates prototype values that the fuzz program can convert to contract values with the standard soroban conversion traits, [`FromVal`] or [`IntoVal`]. @@ -658,7 +658,7 @@ Types that implement `SorobanArbitrary` include: All user-defined contract types, those with the [`contracttype`] attribute, automatically derive `SorobanArbitrary`. Note that `SorobanArbitrary` is only derived when the "testutils" Cargo feature is active. This implies that, in general, to make a Soroban contract fuzzable, the contract crate must define a "testutils" Cargo feature, that feature should turn on the "soroban-sdk/testutils" feature, and the fuzz test, which is its own crate, must turn that feature on. -## A More Complex Fuzz Test {#a-more-complex-fuzz-test} +## A More Complex Fuzz Test The [`fuzz_target_2.rs`] example, demonstrates the use of `SorobanArbitrary`, the advancement of time, and more advanced fuzzing techniques. @@ -785,7 +785,7 @@ for step in &config.input.steps { } ``` -## Converting a Fuzz Test to a Property Test {#converting-a-fuzz-test-to-a-property-test} +## Converting a Fuzz Test to a Property Test In addition to fuzz testing, Soroban supports property testing in the style of quickcheck, by using the [`proptest`] and [`proptest-arbitrary-interop`] crates in conjunction with the `SorobanArbitrary` trait. diff --git a/docs/build/smart-contracts/example-contracts/liquidity-pool.mdx b/docs/build/smart-contracts/example-contracts/liquidity-pool.mdx index e244c8cb7..0671ac727 100644 --- a/docs/build/smart-contracts/example-contracts/liquidity-pool.mdx +++ b/docs/build/smart-contracts/example-contracts/liquidity-pool.mdx @@ -39,7 +39,7 @@ The Stellar network already has liquidity pool functionality built right in to t [liquidity pool example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/liquidity_pool [source code]: https://github.com/stellar/soroban-examples/blob/v21.6.0/liquidity_pool/src/lib.rs#L143 -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -65,7 +65,7 @@ test test::test ... ok [setup]: ../getting-started/setup.mdx -## Code {#code} +## Code :::info @@ -469,7 +469,7 @@ pub fn create_contract( Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/liquidity_pool -## How it Works {#how-it-works} +## How it Works Every asset created on Stellar starts with zero liquidity. The same is true of tokens created on Soroban (unless a Stellar asset with existing liquidity token is "wrapped" for use in Soroban). In simple terms, "liquidity" means how much of an asset in a market is available to be bough or sold. In the "old days," you could generate liquidity in a market by creating buy/sell orders on an order book. @@ -477,7 +477,7 @@ Liquidity pools automate this process by substituting the orders with math. Depo Open the `liquidity_pool/src/lib.rs` file or see the code above to follow along. -### Initialize the Contract {#initialize-the-contract} +### Initialize the Contract When this contract is first deployed, it could create a liquidity pool for _any_ pair of tokens available on Soroban. It must first be initialized with the following information: @@ -508,7 +508,7 @@ fn initialize(e: Env, token_wasm_hash: BytesN<32>, taken_a: Address, token_b: Ad [`token` example contract]: ./tokens.mdx [lexicographical order]: ../../../learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx#liquidity-pool-participation -### A "Constant Product" Liquidity Pool {#a-constant-product-liquidity-pool} +### A "Constant Product" Liquidity Pool The _type_ of liquidity pool this example contract implements is called a "constant product" liquidity pool. While this isn't the only type of liquidity pool out there, it is the most common variety. These liquidity pools are designed to keep the _total_ value of each asset in _relative_ equilibrium. The "product" in the constant product (also called an "invariant") will change every time the liquidity pool is interacted with (deposit, withdraw, or token swaps). However, the invariant **must** only increase with every interaction. @@ -532,7 +532,7 @@ We have much more in-depth information about how this kind of liquidity pool wor [stellar quest: series 3, quest 5]: https://quest.stellar.org/learn/series/3/quest/5 -### Interacting with Token Contracts in Another Contract {#interacting-with-token-contracts-in-another-contract} +### Interacting with Token Contracts in Another Contract This liquidity pool contract will operate with a total of three different Soroban tokens: @@ -541,7 +541,7 @@ This liquidity pool contract will operate with a total of three different Soroba [token interface]: ../../../tokens/token-interface.mdx -#### Creating a Custom `POOL` Token for LP Shares {#creating-a-custom-pool-token-for-lp-shares} +#### Creating a Custom `POOL` Token for LP Shares We are utilizing the compiled `token` example contract as our asset contract for the `POOL` token. This means it follows all the conventions of the [Token Interface], and can be treated just like any other token. They could be transferred, burned, minted, etc. It also means the LP developer _could_ take advantage of the administrative features such as clawbacks, authorization, and more. @@ -611,7 +611,7 @@ fn deposit(e: Env, to: Address, desired_a: i128, min_a: i128, desired_b: i128, m } ``` -#### Token Transfers to/from the LP Contract {#token-transfers-tofrom-the-lp-contract} +#### Token Transfers to/from the LP Contract As we've already discussed, the liquidity pool contract will make use of the [Token Interface] available in the token contracts that were supplied as `token_a` and `token_b` arguments at the time of initialization. Throughout the rest of the contract, the liquidity pool will make use of that interface to make transfers of those tokens to/from itself. @@ -659,7 +659,7 @@ fn withdraw(e: Env, to: Address, share_amount: i128, min_a: i128, min_b: i128) - You'll notice that by holding the balance of `token_a` and `token_b` on the liquidity pool contract itself it makes, it very easy for us to perform any of the [Token Interface] actions inside the contract. As a bonus, any outside observer could query the balances of `token_a` or `token_b` held by the contract to verify the reserves are actually in line with the values the contract reports when its own `get_rsvs` function is invoked. -## Tests {#tests} +## Tests Open the [`liquidity_pool/src/test.rs`] file to follow along. @@ -880,7 +880,7 @@ These tests examine the "typical" use-case of a liquidity pool, ensuring that th 3. The user performs a swap, buying `token_b` in exchange for `token_a`. The same checks as the previous step are made now, excepting the balances of `POOL`, since a swap has no effect on `POOL` tokens. 4. The user then withdraws all of the deposits it made, trading all of its `POOL` tokens in the process. The same checks are made here as were made in the `deposit` step. -## Build the Contract {#build-the-contract} +## Build the Contract To build the contract, use the `stellar contract build` command. @@ -894,7 +894,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_liquidity_pool_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke contract functions using it. diff --git a/docs/build/smart-contracts/example-contracts/logging.mdx b/docs/build/smart-contracts/example-contracts/logging.mdx index 28dbd709e..adec66c2e 100644 --- a/docs/build/smart-contracts/example-contracts/logging.mdx +++ b/docs/build/smart-contracts/example-contracts/logging.mdx @@ -42,7 +42,7 @@ Logs are not accessible by dapps and other applications. See the [events example [testing]: ../getting-started/hello-world.mdx#run-the-tests [events example]: events.mdx -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -69,7 +69,7 @@ Hello Symbol(Dev) test test::test ... ok ``` -## Code {#code} +## Code ```toml title="Cargo.toml" [profile.release-with-logs] @@ -94,7 +94,7 @@ impl Contract { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/logging -## How it Works {#how-it-works} +## How it Works The [`log!`] macro logs a string. Any logs that occur during execution are outputted to stdout in [`stellar-cli`] and available for tests to assert on or print. @@ -104,7 +104,7 @@ Logs are only recorded in Soroban environments that have logging enabled. The on Open the files above to follow along. -### `Cargo.toml` Profile {#cargotoml-profile} +### `Cargo.toml` Profile Logs are only outputted if the contract is built with the `debug-assertions` compiler option enabled. @@ -122,7 +122,7 @@ To build without logs use the `--release` or `--profile release` option. To build with logs use the `--profile release-with-logs` option. -### Using the `log!` Macro {#using-the-log-macro} +### Using the `log!` Macro The [`log!`] macro builds a string from the format string, and a list of arguments. Arguments are substituted wherever the `{}` value appears in the format string. @@ -142,7 +142,7 @@ The values outputted are currently relatively limited. While primitive values li ::: -## Tests {#tests} +## Tests Open the `logging/src/test.rs` file to follow along. @@ -206,11 +206,11 @@ They can be printed to stdout. std::println!("{}", logs.join("\n")); ``` -## Build the Contract {#build-the-contract} +## Build the Contract To build the contract, use the `stellar contract build` command. -### Without Logs {#without-logs} +### Without Logs To build the contract without logs, use the `--release` option. @@ -224,7 +224,7 @@ A `.wasm` file should be outputted in the `target` directory, in the `release` s target/wasm32-unknown-unknown/release/soroban_logging_contract.wasm ``` -### With Logs {#with-logs} +### With Logs To build the contract with logs, use the `--profile release-with-logs` option. @@ -238,7 +238,7 @@ A `.wasm` file should be outputted in the `target` directory, in the `release-wi target/wasm32-unknown-unknown/release-with-logs/soroban_logging_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke contract functions in the using it. Specify the `-v` option to enable verbose logs. diff --git a/docs/build/smart-contracts/example-contracts/tokens.mdx b/docs/build/smart-contracts/example-contracts/tokens.mdx index a85d2cb53..7eb1b8c61 100644 --- a/docs/build/smart-contracts/example-contracts/tokens.mdx +++ b/docs/build/smart-contracts/example-contracts/tokens.mdx @@ -29,7 +29,7 @@ The [token example] demonstrates how to write a token contract that implements t [token example]: https://github.com/stellar/soroban-examples/tree/v21.6.0/token [token interface]: ../../../tokens/token-interface.mdx -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `v21.6.0` tag of `soroban-examples` repository: @@ -62,7 +62,7 @@ test test::test ... ok [setup]: ../getting-started/setup.mdx -## Code {#code} +## Code :::note @@ -527,7 +527,7 @@ pub enum DataKey { Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/token -## How it Works {#how-it-works} +## How it Works Tokens created on a smart contract platform can take many different forms, include a variety of different functionalities, and meet very different needs or use-cases. While each token can fulfill a unique niche, there are some "normal" features that almost all tokens will need to make use of (e.g., payments, transfers, balance queries, etc.). In an effort to minimize repetition and streamline token deployments, Soroban implements the [Token Interface], which provides a uniform, predictable interface for developers and users. @@ -537,7 +537,7 @@ This example contract, however, demonstrates how a smart contract token might be [stellar asset contract]: ../../../tokens/stellar-asset-contract.mdx -### Separation of Functionality {#separation-of-functionality} +### Separation of Functionality You have likely noticed that this example contract is broken into discrete modules, with each one responsible for a siloed set of functionality. This common practice helps to organize the code and make it more maintainable. @@ -570,7 +570,7 @@ fn mint(e: Env, to: Address, amount: i128) { This same convention is used to separate from the "main" contract code the metadata for the token, the storage type definitions, etc. -### Standardized Interface, Customized Behavior {#standardized-interface-customized-behavior} +### Standardized Interface, Customized Behavior This example contract follows the standardized [Token Interface], implementing all of the same functions as the [Stellar Asset Contract]. This gives wallets, users, developers, etc. a predictable interface to interact with the token. Even though we are implementing the same _interface_ of functions, that doesn't mean we have to implement the same _behavior_ inside those functions. While this example contract doesn't actually modify any of the functions that would be present in a deployed instance of the Stellar Asset Contract, that possibility remains open to the contract developer. @@ -602,7 +602,7 @@ Of course, you will want your token to behave in an _intuitive_ and _transparent ::: -## Tests {#tests} +## Tests Open the `token/src/test.rs` file to follow along. @@ -968,7 +968,7 @@ The eight tests created for this example contract test a range of possible condi - **`initialize_already_initialized()`** - This function checks that the contract cannot have it's `initialize()` function invoked a second time. - **`decimal_is_over_eighteen()`** - This function tests that invoking `initialize()` with too high of a decimal precision will not succeed. -## Build the Contract {#build-the-contract} +## Build the Contract To build the contract, use the `stellar contract build` command. @@ -982,7 +982,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/soroban_token_contract.wasm ``` -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke contract functions using it. diff --git a/docs/build/smart-contracts/example-contracts/workspace.mdx b/docs/build/smart-contracts/example-contracts/workspace.mdx index bd65cadb8..85b3c9914 100644 --- a/docs/build/smart-contracts/example-contracts/workspace.mdx +++ b/docs/build/smart-contracts/example-contracts/workspace.mdx @@ -15,7 +15,7 @@ The [workspace example] demonstrates how multiple smart contracts can be develop [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/main [workspace example]: https://github.com/stellar/soroban-examples/tree/main/workspace -## Run the Example {#run-the-example} +## Run the Example First go through the [Setup] process to get your development environment configured, then clone the `soroban-examples` repository: @@ -41,7 +41,7 @@ running 1 test test test::test_token_auth ... ok ``` -## Code {#code} +## Code @@ -132,7 +132,7 @@ fn test() { Ref: https://github.com/stellar/soroban-examples/tree/main/workspace -## How It Works {#how-it-works} +## How It Works There are three crates that are part of the workspace. @@ -142,7 +142,7 @@ There are three crates that are part of the workspace. Let's take a look at each crate, and see how they all work together. -### Contract A Interface: The Trait {#contract-a-interface-the-trait} +### Contract A Interface: The Trait The `contract_a_interface` crate defines a trait containing a contract interface. This interface is defined separate from the implementation and only defines what the exported functions of the implementation. @@ -150,7 +150,7 @@ The interface defines `add` as the only function the contract will contain. The The use of `contractclient` as an attribute macro on `ContractAInterface` means a client will be created, conforming to this interface, that can be used by contracts existing outside of the `contract_a_interface` crate. As you'll see later, the client, `ContractAClient`, is used in the `contract_b` crate to call the `add` function. -### Contract A: The Logic {#contract-a-the-logic} +### Contract A: The Logic The `contract_a` crate contains the implementation for Contract A, defining for each function what it should actually _do_. @@ -166,7 +166,7 @@ All that is required to make use of the previously defined `ContractAInterface` This crate uses the `contractimpl` attribute macro on the `ContractA` implementation, making the `add` function public and invocable by others on the Stellar network. -### Contract B: The Invocation {#contract-b-the-invocation} +### Contract B: The Invocation Now that we've created a trait in `contract_a_interface`, and implemented it in `contract_a`, we can use the `contract_b` crate to invoke the `add` function and get the sum of our integers. @@ -185,14 +185,14 @@ Defining the contract interface with a `trait` separately is optional. It's a gr `ContractB` invokes `ContractA`'s `add` function, returning its value back to the original invoker. It's a bit of a long round-trip for this simple example, but it illustrates a really powerful way you can separate out interface/trait definitions from contract logic and share it and its client in a multi-contract workspace. -## Practical Use-Case Examples {#practical-use-case-examples} +## Practical Use-Case Examples Beyond this simple example, this technique is versatile and useful. For example, this strategy could be used to: - Create and reference a standardized, consistent token interface. - Reuse a single interface that you want to incorporate across many different contracts. -## Build the Contracts {#build-the-contracts} +## Build the Contracts To build the contracts into a set of `.wasm` files, use the `stellar contract build` command. Both `workspace/contract_a` and `workspace/contract_b` will be built, and you can use a single command, since our workspace defines its `members` in the `Cargo.toml` file: @@ -209,7 +209,7 @@ target/wasm32-unknown-unknown/release/soroban_workspace_contract_b.wasm The [`stellar-cli`] knows the `contract_a_interface` is not intended to be compiled into a .wasm, because the `contract_a_interface`'s `Cargo.toml` has its `crate-type` configured as `rlib` (rust library). Nice! -## Run the Contract {#run-the-contract} +## Run the Contract If you have [`stellar-cli`] installed, you can invoke contract the functions. Both contracts must be deployed. diff --git a/docs/build/smart-contracts/getting-started/deploy-increment-contract.mdx b/docs/build/smart-contracts/getting-started/deploy-increment-contract.mdx index 9b4c2315d..29d26e123 100644 --- a/docs/build/smart-contracts/getting-started/deploy-increment-contract.mdx +++ b/docs/build/smart-contracts/getting-started/deploy-increment-contract.mdx @@ -21,7 +21,7 @@ import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; import { getPlatform } from "@site/src/helpers/getPlatform"; -## Two-step deployment {#two-step-deployment} +## Two-step deployment It's worth knowing that `deploy` is actually a two-step process. @@ -125,7 +125,7 @@ You should see the following output: Run it a few more times to watch the count change. -## Run your own network/node {#run-your-own-networknode} +## Run your own network/node Sometimes you'll need to run your own node: @@ -134,6 +134,6 @@ Sometimes you'll need to run your own node: The RPC team maintains Docker containers that makes this as straightforward as possible. See the [RPC](../../../data/rpc/admin-guide.mdx) reference for details. -## Up next {#up-next} +## Up next Ready to turn these deployed contracts into a simple web application? Head over to the [Build a Dapp Frontend section](../../apps/dapp-frontend.mdx). diff --git a/docs/build/smart-contracts/getting-started/deploy-to-testnet.mdx b/docs/build/smart-contracts/getting-started/deploy-to-testnet.mdx index b6417aa98..1a287dead 100644 --- a/docs/build/smart-contracts/getting-started/deploy-to-testnet.mdx +++ b/docs/build/smart-contracts/getting-started/deploy-to-testnet.mdx @@ -29,7 +29,7 @@ To recap what we've done so far, in [Setup](setup.mdx): In [Hello World](./hello-world.mdx) we created a `hello-world` project, and learned how to test and build the `HelloWorld` contract. Now we are ready to deploy that contract to Testnet, and interact with it. -## Deploy {#deploy} +## Deploy To deploy your HelloWorld contract, run the following command: @@ -61,7 +61,7 @@ stellar contract deploy ` This returns the contract's id, starting with a `C`. In this example, we're going to use `CACDYF3CYMJEJTIVFESQYZTN67GO2R5D5IUABTCUG3HXQSRXCSOROBAN`, so replace it with your actual contract id. -## Interact {#interact} +## Interact Using the code we wrote in [Write a Contract](./hello-world.mdx#contract-source-code) and the resulting `.wasm` file we built in [Build](hello-world.mdx#build-the-contract), run the following command to invoke the `hello` function. @@ -127,7 +127,7 @@ stellar contract invoke ... -- hello --help ::: -## Summary {#summary} +## Summary In this lesson, we learned how to: diff --git a/docs/build/smart-contracts/getting-started/hello-world.mdx b/docs/build/smart-contracts/getting-started/hello-world.mdx index 4b946b17b..b6582da17 100644 --- a/docs/build/smart-contracts/getting-started/hello-world.mdx +++ b/docs/build/smart-contracts/getting-started/hello-world.mdx @@ -21,7 +21,7 @@ import TabItem from "@theme/TabItem"; Once you've [set up](./setup.mdx) your development environment, you're ready to create your first smart contract. -## Create a New Project {#create-a-new-project} +## Create a New Project Create a new project using the `init` command to create a `soroban-hello-world` project. @@ -44,11 +44,11 @@ The `init` command will create a Rust workspace project, using the recommended s └── test.rs ``` -### Cargo.toml {#cargotoml} +### Cargo.toml The `Cargo.toml` file at the root of the project is set up as Rust Workspace, which allows us to include multiple smart contracts in one project. -#### Rust Workspace {#rust-workspace} +#### Rust Workspace The `Cargo.toml` file sets the workspace’s members as all contents of the `contracts` directory and sets the workspace’s `soroban-sdk` dependency version including the `testutils` feature, which will allow test utilities to be generated for calling the contract in tests. @@ -69,7 +69,7 @@ The `testutils` are automatically enabled inside [Rust unit tests] inside the sa ::: -#### `release` Profile {#release-profile} +#### `release` Profile Configuring the `release` profile to optimize the contract build is critical. Soroban contracts have a maximum size of 64KB. Rust programs, even small ones, without these configurations almost always exceed this size. @@ -87,7 +87,7 @@ codegen-units = 1 lto = true ``` -#### `release-with-logs` Profile {#release-with-logs-profile} +#### `release-with-logs` Profile Configuring a `release-with-logs` profile can be useful if you need to build a `.wasm` file that has logs enabled for printing debug logs when using the [`stellar-cli`]. Note that this is not necessary to access debug logs in tests or to use a step-through-debugger. @@ -101,11 +101,11 @@ See the [logging example] for more information about how to log. [logging example]: ../example-contracts/logging.mdx -### Contracts Directory {#contracts-directory} +### Contracts Directory The `contracts` directory is where Soroban contracts will live, each in their own directory. There is already a `hello_world` contract in there to get you started. -#### Contract-specific Cargo.toml file {#contract-specific-cargotoml-file} +#### Contract-specific Cargo.toml file Each contract should have its own `Cargo.toml` file, which relies on the top-level `Cargo.toml` that we just discussed. @@ -137,7 +137,7 @@ soroban-sdk = { workspace = true } soroban-sdk = { workspace = true, features = ["testutils"] } ``` -#### Contract Source Code {#contract-source-code} +#### Contract Source Code Creating a Soroban contract involves writing Rust code in the project’s `lib.rs` file. @@ -196,7 +196,7 @@ mod test; Note the `mod test` line at the bottom, this will tell Rust to compile and run the test code, which we’ll take a look at next. -#### Contract Unit Tests {#contract-unit-tests} +#### Contract Unit Tests Writing tests for Soroban contracts involves writing Rust code using the test facilities and toolchain that you'd use for testing any Rust code. @@ -276,7 +276,7 @@ assert_eq!( ); ``` -## Run the Tests {#run-the-tests} +## Run the Tests Run `cargo test` and watch the unit test run. You should see the following output: @@ -297,7 +297,7 @@ The first time you run the tests you may see output in the terminal of cargo com ::: -## Build the contract {#build-the-contract} +## Build the contract To build a smart contract to deploy or run, use the `stellar contract build` command. @@ -321,7 +321,7 @@ A `.wasm` file will be outputted in the `target` directory, at `target/wasm32-un The `.wasm` file contains the logic of the contract, as well as the contract's [specification / interface types](../../../learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx), which can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. -## Optimizing Builds {#optimizing-builds} +## Optimizing Builds Use `stellar contract optimize` to further minimize the size of the `.wasm`. First, re-install stellar-cli with the `opt` feature: @@ -343,7 +343,7 @@ Building optimized contracts is only necessary when deploying to a network with ::: -## Summary {#summary} +## Summary In this section, we wrote a simple contract that can be deployed to a Soroban network. diff --git a/docs/build/smart-contracts/getting-started/setup.mdx b/docs/build/smart-contracts/getting-started/setup.mdx index 18a62588b..9faf8bbeb 100644 --- a/docs/build/smart-contracts/getting-started/setup.mdx +++ b/docs/build/smart-contracts/getting-started/setup.mdx @@ -34,7 +34,7 @@ To build and develop contracts you need only a couple prerequisites: - An editor that supports Rust - [Stellar CLI] -## Install Rust {#install-rust} +## Install Rust @@ -70,7 +70,7 @@ For other methods of installing [Rust], see: https://www.rust-lang.org/tools/ins -## Install the target {#install-the-target} +## Install the target Install the `wasm32-unknown-unknown` target. @@ -78,7 +78,7 @@ Install the `wasm32-unknown-unknown` target. rustup target add wasm32-unknown-unknown ``` -## Configure an Editor {#configure-an-editor} +## Configure an Editor Many editors have support for Rust. Visit the following link to find out how to configure your editor: https://www.rust-lang.org/tools @@ -92,13 +92,13 @@ A popular editor is Visual Studio Code: [rust analyzer]: https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer [codelldb]: https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb -## Install the Stellar CLI {#install-the-stellar-cli} +## Install the Stellar CLI The [Stellar CLI](https://github.com/stellar/stellar-cli) can execute smart contracts on futurenet, testnet, mainnet, as well as in a local sandbox. The latest stable release is [v{latestVersion}](https://github.com/stellar/stellar-cli/releases/latest). -### Install {#install} +### Install There are a few ways to install the [latest release](https://github.com/stellar/stellar-cli/releases) of Stellar CLI. @@ -144,11 +144,11 @@ Report issues and share feedback about the Stellar CLI [here](https://github.com ::: -### Documentation {#documentation} +### Documentation The auto-generated comprehensive reference documentation is available [here](../../../tools/developer-tools/cli/stellar-cli.mdx). -### Autocompletion {#autocompletion} +### Autocompletion You can use `stellar completion` to generate shell completion for different shells. You should absolutely try it out. It will feel like a super power! @@ -245,9 +245,9 @@ echo "source (stellar completion --shell elvish)" >> ~/.elvish/rc.elv -### Configuring the CLI for Testnet {#configuring-the-cli-for-testnet} +### Configuring the CLI for Testnet -### Configure an Identity {#configure-an-identity} +### Configure an Identity When you deploy a smart contract to a network, you need to specify an identity that will be used to sign the transactions. diff --git a/docs/build/smart-contracts/getting-started/storing-data.mdx b/docs/build/smart-contracts/getting-started/storing-data.mdx index 48d3e3c47..fac668fbf 100644 --- a/docs/build/smart-contracts/getting-started/storing-data.mdx +++ b/docs/build/smart-contracts/getting-started/storing-data.mdx @@ -25,7 +25,7 @@ This is going to follow along with the [increment example](https://github.com/st This tutorial assumes that you've already completed the previous steps in Getting Started: [Setup](./setup.mdx), [Hello World](./hello-world.mdx), and [Deploy to Testnet](./deploy-to-testnet.mdx). -## Adding the increment contract {#adding-the-increment-contract} +## Adding the increment contract The `stellar contract init` command allows us to initialize a new project with any of the example contracts from the [soroban-examples](https://github.com/stellar/soroban-examples) repo, using the `--with-example` (or `-w`) flag. @@ -79,7 +79,7 @@ impl IncrementorContract { mod test; ``` -### Imports {#imports} +### Imports This contract begins similarly to our Hello World contract, with an annotation to exclude the Rust standard library, and imports of the types and macros we need from the `soroban-sdk` crate. @@ -88,7 +88,7 @@ This contract begins similarly to our Hello World contract, with an annotation t use soroban_sdk::{contract, contractimpl, log, symbol_short, Env, Symbol}; ``` -### Contract Data Keys {#contract-data-keys} +### Contract Data Keys ```rust const COUNTER: Symbol = symbol_short!("COUNTER"); @@ -100,7 +100,7 @@ Contract data is associated with a key, which can be used at a later time to loo The `symbol_short!()` macro is a convenient way to pre-compute short symbols up to 9 characters in length at compile time using `Symbol::short`. It generates a compile-time constant that adheres to the valid character set of letters (a-zA-Z), numbers (0-9), and underscores (\_). If a symbol exceeds the 9-character limit, `Symbol::new` should be utilized for creating symbols at runtime. -### Contract Data Access {#contract-data-access} +### Contract Data Access ```rust let mut count: u32 = env @@ -126,7 +126,7 @@ env.storage() The `set()` function stores the new count value against the key, replacing the existing value. -### Managing Contract Data TTLs with `extend_ttl()` {#managing-contract-data-ttls-with-extend_ttl} +### Managing Contract Data TTLs with `extend_ttl()` ```rust env.storage().instance().extend_ttl(100, 100); @@ -136,7 +136,7 @@ All contract data has a Time To Live (TTL), measured in ledgers, that must be pe For now, it's worth knowing that there are three kinds of storage: `Persistent`, `Temporary`, and `Instance`. This contract only uses `Instance` storage: `env.storage().instance()`. Every time the counter is incremented, this storage's TTL gets extended by 100 [ledgers](../../../learn/fundamentals/stellar-data-structures/ledgers.mdx), or about 500 seconds. -### Build the contract {#build-the-contract} +### Build the contract From inside `soroban-hello-world`, run: @@ -152,7 +152,7 @@ ls target/wasm32-unknown-unknown/release/*.wasm You should see both `hello_world.wasm` and `soroban_increment_contract.wasm`. -## Tests {#tests} +## Tests The following test has been added to the `contracts/increment/src/test.rs` file. @@ -198,11 +198,11 @@ count: U32(2) test test::incrementor ... ok ``` -## Take it further {#take-it-further} +## Take it further Can you figure out how to add `get_current_value` function to the contract? What about `decrement` or `reset` functions? -## Summary {#summary} +## Summary In this section, we added a new contract to this project, that made use of Soroban's storage capabilities to store and retrieve data. We also learned about the different kinds of storage and how to manage their TTLs. diff --git a/docs/build/smart-contracts/overview.mdx b/docs/build/smart-contracts/overview.mdx index 314feea6c..b40d7dd5d 100644 --- a/docs/build/smart-contracts/overview.mdx +++ b/docs/build/smart-contracts/overview.mdx @@ -7,7 +7,7 @@ Soroban is the smart contracts platform on the Stellar network. Contracts are sm To begin writing contracts, [install a Rust toolchain](https://www.rust-lang.org/tools/install), configure your [editor to support Rust programs](https://www.rust-lang.org/tools), and [learn some basic Rust concepts](https://www.rust-lang.org/learn). -## Rust on Stellar {#rust-on-stellar} +## Rust on Stellar Stellar smart contracts have several characteristics (such as resource limits, security considerations, and more) that force contracts to use only a narrow subset of the full Rust language and must use specialized libraries for most tasks. Read more in the [Contract Rust Dialect section](../../learn/encyclopedia/contract-development/rust-dialect.mdx). @@ -15,7 +15,7 @@ In particular, the Rust standard library and most third-party libraries (called Support for other languages may be supported in the future, but at this time, only Rust is supported. -## Soroban Rust SDK {#soroban-rust-sdk} +## Soroban Rust SDK Contracts are developed using a software development kit (SDK). The [Soroban Rust SDK](../../tools/sdks/library.mdx#soroban-rust-sdk) consists of a Rust crate and a command-line tool. @@ -23,7 +23,7 @@ The SDK crate acts as a substitute for the Rust standard library — providing d The Soroban SDK command-line tool provides a developer-focused front-end for compiling, testing, inspecting, versioning, and deploying contracts. It also includes a complete implementation of the contract host environment that is identical to the one that runs on-chain, called **local testing mode**. With this capability, contracts can be run locally on a developer's workstation and can be [tested and debugged] directly with a local debugger within a standard IDE, as well as a native test harness for fast-feedback unit testing and high-speed fuzzing or property testing. -## Host environment {#host-environment} +## Host environment The host environment is a set of Rust crates compiled into the SDK command-line tool and stellar-core. It comprises a set of host objects and functions, an interface to on-chain storage and contract invocation, a resource-accounting and fee-charging system, and a Wasm interpreter. @@ -31,7 +31,7 @@ Most contract developers will not frequently need to interact with the host envi Read more in the [Environment Concepts section](../../learn/encyclopedia/contract-development/environment-concepts.mdx). -## Soroban FAQs {#soroban-faqs} +## Soroban FAQs **What is Soroban to Stellar? Is it a new blockchain?​** diff --git a/docs/data/README.mdx b/docs/data/README.mdx index 8dabf2094..4a983a068 100644 --- a/docs/data/README.mdx +++ b/docs/data/README.mdx @@ -27,7 +27,7 @@ This section will walk you through the differences between the various platforms -## [RPC](./rpc/README.mdx) {#rpc} +## [RPC](./rpc/README.mdx) The RPC primarily provides information that the Stellar network currently has in view, i.e., **the current state**, which includes the current balances of all accounts, the current state of smart contracts, and any other relevant information that constitutes the present condition of the blockchain. It has the ability to send a transaction to the network and query the network for the status of previous transactions (subject to the retention window of seven days, transactions older than that will return a `NOT_FOUND` response). The RPC is meant to be simple, minimal, and scalable. @@ -39,7 +39,7 @@ If the RPC does not otherwise serve your needs, please tell us why in the [Stell You have the option of [setting up your own RPC instance](./rpc/admin-guide.mdx) or using a publicly available service from [an infrastructure provider](./rpc/rpc-providers.mdx). -## [Hubble](./hubble/README.mdx) {#hubble} +## [Hubble](./hubble/README.mdx) Hubble is an SDF-maintained, open-source, publicly available BigQuery data warehouse that provides a complete, holistic historical record of the Stellar network. It is a read-only platform and does not have the capability to send transactions to the network like you can with RPC. @@ -49,7 +49,7 @@ Hubble is not good for use cases that need real-time data availability, like wal The [Hubble documentation](./hubble/README.mdx) focuses on exploratory data analysis, outlines different ways developers or end users can connect to Hubble (programmatically or through a UI), and provides guidance on query optimization (users are charged per query, so it’s important to craft your query thoughtfully). -## [Horizon](./horizon/README.mdx) {#horizon} +## [Horizon](./horizon/README.mdx) Horizon is an API for accessing and interacting with the Stellar network data. It does not store smart contract data. Horizon does, however, have a limited view of the Stellar Asset Contract (SAC) and smart contract operation types (i.e., it ingests transactions with invokeHostFunction operations and asset-related operations, whether they’re made through an asset’s SAC or using the built-in transaction operations). @@ -57,11 +57,11 @@ Horizon stores three types of data (current state, historical state, and derived You can [run your own instance of Horizon](./horizon/admin-guide/README.mdx) or use one of the publicly available Horizon services from [these infrastructure providers](./horizon/horizon-providers.mdx). -## [Galexie](./galexie/README.mdx) {#galexie} +## [Galexie](./galexie/README.mdx) Galexie is a tool for exporting Stellar ledger metadata to external data storage. Learn more about its [use cases](./galexie/README.mdx) and how to [run](./galexie/admin_guide/README.mdx) your own instance of Galexie. -## [Data Indexers](../tools/developer-tools/data-indexers.mdx) {#data-indexers} +## [Data Indexers](../tools/developer-tools/data-indexers.mdx) Data indexers are specialized tools that process and index blockchain data, making it more accessible and queryable to end users. They transform raw blockchain data into a more structured format that’s easier for end users to interact with. @@ -69,7 +69,7 @@ Data indexers have advanced querying capabilities and enhanced analytics. They p Data indexers are a potentially more user-friendly, cost-effective choice for users. Check out several available data indexers for the Stellar network in our [Tools section](../tools/developer-tools/data-indexers.mdx). -## [Analytics Platforms](../tools/developer-tools/analytics-platforms.mdx) {#analytics-platforms} +## [Analytics Platforms](../tools/developer-tools/analytics-platforms.mdx) Analytics Platforms are specialized tools that process and make historical Stellar network data available. The Stellar network data is loaded into database tables for large data analytics using SQL. Users can create complex ad hoc analysis, dashboarding, and curate actionable data insights (e.g., business intelligence or business analytics). diff --git a/docs/data/galexie/README.mdx b/docs/data/galexie/README.mdx index a74bfbc5b..b91893eda 100644 --- a/docs/data/galexie/README.mdx +++ b/docs/data/galexie/README.mdx @@ -3,11 +3,11 @@ title: Galexie Introduction sidebar_position: 0 --- -## What is Galexie? {#what-is-galexie} +## What is Galexie? Galexie is a tool for extracting, processing, exporting Stellar ledger metadata to external storage, and creating a data lake of pre-processed ledger metadata. Galexie is the foundation of the Composable Data Pipeline (CDP) and serves as the first step in extracting raw Stellar ledger metadata and making it accessible. Learn more about CDP’s benefits and applications in this [blog post](https://stellar.org/blog/developers/composable-data-platform). -## What Are the Key Features of Galexie? {#what-are-the-key-features-of-galexie} +## What Are the Key Features of Galexie? Galexie is designed to make streamlined and efficient export of ledger metadata via a simple user-friendly interface. Its key features include: @@ -18,15 +18,15 @@ Galexie is designed to make streamlined and efficient export of ledger metadata ![](/assets/galexie-architecture.png) -## Why XDR Format? {#why-xdr-format} +## Why XDR Format? Exporting data in XDR—the native Stellar Core format—enables Galexie to preserve full transaction metadata, ensuring data integrity while keeping storage efficient. The XDR format maintains compatibility with all Stellar components, providing a solid foundation for applications that require consistent access to historical data. Refer to the [XDR](/docs/learn/encyclopedia/data-format/xdr) documentation for more information on this format. -## Why Run Galexie? {#why-run-galexie} +## Why Run Galexie? Galexie enables you to make a copy of Stellar ledger metadata over which you have complete control. Galexie can continuously sync your data lake with the latest ledger data freeing you up from tedious data ingestion and allowing you to focus on building customized applications that consume and analyze exported data. -## What Can You Do with the Data Lake Created by Galexie? {#what-can-you-do-with-the-data-lake-created-by-galexie} +## What Can You Do with the Data Lake Created by Galexie? Once data is stored in the cloud, it becomes easily accessible for integration with modern data processing and analytics tools, enabling various workflows and insights. diff --git a/docs/data/galexie/admin_guide/configuring.mdx b/docs/data/galexie/admin_guide/configuring.mdx index 35a30e696..a98f03758 100644 --- a/docs/data/galexie/admin_guide/configuring.mdx +++ b/docs/data/galexie/admin_guide/configuring.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 # Configuring -## Steps to Configure Galexie {#steps-to-configure-galexie} +## Steps to Configure Galexie 1. **Copy the Sample Configuration** diff --git a/docs/data/galexie/admin_guide/monitoring.mdx b/docs/data/galexie/admin_guide/monitoring.mdx index 06c4f185a..90b2146c3 100644 --- a/docs/data/galexie/admin_guide/monitoring.mdx +++ b/docs/data/galexie/admin_guide/monitoring.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 # Monitoring -### Metrics {#metrics} +### Metrics Galexie publishes metrics through an HTTP-based admin endpoint, which makes it easier to monitor its performance. This endpoint is configurable in the `config.toml` file, where you can specify the port on which metrics are made available. The data is exposed in Prometheus format, enabling easy integration with existing monitoring and alerting systems. @@ -40,7 +40,7 @@ Use these metrics to build queries that monitor Galexie’s performance and expo For a quick start, download our pre-built Grafana dashboard for Galexie [here](https://grafana.com/grafana/dashboards/22285-stellar-galexie/). This dashboard provides pre-configured queries and visualizations to help you monitor Galexie's health. You can customize it to fit your specific needs. -### Logging {#logging} +### Logging Galexie emits logs to stdout and generates a log line for every object being exported to help monitor progress. diff --git a/docs/data/galexie/admin_guide/prerequisites.mdx b/docs/data/galexie/admin_guide/prerequisites.mdx index 0f8aa4d6b..c610a1846 100644 --- a/docs/data/galexie/admin_guide/prerequisites.mdx +++ b/docs/data/galexie/admin_guide/prerequisites.mdx @@ -5,27 +5,27 @@ sidebar_position: 10 # Prerequisites -### 1. Google Cloud Platform (GCP) Account {#1-google-cloud-platform-gcp-account} +### 1. Google Cloud Platform (GCP) Account Galexie exports Stellar ledger metadata to Google Cloud Storage (GCS), so you need a GCP account with: - Permissions to create a new GCS bucket, or - Access to an existing bucket with read/write permissions. -### 2. Docker (Recommended) {#2-docker-recommended} +### 2. Docker (Recommended) > **_NOTE:_** While it is possible to natively install Galexie (without Docker), this requires manual dependency management and is recommended only for advanced users.] Galexie is available as a Docker image, which simplifies installation and setup. Ensure you have Docker Engine installed on your system ([Docker installation guide](https://docs.docker.com/engine/install/)). -## Hardware Requirements {#hardware-requirements} +## Hardware Requirements The minimum hardware requirements for running Galexie are:\ **RAM**: 8 GB\ **CPU**: 2 vCPUs\ **Disk**: 100 GB with at least 5K IOPS -### Full History Export {#full-history-export} +### Full History Export Exporting the full history (as of November 2024): diff --git a/docs/data/galexie/admin_guide/running.mdx b/docs/data/galexie/admin_guide/running.mdx index 680a8a018..6651889a4 100644 --- a/docs/data/galexie/admin_guide/running.mdx +++ b/docs/data/galexie/admin_guide/running.mdx @@ -7,9 +7,9 @@ sidebar_position: 40 With the Docker image available and the configuration file set up, you're now ready to run Galexie and start exporting Stellar ledger data to the GCS bucket. -## Command Line Usage {#command-line-usage} +## Command Line Usage -### Append Command {#append-command} +### Append Command This is the primary way of running Galexie. The `append` command operates in two distinct modes: @@ -64,11 +64,11 @@ append --start 350000 --end 450000 --config-file config.toml - The Docker image name. -#### Data Integrity and Resumability: {#data-integrity-and-resumability} +#### Data Integrity and Resumability: The append command maintains strict sequential integrity within each export session. If interrupted and then restarted with the same range, it automatically resumes from where it left off before interruption, ensuring no ledgers are missed within a session. -### Scan-and-fill Command {#scan-and-fill-command} +### Scan-and-fill Command The `scan-and-fill` command is useful in cases where there are gaps in the exported ledgers in the data lake. The command works by scanning all ledgers in the specified range, identifying missing ledgers and exporting only the missing ledgers while skipping existing ledgers in the data lake. diff --git a/docs/data/galexie/admin_guide/setup.mdx b/docs/data/galexie/admin_guide/setup.mdx index 354eec8e5..70632debb 100644 --- a/docs/data/galexie/admin_guide/setup.mdx +++ b/docs/data/galexie/admin_guide/setup.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 # Setup -### Google Cloud Platform (GCP) credentials {#google-cloud-platform-gcp-credentials} +### Google Cloud Platform (GCP) credentials Create application default credentials by using your user account for your GCP project by following these steps: @@ -14,7 +14,7 @@ Create application default credentials by using your user account for your GCP p 3. Create [application default credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc#google-idp) and it should automatically store in this location: `$HOME/.config/gcloud/application_default_credentials.json.` 4. Verify that this file exists before moving on to the next step. -### Google Cloud Storage (GCS) bucket {#google-cloud-storage-gcs-bucket} +### Google Cloud Storage (GCS) bucket If you already have a GCS bucket with read and write permissions, you can skip this section. If not, follow these steps: diff --git a/docs/data/horizon/README.mdx b/docs/data/horizon/README.mdx index 48dbc20fb..c5de28872 100644 --- a/docs/data/horizon/README.mdx +++ b/docs/data/horizon/README.mdx @@ -17,7 +17,7 @@ This guide describes how to administer a production Horizon instance (refer to t Before we begin, it's worth reiterating the sentiment echoed in the [Core Node](../../validators/README.mdx) documentation: **we do not endorse running Horizon backed by a standalone Stellar Core instance**, and especially not by a _validating_ Stellar Core. These are two separate concerns, and decoupling them is important for both reliability and performance. Horizon instead manages its own, pared-down version of Stellar Core optimized for its own subset of needs (we'll refer to this as a "Captive Core" instance). -## Why Run Horizon? {#why-run-horizon} +## Why Run Horizon? Running Horizon within your own infrastructure provides a number of benefits. You can: @@ -29,7 +29,7 @@ The Stellar Development Foundation (SDF) runs two instances of Horizon: - [horizon-testnet.stellar.org](https://horizon-testnet.stellar.org/) for interacting with the [testnet](../../learn/fundamentals/networks.mdx) - [horizon-futurenet.stellar.org](https://horizon-futurenet.stellar.org/) for interacting with the [futurenet](../../learn/fundamentals/networks.mdx) -## In These Docs {#in-these-docs} +## In These Docs - [Admin Guide](./admin-guide/README.mdx): how to set up your own Horizon instance. - [Structure](./api-reference/structure/README.mdx): how Horizon is structured. diff --git a/docs/data/horizon/admin-guide/configuring.mdx b/docs/data/horizon/admin-guide/configuring.mdx index 0ddf756ec..ed0ca352d 100644 --- a/docs/data/horizon/admin-guide/configuring.mdx +++ b/docs/data/horizon/admin-guide/configuring.mdx @@ -5,7 +5,7 @@ sidebar_position: 30 import { Alert } from "@site/src/components/Alert"; -## Prerequisites {#prerequisites} +## Prerequisites - You have identified the [installation](./installing.mdx) method for the host system: @@ -23,7 +23,7 @@ You are now ready to identify the configuration parameters needed to perform thr To perform these roles, you can choose from one of two deployment modes below (single instance deployment or multiple instance deployment). Each has its own configuration parameters. -## Single Instance Deployment {#single-instance-deployment} +## Single Instance Deployment Run `stellar-horizon` in a single o/s process and it will perform all three roles simultaneously. @@ -33,11 +33,11 @@ Run `stellar-horizon` in a single o/s process and it will perform all three role | `NETWORK` | pubnet | | `HISTORY_RETENTION_COUNT` | 518400 | -## Multiple Instance Deployment {#multiple-instance-deployment} +## Multiple Instance Deployment In this scalable deployment variant, you run multiple instances of `stellar-horizon`, each performing a subset of the roles. This allows you to horizontally scale each of the role functions independently. -### Ingestion Role Instance {#ingestion-role-instance} +### Ingestion Role Instance You must allocate **at least** one instance to perform ongoing ingestion to capture network activity. This will default to limiting storage of ingested network activity in the database to our recommendation of a sliding window of the last 30 days. @@ -48,7 +48,7 @@ You must allocate **at least** one instance to perform ongoing ingestion to capt | `HISTORY_RETENTION_COUNT` | 518400 | | `DISABLE_TX_SUB` | true | -### API Role Instance {#api-role-instance} +### API Role Instance You can run none or multiple instances to serve read-only API requests. Notice there is no need to define network settings here, as Horizon only reads from database. @@ -58,7 +58,7 @@ You can run none or multiple instances to serve read-only API requests. Notice t | `INGEST` | false | | `DISABLE_TX_SUB` | true | -### Transaction Submission Role Instance {#transaction-submission-role-instance} +### Transaction Submission Role Instance You can run none or multiple instances to serve transaction submission requests. If you run an instance with transaction submission enabled, the Horizon deployment is required to have at least one instance perform the ingestion role on the same database. Horizon transaction submission depends on this **live** ingestion taking place against the database in order to confirm tx submission status. @@ -72,40 +72,40 @@ If setting `INGEST=false`, then **must** define the `STELLAR_CORE_URL` variable | `STELLAR_CORE_URL` | http://example.watcher.core:11626 | | `INGEST` | false | -## Notes {#notes} +## Notes -### Ingestion {#ingestion} +### Ingestion If you have configured your deployment to perform the ingestion role, then it is **strongly** recommended to review [Ingestion](./ingestion.mdx) first and [Filtering](./ingestion-filtering.mdx) second and factor that into configuration parameters to achieve best performance related to your application requirements before proceeding further. - Horizon will create a sub-directory under the current working directory of the o/s process to store captive core runtime data files. Refer to [Prerequisites](./prerequisites.mdx) for the type and amount of storage recommended. You can override this location with the optional `CAPTIVE_CORE_STORAGE_PATH` environment variable, set to a directory on the file system where captive core will store the runtime files. -### `DISABLE_TX_SUB` {#disable_tx_sub} +### `DISABLE_TX_SUB` This config parameter is optional, set as FALSE by default. Controls whether Horizon will accept HTTP requests to the `/tx` API endpoint and forward to the network. Refer to [Channel Accounts](../../../learn/encyclopedia/transactions-specialized/channel-accounts.mdx) for some recommendations on optional client transaction submission optimizations. - When set to FALSE, it requires **live** ingestion process to be running on the same database because Horizon depends on new ledgers from the network to confirm a transaction submission status, Horizon will report a startup error if it detects no **live** ingestion. Requires `INGEST=true` or `STELLAR_CORE_URL` to be defined for access to a Core instance. - When transaction submission is disabled by setting it to TRUE, Horizon will return 405 on POSTs to /tx. -### `NETWORK` {#network} +### `NETWORK` This config parameter is optional, can be one of Stellar's public networks, 'pubnet', or 'testnet'. Triggers Horizon to automatically set configurations for remaining Horizon settings and generate the correct core toml/cfg settings. If you only need Horizon to connect to one of those public Stellar networks, this will take care of all related configurations. - If you want to connect Horizon to a different Stellar network other than pubnet or testnet or override any of the defaults that `NETWORK` usage will initiate, the key environment variables that can be set are: `HISTORY_ARCHIVE_URLS`, `CAPTIVE_CORE_CONFIG_PATH`, `NETWORK_PASSPHRASE`, `CAPTIVE_CORE_STORAGE_PATH`, `STELLAR_CORE_URL`. -### `DB_URL` {#db_url} +### `DB_URL` This config parameter is required, specifies the Horizon database. It's value follows this format: `dbname= user= password= host=` -### `LOG_LEVEL` {#log_level} +### `LOG_LEVEL` This config parameter is optional, can be one of 'info', 'error', 'debug'. -### `HISTORY_RETENTION_COUNT` {#history_retention_count} +### `HISTORY_RETENTION_COUNT` This config parameter is optional, it determines the maximum sliding window of historical network data to retain on the database from ingestion. The value is expressed as absolute ledger count, which is an indirect way to define a duration of time, each ledger being approximately 5 seconds. It is defaulted to 0, which means it will not purge any history from the database. To enact the recommended sliding window of one month, set this to 518400, which is the approximate number of ledgers in 30 days. Refer to [Compute Resources](./prerequisites.mdx) for how database storage space is closely related to this setting. -## Passing Configurations to Horizon {#passing-configurations-to-horizon} +## Passing Configurations to Horizon The `stellar-horizon` binary searches process environment variables for configuration. Depending on how Horizon was installed, the method you perform to configure the process environment will differ: @@ -122,7 +122,7 @@ The `stellar-horizon` binary searches process environment variables for configur - Non-Helm: pass all configuration parameters to the horizon docker image as [docker environment variables](https://docs.docker.com/engine/reference/commandline/run/#env). - Helm: pass all configuration parameters in the [Helm install command](https://helm.sh/docs/helm/helm_install/) as a values file. -## Initialize Horizon Database {#initialize-horizon-database} +## Initialize Horizon Database Before running the Horizon server for the first time, you must initialize the Horizon database. This database will be used for all of the information produced by Horizon, most notably historical information about transactions that have occurred on the Stellar network. @@ -151,7 +151,7 @@ $ export DATABASE_URL="dbname=horizon user=horizon password= host=:/ingestion/filters/asset`. diff --git a/docs/data/horizon/admin-guide/ingestion.mdx b/docs/data/horizon/admin-guide/ingestion.mdx index 1b74f9cff..b2e386964 100644 --- a/docs/data/horizon/admin-guide/ingestion.mdx +++ b/docs/data/horizon/admin-guide/ingestion.mdx @@ -7,14 +7,14 @@ import { CodeExample } from "@site/src/components/CodeExample"; Horizon API provides most of its utility through ingested data, and your Horizon server can be configured to listen for and ingest transaction results from the Stellar network. Ingestion enables API access to both current state (e.g. someone's balance) and historical state (e.g. someone's transaction history). -## Ingestion Types {#ingestion-types} +## Ingestion Types There are two primary ingestion use cases for Horizon operations: - Ingesting **live** data to stay up to date with the latest ledgers from the network, accumulating a sliding window of aged ledgers; - Ingesting **historical** data to retroactively add network data from a time range in the past to the database. -## Determine Storage Space {#determine-storage-space} +## Determine Storage Space You should think carefully about the historical timeframe of ingested data you'd like to retain in Horizon's database. The storage requirements for transactions on the Stellar network are substantial and are growing unbounded over time. This is something that you may need to continually monitor and reevaluate as the network continues to grow. We have found that most organizations need only a small fraction of recent historical data to satisfy their use cases. Through analyzing traffic patterns on SDF's Horizon instance, we see that most requests are for very recent data. @@ -25,13 +25,13 @@ To keep your storage footprint small, we recommend the following: - If your application can work on a [filtered network dataset](./ingestion-filtering.mdx) based on specific accounts and assets, then we recommend applying ingestion filter rules. When using filter rules, it provides benefit of choice in longer historical retention timeframe since the filtering is reducing the overall database size to such a degree, historical retention(`HISTORY_RETENTION_COUNT`) can be set in terms of years rather than months or even disabled(`HISTORY_RETENTION_COUNT=0`). - If you cannot limit your history retention window to 30 days and cannot use filter rules, we recommend considering [Stellar Hubble Data Warehouse](../../hubble/README.mdx) for any historical data. -### Ingesting Live Data {#ingesting-live-data} +### Ingesting Live Data This option is enabled by default and is the recommended mode of ingestion to run. It is controlled with environment configuration flag `INGEST`. Refer to [Configuration](./configuring.mdx) for how an instance of Horizon performs the ingestion role. For high availability requirements, **we recommend deploying more than one live ingesting instance**, as this makes it easier to avoid downtime during upgrades and adds resilience, ensuring you always have the latest network data (refer to [Ingestion Role Instance](./configuring.mdx#multiple-instance-deployment)). -### Ingesting Historical Data {#ingesting-historical-data} +### Ingesting Historical Data Import network data from a past date range into the database: @@ -49,7 +49,7 @@ Typically the only time you need to run historical ingestion is once when boot-s You can run historical ingestion in parallel in background while your main Horizon server separately performs **live** ingestion. If the range specified overlaps with data already in the database, it is ok and will simply be overwritten, effectively idempotent. -#### Parallel Ingestion Workers {#parallel-ingestion-workers} +#### Parallel Ingestion Workers You can parallelize the ingestion of target historical ledger range by dividing it into sequential slices of smaller ranges and run the db reingest range command for each sub-range in parallel as a separate process on the same or a different machine. The shorthand rule for best performance is to identify the number of CPU cores available per target machine, if multi-core, then add `--parallel-workers ` to the command, this will enable the command to further parallelize internally within a single process using multiple threads and sub-divided smaller ranges. @@ -69,13 +69,13 @@ horizon2> stellar-horizon db reingest range 15001 30000 --parallel-workers 2 -### Notes {#notes} +### Notes -#### Some endpoints may report not available during **live** ingestion {#some-endpoints-may-report-not-available-during-live-ingestion} +#### Some endpoints may report not available during **live** ingestion - Endpoints that display current state information from **live** ingestion may return `503 Service Unavailable`/`Still Ingesting` error. An example is the `/paths` endpoint (built using offers). Such endpoints will become available after **live** ingestion has finished network synchronization and catch up (usually within a couple of minutes). -#### If more than five minutes has elapsed with no new ingested data: {#if-more-than-five-minutes-has-elapsed-with-no-new-ingested-data} +#### If more than five minutes has elapsed with no new ingested data: - Verify the host machine meets recommended [Prerequisites](./prerequisites.mdx). @@ -92,6 +92,6 @@ horizon2> stellar-horizon db reingest range 15001 30000 --parallel-workers 2 sudo dd if=/dev/zero of=/tmp/test_speed.img bs=1G count=1 ``` -#### Monitoring Ingestion Process {#monitoring-ingestion-process} +#### Monitoring Ingestion Process For high-availability deployments, it is recommended to implement monitoring of ingestion process for visibility on performance/health. Refer to [Monitoring](./monitoring.mdx) for accessing logs and metrics from Horizon. Stellar publishes the example [Horizon Grafana Dashboard](https://grafana.com/grafana/dashboards/13793-stellar-horizon/), which demonstrates queries against key horizon ingestion metrics, specifically look at the `Local Ingestion Delay [Ledgers]` and `Last ledger age` in the `Health Summary` panel. diff --git a/docs/data/horizon/admin-guide/installing.mdx b/docs/data/horizon/admin-guide/installing.mdx index 3fc27d341..e244cd482 100644 --- a/docs/data/horizon/admin-guide/installing.mdx +++ b/docs/data/horizon/admin-guide/installing.mdx @@ -7,21 +7,21 @@ import { CodeExample } from "@site/src/components/CodeExample"; To install Horizon in production or non-development environments, we recommend the following based on target infrastructure: -### Bare-Metal {#bare-metal} +### Bare-Metal - If host is Debian Linux, install prebuilt binaries [from repositories](#package-manager) using a package manager. - For any other hosts, download [prebuilt release binaries](#prebuilt-releases) of Stellar Horizon and Core for host target architecture and operation system or [compile from the source](https://github.com/stellar/go/blob/master/services/horizon/internal/docs/GUIDE_FOR_DEVELOPERS.md#building-horizon). -### Containerized {#containerized} +### Containerized - Non-Orchestrated: if the target deployment environment does not include a container orchestrator such as Kubernetes, then this means you intend to run the Horizon release image from [dockerhub.com/stellar/stellar-horizon](https://hub.docker.com/r/stellar/stellar-horizon) as a container directly with Docker daemon on host. Choose the tag of the Horizon image for the specific release version and then pull the image using `docker pull stellar/stellar-horizon:` to get it locally onto host. - Orchestrated: when the target environment has container orchestration, such as Kubernetes cluster, we recommend using the [Horizon Helm Chart](https://github.com/stellar/helm-charts/tree/main/charts/horizon) to manage the installation and deployment lifecycle of the Horizon image as container(s) on the cluster. To install Horizon in development environments, refer to the [Horizon README](https://github.com/stellar/go/blob/master/services/horizon/README.md#try-it-out) from the source code repo for options available. -### Notes on Installation {#notes-on-installation} +### Notes on Installation -#### Package Manager {#package-manager} +#### Package Manager SDF publishes new releases to its custom Ubuntu repositories. Follow [this guide](https://github.com/stellar/packages/blob/master/docs/adding-the-sdf-stable-repository-to-your-system.md#adding-the-sdf-stable-repository-to-your-system) to add the stable SDF repository to your host system. If you are interested in installing release candidate versions of software that have yet to reach stable, refer to [Adding the Bleeding Edge Testing Repository](https://github.com/stellar/packages/blob/master/docs/adding-the-sdf-stable-repository-to-your-system.md#adding-the-bleeding-edge-testing-repository). Lastly, [install package](https://github.com/stellar/packages/blob/master/docs/installing-individual-packages.md#installing-individual-packages) outlines the various commands that these packages make available. @@ -36,17 +36,17 @@ sudo apt install stellar-horizon stellar-core -#### Prebuilt Releases {#prebuilt-releases} +#### Prebuilt Releases Refer to the list of [Horizon releases](https://github.com/stellar/go/releases) and [Core releases](https://github.com/stellar/stellar-core/releases). Copy the binaries to host PATH. -#### Verify Bare-Metal Installations {#verify-bare-metal-installations} +#### Verify Bare-Metal Installations Run `stellar-horizon --help` from a terminal. If the help for Horizon is displayed, your installation was successful. Some shells (such as [zsh](https://www.zsh.org/)) cache PATH lookups. You may need to clear your cache (by using `rehash` in zsh, for example) or restart your shell before trying to run the command above. -#### Helm Chart Installation {#helm-chart-installation} +#### Helm Chart Installation If the deployment can be done on Kubernetes, there is a [Horizon Helm Chart](https://github.com/stellar/helm-charts/blob/main/charts/horizon) available. Install the [Helm CLI tool](https://helm.sh/docs/intro/install/), if you haven't already on your workstation, minimum of version 3. Next, add the Stellar repo to the helm client's list of repos and confirm that you can view the list of available chart versions for the repo: @@ -73,6 +73,6 @@ helm template -f charts/horizon/values.yaml charts/horizon/ -## Next Step {#next-step} +## Next Step After installation is complete, you are now ready to proceed to [Configuring Horizon](./configuring.mdx)! diff --git a/docs/data/horizon/admin-guide/monitoring.mdx b/docs/data/horizon/admin-guide/monitoring.mdx index 91fc394dc..2b0389e43 100644 --- a/docs/data/horizon/admin-guide/monitoring.mdx +++ b/docs/data/horizon/admin-guide/monitoring.mdx @@ -5,11 +5,11 @@ sidebar_position: 60 import { CodeExample } from "@site/src/components/CodeExample"; -## Metrics {#metrics} +## Metrics Metrics are emitted from Horizon over HTTP in [the de facto text-based exposition format](https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#text-based-format). The Metrics are published on the _private_ `/metrics` path of Horizon Admin port, which is an optional service to be started and will be bound by the Horizon process onto the host machine loopback network(localhost or 127.0.0.1). To enable the Admin port, add environment configuration parameter `ADMIN_PORT=XXXXX`, the metrics endpoint will be reachable on the host machine as `localhost:/metrics`. You can verify this by pointing any browser that can reach this address, it will print out all metrics keys. -### Exporting {#exporting} +### Exporting Once the Admin port is enabled, the Horizon metrics endpoint can be 'scraped' by external monitoring infrastructure. Since the metrics output is encoded to [standard text-based format](https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#text-based-format) it will be compatible for usage with many types of monitoring infrastructure that interoperate with the same standard format. @@ -19,7 +19,7 @@ One real-world example for exporting from a bare metal Horizon installation (Hor In container-orchestrated environments such as Kubernetes, you can use the same exporter strategy. We assume you already have a metrics infrastructure deployment like Prometheus and Grafana setup on the cluster via the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator), and will just need to configure that infrastructure to scrape the Horizon pod based on the ADMIN_PORT. -### Data model {#data-model} +### Data model There are numerous application metrics keys emitted by Horizon at runtime, encoded in four types of exposition formats: `counter`, `gauge`, `histogram`, `summary`. Each key is further qualified with labels for more granularity. To summarize, we can highlight the groupings of metrics keys by common function denoted in the prefix of their name: @@ -52,7 +52,7 @@ horizon_http_requests_duration_seconds{method="GET",route="/",status="200",strea ``` -### Queries {#queries} +### Queries Build queries against the metrics data model to highlight the performance of a given Horizon deployment. Refer to Stellar's [Grafana Horizon Dashboard](https://grafana.com/grafana/dashboards/13793-stellar-horizon/) for examples of metrics queries to derive application performance: @@ -70,7 +70,7 @@ Build queries against the metrics data model to highlight the performance of a g Choose the [revisions tab](https://grafana.com/grafana/dashboards/13793-stellar-horizon/?tab=revisions), and download the dashboard source file to have access to the Grafana dashboard source code and metrics queries that build each panel in dashboards. -### Alerts {#alerts} +### Alerts Once queries are developed on a Grafana dashboard, it enables a convenient follow-on step to add [alert rules](https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-grafana-managed-rule/) based on specific queries to trigger notifications when thresholds are exceeded. @@ -82,7 +82,7 @@ Here are some example alerts to consider with potential causes and solutions. | Ingestion is slow | host server compute resources are low | increase compute specs | | HTTP API responses are returning errors | host server compute resources are low or networking to DB is lost | check the [Horizon logs](#logs) to see what errors are being emitted, narrow down root cause from there | -## Logs {#logs} +## Logs Horizon will output logs to operating system's standard out. It will log on all aspects of runtime, including HTTP requests and ingestion. Typically, there are very few `warn` or `error` severity level messages emitted. The default severity level logged in Horizon is configured to `LOG_LEVEL=info`, this environment configuration parameter can be set to one of `trace, debug, info, warn, error`. The verbosity of log output is inverse of the severity level chosen. I.e. for most verbose logs use 'trace', for least verbose logs use 'error'. @@ -91,7 +91,7 @@ For production deployments, we recommend using the default severity setting of ` - Bare metal deployment direct to operating system, redirect the standard out from Horizon process to a file on disk and apply a log rotation tool on the file such as [logrotate](https://man7.org/linux/man-pages/man8/logrotate.8.html) to manage disk space usage. - Orchestrated deployment on Kubernetes, use an EFK/ELK stack on the cluster and it can be configured to capture the standard out from Horizon pod. -## Runtime Profiling {#runtime-profiling} +## Runtime Profiling Horizon is written in Golang, therefore it has been enabled to optionally emit the Golang runtime diagnostics and profiling output [pprof](https://go.dev/doc/diagnostics). The pprof HTTP endpoints are hosted on Horizon's admin HTTP port, it can be enabled by adding environment configuration parameter `ADMIN_PORT=XXXXX`, since the admin port binding is disabled by default. @@ -113,6 +113,6 @@ Entering interactive mode (type "help" for commands, "o" for options) (pprof) web ``` -## I'm Stuck! Help! {#im-stuck-help} +## I'm Stuck! Help! If any of the above steps don't work or you are otherwise prevented from correctly setting up Horizon, please join our community and let us know. Either post a question at [our Stack Exchange](https://stellar.stackexchange.com/) or chat with us on [Horizon Discord](https://discord.com/channels/897514728459468821/912466080960766012) to ask for help. diff --git a/docs/data/horizon/admin-guide/overview.mdx b/docs/data/horizon/admin-guide/overview.mdx index d1acf65d7..54ff38779 100644 --- a/docs/data/horizon/admin-guide/overview.mdx +++ b/docs/data/horizon/admin-guide/overview.mdx @@ -9,7 +9,7 @@ This guide describes how to administer a production Horizon instance (refer to t Before we begin, it's worth reiterating the sentiment echoed in the [Run a Core Node](../../../validators/README.mdx) guide: **we do not endorse running Horizon backed by a standalone Stellar Core instance**, and especially not by a _validating_ Stellar Core. These are two separate concerns, and decoupling them is important for both reliability and performance. Horizon instead manages its own, pared-down version of Stellar Core optimized for its own subset of needs (we'll refer to this as a "Captive Core" instance). -## Why Run Horizon? {#why-run-horizon} +## Why Run Horizon? Running Horizon within your own infrastructure provides a number of benefits. You can: diff --git a/docs/data/horizon/admin-guide/prerequisites.mdx b/docs/data/horizon/admin-guide/prerequisites.mdx index 8e4578ba1..f6a68526f 100644 --- a/docs/data/horizon/admin-guide/prerequisites.mdx +++ b/docs/data/horizon/admin-guide/prerequisites.mdx @@ -7,18 +7,18 @@ The Horizon service is responsible for synchronizing with the Stellar network an The Horizon service can be [installed](./installing.mdx) on bare metal or a virtual machine. It is natively supported on both Linux and Windows operating systems. -## Single Instance Deployment Model {#single-instance-deployment-model} +## Single Instance Deployment Model For a basic setup using the [Single Instance Deployment model](./configuring.mdx#single-instance-deployment), you will need a sum of two distinct compute profiles: - One for hosting the Horizon service - Another for hosting the PostgreSQL server -### Hardware requirements {#hardware-requirements} +### Hardware requirements The minimum hardware specifications to effectively run Horizon are as follows: -#### Horizon Compute Instance: {#horizon-compute-instance} +#### Horizon Compute Instance: | Node Type | CPU | RAM | Disk | AWS SKU | Google Cloud SKU | | --- | --- | --- | --- | --- | --- | @@ -26,7 +26,7 @@ The minimum hardware specifications to effectively run Horizon are as follows: _\* Assuming a 30-day retention window for data storage._ -#### PostgreSQL Database Server Compute Instance: {#postgresql-database-server-compute-instance} +#### PostgreSQL Database Server Compute Instance: | Node Type | CPU | RAM | Disk | AWS SKU | Google Cloud SKU | | --- | --- | --- | --- | --- | --- | @@ -38,11 +38,11 @@ Please note that a minimum of PostgreSQL version 12 is required. These specifications assume a 30-day retention window for data storage. For a longer retention window, the system requirements will be higher. For more information about data ingestion, history retention, and managing storage, check the [ingestion](./ingestion.mdx) section. -## Multiple Instance Deployment {#multiple-instance-deployment} +## Multiple Instance Deployment To achieve high availability, redundancy, and high throughput, refer to the [scaling](./scaling.mdx) documentation. It provides a detailed overview of several different deployment strategies you can employ, depending on the SLA you need your Horizon instance to achieve. -## Network Access {#network-access} +## Network Access - Ensure that the Horizon instance can establish a connection with the PostgreSQL database instance. The default port for PostgreSQL is 5432. diff --git a/docs/data/horizon/admin-guide/running.mdx b/docs/data/horizon/admin-guide/running.mdx index b4916a5bd..2877ec23c 100644 --- a/docs/data/horizon/admin-guide/running.mdx +++ b/docs/data/horizon/admin-guide/running.mdx @@ -7,19 +7,19 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once you have [established the Horizon database](./configuring.mdx#initialize-horizon-database) and have [identified the Horizon runtime config per host](./configuring.mdx#prerequisites), you're ready to run Horizon. -## Bare-metal installation {#bare-metal-installation} +## Bare-metal installation Run the `stellar-horizon` binary with the [appropriate environment parameters](./configuring.mdx#passing-configurations-to-horizon) set (or `stellar-horizon-cmd serve` if you [installed via the package manager](./installing.mdx#package-manager), which will automatically import your configuration from `/etc/default/stellar-horizon`). -## Containerized installation {#containerized-installation} +## Containerized installation You don't execute the Horizon binary directly, instead the [stellar/stellar-horizon](https://hub.docker.com/r/stellar/stellar-horizon) image has a pre-defined entrypoint that will start running Horizon at image startup time. The Horizon process will get all configuration settings from container environment variables. -### Docker daemon {#docker-daemon} +### Docker daemon Use `docker run stellar/stellar-horizon: --env-file `, and specify each Horizon configuration flag identified during [Configuring](./configuring.mdx) as a separate line in `` of `HORIZON_CONFIG_PARAM=value`. -### Kubernetes using Helm Chart {#kubernetes-using-helm-chart} +### Kubernetes using Helm Chart Ensure you have followed the [pre-requisite](./installing.mdx#helm-chart-installation) of installing the Helm CLI tool and added the Stellar chart repo to Helm client. diff --git a/docs/data/horizon/admin-guide/scaling.mdx b/docs/data/horizon/admin-guide/scaling.mdx index f473faf6b..a80602aca 100644 --- a/docs/data/horizon/admin-guide/scaling.mdx +++ b/docs/data/horizon/admin-guide/scaling.mdx @@ -9,7 +9,7 @@ Horizon enables different logical tiers that can be scaled independently for inc - Captive Core (ingestion and transaction submission) - Database (storage) -## Single Instance Deployment {#single-instance-deployment} +## Single Instance Deployment It is recommend to start with a [single instance deployment](./prerequisites.mdx), and scale up based on the needs of your particular use-case. @@ -19,7 +19,7 @@ In this setup, a single instance of Horizon performs all three [roles](./configu ![](/assets/horizon-scaling/Topology-single.png) -## Scaling to Multiple Instances {#scaling-to-multiple-instances} +## Scaling to Multiple Instances There are a few reasons you may choose to scale to multiple instances of Horizon. @@ -33,7 +33,7 @@ When scaling Horizon, it is worth it to note that Horizon's [rate limiting](../a ![](/assets/horizon-scaling/Topology-multiple.png) -## Logically Isolating Ingestion {#logically-isolating-ingestion} +## Logically Isolating Ingestion Ingestion is the process by which new ledgers are propagated into Horizon's database. It's health is critical, as degredations in performance can result in falling behind the last closed ledger, leaving your end-users unaware of the current state of the network, and unable to successfully submit new transactions. Any lag in ingestion would likely be considered downtime for your service @@ -48,7 +48,7 @@ The Horizon API role requires only read-only permissions to a database for all a ![](/assets/horizon-scaling/Topology-ingestion-isolation.png) -## Logically Isolating Transaction Submission {#logically-isolating-transaction-submission} +## Logically Isolating Transaction Submission In the above example, ingestion is safely isolated from most API traffic, which has historically been the large majority of traffic. However, transaction submission still needs to be served by a core instance, and so API instances must passthrough their transaction submission requests to an ingesting instance. diff --git a/docs/data/horizon/admin-guide/upgrading.mdx b/docs/data/horizon/admin-guide/upgrading.mdx index 9c24e2e96..3d15a16ba 100644 --- a/docs/data/horizon/admin-guide/upgrading.mdx +++ b/docs/data/horizon/admin-guide/upgrading.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Here we'll describe the recommended steps for upgrading a Horizon 2.x installation. -### Pre-requisites {#pre-requisites} +### Pre-requisites - An existing Horizon deployment consisting of one or more instances of Horizon. - All instances are on same 2.x version to begin. @@ -16,7 +16,7 @@ Here we'll describe the recommended steps for upgrading a Horizon 2.x installati - If [deployed direct on Docker daemon](./installing.mdx#containerized), you have command line access to the host that is running the Docker daemon. - If [deployed on Kubernetes with Helm chart](./installing.mdx#helm-chart-installation), you have kubectl and helm command line tools on your workstation and a user login with appropriate access levels to change resources in target namespace of Horizon deployment on the cluster. -### Assess current installation {#assess-current-installation} +### Assess current installation - Identify the list of all instances of Horizon that need to be upgraded. @@ -42,11 +42,11 @@ Here we'll describe the recommended steps for upgrading a Horizon 2.x installati - All instances should report the same version, if not, the system may be inconsistent, use this upgrade as opportunity to establish consistency and get them all on same version. -### Determine the target version for upgrade {#determine-the-target-version-for-upgrade} +### Determine the target version for upgrade Now that you know your current Horizon version, visit [Horizon Releases](https://github.com/stellar/go/releases) and choose the next greater version above your current version to upgrade. Follow steps [recommended by GitHub to compare releases](https://docs.github.com/en/repositories/releasing-projects-on-github/comparing-releases), click on the `Compare` dropdown of the chosen release, and then select your current release and GH will display the differences between versions, select the `Files changed` tab, and go to the `services/horizon/CHANGELOG.md`, it will highlight the new release notes for changes that have occurred between your current version and the new version you selected. Review this and look for any `Breaking Changes`, `State Rebuild` and `DB Schema Migration` sections for consideration, as the latter two will also mention expected time for the state rebuild or db migration to apply respectively. -### Install the new version {#install-the-new-version} +### Install the new version Now that you have indentified the new version and are aware of the potential impacts from upgrading to new version based on release notes, such as state rebuilds and db migrations, you are informed and ready to proceed with upgrade. @@ -95,7 +95,7 @@ A good strategy for upgrading Horizon and applicable to single or multi-instance -### Confirming the upgrade on single ingestion instance first {#confirming-the-upgrade-on-single-ingestion-instance-first} +### Confirming the upgrade on single ingestion instance first If you have [monitoring](./monitoring.mdx) infrastructure in place, then you have two options for assessing the upgrade status: @@ -122,7 +122,7 @@ If metrics and/or the Horizon 'status' url respones don't indicate healthy statu 2023/09/22 18:27:01 successfully applied 5 Horizon migrations ``` -### Upgrade all remaining instances {#upgrade-all-remaining-instances} +### Upgrade all remaining instances At this point, you have upgraded one ingesting instance to the new Horizon version, it has automatically updated the database if required and the instance is running with healthy status. Now, install the same Horizon software version on the remainder of instances, restarting each after the upgrade. For bare-metal and docker daemon installations that will likely be self explanatory on how to accomplish that for remainder of instances, on helm chart installations, run the helm upgrade again, setting the image tag and also restoring original `replicaCount`s: diff --git a/docs/data/horizon/api-reference/errors/error-handling.mdx b/docs/data/horizon/api-reference/errors/error-handling.mdx index bc51615d6..1f711da82 100644 --- a/docs/data/horizon/api-reference/errors/error-handling.mdx +++ b/docs/data/horizon/api-reference/errors/error-handling.mdx @@ -16,7 +16,7 @@ There are many possible error codes when executing these actions, and you can ty - Request adjustments: adjusting the request to resolve structural errors with queries or transaction submissions. Suppose you’ve included a bad parameter, malformed your XDR, or otherwise didn’t follow the endpoint’s specification. In these cases, resolve the error by referencing the details or result codes of the error response. - Polling and retrying: this is the recommended way to work around latency or congestion issues encountered along the pipeline between your computer and the Stellar network, which can sometimes happen due to the nature of distributed systems. -## Error Handling for Queries {#error-handling-for-queries} +## Error Handling for Queries Many `GET` requests have specific parameter requirements, and while the SDKs can help enforce them, you can still pass invalid arguments (for example, an asset string that isn’t [SEP-11](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0011.md#asset-trustlineasset) compatible) that error out every time. In this scenario, there’s nothing you can do aside from following the API specification. The `extras` field of the error response will often clue you in on where to look and what to look for. @@ -34,7 +34,7 @@ curl -s https://horizon-testnet.stellar.org/claimable_balances/0000 | jq '.extra Note that the SDKs make it a point to distinguish an invalid request (as above) versus a missing resource (a `404 Not Found`) (for example, the generic `NetworkError` versus a `NotFoundError` in the JavaScript SDK), where the latter might not be considered an error depending on your situation. -## Error Handling for Transaction Submissions {#error-handling-for-transaction-submissions} +## Error Handling for Transaction Submissions Horizon currently supports two types of transaction submission endpoints: @@ -45,16 +45,16 @@ Note that polling the transaction hash will return a 404 until it gets included There are some resolution strategies that are common between the 2 endpoints while others strategies are more endpoint specific. -### Request Adjustments {#request-adjustments} +### Request Adjustments Certain transaction submission failures also need adjustments to succeed. - If the XDR is malformed, or the transaction is otherwise invalid, you’ll encounter a `400 Bad Request` (for example, an invalid source account). Both transactions and their operations can be easily malformed or invalid: look at the `extras.result_codes` field for details and cross-reference them with the appropriate result codes documentation to determine specifics. - Transaction fees are also a safe adjustment by modifying the fees via a [fee-bump transaction](../../../../learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx) if you get a `tx_insufficient_fee` error. Refer to the [Insufficient Fees and Surge Pricing](#insufficient-fees-and-surge-pricing) section later in this document for more information on managing fees and strategies around it. -### Polling and Retrying Transactions {#polling-and-retrying-transactions} +### Polling and Retrying Transactions -#### Async Transaction Submission {#async-transaction-submission} +#### Async Transaction Submission Submissions using the `/transactions_async` endpoint return an immediate response back from Stellar-Core. There are different actions that clients can take based on the specific `tx_status` returned: @@ -108,7 +108,7 @@ server -#### Synchronous Transaction Submission {#synchronous-transaction-submission} +#### Synchronous Transaction Submission Due to the blocking nature of this endpoint, things are a little different compared to the asynchronous strategy. There are 3 possible scenarios that clients can encounter: @@ -124,7 +124,7 @@ Do note that resubmitting a transaction is only safe when it is unchanged - same ::: -### Example: Using Time Bounds {#example-using-time-bounds} +### Example: Using Time Bounds Timebounds are optional but **highly** recommended as they put a definitive time limit on the transaction's finality - after it times out, you will know for sure whether it made it into a ledger. For example, you submit a transaction, and it enters the queue of the Stellar network, but Horizon crashes while giving you a response. Uncertain about the transaction status, you resubmit the transaction (with no changes!) until either (a) Horizon comes back up to give you a reply or (b) your time bounds are exceeded. @@ -168,7 +168,7 @@ function submitTransaction(tx, timeout) { We assume the existence of a sleep implementation similar to the one [here](https://stackoverflow.com/a/39914235). Be sure to integrate backoff into your retry mechanism. In our example error-handling code above, we implement a simple linear backoff, but there are [plenty of recommendations](https://backoff-utils.readthedocs.io/en/latest/strategies.html#why-are-backoff-strategies-useful) for various other strategies. Backoff is important both for maintaining performance and avoiding rate-limiting issues. -### Example: Invalid Sequence Numbers {#example-invalid-sequence-numbers} +### Example: Invalid Sequence Numbers These errors typically occur when you have an outdated view of an account. This could be because multiple devices are using this account, you have concurrent submissions happening, or other reasons. The solution is relatively simple: retrieve the account details and try again with an updated sequence number. @@ -196,7 +196,7 @@ Despite the solution’s simplicity, things can go wrong fast if you don’t und Suppose you submit transactions from multiple places in your application simultaneously, and your user spammed a _Send Payment_ button a few times in their impatience. If you send the exact same payment transaction for each tap, naturally, only one will succeed. The others will fail with an invalid sequence number (`tx_bad_seq`), and if you resubmit blindly with an updated sequence number (as we do above), these payments will also succeed, resulting in more than one payment being made when only one was intended. So **be very careful when resubmitting transactions** that have been modified to work around an error. -## Managing specific Errors {#managing-specific-errors} +## Managing specific Errors Here, we will cover specific errors commonly encountered during transaction submission and direct you to the appropriate resolution. @@ -217,15 +217,15 @@ Here, we will cover specific errors commonly encountered during transaction subm | `FEE_BUMP_INNER_FAILED` | -13 | The inner transaction of a fee-bump transaction failed | | `BAD_SPONSORSHIP` | -14 | The sponsorship is not confirmed | -### Insufficient fees and surge pricing {#insufficient-fees-and-surge-pricing} +### Insufficient fees and surge pricing See the [Fees section](../../../../learn/fundamentals/fees-resource-limits-metering.mdx) -### Rate limiting {#rate-limiting} +### Rate limiting Horizon may rate limit requests and return `429 Too Many Requests` error when exceeding the rate limits. If using your own instance, you may want to either increase or disable rate limiting. If you're using a third-party Horizon instance, you may want to deploy your own to have more control over this configuration or send requests less frequently. -### Insufficient XLM balance {#insufficient-xlm-balance} +### Insufficient XLM balance Any transaction that would reduce an account’s balance to less than the minimum will be rejected with an `INSUFFICIENT_BALANCE` error. Likewise, lumen selling liabilities that would reduce an account’s balance to less than the minimum plus lumen selling liabilities will be rejected with an `INSUFFICIENT_BALANCE` error. diff --git a/docs/data/horizon/api-reference/resources/effects/types.mdx b/docs/data/horizon/api-reference/resources/effects/types.mdx index e58a36b77..8abd3bd16 100644 --- a/docs/data/horizon/api-reference/resources/effects/types.mdx +++ b/docs/data/horizon/api-reference/resources/effects/types.mdx @@ -8,7 +8,7 @@ import { AttributeTable } from "@site/src/components/AttributeTable"; There are eight groups of effect types. Each effect type has its own set of attributes. -### Account Effects {#account-effects} +### Account Effects @@ -42,7 +42,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Signer Effects {#signer-effects} +### Signer Effects @@ -61,7 +61,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Trustline Effects {#trustline-effects} +### Trustline Effects @@ -86,7 +86,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Trading Effects {#trading-effects} +### Trading Effects @@ -108,7 +108,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Data Effects {#data-effects} +### Data Effects @@ -127,7 +127,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Claimable Balance Effects {#claimable-balance-effects} +### Claimable Balance Effects @@ -146,7 +146,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Sponsorship Effects {#sponsorship-effects} +### Sponsorship Effects @@ -201,7 +201,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Liquidity Pool Effects {#liquidity-pool-effects} +### Liquidity Pool Effects @@ -229,7 +229,7 @@ There are eight groups of effect types. Each effect type has its own set of attr -### Miscellaneous Effects {#miscellaneous-effects} +### Miscellaneous Effects diff --git a/docs/data/horizon/horizon-providers.mdx b/docs/data/horizon/horizon-providers.mdx index 5dc68b193..704046896 100644 --- a/docs/data/horizon/horizon-providers.mdx +++ b/docs/data/horizon/horizon-providers.mdx @@ -3,7 +3,7 @@ sidebar_position: 70 title: Ecosystem Horizon Providers --- -## Ecosystem Horizon Providers {#ecosystem-horizon-providers} +## Ecosystem Horizon Providers :::info @@ -36,6 +36,6 @@ SDF provides a Horizon endpoint but it is rate-limited and subject to changes su | `Futurenet` | `https://horizon-futurenet.stellar.org` | `https://friendbot-futurenet.stellar.org` | [SDF](http://www.stellar.org) | | `Testnet` | `https://horizon-testnet.stellar.org` | `https://friendbot.stellar.org` | [SDF](http://www.stellar.org) | -## Run Your Own Horizon {#run-your-own-horizon} +## Run Your Own Horizon If you are interested in running your own Horizon, please checkout [this page](./admin-guide/overview.mdx). diff --git a/docs/data/hubble/README.mdx b/docs/data/hubble/README.mdx index 88bca51dd..92e20d2cf 100644 --- a/docs/data/hubble/README.mdx +++ b/docs/data/hubble/README.mdx @@ -3,13 +3,13 @@ title: Hubble Introduction sidebar_position: 0 --- -## What is Hubble? {#what-is-hubble} +## What is Hubble? Hubble is an open-source, publicly available dataset that provides a complete historical record of the Stellar network. Similar to Horizon, it ingests and presents the data produced by the Stellar network in a format that is easier to consume than the performance-oriented data representations used by Stellar Core. The dataset is hosted on BigQuery–meaning it is suitable for large, analytic workloads, historical data retrieval and complex data aggregation. **Hubble should not be used for real-time data retrieval and cannot submit transactions to the network.** For real time use cases, we recommend [running an API server](../horizon/admin-guide/README.mdx). This guide describes when to use Hubble and how to connect. To view the underlying data structures, queries and examples, use the [Viewing Metadata](./analyst-guide/viewing-metadata.mdx) and [Optimizing Queries](./analyst-guide/optimizing-queries.mdx) tutorials. -## Why Use Hubble? {#why-use-hubble} +## Why Use Hubble? Some questions are hard to answer with the Horizon API and its underlying PostgreSQL database. This is because its infrastructure is optimized for quick database reads and writes so that it can process online transactions. Horizon can accurately store the results of these smaller transactions, however it sacrifices the ability to execute complex queries easily. The Stellar Network’s data footprint has also increased exponentially, which is creating space constraints and performance issues for Horizon instances that store the full historical record. @@ -21,7 +21,7 @@ Users should be aware of the following limitations: - The database is updated in intraday batches. There is no guarantee for same-day data availability. - The SDF hosts a public instance of Hubble, and end users incur the cost to execute queries. Visit the [BigQuery Pricing Page](https://cloud.google.com/bigquery/pricing#analysis_pricing_models) to learn more. -## Why We Chose BigQuery {#why-we-chose-bigquery} +## Why We Chose BigQuery BigQuery is Google Cloud’s data warehouse that comes with some key features that fulfill Stellar’s analytic needs. diff --git a/docs/data/hubble/admin-guide/data-curation/architecture.mdx b/docs/data/hubble/admin-guide/data-curation/architecture.mdx index f2d5d6d22..001650067 100644 --- a/docs/data/hubble/admin-guide/data-curation/architecture.mdx +++ b/docs/data/hubble/admin-guide/data-curation/architecture.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import stellar_dbt_arch from "/img/hubble/stellar_dbt_architecture.png"; -## Architecture Overview {#architecture-overview} +## Architecture Overview diff --git a/docs/data/hubble/admin-guide/data-curation/getting-started.mdx b/docs/data/hubble/admin-guide/data-curation/getting-started.mdx index 936177bb7..dfd520ed1 100644 --- a/docs/data/hubble/admin-guide/data-curation/getting-started.mdx +++ b/docs/data/hubble/admin-guide/data-curation/getting-started.mdx @@ -7,9 +7,9 @@ sidebar_position: 20 [stellar/stellar-dbt-public docker images](https://hub.docker.com/r/stellar/stellar-dbt-public) -## Recommended Usage {#recommended-usage} +## Recommended Usage -### Docker Image {#docker-image} +### Docker Image Generally if you do not need to modify any of the stellar-dbt-public code, it is recommended that you use the [stellar/stellar-dbt-public docker images](https://hub.docker.com/r/stellar/stellar-dbt-public) @@ -19,7 +19,7 @@ Example to run locally with docker: docker run --platform linux/amd64 -ti stellar/stellar-dbt-public:latest ``` -### Import stellar-dbt-public as a dbt Package {#import-stellar-dbt-public-as-a-dbt-package} +### Import stellar-dbt-public as a dbt Package Alternatively, if you need to build your own models on top of stellar-dbt-public, you can import stellar-dbt-public as a dbt package into a separate dbt project. @@ -94,28 +94,28 @@ models: - Models from the stellar-dbt-public package/repo will now be available in your new dbt project -## Building and Running Locally {#building-and-running-locally} +## Building and Running Locally -### Clone the repo {#clone-the-repo} +### Clone the repo ``` git clone https://github.com/stellar/stellar-dbt-public ``` -### Install required python packages {#install-required-python-packages} +### Install required python packages ``` pip install --upgrade pip && pip install -r requirements.txt ``` -### Install required dbt packages {#install-required-dbt-packages} +### Install required dbt packages ``` dbt deps ``` -### Running dbt {#running-dbt} +### Running dbt - There are many useful commands that come with dbt which can be found in the [dbt documentation](https://docs.getdbt.com/reference/dbt-commands#available-commands) - stellar-dbt-public is designed to use the `dbt build` command which will `run` the model and `test` the model table output diff --git a/docs/data/hubble/admin-guide/data-curation/overview.mdx b/docs/data/hubble/admin-guide/data-curation/overview.mdx index 5adf654d6..b97d88254 100644 --- a/docs/data/hubble/admin-guide/data-curation/overview.mdx +++ b/docs/data/hubble/admin-guide/data-curation/overview.mdx @@ -7,7 +7,7 @@ Data curation in Hubble is done through [stellar-dbt-public](https://github.com/ It is worth noting that most users will not need to standup and run their own stellar-dbt-public instance. The Stellar Development Foundation provides public access to fully transformed Stellar network data through the public datasets and tables in GCP BigQuery. Instructions on how to access this data can be found in the [Connecting](../../analyst-guide/connecting.mdx) section. -## Why Run stellar-dbt-public? {#why-run-stellar-dbt-public} +## Why Run stellar-dbt-public? Running stellar-dbt-public within your own infrastructure provides a number of benefits. You can: diff --git a/docs/data/hubble/admin-guide/scheduling-and-orchestration/architecture.mdx b/docs/data/hubble/admin-guide/scheduling-and-orchestration/architecture.mdx index f174c0a81..21be8c3df 100644 --- a/docs/data/hubble/admin-guide/scheduling-and-orchestration/architecture.mdx +++ b/docs/data/hubble/admin-guide/scheduling-and-orchestration/architecture.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import stellar_etl_airflow_arch from "/img/hubble/stellar_etl_airflow_architecture.png"; -## Architecture Overview {#architecture-overview} +## Architecture Overview diff --git a/docs/data/hubble/admin-guide/scheduling-and-orchestration/getting-started.mdx b/docs/data/hubble/admin-guide/scheduling-and-orchestration/getting-started.mdx index b220feca9..52ae47ba8 100644 --- a/docs/data/hubble/admin-guide/scheduling-and-orchestration/getting-started.mdx +++ b/docs/data/hubble/admin-guide/scheduling-and-orchestration/getting-started.mdx @@ -9,13 +9,13 @@ import dbt_enriched_base_tables from "/img/hubble/dbt_enriched_base_tables.png"; [stellar-etl-airflow GitHub repository](https://github.com/stellar/stellar-etl-airflow/tree/master) -## GCP Account Setup {#gcp-account-setup} +## GCP Account Setup The Stellar Development Foundation runs Hubble in GCP using Composer and BigQuery. To follow the same deployment you will need to have access to GCP project. Instructions can be found in the [Get Started](https://cloud.google.com/docs/get-started) documentation from Google. Note: BigQuery and Composer should be available by default. If they are not you can find instructions for enabling them in the [BigQuery](https://cloud.google.com/bigquery?hl=en) or [Composer](https://cloud.google.com/composer?hl=en) Google documentation. -## Create GCP Composer Instance to Run Airflow {#create-gcp-composer-instance-to-run-airflow} +## Create GCP Composer Instance to Run Airflow Instructions on bringing up a GCP Composer instance to run Hubble can be found in the [Installation and Setup](https://github.com/stellar/stellar-etl-airflow?tab=readme-ov-file#installation-and-setup) section in the [stellar-etl-airflow](https://github.com/stellar/stellar-etl-airflow) repository. @@ -25,7 +25,7 @@ Hardware requirements can be very different depending on the Stellar network dat ::: -## Configuring GCP Composer Airflow {#configuring-gcp-composer-airflow} +## Configuring GCP Composer Airflow There are two things required for the configuration and setup of GCP Composer Airflow: @@ -34,17 +34,17 @@ There are two things required for the configuration and setup of GCP Composer Ai For more detailed instructions please see the [stellar-etl-airflow Installation and Setup](https://github.com/stellar/stellar-etl-airflow?tab=readme-ov-file#installation-and-setup) documentation. -### Uploading DAGs {#uploading-dags} +### Uploading DAGs Within the [stellar-etl-airflow](https://github.com/stellar/stellar-etl-airflow) repo there is an [upload_static_to_gcs.sh](https://github.com/stellar/stellar-etl-airflow/blob/master/upload_static_to_gcs.sh) shell script that will upload all the DAGs and schemas into your Composer Airflow bucket. This can also be done using the [gcloud CLI or console](https://cloud.google.com/storage/docs/uploading-objects) and manually selecting the dags and schemas you wish to upload. -### Configuring Airflow Variables {#configuring-airflow-variables} +### Configuring Airflow Variables Please see the [Airflow Variables Explanation](https://github.com/stellar/stellar-etl-airflow?tab=readme-ov-file#airflow-variables-explanation) documentation for more information about what should and needs to be configured. -## Running the DAGs {#running-the-dags} +## Running the DAGs To run a DAG all you have to do is toggle the DAG on/off as seen below @@ -52,11 +52,11 @@ To run a DAG all you have to do is toggle the DAG on/off as seen below More information about each DAG can be found in the [DAG Diagrams](https://github.com/stellar/stellar-etl-airflow?tab=readme-ov-file#dag-diagrams) documentation. -## Available DAGs {#available-dags} +## Available DAGs More information can be found [here](https://github.com/stellar/stellar-etl-airflow/blob/master/README.md#public-dags) -### History Table Export DAG {#history-table-export-dag} +### History Table Export DAG [This DAG](https://github.com/stellar/stellar-etl-airflow/blob/master/dags/history_tables_dag.py): @@ -66,7 +66,7 @@ More information can be found [here](https://github.com/stellar/stellar-etl-airf -### State Table Export DAG {#state-table-export-dag} +### State Table Export DAG [This DAG](https://github.com/stellar/stellar-etl-airflow/blob/master/dags/state_table_dag.py) @@ -75,7 +75,7 @@ More information can be found [here](https://github.com/stellar/stellar-etl-airf -### DBT Enriched Base Tables DAG {#dbt-enriched-base-tables-dag} +### DBT Enriched Base Tables DAG [This DAG](https://github.com/stellar/stellar-etl-airflow/blob/master/dags/dbt_enriched_base_tables_dag.py) diff --git a/docs/data/hubble/admin-guide/scheduling-and-orchestration/overview.mdx b/docs/data/hubble/admin-guide/scheduling-and-orchestration/overview.mdx index a7a1b00b1..6890d8dd9 100644 --- a/docs/data/hubble/admin-guide/scheduling-and-orchestration/overview.mdx +++ b/docs/data/hubble/admin-guide/scheduling-and-orchestration/overview.mdx @@ -7,7 +7,7 @@ Hubble uses [stellar-etl-airflow](https://github.com/stellar/stellar-etl-airflow It is worth noting that most users will not need to standup and run their own Hubble. The Stellar Development Foundation provides public access to the data through the public datasets and tables in GCP BigQuery. Instructions on how to access this data can be found in the [Connecting](../../analyst-guide/connecting.mdx) section. -## Why Run stellar-etl-ariflow? {#why-run-stellar-etl-ariflow} +## Why Run stellar-etl-ariflow? Running stellar-etl-airflow within your own infrastructure provides a number of benefits. You can: diff --git a/docs/data/hubble/admin-guide/source-system-ingestion/architecture.mdx b/docs/data/hubble/admin-guide/source-system-ingestion/architecture.mdx index 98c5ff7a2..36abdd1aa 100644 --- a/docs/data/hubble/admin-guide/source-system-ingestion/architecture.mdx +++ b/docs/data/hubble/admin-guide/source-system-ingestion/architecture.mdx @@ -6,7 +6,7 @@ sidebar_position: 10 import stellar_arch from "/img/hubble/stellar_overall_architecture.png"; import stellar_etl_arch from "/img/hubble/stellar_etl_architecture.png"; -## Architecture Overview {#architecture-overview} +## Architecture Overview diff --git a/docs/data/hubble/admin-guide/source-system-ingestion/getting-started.mdx b/docs/data/hubble/admin-guide/source-system-ingestion/getting-started.mdx index ccd5942c6..8b09a67a7 100644 --- a/docs/data/hubble/admin-guide/source-system-ingestion/getting-started.mdx +++ b/docs/data/hubble/admin-guide/source-system-ingestion/getting-started.mdx @@ -7,7 +7,7 @@ sidebar_position: 20 [stellar/stellar-etl docker images](https://hub.docker.com/r/stellar/stellar-etl) -## Recommended Usage {#recommended-usage} +## Recommended Usage Generally if you do not need to modify any of the stellar-etl code, it is recommended that you use the [stellar/stellar-etl docker images](https://hub.docker.com/r/stellar/stellar-etl). @@ -17,20 +17,20 @@ Example to run locally with docker: docker run --platform linux/amd64 -ti stellar/stellar-etl:latest ``` -## Building and Running Locally {#building-and-running-locally} +## Building and Running Locally -### Install Golang {#install-golang} +### Install Golang - Make sure your golang version >= `1.22.1` - Instructions to install golang can be found at [go.dev/doc/install](https://go.dev/doc/install) -### Clone the repo {#clone-the-repo} +### Clone the repo ``` git clone https://github.com/stellar/stellar-etl ``` -### Build stellar-etl {#build-stellar-etl} +### Build stellar-etl - Run `go build` in the cloned stellar-etl repo @@ -38,7 +38,7 @@ git clone https://github.com/stellar/stellar-etl go build ``` -### Run stellar-etl {#run-stellar-etl} +### Run stellar-etl - A `stellar-etl` executable should have been created in your stellar-etl repo - Example stellar-etl command: @@ -54,9 +54,9 @@ This should create a `exported_ledgers.txt` file with the output of ledgers from {"base_fee":100,"base_reserve":100000000,"closed_at":"2024-02-06T17:34:17Z","failed_transaction_count":0,"fee_pool":0,"id":47244640256,"ledger_hash":"5b9ac11c6040f4e2fa6a120b3dee9a4b338b7a25bcb8437dab0c0a5c557a41f5","ledger_header":"AAAAAPfImzXFD3TcaerNndqOnsnxrza2opKLd2GcG+tfXKjUK858NP5gM0pneHF0nRowsJBAzMwWDx0+tmbYIZkIT+8AAAAAZcJtmQAAAAAAAAABAAAAANVyadliUPdJbQeb4ug1Ejbv/+jTnC4Gv6uxQh8X/GccAAAAQDhZKPKBdeD4Sthcu+EsuzEtSyiXzXkHboOsgYT1tuV/juZyKqgrsVmg+RmMoRun+NKCdcB8LV9gaehiFm+XDgnfP2GYBKkv20BXGS3EPddI6neK3FK8SYzoBSTAFLgRGfBr+YHFQTIEJ0Y81WEOYClgyjOER8vd4qMQb3gM9nRvAAAACw3gtrOnZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkBfXhAAAAAGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","max_tx_set_size":100,"operation_count":0,"previous_ledger_hash":"f7c89b35c50f74dc69eacd9dda8e9ec9f1af36b6a2928b77619c1beb5f5ca8d4","protocol_version":0,"sequence":11,"soroban_fee_write_1kb":0,"successful_transaction_count":0,"total_coins":1000000000000000000,"transaction_count":0,"tx_set_operation_count":"0"} ``` -## stellar-etl Commands {#stellar-etl-commands} +## stellar-etl Commands -### export_ledgers {#export_ledgers} +### export_ledgers ``` stellar-etl export_ledgers --start-ledger 1000 --end-ledger 500000 --output exported_ledgers.txt @@ -64,7 +64,7 @@ stellar-etl export_ledgers --start-ledger 1000 --end-ledger 500000 --output expo This command exports ledgers within the provided range. -### export_transactions {#export_transactions} +### export_transactions ``` stellar-etl export_transactions --start-ledger 1000 --end-ledger 500000 --output exported_transactions.txt @@ -72,7 +72,7 @@ stellar-etl export_transactions --start-ledger 1000 --end-ledger 500000 --output This command exports transactions within the provided range. -### export_operations {#export_operations} +### export_operations ``` stellar-etl export_operations --start-ledger 1000 --end-ledger 500000 --output exported_operations.txt @@ -80,7 +80,7 @@ stellar-etl export_operations --start-ledger 1000 --end-ledger 500000 --output e This command exports operations within the provided range. -### export_effects {#export_effects} +### export_effects ``` stellar-etl export_effects --start-ledger 1000 --end-ledger 500000 --output exported_effects.txt @@ -88,7 +88,7 @@ stellar-etl export_effects --start-ledger 1000 --end-ledger 500000 --output expo This command exports effects within the provided range. -### export_assets {#export_assets} +### export_assets ``` stellar-etl export_assets --start-ledger 1000 --end-ledger 500000 --output exported_assets.txt @@ -96,7 +96,7 @@ stellar-etl export_assets --start-ledger 1000 --end-ledger 500000 --output expor Exports the assets that are created from payment operations over a specified ledger range. -### export_trades {#export_trades} +### export_trades ``` stellar-etl export_trades --start-ledger 1000 --end-ledger 500000 --output exported_trades.txt @@ -104,7 +104,7 @@ stellar-etl export_trades --start-ledger 1000 --end-ledger 500000 --output expor Exports trade data within the specified range to an output file -### export_diagnostic_events {#export_diagnostic_events} +### export_diagnostic_events ``` stellar-etl export_diagnostic_events --start-ledger 1000 --end-ledger 500000 --output export_diagnostic_events.txt @@ -112,7 +112,7 @@ stellar-etl export_diagnostic_events --start-ledger 1000 --end-ledger 500000 --o Exports diagnostic events data within the specified range to an output file -### export_ledger_entry_changes {#export_ledger_entry_changes} +### export_ledger_entry_changes ``` stellar-etl export_ledger_entry_changes --start-ledger 1000 --end-ledger 500000 --output exported_changes_folder/ diff --git a/docs/data/hubble/admin-guide/source-system-ingestion/overview.mdx b/docs/data/hubble/admin-guide/source-system-ingestion/overview.mdx index 692168c76..f41d45095 100644 --- a/docs/data/hubble/admin-guide/source-system-ingestion/overview.mdx +++ b/docs/data/hubble/admin-guide/source-system-ingestion/overview.mdx @@ -7,7 +7,7 @@ Stellar network data ingestion in Hubble is done through [stellar-etl](https://g It is worth noting that most users will not need to standup and run their own stellar-etl instance. The Stellar Development Foundation provides public access to fully transformed Stellar network data through the public datasets and tables in GCP BigQuery. Instructions on how to access this data can be found in the [Connecting](../../analyst-guide/connecting.mdx) section. -## Why Run stellar-etl? {#why-run-stellar-etl} +## Why Run stellar-etl? Running stellar-etl within your own infrastructure provides a number of benefits. You can: diff --git a/docs/data/hubble/admin-guide/visualization/getting-started.mdx b/docs/data/hubble/admin-guide/visualization/getting-started.mdx index b7f009768..8600d0495 100644 --- a/docs/data/hubble/admin-guide/visualization/getting-started.mdx +++ b/docs/data/hubble/admin-guide/visualization/getting-started.mdx @@ -7,11 +7,11 @@ This sections goes through using [Google's Looker Studio](https://lookerstudio.g There are many other free/paid visualization tools available. Hubble is compatible with any visualization tool with a BigQuery connector. -## Creating your first visualization {#creating-your-first-visualization} +## Creating your first visualization - Follow [Google's Quick Start Guide](https://support.google.com/looker-studio/answer/9171315?hl=en) -## Hooking Up Data Sources {#hooking-up-data-sources} +## Hooking Up Data Sources The following will use the Stellar Development Foundations public datasets and tables as an example to hook up data sources to Looker Studio @@ -25,7 +25,7 @@ The following will use the Stellar Development Foundations public datasets and t When you create a new report you should be able to now access data from `crypto-stellar.crypto_stellar.
` -## Making your first pie chart {#making-your-first-pie-chart} +## Making your first pie chart - Click `Create` in [Google's Looker Studio](https://lookerstudio.google.com/u/0/navigation/reporting) - Click `Report` diff --git a/docs/data/hubble/analyst-guide/connecting.mdx b/docs/data/hubble/analyst-guide/connecting.mdx index fb750321a..2224d3384 100644 --- a/docs/data/hubble/analyst-guide/connecting.mdx +++ b/docs/data/hubble/analyst-guide/connecting.mdx @@ -9,13 +9,13 @@ BigQuery offers multiple connection methods to Hubble. This guide details three - [BigQuery SDK](#bigquery-sdk) - developers that need to integrate data into applications - [Looker Studio](#looker-studio) - business people that need to visualize data -## Prerequisites {#prerequisites} +## Prerequisites To access Hubble, you will need a Google Cloud Project with billing and the BigQuery API enabled. For more information, please follow the instructions provided by [Google Cloud](https://cloud.google.com/bigquery/docs/quickstarts/query-public-dataset-console). Google does provide a BigQuery Sandbox for free that allows users to explore datasets in a limited capacity. -## BigQuery UI {#bigquery-ui} +## BigQuery UI 1. From a browser, open the [crypto-stellar.crypto_stellar](http://console.cloud.google.com/bigquery?ws=!1m4!1m3!3m2!1scrypto-stellar!2scrypto_stellar) dataset. 2. This will open the public dataset `crypto_stellar`, where you can browse its contents in the **Explorer** pane. @@ -43,7 +43,7 @@ order by balance desc; This query will return the XLM balances for all Stellar wallet addresses, ordered from largest to smallest amounts. -## BigQuery SDK {#bigquery-sdk} +## BigQuery SDK There are multiple [BigQuery API Client Libraries](https://cloud.google.com/bigquery/docs/reference/libraries) available. @@ -121,7 +121,7 @@ for row in query_job: There are various ways to extract and load data using BigQuery. See the [BigQuery Client Documentation](https://cloud.google.com/python/docs/reference/bigquery/latest/google.cloud.bigquery.client.Client) for more information. -## Looker Studio {#looker-studio} +## Looker Studio [Looker Studio](https://cloud.google.com/looker-studio) is a business intelligence tool that can be used to connect to and visualize data from the Hubble dataset. diff --git a/docs/data/hubble/analyst-guide/creating-visualizations.mdx b/docs/data/hubble/analyst-guide/creating-visualizations.mdx index 6aad7b8ca..96f78e954 100644 --- a/docs/data/hubble/analyst-guide/creating-visualizations.mdx +++ b/docs/data/hubble/analyst-guide/creating-visualizations.mdx @@ -31,15 +31,15 @@ By the end of the tutorial you will have created two graphs that will help visua As you can see, persistent contract data entries account for roughly 25% of all contract data entries with the rest being temporary. There are also a lot more expired temporary contract data entries. This is expected because temporay entries cannot be bumped whereas persistent entries can be bumped/restored. For more information, you can read about [State Archival and the Contract Data Lifecycle](https://developers.stellar.org/docs/learn/encyclopedia/storage/state-archival#contract-data-type-descriptions). -## Prerequisites {#prerequisites} +## Prerequisites 1. Make sure you have connected to Hubble by following the instructions in the [Connecting](./connecting.mdx) page 2. You have access to [Google Looker Studio](https://cloud.google.com/looker-studio?hl=en) 3. You have read and understand the general [Best Practices](https://developers.stellar.org/docs/data/hubble/analyst-guide/optimizing-queries#best-practices) for querying BigQuery data -## Create a Report in Looker Studio {#create-a-report-in-looker-studio} +## Create a Report in Looker Studio -### Attach Data Sources to Looker Studio {#attach-data-sources-to-looker-studio} +### Attach Data Sources to Looker Studio 1. Select `Create --> Data source` @@ -54,7 +54,7 @@ As you can see, persistent contract data entries account for roughly 25% of all -### Create a New Report (Dashboard) {#create-a-new-report-dashboard} +### Create a New Report (Dashboard) 1. Select `Create --> Report` @@ -80,7 +80,7 @@ As you can see, persistent contract data entries account for roughly 25% of all -### Use Custom SQL to Create a Chart {#use-custom-sql-to-create-a-chart} +### Use Custom SQL to Create a Chart 1. In your report, click `Add Data` which will be near the bottom right of your window @@ -147,7 +147,7 @@ order by 1 desc, 2 -### Applying a Global Filter {#applying-a-global-filter} +### Applying a Global Filter 1. Click `+Add quick filter` to apply a filter throughout the whole report diff --git a/docs/data/hubble/analyst-guide/optimizing-queries.mdx b/docs/data/hubble/analyst-guide/optimizing-queries.mdx index 06f0d4b58..e7cb9323c 100644 --- a/docs/data/hubble/analyst-guide/optimizing-queries.mdx +++ b/docs/data/hubble/analyst-guide/optimizing-queries.mdx @@ -7,9 +7,9 @@ Hubble has terabytes of data to explore—that’s a lot of data! With acces One of the strengths of BigQuery is also its pitfall: you have access to tremendous compute capabilities, but you pay for what you use. If you fine-tune your queries, you will have access to powerful insights at the fraction of the cost of maintaining a data warehouse yourself. It is, however, easy to incur burdensome costs if you are not careful. -## Best Practices {#best-practices} +## Best Practices -### Pay attention to table structure. {#pay-attention-to-table-structure} +### Pay attention to table structure. Large tables are partitioned and clustered according to common access patterns. Prune only the partitions you need, and filter or aggregate by clustered fields when possible. @@ -17,7 +17,7 @@ Joining tables on strings is expensive. Refrain from joining on string keys if y Read the docs on [Viewing Metadata](./viewing-metadata.mdx) to learn more about table metadata. -#### Example - Profiling Operation Types {#example---profiling-operation-types} +#### Example - Profiling Operation Types Let’s say you wanted to profile the [types of operations](../../../learn/fundamentals/transactions/list-of-operations.mdx) submitted to the Stellar Network monthly. ======== Let’s say you wanted to profile the [types of operations](../../../learn/fundamentals/transactions/list-of-operations.mdx) submitted to the Stellar Network monthly. @@ -84,11 +84,11 @@ By pruning partitions and aggregating on a clustered field, the query processing | Improved Query 1 | 83.06 GB | $0.415 | | Improved Query 2 | 54.8 GB | $0.274 | -### Be as specific as possible. {#be-as-specific-as-possible} +### Be as specific as possible. Do not write `SELECT *` statements unless you need every column returned in the query response. Since BigQuery is a columnar database, it can skip reading data entirely if the columns are not included in the select statement. The wider the table is, the more crucial it is to select _only_ what you need. -#### Example - Transaction Fees {#example---transaction-fees} +#### Example - Transaction Fees Let’s say you needed to view the fees for all transactions submitted in May 2023. What happens if you write a `SELECT *`? @@ -142,7 +142,7 @@ The BigQuery console lets you preview table data for free, which is the equivale ::: -### Filter early. {#filter-early} +### Filter early. When writing complex queries, filter the data as early as possible. Push `WHERE` and `GROUP BY` clauses up in the query to reduce the amount of data scanned. @@ -154,11 +154,11 @@ When writing complex queries, filter the data as early as possible. Push `WHERE` Push transformations and mathematical functions to the end of the query when possible. Functions like `TRIM()`, `CAST()`, `SUM()`, and `REGEXP_*` are resource intensive and should only be applied to final table results. -## Estimating Costs {#estimating-costs} +## Estimating Costs If you need to estimate costs before running a query, there are several options available to you: -### BigQuery Console {#bigquery-console} +### BigQuery Console The BigQuery Console comes with a built-in query validator. It verifies query syntax and provides an estimate of the number of bytes processed. The validator can be found in the upper right hand corner of the Query Editor, next to the green checkmark. @@ -187,7 +187,7 @@ The validator estimates that 51.95MB of data will be read. 0.00005195 TB \* $5 = $0.000259. _That’s a cheap query!_ -### dryRun Config Parameter {#dryrun-config-parameter} +### dryRun Config Parameter If you are submitting a query through a [BigQuery client library](https://cloud.google.com/bigquery/docs/reference/libraries), you can perform a dry run to estimate the total bytes processed before submitting the query job. diff --git a/docs/data/hubble/analyst-guide/queries-for-horizon-like-data.mdx b/docs/data/hubble/analyst-guide/queries-for-horizon-like-data.mdx index 0dc2d364d..d2e3068bb 100644 --- a/docs/data/hubble/analyst-guide/queries-for-horizon-like-data.mdx +++ b/docs/data/hubble/analyst-guide/queries-for-horizon-like-data.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 [Horizon](../../horizon/README.mdx) and [RPC](../../rpc/README.mdx) both provide API endpoints to retrieve data from the Stellar network. The following example queries retrieve the same data by using Hubble with the added benefit of being able to return historical data. -## Accounts {#accounts} +## Accounts [horizon/accounts](../../horizon/api-reference/resources/accounts/README.mdx) @@ -13,7 +13,7 @@ Users interact with the Stellar network through accounts. Everything else in the Learn more about [accounts](../../../learn/glossary.mdx#account). -### General account information and XLM balance {#general-account-information-and-xlm-balance} +### General account information and XLM balance ```sql select @@ -35,7 +35,7 @@ where true order by closed_at desc ``` -### Non-XLM asset balance information {#non-xlm-asset-balance-information} +### Non-XLM asset balance information ```sql select @@ -54,7 +54,7 @@ where true order by closed_at desc ``` -### Account signer information {#account-signer-information} +### Account signer information ```sql select @@ -70,7 +70,7 @@ where true order by closed_at desc ``` -### List all accounts {#list-all-accounts} +### List all accounts ```sql select @@ -81,7 +81,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Transactions {#retrieve-an-accounts-transactions} +### Retrieve an Account’s Transactions ```sql select @@ -101,7 +101,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Operations {#retrieve-an-accounts-operations} +### Retrieve an Account’s Operations ```sql select @@ -120,7 +120,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Payments {#retrieve-an-accounts-payments} +### Retrieve an Account’s Payments ```sql select @@ -147,7 +147,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Effects {#retrieve-an-accounts-effects} +### Retrieve an Account’s Effects ```sql select @@ -172,7 +172,7 @@ where true limit 1000 ``` -### Retrieve an Account’s Offers {#retrieve-an-accounts-offers} +### Retrieve an Account’s Offers ```sql select @@ -188,7 +188,7 @@ where true and seller_id= ``` -### Retrieve an Account’s Trades {#retrieve-an-accounts-trades} +### Retrieve an Account’s Trades ```sql with selling_side as ( @@ -242,7 +242,7 @@ union_data as ( select * from union_data ``` -## Assets {#assets} +## Assets [horizon/assets](../../horizon/api-reference/resources/assets/README.mdx) @@ -250,7 +250,7 @@ Assets are representations of value issued on the Stellar network. An asset cons Learn more about [assets](../../../learn/glossary.mdx#asset). -### List all Assets {#list-all-assets} +### List all Assets ```sql with assets as ( @@ -320,7 +320,7 @@ from assets join claimable_balances on true ``` -### Getting Stellar Asset Contract Information for an Asset {#getting-stellar-asset-contract-information-for-an-asset} +### Getting Stellar Asset Contract Information for an Asset ```sql select @@ -332,13 +332,13 @@ where true and balance != "" ``` -## Claimable Balances {#claimable-balances} +## Claimable Balances [horizon/claimable_balances](../../horizon/api-reference/resources/claimablebalances/README.mdx) A Claimable Balance represents the transfer of ownership of some amount of an asset. Claimable balances provide a mechanism for setting up a payment which can be claimed in the future. This allows you to make payments to accounts which are currently not able to accept them. -### List All Claimable Balances {#list-all-claimable-balances} +### List All Claimable Balances ```sql current_claimable_balances as ( @@ -370,7 +370,7 @@ where true --and claimants.destination = ``` -### Retrieve a Claimable Balance {#retrieve-a-claimable-balance} +### Retrieve a Claimable Balance ```sql with assets as ( @@ -411,7 +411,7 @@ where true and balance_id = ``` -### Retrieve Related Operations and Transactions {#retrieve-related-operations-and-transactions} +### Retrieve Related Operations and Transactions ```sql select @@ -425,13 +425,13 @@ where true and closed_at between and ``` -## Effects {#effects} +## Effects [horizon/effects](../../horizon/api-reference/resources/effects/README.mdx) Effects represent specific changes that occur in the ledger as a result of successful operations, but are not necessarily directly reflected in the ledger or history, as transactions and operations are. -### List All Effects {#list-all-effects} +### List All Effects ```sql select @@ -448,7 +448,7 @@ where true and closed_at between and ``` -## Ledgers {#ledgers} +## Ledgers [horizon/ledgers](../../horizon/api-reference/resources/ledgers/README.mdx) @@ -456,7 +456,7 @@ Each ledger stores the state of the network at a point in time and contains all Learn more about [ledgers](../../../learn/glossary.mdx#ledger). -### List All Ledgers {#list-all-ledgers} +### List All Ledgers ```sql select @@ -468,7 +468,7 @@ where true and closed_at between and ``` -### Retrieve a Ledger’s Transactions and Operations {#retrieve-a-ledgers-transactions-and-operations} +### Retrieve a Ledger’s Transactions and Operations ```sql select @@ -481,7 +481,7 @@ where true and closed_at between and ``` -### Retrieve a Ledger’s Payments {#retrieve-a-ledgers-payments} +### Retrieve a Ledger’s Payments ```sql select @@ -495,13 +495,13 @@ where true and closed_at between and ``` -## Liquidity Pools {#liquidity-pools} +## Liquidity Pools [horizon/liquidity_pools](../../horizon/api-reference/resources/liquiditypools/README.mdx) Liquidity Pools provide a simple, non-interactive way to trade large amounts of capital and enable high volumes of trading. -### List Liquidity Pools {#list-liquidity-pools} +### List Liquidity Pools ```sql select @@ -516,7 +516,7 @@ from `crypto-stellar.crypto_stellar_dbt.liquidity_pools_current` where true ``` -### Retrieve a Liquidity Pool {#retrieve-a-liquidity-pool} +### Retrieve a Liquidity Pool ```sql select @@ -532,7 +532,7 @@ where true and liquidity_pool_id = ``` -### Retrieve a Liquidity Pool’s Transactions and Operations {#retrieve-a-liquidity-pools-transactions-and-operations} +### Retrieve a Liquidity Pool’s Transactions and Operations ```sql select @@ -544,7 +544,7 @@ where true and liquidity_pool_id = ``` -### Retrieve a Liquidity Pool’s Related Trades {#retrieve-a-liquidity-pools-related-trades} +### Retrieve a Liquidity Pool’s Related Trades ```sql select @@ -557,7 +557,7 @@ where true and selling_liquidity_pool_id = ``` -## Offers {#offers} +## Offers [horizon/offers](../../horizon/api-reference/resources/offers/README.mdx) @@ -565,7 +565,7 @@ Offers are statements about how much of an asset an account wants to buy or sell Learn more about [offers](../../../learn/glossary.mdx#decentralized-exchange). -### List All Offers {#list-all-offers} +### List All Offers ```sql select @@ -582,7 +582,7 @@ where true and closed_at between and ``` -### Retrieve an Offer {#retrieve-an-offer} +### Retrieve an Offer ```sql select @@ -598,7 +598,7 @@ where true and closed_at between and ``` -### Retrieve an Offer’s Trades {#retrieve-an-offers-trades} +### Retrieve an Offer’s Trades ```sql select @@ -612,7 +612,7 @@ where true --and buying_offer_id = ``` -## Operations {#operations} +## Operations [horizon/operations](../../horizon/api-reference/resources/operations/README.mdx) @@ -620,7 +620,7 @@ Operations are objects that represent a desired change to the ledger: payments, Each of Stellar’s operations have a unique operation object. -### List All Operations {#list-all-operations} +### List All Operations ```sql select @@ -638,7 +638,7 @@ where true and closed_at between and ``` -### List All Payments {#list-all-payments} +### List All Payments ```sql select @@ -657,7 +657,7 @@ where true and closed_at between and ``` -### Retrieve an Operation {#retrieve-an-operation} +### Retrieve an Operation ```sql select @@ -670,7 +670,7 @@ where true and closed_at between and ``` -### Retrieve an Operation’s Effects {#retrieve-an-operations-effects} +### Retrieve an Operation’s Effects ```sql select @@ -683,7 +683,7 @@ where true and closed_at between and ``` -## Trades {#trades} +## Trades [horizon/trades](../../horizon/api-reference/resources/trades/README.mdx) @@ -693,7 +693,7 @@ A trade occurs between two parties—`base` and `counter`. Which is which is eit Learn more about [trades](../../../learn/glossary.mdx#decentralized-exchange). -### List All Trades {#list-all-trades} +### List All Trades ```sql select @@ -719,7 +719,7 @@ where true and closed_at between and ``` -## Transactions {#transactions} +## Transactions [horizon/transactions](../../horizon/api-reference/resources/transactions/README.mdx) @@ -727,7 +727,7 @@ Transactions are commands that modify the ledger state and consist of one or mor Learn more about [transactions](../../../learn/glossary.mdx#transaction). -### List All Transactions {#list-all-transactions} +### List All Transactions ```sql select @@ -744,7 +744,7 @@ where true and closed_at between and ``` -### Retrieve a Transaction {#retrieve-a-transaction} +### Retrieve a Transaction ```sql select @@ -761,7 +761,7 @@ where true and closed_at between and ``` -### Retrieve a Transaction’s Operations {#retrieve-a-transactions-operations} +### Retrieve a Transaction’s Operations ```sql select @@ -779,13 +779,13 @@ where true and closed_at between and ``` -## Trade Aggregations {#trade-aggregations} +## Trade Aggregations [horizon/trade_aggregations](../../horizon/api-reference/aggregations/trade-aggregations/README.mdx) A trade aggregation represents aggregated statistics on an asset pair (base and counter) for a specific time period. Trade aggregations are useful to developers of trading clients and provide historical trade data. -### List Trade Aggregations {#list-trade-aggregations} +### List Trade Aggregations ```sql select @@ -807,13 +807,13 @@ where true group by 1,2,3,4,5 ``` -## Fee Stats {#fee-stats} +## Fee Stats [horizon/fee-stats](../../horizon/api-reference/aggregations/fee-stats/README.mdx) Fee stats are used to predict what fee to set for a transaction before submitting it to the network. -### Retrieve Fee Stats {#retrieve-fee-stats} +### Retrieve Fee Stats ```sql select @@ -826,7 +826,7 @@ where true and day_agg between and ``` -## getEvents {#getevents} +## getEvents [rpc/getEvents](../../rpc/api-reference/methods/getEvents.mdx) @@ -844,13 +844,13 @@ where true and closed_at between and ``` -## getLedgerEntries {#getledgerentries} +## getLedgerEntries [rpc/getLedgerEntries](../../rpc/api-reference/methods/getLedgerEntries.mdx) Enables the retrieval of various ledger states, such as accounts, trustlines, offers, data, claimable balances, and liquidity pools. It also provides direct access to inspect a contract's current state, its code, or any other ledger entry -### Contract Data Entries {#contract-data-entries} +### Contract Data Entries ```sql select @@ -863,7 +863,7 @@ where true and ledger_key_hash = ``` -### Contract Code Entries {#contract-code-entries} +### Contract Code Entries ```sql select @@ -874,7 +874,7 @@ where true and ledger_key_hash = ``` -## getTransaction {#gettransaction} +## getTransaction [rpc/getTransaction](../../rpc/api-reference/methods/getTransaction.mdx) diff --git a/docs/data/hubble/analyst-guide/viewing-metadata.mdx b/docs/data/hubble/analyst-guide/viewing-metadata.mdx index b76e67e8f..bbd3717b9 100644 --- a/docs/data/hubble/analyst-guide/viewing-metadata.mdx +++ b/docs/data/hubble/analyst-guide/viewing-metadata.mdx @@ -7,7 +7,7 @@ Hubble publishes metadata which can help users determine which tables to query, There are two ways to access this information: -## BigQuery Explorer {#bigquery-explorer} +## BigQuery Explorer When accessing Hubble from its starred link, the Explorer pane will load metadata about the `crypto-stellar.crypto_stellar` dataset. @@ -17,7 +17,7 @@ Use the Toggle to view the contents of the Dataset. Clicking a table name will l - _Details_ - general information about the table itself, including partitioning, clustering and table size. Viewing details helps with query optimization - _Preview_ - raw sample data from the table. The data presented is the equivalent of running a `SELECT *` statement -## INFORMATION_SCHEMA {#information_schema} +## INFORMATION_SCHEMA BigQuery supports read-only, system-defined views that provide metadata information about BigQuery objects. The views can be queried via SQL from the BigQuery UI or Client Libraries. diff --git a/docs/data/hubble/analytics-platforms.mdx b/docs/data/hubble/analytics-platforms.mdx index 449590b86..ca3fe07fe 100644 --- a/docs/data/hubble/analytics-platforms.mdx +++ b/docs/data/hubble/analytics-platforms.mdx @@ -3,7 +3,7 @@ sidebar_position: 1000 title: Ecosystem Data Analytics Platforms --- -## Ecosystem Data Analytics Platforms {#ecosystem-data-analytics-platforms} +## Ecosystem Data Analytics Platforms The following is a list of data analytics platforms that make a complete historical record of Pubnet Stellar network data available. @@ -12,10 +12,10 @@ The following is a list of data analytics platforms that make a complete histori | [Dune](https://docs.dune.com/home) | [Access](https://dune.com/) | [Stellar Dashboard](https://dune.com/scoffie/stellar) | | [Ortege](https://www.ortege.ai/) | [Access](https://app.ortege.ai/login/) | | -## SDF Provided Data Analytics {#sdf-provided-data-analytics} +## SDF Provided Data Analytics SDF provides a publicly available dataset with a complete historical record of Stellar network data available. Please see the [Analyst Guide](./analyst-guide) for more information. -## Run Your Own Hubble {#run-your-own-hubble} +## Run Your Own Hubble If you are interested in running your own Hubble, please checkout the [Admin Guide](./admin-guide). diff --git a/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx b/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx index d0e3a2342..92b0b409d 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/accounts.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | account_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.accounts) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx b/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx index 03d9cd89e..430d0b02b 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/claimable-balances.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | asset_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.claimable_balances) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx b/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx index 4b55ebda4..db511097c 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/contract-code.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | last_modified_ledger, contract_code_hash | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.contract_code) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx b/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx index 570b84468..da0370de6 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/contract-data.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | last_modified_ledger, contract_id | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.contract_data) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx b/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx index 6b430d76a..3131a564b 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/enriched-history-operations.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | ledger_sequence, transaction_id, op_account_id, type | | Documentation | [dbt_docs](http://www.stellar-dbt-docs.com/#!/model/model.stellar_dbt_public.enriched_history_operations) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Source Table | Notes | | --- | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx index 93b104350..8d792ebcc 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-assets.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | asset_code, asset_issuer, asset_type | | Documentation | [dbt_docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_assets_staging) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx index 2b9215c88..eeac11dc3 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-effects.mdx @@ -162,7 +162,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -171,7 +171,7 @@ description: "" | Clustered Field(s) | address, operation_id, type | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_effects) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx index 7cf418507..5c80119a7 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-ledgers.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | sequence, closed_at | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_ledgers) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx index e536ab2c4..344ee147d 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-operations.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | transaction_id, source_account, type | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_operations) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx index 83d4e6c6b..171bc87e4 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-trades.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | selling_asset_id, buying_asset_id, trade_type | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_trades) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx b/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx index 0c2362a27..e2d5d3691 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/history-transactions.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | account, ledger_sequence, successful | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.history_transactions) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx b/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx index b9e3aaab6..16799b825 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/liquidity-pools.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | liquidity_pool_id, asset_a_id, asset_b_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.liquidity_pools) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/offers.mdx b/docs/data/hubble/data-catalog/data-dictionary/offers.mdx index 540c47084..92d8ac20d 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/offers.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/offers.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | selling_asset_id, buying_asset_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.offers) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx b/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx index fd6d3c014..6f1120709 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/trustlines.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | account_id, asset_id, liquidity_pool_id, last_modified_ledger | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.trust_lines) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx b/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx index 912175ebd..cb7522181 100644 --- a/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx +++ b/docs/data/hubble/data-catalog/data-dictionary/ttl.mdx @@ -6,7 +6,7 @@ description: ""
-## Table Metadata {#table-metadata} +## Table Metadata | Property | Configuration | | --- | --- | @@ -15,7 +15,7 @@ description: "" | Clustered Field(s) | last_modified_ledger, key_hash | | Documentation | [dbt docs](http://www.stellar-dbt-docs.com/#!/source/source.stellar_dbt_public.crypto_stellar.ttl) | -## Column Details {#column-details} +## Column Details | Name | Description | Data Type | Domain Values | Required? | Notes | | --- | --- | --- | --- | --- | --- | diff --git a/docs/data/rpc/README.mdx b/docs/data/rpc/README.mdx index a21273c5e..8012b38d9 100644 --- a/docs/data/rpc/README.mdx +++ b/docs/data/rpc/README.mdx @@ -22,7 +22,7 @@ Stellar-RPC should support the developer from local testing (via the [quickstart - This implies it should be easy to deploy, and easy to maintain; with low cost, and little "admin" needed. - The developer should be able to simply run the [quickstart] docker image, and quickly be ready to serve requests without needing to set up or maintain dependent infrastructure. -## Anti-Goals {#anti-goals} +## Anti-Goals - Stellar-RPC is not a Horizon replacement. Horizon is better suited for historical reporting and analytics queries. Horizon is more concerned with "classic" Stellar data. - Stellar-RPC should not depend on Horizon. Horizon is expensive and difficult to run, so if Stellar-RPC depended on Horizon, it would inherit that. diff --git a/docs/data/rpc/admin-guide.mdx b/docs/data/rpc/admin-guide.mdx index 0714dce14..c6afe6286 100644 --- a/docs/data/rpc/admin-guide.mdx +++ b/docs/data/rpc/admin-guide.mdx @@ -9,7 +9,7 @@ For example, you can build an application and have it [send a transaction](./api Alternatively, you can use one of Soroban's [client SDKs](/docs/tools/sdks/library), such as the [@stellar/stellar-sdk](/docs/tools/sdks/library#javascript-sdk), which will need to communicate with an RPC instance to access the network. -## Run Your Own Instance for Development {#run-your-own-instance-for-development} +## Run Your Own Instance for Development For local development, we recommend [downloading](https://hub.docker.com/r/stellar/quickstart) and running a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and running a standalone network or communicating with a live development [Testnet]. @@ -31,7 +31,7 @@ The Quickstart image with the RPC service can run on a standard laptop with 8GB [Horizon server]: https://github.com/stellar/go/tree/master/services/horizon [Friendbot server]: https://github.com/stellar/go/tree/master/services/friendbot -### Standalone {#standalone} +### Standalone To run a local standalone network with the Stellar Quickstart Docker image, run the following command: @@ -95,7 +95,7 @@ When you're done with your Standalone node, you can close it with ctrl meth.name === "getLedgerEntries")[0]} /> -### Generating `keys` Parameters {#generating-keys-parameters} +### Generating `keys` Parameters The example above is querying a deployment of the [`increment` example contract] to find out what value is stored in the `COUNTER` ledger entry. This value can be derived using the following code snippets. You should be able to extrapolate from the provided examples how to get `keys` parameters for other types and values. -#### Python {#python} +#### Python :::note @@ -48,7 +48,7 @@ print( ) ``` -#### JavaScript {#javascript} +#### JavaScript If you are using the [JavaScript](https://stellar.github.io/js-stellar-sdk/) `stellar-sdk` to generate these keys, you will need to install the latest pre-release version of the SDK. This can be done like so: @@ -78,7 +78,7 @@ console.log( ); ``` -### Requesting an Account {#requesting-an-account} +### Requesting an Account :::note @@ -149,22 +149,22 @@ const parsed = xdr.LedgerEntryData.fromXDR( console.log(parsed); ``` -### Requesting a Contract's Wasm Code {#requesting-a-contracts-wasm-code} +### Requesting a Contract's Wasm Code This can be a bit tricky to wrap your head around, but the conventions do make sense once you let it sink in. In the previous examples, the `COUNTER` _key_ was used as a `LedgerKey` while the incremented _value_ was stored in a **`LedgerEntry`**. "Ledger Entry" is the relevant term to keep in mind during this discussion. That `LedgerEntry` was stored on the Stellar ledger, and was associated with a corresponding `LedgerKey`. `LedgerKey: LedgerEntry` works the same way you would think of almost any `key: value` storage system. -#### How Soroban Contract Deployment Works {#how-soroban-contract-deployment-works} +#### How Soroban Contract Deployment Works When you deploy a contract, first the code is "installed" (i.e. it is uploaded onto the blockchain). This creates a `LedgerEntry` containing the Wasm byte-code, which is uniquely identified by its hash (that is, the hash of the uploaded code itself). Then, when the contract is "deployed," we create a `LedgerEntry` with a reference to that code's hash. So fetching the contract code is a two-step process: 1. First, we look up the contract itself, to see which code hash it is referencing. 2. Then, we can look up the raw Wasm byte-code using that hash. -#### Request the `LedgerKey` for the Contract Code {#request-the-ledgerkey-for-the-contract-code} +#### Request the `LedgerKey` for the Contract Code -##### Python {#python-1} +##### Python ```python from stellar_sdk import xdr, Address @@ -188,7 +188,7 @@ print( # OUTPUT: AAAABgAAAAGfjJVEBc55drW3U87N1Py0Rw0/nlqUA6tQ6r28khEl4gAAABQAAAAB ``` -##### JavaScript {#javascript-1} +##### JavaScript ```javascript import { Contract } from "@stellar/stellar-sdk"; @@ -238,11 +238,11 @@ And the response we get contains the `LedgerEntryData` that can be used to find } ``` -#### Request the `ContractCode` Using the Retrieved `LedgerKey` {#request-the-contractcode-using-the-retrieved-ledgerkey} +#### Request the `ContractCode` Using the Retrieved `LedgerKey` Now take the `xdr` field from the previous response's `result` object, and create a `LedgerKey` from the hash contained inside. -##### Python {#python-2} +##### Python ```python from stellar_sdk import xdr @@ -269,7 +269,7 @@ print( # OUTPUT: AAAAB+QzbW3JDhlUbDVW/C+1/5SIQDstqORuhpCyl73O1vH6 ``` -##### JavaScript {#javascript-2} +##### JavaScript ```javascript import { xdr } from "@stellar/stellar-sdk"; diff --git a/docs/data/rpc/api-reference/methods/getTransaction.mdx b/docs/data/rpc/api-reference/methods/getTransaction.mdx index f6c275495..2f0a0fbd8 100644 --- a/docs/data/rpc/api-reference/methods/getTransaction.mdx +++ b/docs/data/rpc/api-reference/methods/getTransaction.mdx @@ -11,7 +11,7 @@ import rpcSpec from "@site/static/stellar-rpc.openrpc.json"; method={rpcSpec.methods.filter((meth) => meth.name === "getTransaction")[0]} /> -### SDK Guide {#sdk-guide} +### SDK Guide The example above is querying details of a transaction using RPC methods directly. If you are using the Stellar SDK to build applications, you can use the native functions to get the same information. diff --git a/docs/data/rpc/api-reference/methods/sendTransaction.mdx b/docs/data/rpc/api-reference/methods/sendTransaction.mdx index 7b47bf10c..a92e7ef5f 100644 --- a/docs/data/rpc/api-reference/methods/sendTransaction.mdx +++ b/docs/data/rpc/api-reference/methods/sendTransaction.mdx @@ -10,7 +10,7 @@ import rpcSpec from "@site/static/stellar-rpc.openrpc.json"; method={rpcSpec.methods.filter((meth) => meth.name === "sendTransaction")[0]} /> -### SDK Guide {#sdk-guide} +### SDK Guide The example above is sending a transaction using RPC methods directly. If you are using the Stellar SDK to build applications, you can use the native functions to get the same information. diff --git a/docs/data/rpc/rpc-providers.mdx b/docs/data/rpc/rpc-providers.mdx index d6ec6240b..94c202bbe 100644 --- a/docs/data/rpc/rpc-providers.mdx +++ b/docs/data/rpc/rpc-providers.mdx @@ -3,7 +3,7 @@ sidebar_position: 60 title: Ecosystem RPC Providers --- -## Ecosystem Providers {#ecosystem-providers} +## Ecosystem Providers Multiple infrastructure providers have made Stellar RPC endpoint services available, and offer plans ranging from free to high throughput endpoints. These providers can be used for development, testing, and production. @@ -23,7 +23,7 @@ These providers allow access to the Testnet network and Mainnet network. \*_Blockdaemon, Validation Cloud, and Quicknode combine Horizon and RPC in the same endpoint._ -## Publicly Accessible RPC URLs {#publicly-accessible-rpc-urls} +## Publicly Accessible RPC URLs | Provider | Mainnet RPC Endpoint | Testnet RPC Endpoint | Futurenet RPC Endpoint | | --- | --- | --- | --- | @@ -42,6 +42,6 @@ SDF will not be providing a publicly available RPC endpoint for Mainnet. Develop | `Futurenet` | `https://rpc-futurenet.stellar.org` | `https://friendbot-futurenet.stellar.org` | [SDF](http://www.stellar.org) | | `Testnet` | `https://soroban-testnet.stellar.org` | `https://friendbot.stellar.org` | [SDF](http://www.stellar.org) | -## Run Your Own RPC {#run-your-own-rpc} +## Run Your Own RPC If you are interested in running your own RPC, please checkout [this page](./admin-guide.mdx). diff --git a/docs/learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx b/docs/learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx index d06a63171..16471ea21 100644 --- a/docs/learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx +++ b/docs/learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx @@ -23,7 +23,7 @@ toc_max_heading_level: 4 import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -## Example SDK Usage {#example-sdk-usage} +## Example SDK Usage Some (but not all yet) of the Stellar SDKs have functions built-in to handle most of the process of building a Stellar transaction to interact with a Soroban smart contract. Below, we demonstrate in JavaScript and Python how to build and submit a Stellar transaction that will invoke an instance of the [increment example](../../../../build/smart-contracts/getting-started/storing-data.mdx) smart contract. @@ -374,7 +374,7 @@ public class SorobanExample { -## XDR Usage {#xdr-usage} +## XDR Usage Stellar supports invoking and deploying contracts with a new operation named `InvokeHostFunctionOp`. The [`stellar-cli`] abstracts these details away from the user, but not all SDKs do yet. If you're building a dapp you'll probably find yourself building the XDR transaction to submit to the network. @@ -388,7 +388,7 @@ The `InvokeHostFunctionOp` can be used to perform the following Soroban operatio There is only a single `InvokeHostFunctionOp` allowed per transaction. Contracts should be used to perform multiple actions atomically, for example, to deploy a new contract and initialize it atomically. -### InvokeHostFunctionOp {#invokehostfunctionop} +### InvokeHostFunctionOp The XDR of `HostFunction` and `InvokeHostFunctionOp` below can be found [here][xdr]. @@ -414,7 +414,7 @@ struct InvokeHostFunctionOp }; ``` -#### Function {#function} +#### Function The `hostFunction` in `InvokeHostFunctionOp` will be executed by the Soroban host environment. The supported functions are: @@ -501,7 +501,7 @@ The `hostFunction` in `InvokeHostFunctionOp` will be executed by the Soroban hos - `CONTRACT_ID_PREIMAGE_FROM_ADDRESS` specifies that the contract will be created using the provided address and salt. This operation has to be authorized by `address` (see the following section for details). - `CONTRACT_ID_FROM_ASSET` specifies that the contract will be created using the Stellar asset. This is only supported when `executable == CONTRACT_EXECUTABLE_TOKEN`. Note, that the asset doesn't need to exist when this is applied, however the issuer of the asset will be the initial token administrator. Anyone can deploy asset contracts. -##### JavaScript Usage {#javascript-usage} +##### JavaScript Usage Each of these variations of host function invocation has convenience methods in the [JavaScript SDK](../../../../tools/sdks/library.mdx#javascript-sdk): @@ -510,7 +510,7 @@ Each of these variations of host function invocation has convenience methods in - [`Operation.createStellarAssetContract`](https://stellar.github.io/js-stellar-sdk/Operation.html#.createStellarAssetContract) and [`Operation.createCustomContract`](https://stellar.github.io/js-stellar-sdk/Operation.html#.createCustomContract) are abstractions to instantiate contracts: the former is for wrapping an existing [Stellar asset](../../../../tokens/how-to-issue-an-asset.mdx) into a smart contract and the latter is for deploying your own contract. - [`Operation.uploadContractWasm`](https://stellar.github.io/js-stellar-sdk/Operation.html#.uploadContractWasm) corresponds to the above `HOST_FUNCTION_TYPE_UPLOAD_CONTRACT_WASM` variant, letting you upload the raw WASM buffer to the ledger. -#### Authorization Data {#authorization-data} +#### Authorization Data Soroban's [authorization framework](../../security/authorization.mdx) provides a standardized way for passing authorization data to the contract invocations via `SorobanAuthorizationEntry` structures. @@ -588,7 +588,7 @@ Building `SorobanAuthorizedInvocation` trees may be simplified by using the reco [envelope-xdr]: https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-transaction.x#L703 [simulate-transaction-doc]: transaction-simulation.mdx#authorization -##### Stellar Account Signatures {#stellar-account-signatures} +##### Stellar Account Signatures `signatureArgs` format is user-defined for the [custom accounts], but it is protocol-defined for the Stellar accounts. @@ -605,7 +605,7 @@ pub struct AccountEd25519Signature { [structures]: https://github.com/stellar/rs-soroban-env/blob/99d8c92cdc7e5cd0f5311df8f88d04658ecde7d2/soroban-env-host/src/native_contract/account_contract.rs#L51 [custom accounts]: ../../security/authorization.mdx#account-abstraction -##### JavaScript Usage {#javascript-usage-1} +##### JavaScript Usage There are a couple of helpful methods in the SDK to make dealing with authorization easier: @@ -631,7 +631,7 @@ const signedEntries = simTx.auth.map(async (entry) => - If you, instead, want to _build_ an authorization entry from scratch rather than relying on simulation, you can use [`authorizeInvocation`](https://stellar.github.io/js-stellar-sdk/global.html#authorizeInvocation), which will build the structure with the appropriate fields. -### Transaction resources {#transaction-resources} +### Transaction resources Every Soroban transaction has to have a `SorobanTransactionData` transaction [extension] populated. This is needed to compute the [Soroban resource fee](../../../fundamentals/fees-resource-limits-metering.mdx). @@ -668,6 +668,6 @@ The `SorobanResources` structure includes the ledger footprint and the resource The simplest method to determine the values in `SorobanResources` and `refundableFee` is to use the [`simulateTransaction` mechanism](transaction-simulation.mdx). -#### JavaScript Usage {#javascript-usage-2} +#### JavaScript Usage You can use the [`SorobanDataBuilder`](https://stellar.github.io/js-stellar-sdk/SorobanDataBuilder.html) to leverage the [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) and get/set all of the above resources accordingly. Then, you call `.build()` and pass the resulting structure to the [`setSorobanData`](https://stellar.github.io/js-stellar-sdk/TransactionBuilder.html#setSorobanData) method of the corresponding [`TransactionBuilder`](https://stellar.github.io/js-stellar-sdk/TransactionBuilder.html). diff --git a/docs/learn/encyclopedia/contract-development/contract-interactions/tests.mdx b/docs/learn/encyclopedia/contract-development/contract-interactions/tests.mdx index c1d6dd81b..3738b906f 100644 --- a/docs/learn/encyclopedia/contract-development/contract-interactions/tests.mdx +++ b/docs/learn/encyclopedia/contract-development/contract-interactions/tests.mdx @@ -19,6 +19,6 @@ Some contracts, such as the token contract, also provide a [friendlier interface Note that everything described in this section is only available if the `testutils` feature is enabled. -### Example {#example} +### Example This machinery can also be used to test multiple contracts together. For example, the single offer contract test case [creates a token](https://github.com/stellar/soroban-examples/blob/56fef787395b5aed7cd7b19772cca28e21b3feb5/single_offer/src/test.rs#L22). diff --git a/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx b/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx index f9c8bd440..c9aee7940 100644 --- a/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx +++ b/docs/learn/encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx @@ -4,7 +4,7 @@ title: Transaction Simulation description: Simulate a contract interaction contained in a Stellar transaction. --- -## Footprint {#footprint} +## Footprint As mentioned in the [persisting data](../../storage/persisting-data.mdx) section, a contract can only load or store `CONTRACT_DATA` entries that are declared in a _footprint_ associated with its invocation. @@ -18,7 +18,7 @@ This simulation-provided footprint can then be used to accompany a "real" submis In any event (whether successful or failing), the real transaction will execute atomically, deterministically, and with serializable consistency semantics. An inaccurate footprint simply causes deterministic transaction failure, not a stale-read anomaly. All effects of such a failed transaction are discarded, as they would be in the presence of any other error. -## Authorization {#authorization} +## Authorization See the [authorization overview](../../security/authorization.mdx) docs and authorization in transactions [section][auth-data] for general information on Soroban authorization. diff --git a/docs/learn/encyclopedia/contract-development/contract-lifecycle.mdx b/docs/learn/encyclopedia/contract-development/contract-lifecycle.mdx index b3be92558..4c5dd22be 100644 --- a/docs/learn/encyclopedia/contract-development/contract-lifecycle.mdx +++ b/docs/learn/encyclopedia/contract-development/contract-lifecycle.mdx @@ -19,7 +19,7 @@ description: The process of developing, deploying, and maintaining smart contrac /> -## Development {#development} +## Development Contract development can be done on a local computer with as little as 3 necessary components: an IDE, a copy of the Rust toolchain, and a copy of the Soroban SDK. @@ -29,7 +29,7 @@ To make the local development process even more convenient and fast, the contrac The SDK-provided local contract host also contains a local web server that serves the necessary HTTP API endpoint used for client applications to interact with a contract. This can be used for local development of applications, again without needing to deploy contracts to any test or live network. -## Deployment {#deployment} +## Deployment Once a contract has been tested and debugged locally, it can be deployed. To do this it must be compiled to Wasm code, and then included by value in a transaction sent to the intended deployment network. @@ -39,7 +39,7 @@ Before submitting to the network, developers should inspect the resulting Wasm b The SDK command-line utility can also build and submit the transaction deploying a Wasm contract to the network. Deployment requires sufficient network credentials to sign a transaction performing the deployment and pay its fees. Contracts should be deployed to test networks and thoroughly tested there before being deployed to the live network. -## Execution {#execution} +## Execution Deployed contracts live on chain in a CONTRACT_DATA ledger entry. They are executed within a VM sandbox managed by a host environment inside stellar-core. Each transaction that leads to a contract execution is run in a separate host environment, and each contract called by such a transaction (either directly or indirectly from another contract) is executed in a separate guest Wasm VM contained within the transaction’s host environment. @@ -51,12 +51,12 @@ Each contract execution continues until the contract either completes successful A variety of conditions in either the guest or host environments can cause a contract to trap. If a host function is called with invalid arguments, for example, the host will trap. Similarly if the contract performs an erroneous Wasm bytecode such as a division by zero or access to memory out of bounds, the Wasm VM will trap. Also if the contract uses more resources than its enclosing transaction has paid for, the contract will trap. -## Monitoring {#monitoring} +## Monitoring Contracts can be monitored in two main ways: by observing events emitted during their execution, and by examining the ledger entries written by them. TBD: expand this section. -## Upgrading contracts {#upgrading-contracts} +## Upgrading contracts See the [Upgrading Contracts page](../../../build/guides/conventions/upgrading-contracts.mdx) for details on this. diff --git a/docs/learn/encyclopedia/contract-development/environment-concepts.mdx b/docs/learn/encyclopedia/contract-development/environment-concepts.mdx index f3094411d..3fdf35392 100644 --- a/docs/learn/encyclopedia/contract-development/environment-concepts.mdx +++ b/docs/learn/encyclopedia/contract-development/environment-concepts.mdx @@ -22,7 +22,7 @@ description: The interface that defines objects, functions, and data available t The contract environment is an _interface_ that defines the facilities -- objects, functions, data sources, etc. -- available to contracts. -## Host and Guest {#host-and-guest} +## Host and Guest As an interface, the environment has two sides, which we refer to as the host environment and the guest environment. Code in the host environment _implements_ the environment interface; code in the guest environment _uses_ the environment interface. @@ -30,7 +30,7 @@ The **host environment** is provided by a known set of Rust crates, compiled onc In contrast, a new **guest environment** is established for each invocation of each smart contract. Each contract sees a single environment interface, and can only call functions provided by the environment interface. In other words, the guest environment is a sandbox for executing arbitrary code within safe parameters. -## WebAssembly {#webassembly} +## WebAssembly The on-chain guest environment is isolated inside a WebAssembly (Wasm) virtual machine ("VM"). This means that deployed contract code is compiled to Wasm bytecode rather than native machine code. The host environment includes an interpreter for the VM, and a new short-lived VM is instantiated for each call to a contract, running the bytecode for the contract and then exiting. @@ -44,7 +44,7 @@ As a result, programs compiled to Wasm bytecode often face a dilemma: if they wa The way out of this dilemma is for the environment itself to provide support code for rich standard functionality, in the form of host objects and functions that guest code can use by reference. Each contract refers to the same functionality implemented in the host, ensuring much smaller code size, higher performance, and greater interoperability between contracts. This is what Soroban does. -## Host objects and functions {#host-objects-and-functions} +## Host objects and functions Shared, standard functionality available to all contract guest code is provided through the environment interface in terms of host objects and host functions. @@ -54,11 +54,11 @@ There is also a slightly larger set of host functions that act on host objects: There are also host functions for interacting with select components of the host environment beyond the host object repertoire, such as reading and writing ledger entries, emitting events, calling other contracts, and accessing information about the transaction context in which guest code is executing. -### Serialization {#serialization} +### Serialization Host objects can be passed (by handle) directly to storage routines or between collaborating contracts. **No serialization or deserialization code needs to exist in the guest**: the host knows how to serialize and deserialize all of its object types and does so transparently whenever necessary. -## Values and types {#values-and-types} +## Values and types All host functions can accept as arguments and return values from, at most, the limited Wasm VM repertoire of machine-level types. To simplify matters, Soroban further limits all host functions to passing and returning values from within a single specialized form of 64-bit integers called "value" or "the value type". Through careful bit-packing, the value type can encode any of several separate types more meaningful to users than just "integers". diff --git a/docs/learn/encyclopedia/contract-development/events.mdx b/docs/learn/encyclopedia/contract-development/events.mdx index e189e9540..9bddcce2f 100644 --- a/docs/learn/encyclopedia/contract-development/events.mdx +++ b/docs/learn/encyclopedia/contract-development/events.mdx @@ -19,7 +19,7 @@ description: Monitor off-chain smart contract changes. Events are the mechanism that applications off-chain can use to monitor changes and events in contracts on-chain. -## How are events emitted? {#how-are-events-emitted} +## How are events emitted? `ContractEvents` are emitted in Stellar Core's `TransactionMeta`. You can see in the [TransactionMetaV3] XDR below that there is a list of `OperationEvents` called `events`. Each `OperationEvent` corresponds to an operation in a transaction, and itself contains a list of `ContractEvents`. Note that `events` will only be populated if the transaction succeeds. Take a look at the [events guides](../../../build/guides/events/README.mdx) and [this example](../../../build/smart-contracts/example-contracts/events.mdx) to learn more about how to work with events. @@ -31,7 +31,7 @@ Events are ephemeral, the data retention window is a maximum of 7 days. See the [transactionmetav3]: #transactionmetav3 -### ContractEvent {#contractevent} +### ContractEvent An events topics don't have to be made of the same type. You can mix different types. @@ -60,7 +60,7 @@ struct ContractEvent }; ``` -### OperationEvents {#operationevents} +### OperationEvents ```cpp struct OperationEvents @@ -69,7 +69,7 @@ struct OperationEvents }; ``` -### TransactionMetaV3 {#transactionmetav3} +### TransactionMetaV3 ```cpp struct TransactionMetaV3 @@ -95,7 +95,7 @@ struct TransactionMetaV3 [Link](https://github.com/stellar/stellar-xdr/blob/eab1622f18b8101aa0cea76361c08beaeaa8d715/Stellar-ledger.x#L444) to the XDR above. -### Event types {#event-types} +### Event types There are three `ContractEventType`'s - @@ -103,11 +103,11 @@ There are three `ContractEventType`'s - 2. `SYSTEM` events are events emitted by the host. At the moment, there's only one system event emitted by the host. It is emitted when the `update_current_contract_wasm` host function is called, where `topics = ["executable_update", old_executable: ContractExecutable, old_executable: ContractExecutable]` and `data = []`. 3. `DIAGNOSTIC` events are meant for debugging and will not be emitted unless the host instance explictly enables it. You can read more about this below. -## What are diagnosticEvents? {#what-are-diagnosticevents} +## What are diagnosticEvents? While looking at the `TransactionMetaV3` XDR struct above, you may have noticed the `diagnosticEvents` field. This list will be empty by default unless your stellar-core instance has `ENABLE_SOROBAN_DIAGNOSTIC_EVENTS=true` in its config file. If diagnostic events are enabled, this list will not only include all ContractEvents in `events`, but will also include events from failed contract calls, errors from the host, events to trace the contract call stack, and logs from the `log_from_linear_memory` host function. These events can be identified by `type == DIAGNOSTIC`. The diagnostic events emitted by the host to track the call stack are defined below. -### fn_call {#fn_call} +### fn_call The `fn_call` diagnostic event is emitted when a contract is called and contains - @@ -118,7 +118,7 @@ The `fn_call` diagnostic event is emitted when a contract is called and contains - Data 1. A vector of the arguments passed to the function being called. -### fn_return {#fn_return} +### fn_return The `fn_return` diagnostic event is emitted when a contract call completes and contains - @@ -128,7 +128,7 @@ The `fn_return` diagnostic event is emitted when a contract call completes and c - Data 1. The value returned by the contract function. -### When should diagnostic events be enabled? {#when-should-diagnostic-events-be-enabled} +### When should diagnostic events be enabled? `events` contain `ContractEvents` that should convey information about state changes. `diagnosticEvents` on the other hand contain events that are not useful for most users, but may be helpful in debugging issues or building the contract call stack. Because they won't be used by most users, they can be optionally enabled because they are not hashed into the ledger, and therefore are not part of the protocol. This is done so a stellar-core node can stay in sync with the network while emitting these events that normally would not be useful for most users. diff --git a/docs/learn/encyclopedia/contract-development/rust-dialect.mdx b/docs/learn/encyclopedia/contract-development/rust-dialect.mdx index 3855c2f38..5e51b7e6f 100644 --- a/docs/learn/encyclopedia/contract-development/rust-dialect.mdx +++ b/docs/learn/encyclopedia/contract-development/rust-dialect.mdx @@ -27,7 +27,7 @@ Note: these constraints and priorities are **not enforced when building in local The "contract dialect" has the following characteristics: -## No floating point {#no-floating-point} +## No floating point Floating-point arithmetic in the guest is completely prohibited. Floating-point operations in Wasm have a few nondeterministic or platform-specific aspects: mainly NaN bit patterns, as well as floating-point environment settings such as rounding mode. @@ -35,7 +35,7 @@ While it is theoretically possible to force all floating-point code into determi This restriction may be revisited in a future version. -## Limited (ideally zero) dynamic memory allocation {#limited-ideally-zero-dynamic-memory-allocation} +## Limited (ideally zero) dynamic memory allocation Dynamic memory allocation within the guest is **strongly** discouraged, but not completely prohibited. @@ -49,7 +49,7 @@ This restriction is due to the limited ability of Wasm to support code-sharing: Many instances where dynamic memory allocation might _seem_ to be required can also be addressed just as well with a library such as [heapless](https://docs.rs/heapless/latest/heapless/). This library (and others of its kind) provide data structures with familiar APIs that _appear_ dynamic, but are actually implemented in terms of a single stack or static allocation, with a fixed maximum size established at construction: attempts to grow the dynamic size beyond the maximum size simply fail. In the context of a contract, this can sometimes be perferable behaviour, and avoids the question of dynamic allocation entirely. -## Non-standard I/O {#non-standard-io} +## Non-standard I/O All standard I/O facilities and access to the operating system that a typical Rust program would expect to perform using the Rust standard library is prohibited; programs that try to import such functions from the host through (for example) the WASI interface will fail to instantiate, since they refer to functions not provided by the host. @@ -57,19 +57,19 @@ No operating system, nor any simulation thereof, is present in the contract sand This restriction arises from the fact that contracts need to run with _stronger_ guarantees than those made by typical operating-system APIs. Specifically contracts must perform I/O with all-or-nothing, transactional semantics (relative to their successful execution or failure) as well as serializable consistency. This eliminates most APIs that would relate to typical file I/O. Furthermore contracts must be isolated from all sources of nondeterminism such as networking or process control, which eliminates most of the remaining APIs. Once files, networking and process control are gone, there simply isn't enough left in the standard operating system I/O facililties to bother trying to provide them. -## No multithreading {#no-multithreading} +## No multithreading Multithreading is not available. As with I/O functions, attempting to import any APIs from the host related to multithreading will fail at instantiation time. This restriction is similarly based on the need for contracts to run in an environment with strong determinism and serializable consistency guarantees. -## Immediate panic {#immediate-panic} +## Immediate panic The Rust `panic!()` facility for unrecoverable errors will trap the Wasm virtual machine immediately, halting execution at the instruction that traps rather than unwinding. This means that `Drop` code in Rust types will not run during a panic. This behaviour is similar to the `panic = "abort"` profile that Rust code can (and often is) compiled with. This is not a hard restriction enforced by the host, but a soft configuration made through a mixture of SDK functions and flags used when compiling, in the interest of minimizing code size and limiting execution costs. It can be bypassed with some effort if unwinding and `Drop` code is desired, at the cost of greatly increased code size. -## Pure-functional collections {#pure-functional-collections} +## Pure-functional collections Host objects have significantly different semantics than typical Rust data structures, especially those implementing _collections_ such as maps and vectors. diff --git a/docs/learn/encyclopedia/contract-development/types/built-in-types.mdx b/docs/learn/encyclopedia/contract-development/types/built-in-types.mdx index 1733536b8..2c11cb76d 100644 --- a/docs/learn/encyclopedia/contract-development/types/built-in-types.mdx +++ b/docs/learn/encyclopedia/contract-development/types/built-in-types.mdx @@ -28,31 +28,31 @@ Custom types like structs, enums, and unions are also supported. See [Custom Typ ::: -## Primitive Types {#primitive-types} +## Primitive Types The following primitive types are supported: -### Unsigned 32-bit Integer (`u32`) {#unsigned-32-bit-integer-u32} +### Unsigned 32-bit Integer (`u32`) -### Signed 32-bit Integer (`i32`) {#signed-32-bit-integer-i32} +### Signed 32-bit Integer (`i32`) -### Unsigned 64-bit Integer (`u64`) {#unsigned-64-bit-integer-u64} +### Unsigned 64-bit Integer (`u64`) -### Signed 64-bit Integer (`i64`) {#signed-64-bit-integer-i64} +### Signed 64-bit Integer (`i64`) -### Unsigned 128-bit Integer (`u128`) {#unsigned-128-bit-integer-u128} +### Unsigned 128-bit Integer (`u128`) -### Signed 128-bit Integer (`i128`) {#signed-128-bit-integer-i128} +### Signed 128-bit Integer (`i128`) -### Bool (`bool`) {#bool-bool} +### Bool (`bool`) -## Symbol (`Symbol`) {#symbol-symbol} +## Symbol (`Symbol`) Symbols are small efficient strings up to 32 characters in length and limited to `a-z` `A-Z` `0-9` `_` that are encoded into 64-bit integers. Symbols are primarily used for function names and other identifiers that are exported in the public API of a contract. They can also be used wherever short strings are needed to keep resource costs down. -## Bytes, Strings (`Bytes`, `BytesN`, `String`) {#bytes-strings-bytes-bytesn-string} +## Bytes, Strings (`Bytes`, `BytesN`, `String`) Byte arrays and strings can be passed to contracts and stores using the `Bytes` type. @@ -60,7 +60,7 @@ For byte arrays of fixed length, `BytesN` can be used. For example, contract IDs Note that the bytes contained in `String`s do not necessarily conform to any standard text encoding such as ASCII or Unicode UTF-8. They are plain uninterpreted bytes, and users expecting a particular encoding need to enforce that encoding manually. -## Vec (`Vec`) {#vec-vec} +## Vec (`Vec`) Vec is a sequential and indexable growable collection type. @@ -68,7 +68,7 @@ Values are stored in the environment and are available to contract through the f The values in a Vec are not guaranteed to be of any specific type and conversion will fail if they are not of the expected type. Most functions on Vec return a Result due to this. -## Map (`Map`) {#map-map} +## Map (`Map`) Map is a ordered key-value dictionary. @@ -80,7 +80,7 @@ The keys and values in a Map are not guaranteed to be of type K/V and conversion Maps have at most one entry per key. Setting a value for a key in the map that already has a value for that key replaces the value. -## Address (`Address`) {#address-address} +## Address (`Address`) Address is a universal opaque identifier to use in contracts. It may represent a 'classic' Stellar account, a custom account implemented in Soroban or just an arbitrary contract. diff --git a/docs/learn/encyclopedia/contract-development/types/custom-types.mdx b/docs/learn/encyclopedia/contract-development/types/custom-types.mdx index 2111639e7..9adff35ff 100644 --- a/docs/learn/encyclopedia/contract-development/types/custom-types.mdx +++ b/docs/learn/encyclopedia/contract-development/types/custom-types.mdx @@ -33,7 +33,7 @@ Error enum types are another type contracts can define that have some unique beh ::: -## Structs (with Named Fields) {#structs-with-named-fields} +## Structs (with Named Fields) Structs with named fields are stored on ledger as a map of key-value pairs, where the key is a 32 character string representing the field name, and the value is the value encoded. @@ -59,7 +59,7 @@ When converted to XDR, the value becomes an `ScVal`, containing an `ScMap`, cont } ``` -## Structs (with Unnamed Fields) {#structs-with-unnamed-fields} +## Structs (with Unnamed Fields) Structs with unnamed fields are stored on ledger as a vector of values, and are interchangeable with tuples and vectors. The elements are placed in the vector in order that they appear in the field list. @@ -75,7 +75,7 @@ When converted to XDR, the value becomes an `ScVal`, containing an `ScVec`, cont { "vec": [{ "u32": 0 }, { "u32": 0 }] } ``` -## Enum (Unit and Tuple Variants) {#enum-unit-and-tuple-variants} +## Enum (Unit and Tuple Variants) Enums containing unit and tuple variants are are stored on ledger as a two element vector, where the first element is the name of the enum variant as a string up to 32 characters in length, and the value is the value if the variant has one. @@ -104,7 +104,7 @@ When a tuple variant, such as `Enum::B`, is converted to XDR, the value becomes When tuple variants containing multiple values are implemented, the values will be included into the vector. -## Enum (Integer Variants) {#enum-integer-variants} +## Enum (Integer Variants) Enums containing integer values are stored on ledger as the `u32` value. diff --git a/docs/learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx b/docs/learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx index d4d47d2ae..7070c250e 100644 --- a/docs/learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx +++ b/docs/learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx @@ -25,7 +25,7 @@ When you compile a contract created with [soroban-sdk](../../../../tools/sdks/li These interface types are formatted using [XDR](../../data-format/xdr.mdx), a data format used widely throughout Stellar. It can be tricky to create or consume XDR manually, but tooling can fetch these interface types to make your life easier. [Stellar CLI](../../../../tools/developer-tools/cli/README.mdx#cli) and [Stellar SDK](../../../../tools/sdks/library.mdx#javascript-sdk) are two such tools to do so. Let's look at each. -## Stellar CLI: `stellar contract invoke` {#stellar-cli-stellar-contract-invoke} +## Stellar CLI: `stellar contract invoke` Really, every smart contract is its own program, and deserves its own CLI. @@ -74,7 +74,7 @@ If you're unfamiliar with the `--` double dash separator, this is a pattern used ::: -## Stellar JS SDK: `contract.Client` {#stellar-js-sdk-contractclient} +## Stellar JS SDK: `contract.Client` To create a contract client for the same contract as shown for `contract invoke` above, you would use this JavaScript: @@ -104,7 +104,7 @@ stellar contract bindings typescript \ This creates a fully-typed NPM module for the given contract. -## Already the best; just getting started {#already-the-best-just-getting-started} +## Already the best; just getting started We love that Soroban had all contract interface types available on-chain right from day one. No secondary API calls to external services, no secondary API token management, no signing in or creating an account anywhere else, and near-perfect reliability. It's a game-changer within the blockchain space. diff --git a/docs/learn/encyclopedia/data-format/xdr.mdx b/docs/learn/encyclopedia/data-format/xdr.mdx index 0532f2826..2fe3f403e 100644 --- a/docs/learn/encyclopedia/data-format/xdr.mdx +++ b/docs/learn/encyclopedia/data-format/xdr.mdx @@ -4,17 +4,17 @@ title: XDR Stellar stores and communicates ledger data, transactions, results, history, and messages in a binary format called External Data Representation (XDR). XDR is optimized for network performance but not human readable. Horizon and the Stellar SDKs convert XDRs into friendlier formats. -## .X files {#x-files} +## .X files Data structures in XDR are specified in an interface definition file (IDL). The IDL files used for the Stellar Network are available on [GitHub](https://github.com/stellar/stellar-xdr). -## JSON and XDR Conversion Schema {#json-and-xdr-conversion-schema} +## JSON and XDR Conversion Schema The canonical JSON and XDR Schema is defined by the [stellar-xdr crate](https://docs.rs/stellar-xdr) and also exposed by the [@stellar/stellar-xdr-json-web npm package](https://www.npmjs.com/package/@stellar/stellar-xdr-json-web). The schema provides a round-trippable means for converting any Stellar XDR type to JSON and converting that JSON back to the identical XDR. This conversion is visible in the Stellar CLI, Lab View XDR, and Hubble events table. -### Key Characteristics of the JSON and XDR Conversion Schema {#key-characteristics-of-the-json-and-xdr-conversion-schema} +### Key Characteristics of the JSON and XDR Conversion Schema - **Round-Trippable:** The JSON format allows for converting from XDR to JSON and back to XDR without loss of information. - **Self-Describing:** The JSON format describes the internals of the type but does not identify the type that is encoded. This is similar to XDR, which also does not identify the encoded type. @@ -25,7 +25,7 @@ The defined schema (linked above) is **not** backwards compatible between a give ::: -## More About XDR {#more-about-xdr} +## More About XDR XDR is specified in [RFC 4506](http://tools.ietf.org/html/rfc4506.html) and is similar to tools like Protocol Buffers or Thrift. XDR provides a few important features: @@ -33,7 +33,7 @@ XDR is specified in [RFC 4506](http://tools.ietf.org/html/rfc4506.html) and is s - Data encoded in XDR is reliably and predictably stored. Fields are always in the same order, which makes cryptographically signing and verifying XDR messages simple. - XDR definitions include rich descriptions of data types and structures, which is not possible in simpler formats like JSON, TOML, or YAML. -## Parsing XDR {#parsing-xdr} +## Parsing XDR Since XDR is a binary format and not as widely known as simpler formats like JSON, the Stellar SDKs all include tools for parsing XDR and will do so automatically when retrieving data. diff --git a/docs/learn/encyclopedia/errors-and-debugging/debugging-errors.mdx b/docs/learn/encyclopedia/errors-and-debugging/debugging-errors.mdx index 85885cab8..bfb159d0b 100644 --- a/docs/learn/encyclopedia/errors-and-debugging/debugging-errors.mdx +++ b/docs/learn/encyclopedia/errors-and-debugging/debugging-errors.mdx @@ -6,7 +6,7 @@ description: Debug and Understanding Soroban Errors through the General Transact To understand how to debug Soroban errors, first we must understand how the errors are associated with each step of the transaction flow, and the likely and common errors in each step of the transaction flow. -## General Transaction Flow {#general-transaction-flow} +## General Transaction Flow The typical transaction submission process can be broken down into the following sequential steps, excluding external interactions like wallet interactions. Each step has its own set of potential errors: @@ -31,9 +31,9 @@ The typical transaction submission process can be broken down into the following _For more information about fees, please visit [Fees, Resource Limits, and Metering](https://developers.stellar.org/docs/learn/fundamentals/fees-resource-limits-metering#inclusion-fee)._ -## Detailed Soroban Errors {#detailed-soroban-errors} +## Detailed Soroban Errors -### 1. Preflight {#1-preflight} +### 1. Preflight Errors here are returned by the host and propagated through RPC. This doesn’t cover other possible errors (e.g. network errors, errors in RPC itself etc.) @@ -44,7 +44,7 @@ Errors here are returned by the host and propagated through RPC. This doesn’t | `HostError(WasmVm, InvalidAction)` | There was a failure in some Wasm contract, typically a `panic!()`. Diagnostic events might provide more detailed information, but not always, as the `panic!()` messages are not included in the Wasm builds. | Fix the contract logic or invocation arguments. Since the most typical reason for encountering this is `panic!()`, it might be a good idea to use `panic_with_error!()` instead of `panic!()` everywhere. Writing more unit tests is recommended. | | `HostError()` | An arbitrary execution error, like accessing a value out of container bounds, overflow in i128 arithmetics, incorrect invocation argument type etc. The error code should provide a general idea of what is failing, but refer to diagnostic events for details. | Fix the contract logic or invocation arguments. Additional debugging can be done via unit tests. | -### 2. Core Accepts the Transaction {#2-core-accepts-the-transaction} +### 2. Core Accepts the Transaction The error is returned by the core immediately as a response to the transaction being sent and surfaced to the user through RPC. There are a few error-related fields in the Core’s response: @@ -65,7 +65,7 @@ The error is returned by the core immediately as a response to the transaction b | status: `ERROR`, error: `txFAILED`, operation error: `RESTORE_FOOTPRINT_MALFORMED` | One of the footprint requirements for RestoreFootprint operation has not been fulfilled: Only persistent Soroban ledger entries can be restored; Only readWrite footprint should be populated. | Make sure that footprints conform to the requirements. Ideally, client-side libraries should ensure that the restoration transactions are well-formed. | | status: `ERROR`, error: `tx$CODE` | The remaining error codes have the same semantics for Soroban as they do for Stellar; these include errors like insufficient account balance, bad seq num, etc. These errors are usually straightforward to interpret according to the name. | Fix the issue corresponding to the code. There is nothing Soroban specific here. | -### 3. Core Includes the Transaction in the Ledger {#3-core-includes-the-transaction-in-the-ledger} +### 3. Core Includes the Transaction in the Ledger There are instances when the Core does not appear to include the transaction in the ledger, The following best practice is recommended: @@ -79,7 +79,7 @@ It is strongly recommended that all transactions should include a time bound or ::: -### 4. Core Applies the Transaction to the Ledger {#4-core-applies-the-transaction-to-the-ledger} +### 4. Core Applies the Transaction to the Ledger The errors and diagnostic events are recorded in the transaction meta stream emitted by the Core instance when the ledger is being closed. Then, the RPC ingests the transaction metadata (tx meta) and allows developers to query the tx meta. diff --git a/docs/learn/encyclopedia/errors-and-debugging/debugging.mdx b/docs/learn/encyclopedia/errors-and-debugging/debugging.mdx index d6d6f1e5f..5685a92ff 100644 --- a/docs/learn/encyclopedia/errors-and-debugging/debugging.mdx +++ b/docs/learn/encyclopedia/errors-and-debugging/debugging.mdx @@ -23,7 +23,7 @@ The debugging facilities available differ significantly depending on whether a c Deciding between these two modes and making the most of them while debugging requires a **careful understanding** of which code is compiled-in to deployed contracts and which code is only available for local testing. -## Local-testing mode {#local-testing-mode} +## Local-testing mode It is possible (and encouraged during development) to compile Soroban contracts **natively** (eg. as x86-64 or AArch64 code) and link against the host environment **directly**, such that the contract is not a guest running in a Wasm virtual machine at all: it is simply one native library calling another -- its host -- and both host and contract are linked together as a single program, together with a test harness. @@ -39,7 +39,7 @@ This configuration is referred to as **"local-testing mode"** and since it elimi Local-testing mode is the **default** configuration when compiling code targeting your local computer's CPU and operating system, which is what cargo will do if you set up a new Rust project and don't specify a target. -## Wasm mode {#wasm-mode} +## Wasm mode If on the other hand you wish to compile for deployment, you must tell cargo to build for the Wasm target. diff --git a/docs/learn/encyclopedia/errors-and-debugging/errors.mdx b/docs/learn/encyclopedia/errors-and-debugging/errors.mdx index 0e1d61aaf..6d08488c1 100644 --- a/docs/learn/encyclopedia/errors-and-debugging/errors.mdx +++ b/docs/learn/encyclopedia/errors-and-debugging/errors.mdx @@ -26,7 +26,7 @@ The [errors example] demonstrates how to define your own error types. [errors example]: ../../../build/smart-contracts/example-contracts/errors.mdx -## Error Enums {#error-enums} +## Error Enums Errors are a special type of enum integer type that are stored on ledger as `Status` values containing a `u32` code. diff --git a/docs/learn/encyclopedia/network-configuration/federation.mdx b/docs/learn/encyclopedia/network-configuration/federation.mdx index f0da9a942..cfb40f249 100644 --- a/docs/learn/encyclopedia/network-configuration/federation.mdx +++ b/docs/learn/encyclopedia/network-configuration/federation.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 The [Stellar federation protocol](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0002.md) maps Stellar addresses to an email-like identifier that provides more information about a given user. It’s a way for Stellar client software to resolve email-like addresses such as `name*yourdomain.com` into account IDs like: `GCCVPYFOHY7ZB7557JKENAX62LUAPLMGIWNZJAFV2MITK6T32V37KEJU`. Federated addresses provide an easy way for users to share payment details by using a syntax that interoperates across different domains and providers. -## Federated addresses {#federated-addresses} +## Federated addresses Stellar federated addresses are divided into two parts separated by the asterisk character (`*`): the username and the domain. For example: `jed*stellar.org:` @@ -16,7 +16,7 @@ The domain can be any valid RFC 1035 domain name. The username is limited to pri Note that the `@` symbol is allowed in the username. This means you can use email addresses in the username of a federated address. For example: `maria@gmail.com*stellar.org`. -## Supporting federation {#supporting-federation} +## Supporting federation To support federation, first, create a stellar.toml file, and publish it at `https://YOUR_DOMAIN/.well-known/stellar.toml`. Complete instructions for doing that can be found in the stellar.toml specification (aka SEP-1). @@ -30,7 +30,7 @@ Once you’ve published the location of your federation server, implement federa To make it easier to set up a federation server, you can use the [reference implementation](https://github.com/stellar/go/tree/master/services/federation) designed to be dropped into your existing infrastructure. -## Federation requests {#federation-requests} +## Federation requests You can use the federation endpoint to look up an account ID if you have a Stellar address. You can also do reverse federation and look up a Stellar address from an account ID or a transaction ID. This is useful to see who has sent you a payment. @@ -45,7 +45,7 @@ Supported types: - Id Not supported by all federation servers. Reverse federation will return the federation record of the Stellar address associated with the given account ID. In some cases, this is ambiguous. For instance, if an anchor sends transactions on behalf of its users, the account id will be of the anchor, and the federation server won’t be able to resolve the particular user that sent the transaction. In cases like that, you may need to use txid instead. Example: https://YOUR_FEDERATION_SERVER/federation?q=GD6WU64OEP5C4LRBH6NK3MHYIA2ADN6K6II6EXPNVUR3ERBXT4AN4ACD&type=id - Txid Not supported by all federation servers. Will return the federation record of the sender of the transaction if known by the server. Example: https://YOUR_FEDERATION_SERVER/federation?q=c1b368c00e9852351361e07cc58c54277e7a6366580044ab152b8db9cd8ec52a&type=txid -## Federation Response {#federation-response} +## Federation Response The federation server should respond with an appropriate HTTP status code, headers, and a JSON response. @@ -74,10 +74,10 @@ When a record has not been found 404 Not Found http status code should be return } ``` -## Looking up federation provider via a home domain entry {#looking-up-federation-provider-via-a-home-domain-entry} +## Looking up federation provider via a home domain entry Accounts may optionally have a home domain specified. This allows an account to programmatically specify the main federation provider for that account. -## Caching {#caching} +## Caching You shouldn’t cache responses from federation servers. Some organizations may generate random IDs to protect their users’ privacy. Those IDs may change over time. diff --git a/docs/learn/encyclopedia/network-configuration/ledger-headers.mdx b/docs/learn/encyclopedia/network-configuration/ledger-headers.mdx index f6a8c40f8..e64d71307 100644 --- a/docs/learn/encyclopedia/network-configuration/ledger-headers.mdx +++ b/docs/learn/encyclopedia/network-configuration/ledger-headers.mdx @@ -15,72 +15,72 @@ stateDiagram The genesis ledger has a sequence number of 1. The ledger directly following a ledger with sequence number n has a sequence number of n+1. -## Ledger header fields {#ledger-header-fields} +## Ledger header fields -### Version {#version} +### Version The protocol version of this ledger. -### Previous ledger hash {#previous-ledger-hash} +### Previous ledger hash Hash of the previous ledger. -### SCP value {#scp-value} +### SCP value During consensus, all the validating nodes in the network run SCP and agree on a particular value, which is a transaction set they will apply to a ledger. This value is stored here and in the following three fields (transaction set hash, close time, and upgrades). -### Transaction set hash {#transaction-set-hash} +### Transaction set hash Hash of the transaction set applied to the previous ledger. -### Close time {#close-time} +### Close time The close time is a UNIX timestamp indicating when the ledger closes. Its accuracy depends on the system clock of the validator proposing the block. Consequently, SCP may confirm a close time that lags a few seconds behind or up to 60 seconds ahead. It's strictly monotonic – guaranteed to be greater than the close time of an earlier ledger. -### Upgrades {#upgrades} +### Upgrades How the network adjusts overall values (like the base fee) and agrees to network-wide changes (like switching to a new protocol version). This field is usually empty. When there is a network-wide upgrade, the SDF will inform and help coordinate participants using the #validators channel on the Dev Discord and the Stellar Validators Google Group. -### Transaction set result hash {#transaction-set-result-hash} +### Transaction set result hash Hash of the results of applying the transaction set. This data is not necessary for validating the results of the transactions. However, it makes it easier for entities to validate the result of a given transaction without having to apply the transaction set to the previous ledger. -### Bucket list hash {#bucket-list-hash} +### Bucket list hash Hash of all the objects in this ledger. The data structure that contains all the objects is called the bucket list. -### Ledger sequence {#ledger-sequence} +### Ledger sequence The sequence number of this ledger. -### Total coins {#total-coins} +### Total coins Total number of lumens in existence. -### Fee pool {#fee-pool} +### Fee pool Number of lumens that have been paid in fees. Note this is denominated in lumens, even though a transaction’s fee field is in stroops. -### Inflation sequence {#inflation-sequence} +### Inflation sequence Number of times inflation has been run. Note: the inflation operation was deprecated when validators voted to upgrade the network to Protocol 12 on 10/28/2019. Therefore, inflation no longer runs, so this sequence number no longer changes. -### ID pool {#id-pool} +### ID pool The last used global ID. These IDs are used for generating objects. -### Maximum number of transactions {#maximum-number-of-transactions} +### Maximum number of transactions The maximum number of operations validators have agreed to process in a given ledger. If more transactions are submitted than this number, the network will enter into surge pricing mode. For more about surge pricing and fee strategies, see our [Fees section](../../fundamentals/fees-resource-limits-metering.mdx). -### Base fee {#base-fee} +### Base fee The fee the network charges per operation in a transaction. Calculated in stroops. See the [Fees section](../../fundamentals/fees-resource-limits-metering.mdx) for more information. -### Base reserve {#base-reserve} +### Base reserve The reserve the network uses when calculating an account’s minimum balance. -### Skip list {#skip-list} +### Skip list Hashes of ledgers in the past. Allows you to jump back in time in the ledger chain without walking back ledger by ledger. There are four ledger hashes stored in the skip list. Each slot contains the oldest ledger that is mod of either 50 5000 50000 or 500000 depending on index skipList[0] mod(50), skipList[1] mod(5000), etc. diff --git a/docs/learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx b/docs/learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx index 8c9f23fcc..30093fa5b 100644 --- a/docs/learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx +++ b/docs/learn/encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx @@ -14,11 +14,11 @@ Users can trade and convert assets on the Stellar network with the use of path p In this section, we will talk about the SDEX and liquidity pools. To learn about how these work together to execute transactions, see our [Path Payments Encyclopedia Entry](../transactions-specialized/path-payments.mdx). -## SDEX {#sdex} +## SDEX The Stellar network acts as a decentralized distributed exchange that allows users to trade and convert assets with the [Manage Buy Offer](../../../data/horizon/api-reference/resources/operations/object/buy-offer.mdx) and [Manage Sell Offer](../../../data/horizon/api-reference/resources/operations/object/sell-offer.mdx) operations. The Stellar ledger stores both the balances held by user accounts and orders that user accounts make to buy or sell assets. -### Order books {#order-books} +### Order books Stellar uses order books to operate its decentralized exchange. @@ -32,7 +32,7 @@ A couple of notes on order books on Stellar: To view an order book chart, see the [Order Book Wikipedia Page](https://en.wikipedia.org/wiki/Order_book). In addition, there are also plenty of video tutorials and articles out there that can help you understand how order books work in greater detail. -### Orders {#orders} +### Orders An account can create orders to buy or sell assets using the Manage Buy Offer, Manage Sell Offer, or Passive Order operations. The account must hold the asset it wants to exchange, and it must trust the issuer of the asset it is trying to buy. @@ -42,21 +42,21 @@ Each order constitutes a selling obligation for the selling asset and buying obl Orders are executed on a price-time priority, meaning orders will be executed based first on price; for orders placed at the same price, the order that was entered earlier is given priority and is executed before the newer one. -### Price and operations {#price-and-operations} +### Price and operations Each order in Stellar is quoted with an associated price and is represented as a ratio of the two assets in the order, one being the “quote asset” and the other being the “base asset”. This is to ensure there is no loss of precision when representing the price of the order (as opposed to storing the fraction as a floating-point number). Prices are specified as a {`numerator`, `denominator`} pair with both components of the fraction represented as 32-bit signed integers. The numerator is considered the base asset, and the denominator is considered the quote asset. When expressing a price of “Asset A in terms of Asset B”, the amount of B is the denominator (and therefore the quote asset), and A is the numerator (and therefore the base asset). As a good rule of thumb, it’s generally correct to be thinking about the base asset that is being bought/sold (in terms of the quote asset). -#### Manage Buy Offer {#manage-buy-offer} +#### Manage Buy Offer When creating a buy order in Stellar via the Manage Buy Offer operation, the price is specified as 1 unit of the base currency (the asset being bought), in terms of the quote asset (the asset that is being sold). For example, if you’re buying 100 XLM in exchange for 20 USD, you would specify the price as {20, 100}, which would be the equivalent of 5 XLM for 1 USD (or \$.20 per XLM). -#### Manage Sell Offer {#manage-sell-offer} +#### Manage Sell Offer When creating a sell order in Stellar via the Manage Sell Offer operation, the price is specified as 1 unit of base currency (the asset being sold), in terms of the quote asset (the asset that is being bought). For example, if you’re selling 100 XLM in exchange for 40 USD, you would specify the price as {40, 100}, which would be the equivalent of 2.5 XLM for 1 USD (or \$.40 per XLM). -#### Passive Order {#passive-order} +#### Passive Order Passive orders allow markets to have zero spread. If you want to exchange USD from anchor A for USD from anchor B at a 1:1 price, you can create two passive orders so the two orders don’t fill each other. @@ -64,23 +64,23 @@ A passive order is an order that does not execute against a marketable counter o An account can place a passive sell order via the Create Passive Sell Offer operation. -### Fees {#fees} +### Fees The order price you set is independent of the fee you pay for submitting that order in a transaction. Fees are always paid in XLM, and you specify them as a separate parameter when submitting the order to the network. To learn more about transaction fees, see our section on [Fees section](../../fundamentals/fees-resource-limits-metering.mdx). -## Liquidity pools {#liquidity-pools} +## Liquidity pools Liquidity pools enable automated market making on the Stellar network. Liquidity refers to how easily and cost-effectively one asset can be converted to another. -### Automated Market Makers (AMMs) {#automated-market-makers-amms} +### Automated Market Makers (AMMs) Instead of relying on the buy and sell orders of decentralized exchanges, AMMs keep assets in an ecosystem liquid 24/7 using liquidity pools. Automated market makers provide liquidity using a mathematical equation. AMMs hold two different assets in a liquidity pool, and the quantities of those assets (or reserves) are inputs for that equation (Asset A \* Asset B = k). If an AMM holds more of the reserve assets, the asset prices move less in response to a trade. -#### AMM pricing {#amm-pricing} +#### AMM pricing AMMs are willing to make some trades and unwilling to make others. For example, if 1 EUR = 1.17 USD, then the AMM might be willing to sell 1 EUR for 1.18 USD and unwilling to sell 1 EUR for 1.16 USD. To determine what trades are acceptable, the AMM enforces an invariant. There are many possible invariants, and Stellar enforces a constant product invariant and so is known as a constant product market maker. This means that AMMs on Stellar must never allow the product of the reserves to decrease. @@ -90,7 +90,7 @@ AMMs decide exchange rates based on the ratio of reserves in the liquidity pool. AMMs charge fees on every trade, which is a fixed percentage of the amount bought by the AMM. For example, if an automated market maker sells 100 EUR for 118 USD then the fee is charged on the USD. The fee is 30 bps, which is equal to 0.30%. If you actually wanted to make this trade, you would need to pay about 118.355 USD for 100 EUR. The automated market maker factors the fees into the constant product invariant, so in reality, the product of the reserves grows after every trade. -### Liquidity pool participation {#liquidity-pool-participation} +### Liquidity pool participation Any eligible participant can deposit assets into a liquidity pool, and in return, receive pool shares representing their ownership of that asset. If there are 150 total pool shares and one user owns 30, they are entitled to withdraw 20% of the liquidity pool asset at any time. @@ -100,7 +100,7 @@ A pool share has two representations. The full representation is used with `Chan AMMs charge a fee on all trades and the participants in the liquidity pool receive a share of the fee proportional to their share of the assets in the liquidity pool. Participants collect these fees when they withdraw their assets from the pool. The fee rate on Stellar is 30 bps, which is equal to 0.30%. These fees are completely separate from the network fees. -### Trustlines {#trustlines} +### Trustlines Users need to establish trustlines to three different assets to participate in a liquidity pool: both the reserve assets (unless one of them is XLM) and the pool share itself. @@ -109,7 +109,7 @@ An account needs a trustline for every pool share it wants to own. It is not pos 1. A pool share trustline cannot be created unless the account already has trustlines that are authorized or authorized to maintain liabilities for the assets in the liquidity pool. See below for more information about how authorization impacts pool share trustlines. 2. A pool share trustline requires 2 base reserves instead of 1. For example, an account (2 base reserves) with a trustline for asset A (1 base reserve), a trustline for asset B (1 base reserve), and a trustline for the A-B pool share (2 base reserves) would have a reserve requirement of 6 base reserves. -### Authorization {#authorization} +### Authorization Pool share trustlines cannot be authorized or de-authorized independently. Instead, the authorization of a pool share trustline is derived from the trustlines for the assets in the liquidity pool. This design is necessary because a liquidity pool may contain assets from two different issuers, and both issuers should have a say in whether the pool share trustline is authorized. @@ -126,17 +126,17 @@ There are a few possibilities with regard to authorization. The behavior of the If the issuer of A or B revokes authorization, then the account will automatically withdraw from every liquidity pool containing that asset and those pool share trustlines will be deleted. We say that these pool shares have been redeemed. For example, if the account participates in the A-B, A-C, and B-C liquidity pools and the issuer of A revokes authorization then the account will redeem from A-B and A-C but not B-C. For each redeemed pool share trustline, a Claimable Balance will be created for each asset contained in the pool if there is a balance being withdrawn and the redeemer is not the issuer of that asset. The claimant of the Claimable Balance will be the owner of the deleted pool share trustline, and the sponsor of the Claimable Balance will be the sponsor of the deleted pool share trustline. The BalanceID of each Claimable Balance is the SHA-256 hash of the `revokeID`. -### Operations {#operations} +### Operations There are two operations that facilitate participation in a liquidity pool: `LiquidityPoolDeposit` and `LiquidityPoolWithdraw`. Use `LiquidityPoolDeposit` to start providing liquidity to the market. Use `LiquidityPoolWithdraw` to stop providing liquidity to the market. However, users don’t need to participate in the pool to take advantage of what it’s offering: an easy way to exchange two assets. For that, just use `PathPaymentStrictReceive` or `PathPaymentStrictSend`. If your application is already using path payments, then you don’t need to change anything for users to take advantage of the prices available in liquidity pools. -### Examples {#examples} +### Examples Here we will cover basic liquidity pool participation and querying. -#### Preamble {#preamble} +#### Preamble For all of the following examples, we’ll be working with three funded Testnet accounts. If you’d like to follow along, generate some keypairs and fund them via the friendbot. @@ -286,7 +286,7 @@ Here, we use `distributeAssets()` to establish trustlines and set up initial bal Note the `orderAssets()` helper here. Operations related to liquidity pools refer to the asset pair arbitrarily as `A` and `B`; however, they must be “ordered” such that `A` < `B`. This ordering is defined by the protocol, but its details should not be relevant (if you’re curious, it’s essentially lexicographically ordered by asset type, code, then issuer). We can use the comparison methods built into the SDKs (like `Asset.compare`) to ensure we pass them in the right order and avoid errors. -#### Participation: Creation {#participation-creation} +#### Participation: Creation First, let's create a liquidity pool for the asset pair defined in the preamble. This involves establishing a trustline to the pool itself: @@ -331,7 +331,7 @@ def establish_pool_trustline(source: Keypair, pool_asset: LiquidityPoolAsset) -> This lets the participants hold pool shares, which means now they can perform deposits and withdrawals. -#### Participation: Deposits {#participation-deposits} +#### Participation: Deposits To work with a liquidity pool, you need to know its ID beforehand. It’s a deterministic value, and only a single liquidity pool can exist for a particular asset pair, so you can calculate it locally from the pool parameters. @@ -400,7 +400,7 @@ When depositing assets into a liquidity pool, you need to define your acceptable Notice that we also specify the maximum amount of each reserve we’re willing to deposit. This, alongside the minimum and maximum prices, helps define boundaries for the deposit, since there can always be a change in the exchange rate between submitting the operation and it getting accepted by the network. -#### Participation: Withdrawals {#participation-withdrawals} +#### Participation: Withdrawals If you own shares of a particular pool, you can withdraw reserves from it. The operation structure mirrors the deposit closely: @@ -471,7 +471,7 @@ def remove_liquidity( Notice here that we specify the minimum amount. Much like with a strict-receive path payment, we’re specifying that we’re not willing to receive less than this amount of each asset from the pool. This effectively defines a minimum withdrawal price. -#### Putting it all together {#putting-it-all-together} +#### Putting it all together Finally, we can combine these pieces together to simulate some participation in a liquidity pool. We’ll have everyone deposit increasing amounts into the pool, then one participant withdraws their shares. Between each step, we’ll retrieve the spot price. @@ -577,7 +577,7 @@ if __name__ == '__main__': -#### Watching Liquidity Pool Activity {#watching-liquidity-pool-activity} +#### Watching Liquidity Pool Activity You can access the transactions, operations, and effects related to a liquidity pool if you want to track its activity. Let’s see how we can track the latest deposits in a pool (suppose `poolId` is defined as before): diff --git a/docs/learn/encyclopedia/security/authorization.mdx b/docs/learn/encyclopedia/security/authorization.mdx index 2ec5027fb..6184e5f33 100644 --- a/docs/learn/encyclopedia/security/authorization.mdx +++ b/docs/learn/encyclopedia/security/authorization.mdx @@ -19,7 +19,7 @@ Authorization differs from _authentication_, which is the narrower problem of ju Authorization often uses cryptographic authentication (via signatures) to support its judgments, but is a broader, more general process. -## Soroban Authorization Framework {#soroban-authorization-framework} +## Soroban Authorization Framework Soroban aims to provide a light-weight, but flexible and extensible framework that allows contracts to implement arbitrarily complex authorization rules, while providing built-in implementation for some common tasks (such as replay prevention). The framework consists of the following components: @@ -33,13 +33,13 @@ Contracts that use Soroban authorization framework are interoperable with each o We realize that it's not possible to cover each and every case, but we hope that the vast majority of the contracts can operate within the framework and thus contribute to building a more cohesive ecosystem. Custom authorization frameworks are still possible to implement, but are not encouraged (unless there are no alternatives). -### Contract-Specific Authorization {#contract-specific-authorization} +### Contract-Specific Authorization -#### Contract storage {#contract-storage} +#### Contract storage Contracts have an exclusive read and write access to their [storage](../../../build/smart-contracts/getting-started/storing-data.mdx) in the ledger. This allows contracts to safely control and manage user access to their data. For example, a token contract may ensure that only the administrator can mint more of the token by storing the administrator identity in its storage. Similarly, it can make sure that only an owner of the balance may transfer that balance. -#### `Address` {#address} +#### `Address` The storage-based approach described in the previous section requires a way to represent the user identities and authenticate them. `Address` type is a host-managed type that performs these functions. @@ -51,7 +51,7 @@ Both functions ensure that the `Address` has authorized the call of the current [auth example]: ../../../build/smart-contracts/example-contracts/auth.mdx -#### Authorizing Sub-contract Calls {#authorizing-sub-contract-calls} +#### Authorizing Sub-contract Calls One of the key features of Soroban Authorization Framework is the ability to easily make authorized sub-contract calls. For example, it is possible for a contract to call `require_auth` for an `Address` and then call `token.xfer` authorized for the same `Address` (see [timelock example] that demonstrates this pattern). @@ -59,7 +59,7 @@ Contracts don't need to do anything special to benefit from this feature. Just c [timelock example]: ../../../build/smart-contracts/example-contracts/timelock.mdx -#### When to `require_auth` {#when-to-require_auth} +#### When to `require_auth` The main authorization-related decision a contract writer needs to make for any given `Address` is whether they need to call `require_auth` for it. While the decision needs to be made on case-by-case basis, here are some rules of thumb: @@ -67,7 +67,7 @@ The main authorization-related decision a contract writer needs to make for any - If the `Address` data in this contract is being modified in a way that's not strictly beneficial to the user, then `require_auth` is probably needed (e.g. reducing the user's token balance needs to be authorized, while increasing it doesn't need to be authorized) - If a contract calls another contract that will call `require_auth` for the `Address` (e.g. `token.xfer`), then adding `require_auth` in the caller would ensure that the authorization for the inner call can't be reused outside of your contract. For example, if you want to do something positive for the user, but only when they have transferred some token to your contract, then the contract call itself should `require_auth`. -#### Authorizing Multiple `Address`es {#authorizing-multiple-addresses} +#### Authorizing Multiple `Address`es There is no explicit restriction on how many `Address` entities the contract uses and how many `Address`es have `require_auth` called. That means that it is possible to authorize a contract call on behalf of multiple users, which may even have different authorization contexts (customized via arguments in `require_auth_for_args`). [Atomic swap] is an example that deals with authorization of two `Address`es. @@ -75,7 +75,7 @@ There is no explicit restriction on how many `Address` entities the contract use Note though, that contracts that deal with multiple authorized `Address`es need a bit more complex support on the client side (to collect and attach the proper signatures). -### Account Abstraction {#account-abstraction} +### Account Abstraction Account abstraction is a way to decouple the authentication logic from the contract-specific authorization rules. The `Address` defined above is in fact an identifier of an 'abstract' account. That is, the contracts know the `Address` and can require authorization from it, but they don't know how exactly it is implemented. @@ -83,13 +83,13 @@ For example, imagine a token contract. Its responsibilities are to manage the ba Account abstraction provides a convenient extension point for every contract that uses `Address` for authorization. It doesn't solve all the issues automatically - client-side tooling may still need to be adapted to support different authentication schemes or different wallets. But the on-chain state doesn't need to be modified and modifying the on-chain state is a much harder problem. -#### Types of Account Implementations {#types-of-account-implementations} +#### Types of Account Implementations Conceptually, every abstract account is a special contract that defines authentication rules and potentially some additional account-specific authorization policies. However, for the sake of optimization and integration with the existing Stellar accounts, Soroban supports 4 different kinds of the account implementations. Below are the general descriptions of these implementations. See the transaction [guide](../contract-development/contract-interactions/stellar-transaction.mdx) for the concrete information of how different accounts are represented. -##### Stellar Account {#stellar-account} +##### Stellar Account Corresponds to `Address::Account`. @@ -99,7 +99,7 @@ This supports the Stellar multisig with medium threshold. See Stellar [documenta [documentation]: ../../encyclopedia/security/signatures-multisig.mdx -##### Transaction Invoker {#transaction-invoker} +##### Transaction Invoker Corresponds to `Address::Account`. @@ -107,13 +107,13 @@ This is also a Stellar account, but its signature is inferred from the source ac This is purely an optimization of the [Stellar Account](#stellar-account) that can skip one signature in case the transaction source account also authorizes the contract invocation. -##### Contract Invoker {#contract-invoker} +##### Contract Invoker Corresponds to `Address::Contract`. This is a special case of an 'account' that may appear only when a contract calls another contract. We consider that since the contract makes a call, then it must be authorizing it (otherwise, it shouldn't have made that call). Hence all the `require_auth` calls made on behalf of the **direct** invoker contract `Address` are considered to be authorized (but not any calls on behalf of the contract deeper down the stack). -##### Custom Account {#custom-account} +##### Custom Account Corresponds to `Address::Contract`. @@ -127,15 +127,15 @@ For the exact interface and more details, see the [custom account example]. [custom account example]: ../../../build/smart-contracts/example-contracts/custom-account.mdx -### Secp256r1, passkeys and smart wallets {#secp256r1-passkeys-and-smart-wallets} +### Secp256r1, passkeys and smart wallets After a successful public validator vote to upgrade Stellar's Mainnet to Protocol 21, the secp256r1 signature scheme was enabled for smart contract transactions. This allows developers to implement passkeys to sign transactions instead of using secret keys or seed phrases. Official documentation is a work in progress, view all passkey and smart wallet information in the [Smart Wallets](../../../build/apps/smart-wallets.mdx) page in the docs. -### Advanced Concepts {#advanced-concepts} +### Advanced Concepts Most of the contracts shouldn't need the concepts described in this section. Refer to this when developing complex contracts that deal with deep contract call trees and/or multiple `Address`es. -#### `require_auth` implementation details {#require_auth-implementation-details} +#### `require_auth` implementation details When a Soroban transaction is executed on-chain, the host collects a list of `SorobanAuthorizationEntry` entries from the transaction ([XDR][soroban-auth-entry]). These entries contain signed authorizer credentials and authorized invocation trees. The host uses these entries to verify authorization during the contract execution. @@ -156,7 +156,7 @@ Notice, that authentication happens just once per tree, as the whole tree needs [soroban-auth-entry]: https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-transaction.x#L570 [signature payload preimage]: https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-transaction.x#L703 -#### Matching Authorized Invocation Trees {#matching-authorized-invocation-trees} +#### Matching Authorized Invocation Trees In order for authorizations to succeed, all the `require_auth`/`require_auth_for_args` calls have to be covered by the corresponding `SorobanAuthorizedInvocation` trees in a transaction (defined in transaction [XDR][invocation-xdr]). @@ -170,7 +170,7 @@ In simpler terms, `SorobanAuthorizedInvocation` trees for an `Address` are subse During the matching process that happens for every `require_auth` host tries to match the current path in `T` to a `SorobanAuthorizedInvocation` tree for the corresponding `Address`. The path is considered to be matched only when there is a corresponding path of _exhausted_ `R` nodes leading to the current call. This means that if the `Address` signs a sequence of calls `A.foo->B.bar->C.baz`, then its authorization check will fail in case if `A.foo` directly calls `C.baz` because `C.baz` strictly has to be called from `B.bar`. -##### Duplicate Addresses {#duplicate-addresses} +##### Duplicate Addresses In case if the same contract function calls `require_auth` for the same `Address` multiple times (e.g. when multiple operations from the same user are being batched), every `require_auth` call still has to have a corresponding node in the `SorobanAuthorizedInvocation` tree. Due to that, there might be multiple valid trees that make all the authorization checks pass. There is nothing wrong about that - the address still must have authorized all the invocations. The only requirement for such cases to be handled correctly is to ensure that the `require_auth` calls for an `Address` happen before the corresponding sub-contract calls. diff --git a/docs/learn/encyclopedia/security/securing-web-based-projects.mdx b/docs/learn/encyclopedia/security/securing-web-based-projects.mdx index df52b9d3b..e12a2237f 100644 --- a/docs/learn/encyclopedia/security/securing-web-based-projects.mdx +++ b/docs/learn/encyclopedia/security/securing-web-based-projects.mdx @@ -5,23 +5,23 @@ sidebar_position: 30 Any application managing cryptocurrency is a frequent target of malicious actors and needs to follow security best practices. The below checklist offers guidance on the most common vulnerabilities. However, even if you follow every piece of advice, security is not guaranteed. Web security and malicious actors are constantly evolving, so it’s good to maintain a healthy amount of paranoia. -## SSL/TLS {#ssltls} +## SSL/TLS Ensure that TLS is enabled. Redirect HTTP to HTTPS where necessary to ensure that Man in the Middle attacks can’t occur and sensitive data is securely transferred between the client and browser. Enable TLS and get an SSL certificate for free at [LetsEncrypt](https://letsencrypt.org/getting-started/). If you don’t have SSL/TLS enabled, stop everything and do this first. -## Content security policy (CSP) headers {#content-security-policy-csp-headers} +## Content security policy (CSP) headers CSP headers tell the browser where it can download static resources from. For example, if you astralwallet.io and it requests a JavaScript file from myevilsite.com, your browser will block it unless it was whitelisted with CSP headers. You can read about how to implement CSP headers [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). Most web frameworks have a configuration file or extensions to specify your CSP policy, and the headers are auto-generated for you. For example, see [Helmet](https://www.npmjs.com/package/helmet) for Node.js. This would have prevented the [Blackwallet Hack](https://www.ccn.com/yet-another-crypto-wallet-hack-causes-users-lose-400000/). -## HTTP strict-transport-security headers {#http-strict-transport-security-headers} +## HTTP strict-transport-security headers This is an HTTP header that tells the browser that all future connections to a particular site should use HTTPS. To implement this, add the [header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) to your website. Some web frameworks (like [Django](https://docs.djangoproject.com/en/2.0/topics/security/#ssl-https)) have this built-in. This would have prevented the [MyEtherWallet DNS Hack](https://bitcoinmagazine.com/articles/popular-ether-wallet-mew-hijacked-dns-attack/). -## Storing sensitive data {#storing-sensitive-data} +## Storing sensitive data Ideally, you don’t have to store much sensitive data. If you must, be sure to tread carefully. There are many strategies to store sensitive data: @@ -31,13 +31,13 @@ Ideally, you don’t have to store much sensitive data. If you must, be sure to - Consult a good cryptographer and read up on best practices. Look into the documentation of your favorite web framework. - Rolling your own crypto is a bad idea. Always use tried and tested libraries such as [NaCI](). -## Monitoring {#monitoring} +## Monitoring Attackers often need to spend time exploring your website for unexpected or overlooked behavior. Examining logs defensively can help you catch onto what they’re trying to achieve. You can at least block their IP or automate blocking based on suspicious behavior. It’s also worth setting up an error reporting (like [Sentry](https://sentry.io/welcome/)). Often, people trigger strange bugs when trying to hack things. -## Authentication weaknesses {#authentication-weaknesses} +## Authentication weaknesses You must build your authentication securely if you have logins for users. The best way to do this is to use something off the shelf. Both Ruby on Rails and Django have robust, built-in authentication schemes. @@ -49,22 +49,22 @@ We strongly prefer 2FA and require U2F or [TOTP](https://tools.ietf.org/html/rfc Finally, require strong passwords. Common and short passwords can be brute-forced. Dropbox has a great [open-source tool](https://blogs.dropbox.com/tech/2012/04/zxcvbn-realistic-password-strength-estimation/) that gauges password strength fairly quickly, making it usable for user interactions. -## Denial of service attacks (DOS) {#denial-of-service-attacks-dos} +## Denial of service attacks (DOS) DOS attacks are usually accomplished by overloading your web servers with traffic. To mitigate this risk, rate limit traffic from IPs and browser fingerprints. Sometimes people will use proxies to bypass IP rate-limiting. In the end, malicious actors can always find ways to spoof their identity, so the surest way to block DOS attacks is to implement proof of work checks in your client or use a managed service like [Cloudflare](https://www.cloudflare.com/ddos/). -## Lockdown unused ports {#lockdown-unused-ports} +## Lockdown unused ports Attackers will often scan your ports to see if you were negligent and left any open. Services like Heroku do this for you- [read about how to enable this on AWS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html). -## Phishing and social engineering {#phishing-and-social-engineering} +## Phishing and social engineering Phishing attacks will thwart any well-formed security infrastructure. Have clear policies published on your website and articulate them to users when they sign up (you will never ask for their password, etc.). Sign messages to your users and prompt users to check the website's domain they are on. -## Scan your website and libraries for vulnerabilities {#scan-your-website-and-libraries-for-vulnerabilities} +## Scan your website and libraries for vulnerabilities Use a tool like [Snyk](https://snyk.io/) to scan your third-party client libraries for vulnerabilities. Make sure to keep your third-party libraries up to date. Often, upgrades are triggered by security exploits. You can use [Mozilla Observatory](https://observatory.mozilla.org/) to check your HTTP security as well. -## Cross-Site Request Forgery Protection (CSRF), SQL injections {#cross-site-request-forgery-protection-csrf-sql-injections} +## Cross-Site Request Forgery Protection (CSRF), SQL injections Most modern web and mobile frameworks handle both CSRF protection and SQL injections. Ensure CSRF protection is enabled and that you are using a database ORM instead of running raw SQL based on user input. For example, see what [Ruby on Rails documentation](http://guides.rubyonrails.org/security.html#sql-injection) says about SQL injections. diff --git a/docs/learn/encyclopedia/security/signatures-multisig.mdx b/docs/learn/encyclopedia/security/signatures-multisig.mdx index 2ca6c150f..29f4db72d 100644 --- a/docs/learn/encyclopedia/security/signatures-multisig.mdx +++ b/docs/learn/encyclopedia/security/signatures-multisig.mdx @@ -15,7 +15,7 @@ Signatures are authorization for transactions on the network. Transactions alway Transaction signatures are created by signing the transaction object contents with a secret key. Stellar uses the ed25519 signature scheme, but there is also a mechanism for adding additional types of public and private key schemes. A transaction with an attached signature is considered to have authorization from that public key. -### Thresholds {#thresholds} +### Thresholds Each operation falls under a specific threshold category: low, medium, or high with a number level between 0-255 (to read more about this see our section on [Operations and Transactions](../../fundamentals/transactions/operations-and-transactions.mdx#operations)). This threshold determines what signature weight is needed to authorize an operation. @@ -25,13 +25,13 @@ Accounts can set their own signature weight, threshold values, and additional si If the master key’s weight is set at 0, it cannot be used to sign transactions, even for operations with a threshold value of 0. Be very careful setting your master key weight to 0. Doing so may permanently lock you out of your account (although if there are other signers listed on the account, they can still continue to sign transactions.) -### Authorization {#authorization} +### Authorization To determine if a transaction has the necessary authorization to run, the weights of all the signatures in the transaction envelope are added up. If this sum is equal to or greater than the threshold for that operation type, then the operation is authorized. This scheme is very flexible. You can require many signers to authorize payments from a particular account. You can have an account that any number of people can authorize for. You can have a master key that grants access or revokes access from others. It supports any m of n setup. -## Multisig {#multisig} +## Multisig In some cases, a transaction may need more than one signature: @@ -40,11 +40,11 @@ In some cases, a transaction may need more than one signature: Each additional signer beyond the master key increases the account’s minimum balance by one base reserve. Up to 20 signatures can be attached to one transaction. Once a signature threshold is met, if there are leftover signatures, the transaction will fail. For example, if your transaction requires three signatures, providing more than three signatures, even if they are all valid, will result in a failed transaction error: `TX_BAD_AUTH_EXTRA`. This design is because unnecessary signature verification has a large effect on performance before accepting transactions in consensus. -### Alternate signature types {#alternate-signature-types} +### Alternate signature types To enable some advanced smart contract features there are a couple of additional signature types. These signature types also have weights and can be added and removed similarly to normal signature types. But rather than check a cryptographic signature for authorization they have a different method of proving validity to the network. -#### Pre-authorized Transaction {#pre-authorized-transaction} +#### Pre-authorized Transaction It is possible for an account to pre-authorize a particular transaction by adding the hash of the future transaction as a signer on the account. To do that, you need to prepare the transaction beforehand with the proper sequence number. Then you can obtain the hash of this transaction and add it as a signer to the account. @@ -52,7 +52,7 @@ Signers of this type are automatically removed from the account when a matching This type of signer is especially useful in escrow accounts. You can pre-authorize two different transactions. Both could have the same sequence number but different destinations. This means that only one of them can be executed. -#### Hash(x) {#hashx} +#### Hash(x) :::note @@ -64,14 +64,14 @@ Adding a signature of type hash(x) allows anyone who knows x to sign the transac First, create a random 256-bit value, which we call x. The SHA256 hash of that value can be added as a signer of type hash(x). Then in order to authorize a transaction, x is added as one of the signatures of the transaction. Keep in mind that x will be known to the world as soon as a transaction is submitted to the network with x as a signature. This means anyone will be able to sign for that account with the hash(x) signer at that point. Often you want there to be additional signers so someone must have a particular secret key and know x in order to reach the weight threshold required to authorize transactions on the account. -## Examples {#examples} +## Examples - Example 1: Anchors - Example 2: Joint accounts - Example 3: Expense accounts - Example 4: Company accounts -### Example 1: Anchors {#example-1-anchors} +### Example 1: Anchors You run an anchor that would like to keep its issuing key offline. That way, it's less likely a bad actor can get ahold of the anchor's key and start issuing credit improperly. However, your anchor needs to authorize people holding credit by running the `Set Trust Line Flags` operation. Before you issue credit to an account, you need to verify that account is OK. @@ -91,7 +91,7 @@ High Threshold: 2 -### Example 2: Joint accounts {#example-2-joint-accounts} +### Example 2: Joint accounts You want to set up a joint account with Bilal and Carina such that any of you can authorize a payment. You also want to set up the account so that, if you choose to change signers (e.g., remove or add someone), a high-threshold operation, all 3 of you must agree. You add Bilal and Carina as signers to the joint account. You also ensure that it takes all of your key weights to clear the high threshold but only one to clear the medium threshold. @@ -110,7 +110,7 @@ Carina's Signing Key Weight: 1 -### Example 3: Expense accounts {#example-3-expense-accounts} +### Example 3: Expense accounts You fully control an expense account, but you want your two coworkers Diyuan and Emil to be able to authorize transactions from this account. You add Diyuan and Emil’s signing keys to the expense account. If either Diyuan or Emil leave the company, you can remove their signing key, a high-threshold operation. @@ -129,7 +129,7 @@ Emil's Key Weight: 1 -### Example 4: Company accounts {#example-4-company-accounts} +### Example 4: Company accounts **Warning**: this example involves setting the master key weight of an account to 0. Be very careful if you decide to do that: that key will no longer be able to sign any kind of transaction, so you are in danger of permanently locking yourself out of your account. Make sure you’ve thought carefully about what you’re doing, that you understand the implications, and that you change weights in the correct order. diff --git a/docs/learn/encyclopedia/storage/persisting-data.mdx b/docs/learn/encyclopedia/storage/persisting-data.mdx index a94d1cf07..12d2297f1 100644 --- a/docs/learn/encyclopedia/storage/persisting-data.mdx +++ b/docs/learn/encyclopedia/storage/persisting-data.mdx @@ -14,7 +14,7 @@ description: Store and access smart contract data. /> -## Ledger entries {#ledger-entries} +## Ledger entries Contracts can access ledger entries of type `CONTRACT_DATA`. Host functions are provided to probe, read, write, and delete `CONTRACT_DATA` ledger entries. @@ -24,23 +24,23 @@ Each `CONTRACT_DATA` ledger entry also holds (in addition to its key) a single v No serialization or deserialization is required in contract code when accessing `CONTRACT_DATA` ledger entries: the host automatically serializes and deserializes any ledger entries accessed, exchanging them with the contract as deserialized values. If a contract wishes to use a custom serialization format, it can store a binary-valued `CONTRACT_DATA` ledger entry and provide its own code to serialize and deserialize, but Soroban has been designed with the intent to minimize the need for contracts to ever do this. -## Access Control {#access-control} +## Access Control Contracts are only allowed to read and write `CONTRACT_DATA` ledger entries owned by the contract: those keyed by the same contract ID as the contract performing the read or write. Attempting to access other `CONTRACT_DATA` ledger entries will cause a transaction to fail. There is no access control for TTL extension operations. Any user may invoke `ExtendFootprintTTLOp` on any LedgerEntry. -## Granularity {#granularity} +## Granularity A `CONTRACT_DATA` ledger entry is read or written from the ledger in its entirety; there is no way to read or write "only a part" of a `CONTRACT_DATA` ledger entry. There is also a fixed overhead cost to accessing any `CONTRACT_DATA` ledger entry. Contracts are therefore responsible for dividing logically "large" data structures into "pieces" with an appropriate size granularity, to use for reading and writing. If pieces are too large there may be unnecessary costs paid for reading and writing unused data, as well as unnecessary contention in parallel execution; but if pieces are too small there may be unnecessary costs paid for the fixed overhead of each entry. -## Footprints and parallel contention {#footprints-and-parallel-contention} +## Footprints and parallel contention Contracts are only allowed to access ledger entries specified in the footprint of their transaction. Transactions with overlapping footprints are said to contend, and will only execute sequentially with respect to one another, on a single thread. Transactions with non-overlapping footprints may execute in parallel. This means that a finer granularity of `CONTRACT_DATA` ledger entries may reduce artificial contention among transactions using a contract, and thereby increase parallelism. -## Contract Data Best Practices {#contract-data-best-practices} +## Contract Data Best Practices -### Account State vs. Shared State {#account-state-vs-shared-state} +### Account State vs. Shared State While there is no distinction between "account" state and "shared" state at the protocol level, it can be helpful to think of data in these terms when deciding what storage type and TTL Extension strategy to use for a given use case. As a guideline, account and shared state can be described as follows: @@ -57,7 +57,7 @@ While there is no distinction between "account" state and "shared" state at the - Note: Sometimes account and shared state can merge when the contract scope is small - I.e. smart wallet or a single nft, where a new contract instance is generated for each account -### Owned Contracts vs. Autonomous Contracts {#owned-contracts-vs-autonomous-contracts} +### Owned Contracts vs. Autonomous Contracts In addition to the types of state, it is also helpful to consider the type of contract instance being used. Again, these types are not enforced at the protocol level, but can be helpful. @@ -69,7 +69,7 @@ In addition to the types of state, it is also helpful to consider the type of co - Contract instance that have not clear owner, or have a decentralized group of owners - Most DeFi protocols, especially non-upgradable ones -### Best Practices {#best-practices} +### Best Practices - Prefer `Temporary` over `Persistent` and `Instance` storage - Anything that can have a timeout should be `Temporary` with TTL set to the timeout. See the [resource limits table](../../../networks/resource-limits-fees.mdx) for the current maximum TTL/timeout. diff --git a/docs/learn/encyclopedia/storage/state-archival.mdx b/docs/learn/encyclopedia/storage/state-archival.mdx index 6310c2c0c..db558a929 100644 --- a/docs/learn/encyclopedia/storage/state-archival.mdx +++ b/docs/learn/encyclopedia/storage/state-archival.mdx @@ -23,18 +23,18 @@ All contract data has a Time To Live (TTL) that must be periodically extended. I - When a `Temporary` entry's TTL is 0, it is deleted from the ledger and is permanently inaccessible. - When a `Persistent` or `Instance` entry TTL is 0, it becomes inaccessible and is "archived", but can be "restored" and used again via the [`RestoreFootprintOp`](#restorefootprintop). -## Contract Data Type Descriptions {#contract-data-type-descriptions} +## Contract Data Type Descriptions The general usage and interface are identical for all storage types. They differ only in fees and archival behavior as follows: -### `Temporary` {#temporary} +### `Temporary` - Cheapest fees. - Permanently deleted when TTL goes to 0, cannot be restored. - Suitable for time-bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data. - Unlimited amount of storage. -### `Instance` {#instance} +### `Instance` - Most expensive fees (same price as `Persistent` storage). - Archived when TTL goes to 0, can be restored using the [`RestoreFootprintOp`](#restorefootprintop) operation. @@ -42,7 +42,7 @@ The general usage and interface are identical for all storage types. They differ - Limited amount of storage available. - Suitable for "shared" contract state that cannot be `Temporary` (i.e. admin accounts, contract metadata, etc.). -### `Persistent` {#persistent} +### `Persistent` - Most expensive fees (same price as `Instance` storage). - Archived when TTL goes to 0, can be restored using the [`RestoreFootprintOp`](#restorefootprintop) operation. @@ -50,7 +50,7 @@ The general usage and interface are identical for all storage types. They differ - Unlimited amount of storage. - Suitable for user data that cannot be `Temporary` (i.e. balances). -## Contract Data Best Practices {#contract-data-best-practices} +## Contract Data Best Practices As a general rule, `Temporary` storage should only be used for data that can be easily recreated or is only valid for a period of time, whereas `Persistent` or `Instance` storage should be used for data that cannot be recreated and should be kept permanently, such as a user's token balance. @@ -71,13 +71,13 @@ A call to `extend_ttl(N)` ensures that the current TTL of the contract instance In addition to contract-defined TTL extensions using the `extend_ttl()` function, a contract data entry's TTL can be extended via the [`ExtendFootprintTTLOp`](#extendfootprintttlop) operation. -## Contract Code and Contract Instance lifetimes {#contract-code-and-contract-instance-lifetimes} +## Contract Code and Contract Instance lifetimes Contract code entries and contract instances have lifetimes, and there are a couple ways to extend them. Methods like `env.storage().instance().extend_ttl()` and `env.deployer().extend_ttl()` extend both the contract code and contract instance. The threshold check and extensions are done independently for both the contract code and contract instance, so it’s possible that one is bumped but not the other depending on what the current TTL’s are. If you would like to extend the contract code or contract instance separately, you can use `env.deployer().extend_ttl_for_code()` and `env.deployer().extend_ttl_for_contract_instance()` respectively. Calling both with the same parameters is equivalent to calling only `env.deployer().extend_ttl()`. -## Behavior of transactions that try to access an archived Persistent entry {#behavior-of-transactions-that-try-to-access-an-archived-persistent-entry} +## Behavior of transactions that try to access an archived Persistent entry Here are some important points to keep in mind when it comes to archived entries - @@ -85,31 +85,31 @@ Here are some important points to keep in mind when it comes to archived entries 2. Due to the previous point that archived entries can never make it into smart contract logic, there is no reason to write code in your contract to handle archived entries. The same applies to contract test cases - while you may want to write tests that check if your extension logic is correct, you don't need to write archival tests because the transaction will fail before getting to the contract. It is possible though to access an archived entry in a Soroban test case, in which case the host will panic. You can read more about this in [Test TTL Extensions](../../../build/guides/archival/test-ttl-extension.mdx). 3. Archived persistent entries can never be re-created. They must instead be restored. Once they are restored, then they can be modified or deleted. -## Terms and Semantics {#terms-and-semantics} +## Terms and Semantics -### Live Until Ledger {#live-until-ledger} +### Live Until Ledger Each `ContractData` and `ContractCode` entry has a `liveUntilLedger` field stored in its `LedgerEntry`. The entry is no longer live (i.e. either archived or deleted depending on storage type) when `current_ledger > liveUntilLedger`. -### TTL {#ttl} +### TTL An entry's Time To Live (TTL) is defined as how many ledgers remain until the entry is no longer live. For example, if the current ledger is 5 and an entry's live until ledger is 15, then the entry's TTL is 10 ledgers. -### Minimum TTL {#minimum-ttl} +### Minimum TTL For each entry type, there is a minimum TTL that the entry will have when being created or restored. This TTL minimum is enforced automatically at the protocol level. Minimum TTL is a network parameter. Refer to the [resource reference](../../../networks/resource-limits-fees.mdx) to find the current values. -### Maximum TTL {#maximum-ttl} +### Maximum TTL On any given ledger, an entry's TTL can be extended up to the maximum TTL. This is a network parameter (see the [resource limits table](../../../networks/resource-limits-fees.mdx) for the current maximum TTL). Maximum TTL is not enforced based on when an entry was created, but based on the current ledger. For example, if an entry is created on January 1st, 2024, its TTL could initially be extended up to January 1st, 2025. After this initial TTL extension, if the entry received another TTL extension later on January 10th, 2024, the TTL could be extended up to January 10th, 2025. The `max_ttl()` function can be used to determine the current maximum allowed TTL. -## Operations {#operations} +## Operations -### ExtendFootprintTTLOp {#extendfootprintttlop} +### ExtendFootprintTTLOp -#### Semantics {#semantics} +#### Semantics XDR: @@ -143,11 +143,11 @@ entry2 and entry3 will not be updated because they already have an liveUntilLedger that is large enough. ``` -#### Transaction resources {#transaction-resources} +#### Transaction resources `ExtendFootprintTTLOp` is a Soroban operation, and therefore must be the only operation in a transaction. The transaction also needs to populate `SorobanTransactionData` transaction extension explained [here](../contract-development/contract-interactions/stellar-transaction.mdx#transaction-resources). To fill out `SorobanResources`, use the transaction simulation mentioned in the provided link, or make sure `readBytes` includes the key and entry size of every entry in the `readOnly` set. -### RestoreFootprintOp {#restorefootprintop} +### RestoreFootprintOp XDR: @@ -168,17 +168,17 @@ The restored entry will have its live until ledger extended to the [minimum] the [minimum]: https://github.com/stellar/stellar-core/blob/2109a168a895349f87b502ae3d182380b378fa47/src/ledger/NetworkConfig.h#L77-L78 -#### Transaction resources {#transaction-resources-1} +#### Transaction resources `RestoreFootprintOp` is a Soroban operation, and therefore must be the only operation in a transaction. The transaction also needs to populate `SorobanTransactionData` transaction extension explained [here](../contract-development/contract-interactions/stellar-transaction.mdx#transaction-resources). To fill out `SorobanResources`, use the transaction simulation mentioned in the provided link, or make sure `writeBytes` includes the key and entry size of every entry in the `readWrite` set and make sure `extendedMetaDataSizeBytes` is at least double of `writeBytes`. --- -## Examples {#examples} +## Examples We've done our best to build tooling around state archival in both the Stellar RPC server as well as the JavaScript SDK to make it easier to deal with, and this set of examples demonstrates how to leverage it. -### Overview {#overview} +### Overview Both restoring and extending the TTL of ledger entries follows a three-step process regardless of their nature (contract data, instances, etc.): @@ -195,13 +195,13 @@ Each of the examples below will follow a structure like this. We'll work our way Remember, though, that any combination of these scenarios can occur in reality. -### Preparation {#preparation} +### Preparation In order to help the scaffolding of the code, we'll reuse the rudimentary, retry-enabled transaction polling function `yeetTx` which we outlined in [another guide](/build/guides/transactions/submit-transaction-wait-js.mdx). In the following code, we will also leverage [`Server.prepareTransaction`](https://stellar.github.io/js-soroban-client/Server.html#prepareTransaction). This is a helpful method that, given a transaction, will simulate it, then amend the transaction with the simulation results (fees, etc.) and return that. Then, it can just be signed and submitted. We will also use [`SorobanDataBuilder`](https://stellar.github.io/js-stellar-sdk/SorobanDataBuilder.html), a convenient abstraction that lets us use a [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) to set the appropriate storage footprints for a transaction. -### Example: My data is archived! {#example-my-data-is-archived} +### Example: My data is archived! We'll start with the likeliest occurrence: my piece of persistent data is archived because I haven't interacted with my contract in a while. How do I make it accessible again? @@ -291,7 +291,7 @@ Notice that when restoration is required, **simulation still succeeds**. The way This is great, as it means fewer round-trips to get going again! -### Example: My contract is archived! {#example-my-contract-is-archived} +### Example: My contract is archived! As you can imagine, if your deployed contract instance or the code that backs it is archived, it can't be loaded to execute your invocations. Remember, there's a distinct, one-to-many relationship on the chain between a contract's code and deployed instances of that contract: diff --git a/docs/learn/encyclopedia/transactions-specialized/claimable-balances.mdx b/docs/learn/encyclopedia/transactions-specialized/claimable-balances.mdx index 7aadb3036..6d0756885 100644 --- a/docs/learn/encyclopedia/transactions-specialized/claimable-balances.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/claimable-balances.mdx @@ -18,13 +18,13 @@ Each ClaimableBalanceEntry is a ledger entry, and each claimant in that entry in Once a ClaimableBalanceEntry has been claimed, it is deleted. -## Operations {#operations} +## Operations -### Create Claimable Balance {#create-claimable-balance} +### Create Claimable Balance For basic parameters, see the Create Claimable Balance entry in our [List of Operations section](../../fundamentals/transactions/list-of-operations.mdx#create-claimable-balance). -#### Additional parameters {#additional-parameters} +#### Additional parameters `Claim_Predicate_` Claimant — an object that holds both the destination account that can claim the ClaimableBalanceEntry and a ClaimPredicate that must evaluate to true for the claim to succeed. @@ -42,13 +42,13 @@ A ClaimPredicate is a recursive data structure that can be used to construct com A successful Create Claimable Balance operation will return a Balance ID, which is required when claiming the ClaimableBalanceEntry with the Claim Claimable Balance operation. -### Claim Claimable Balance {#claim-claimable-balance} +### Claim Claimable Balance For basic parameters, see the Claim Claimable Balance entry in our [List of Operations section](../../fundamentals/transactions/list-of-operations#claim-claimable-balance). This operation will load the ClaimableBalanceEntry that corresponds to the Balance ID and then search for the source account of this operation in the list of claimants on the entry. If a match on the claimant is found, and the ClaimPredicate evaluates to true, then the ClaimableBalanceEntry can be claimed. The balance on the entry will be moved to the source account if there are no limit or trustline issues (for non-native assets), meaning the claimant must establish a trustline to the asset before claiming it. -### Clawback Claimable Balance {#clawback-claimable-balance} +### Clawback Claimable Balance This operation claws back a claimable balance, returning the asset to the issuer account, burning it. You must claw back the entire claimable balance, not just part of it. Once a claimable balance has been claimed, use the regular clawback operation to claw it back. @@ -56,7 +56,7 @@ Clawback claimable balances require the claimable balance ID. Learn more about clawbacks in our [Clawback Encyclopedia Entry](./clawbacks.mdx). -## Example {#example} +## Example The below code demonstrates via both the JavaScript and Go SDKs how an account (Account A) creates a ClaimableBalanceEntry with two claimants: Account A (itself) and Account B (another recipient). diff --git a/docs/learn/encyclopedia/transactions-specialized/clawbacks.mdx b/docs/learn/encyclopedia/transactions-specialized/clawbacks.mdx index 5327b0319..878391b99 100644 --- a/docs/learn/encyclopedia/transactions-specialized/clawbacks.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/clawbacks.mdx @@ -15,37 +15,37 @@ Clawbacks are useful for: - Responding to regulatory actions - Enabling identity-proofed persons to recover an enabled asset in the event of loss of key custody or theft -## Operations {#operations} +## Operations -### Set Options {#set-options} +### Set Options The issuer sets up their account to enable clawbacks using the `AUTH_CLAWBACK_ENABLED` flag. This causes every subsequent trustline established from the account to have the `TRUSTLINE_CLAWBACK_ENABLED_FLAG` set automatically. If an issuing account wants to set the `AUTH_CLAWBACK_ENABLED_FLAG`, it must have the `AUTH_REVOCABLE_FLAG` set. This allows an asset issuer to claw back balances locked up in offers by first revoking authorization from a trustline, which pulls all offers that involve that trustline. The issuer can then perform the clawback. -### Clawback {#clawback} +### Clawback The issuing account uses this operation to claw back some or all of an asset. Once an account holds a particular asset for which clawbacks have been enabled, the issuing account can claw it back, burning it. You need to provide the asset, a quantity, and the account from which you’re clawing back the asset. -### Clawback Claimable Balance {#clawback-claimable-balance} +### Clawback Claimable Balance This operation claws back a claimable balance, returning the asset to the issuer account, burning it. You must claw back the entire claimable balance, not just part of it. Once a claimable balance has been claimed, use the regular clawback operation to claw it back. Clawback claimable balances require the claimable balance ID. -### Set Trust Line Flag {#set-trust-line-flag} +### Set Trust Line Flag Remove clawback capabilities on a specific trustline by removing the `TRUSTLINE_CLAWBACK_ENABLED_FLAG` via the `SetTrustLineFlags` operation. You can only clear a flag, not set it. So clearing a clawback flag on a trustline is irreversible. This is done so that you don’t retroactively change the rules on your asset holders. If you’d like to enable clawbacks again, holders must reissue their trustlines. -## Examples {#examples} +## Examples Here we’ll cover the following approaches to clawing back an asset. **Example 1:** Issuing account (Account A) creates a clawback-enabled asset and sends it to Account B. Account B sends that asset to Account C. Account A will then clawback the asset from C. **Example 2:** Account B creates a claimable balance for Account C, and Account A claws back the claimable balance. **Example 3:** Account A issues a clawback-enabled asset to Account B. A claws back some of the asset from B, then removes the clawback enabled flag from the trustline and can no longer clawback the asset. -### Preamble: Issuing a Clawback-able Asset {#preamble-issuing-a-clawback-able-asset} +### Preamble: Issuing a Clawback-able Asset First, we’ll set up an account to enable clawbacks and issue an asset accordingly. @@ -139,7 +139,7 @@ function showBalances(accounts) { -### Example 1: Payments {#example-1-payments} +### Example 1: Payments With the shared setup code out of the way, we can now demonstrate how clawback works for payments. This example will highlight how the asset issuer holds control over their asset regardless of how it gets distributed to the world. @@ -221,7 +221,7 @@ Notice that `GCIHA` (Account A, the issuer) holds none of the asset despite claw (It may be strange that A never holds any tokens of its custom asset, but that’s exactly how issuing works: you create value where there used to be none. Sending an asset to its issuing account is equivalent to burning it, and auditing the total amount of an asset in existence is one of the benefits of properly distributing an asset via a distribution account, which we avoid doing here for example brevity.) -### Example 2: Claimable Balances {#example-2-claimable-balances} +### Example 2: Claimable Balances Direct payments aren’t the only way to transfer assets between accounts: claimable balances also do this. Since they are a separate payment mechanism, they need a separate clawback mechanism. @@ -294,7 +294,7 @@ GDS5N: 500 GC2BK: 0 ``` -### Example 3: Selectively Enabling Clawback {#example-3-selectively-enabling-clawback} +### Example 3: Selectively Enabling Clawback When you enable the `AUTH_CLAWBACK_ENABLED_FLAG` on your account, it will make all future trustlines have clawback enabled for any of your issued assets. This may not always be desirable as you may want certain assets to behave as they did before. Though you could work around this by reissuing assets from a “dedicated clawback” account, you can also simply disable clawbacks for certain trustlines by clearing the `TRUST_LINE_CLAWBACK_ENABLED_FLAG` on a trustline. diff --git a/docs/learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx b/docs/learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx index c0eb6dc7d..1db55ff21 100644 --- a/docs/learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/fee-bump-transactions.mdx @@ -12,7 +12,7 @@ A fee-bump transaction is made of two parts: 1. An inner transaction envelope with its signature(s) 2. An outer transaction envelope with the fee-bump transaction and fee account signature -## Common use cases {#common-use-cases} +## Common use cases You may want to consider using fee bumps when: @@ -20,31 +20,31 @@ You may want to consider using fee bumps when: - You want to increase the fee on an existing transaction so it has a better chance of making it to the ledger during surge pricing - You need to adjust the fee on a pre-authorized transaction so it can make it to the ledger if minimum network fees have increased -## Attributes {#attributes} +## Attributes -### Existing transaction envelope (inner transaction) {#existing-transaction-envelope-inner-transaction} +### Existing transaction envelope (inner transaction) Before creating a fee-bump transaction, you must first have a transaction wrapped with its signatures in a transaction envelope. We’ll call this transaction the inner transaction. -### Fee account {#fee-account} +### Fee account The account that will pay the fee for the fee-bump transaction. This account will incur the fee instead of the source account specified in the inner transaction. The sequence number is still taken from the source account, however. -### Fee {#fee} +### Fee The maximum per-operation fee you’re willing to pay for the fee-bump transaction. The fee-bump transaction is one operation. Therefore, the total number of operations is equal to the number of operations in the inner transaction plus one. Read more about transaction fees in our [Fees section](../../fundamentals/fees-resource-limits-metering.mdx). -### Replace-by-fee {#replace-by-fee} +### Replace-by-fee You can apply a fee-bump transaction to increase a fee originating from your own account. However, if you submit two distinct transactions with the same source account and sequence number with the second transaction being a fee-bump transaction, the second transaction will replace the first transaction in the queue if and only if the fee bid of the second transaction is 10x the fee bid of the first transaction. This number may seem random, it is a deliberate design decision to limit DOS attacks without introducing too much complexity to the protocol. -### Fee-bump transaction envelope {#fee-bump-transaction-envelope} +### Fee-bump transaction envelope When a fee-bump transaction is ready to be signed, it’s wrapped in a transaction envelope. This envelope contains the fee-bump transaction and the signature of the specified fee account. -## Validity of a fee-bump transaction {#validity-of-a-fee-bump-transaction} +## Validity of a fee-bump transaction A fee-bump transaction goes through a series of checks in its lifecycle to determine validity. The following conditions must be met: @@ -57,13 +57,13 @@ A fee-bump transaction goes through a series of checks in its lifecycle to deter - **Fee account balance** — the fee account must have a sufficient XLM balance to cover the fee - **Inner transaction** — the inner transaction must be valid, which means it must meet the requirements described in the [Validity of a Transaction section](../../fundamentals/transactions/operations-and-transactions.mdx#transaction-and-operation-validity). If validation of the inner transaction is successful, then the result is `FEE_BUMP_INNER_SUCCESS`, and the validation results from the validation of the inner transaction appear in the inner result. If the inner transaction is invalid, the result is `FEE_BUMP_INNER_FAILED`, and the fee-bump transaction is invalid because the inner transaction is invalid. -## Application {#application} +## Application The sole purpose of a fee-bump transaction is to get an inner transaction included in a transaction set. Since the fee-bump transaction has no side effects other than paying a fee — and at the time the fee is paid the outer transaction must have been valid (otherwise nodes would not have voted for it) — there is no reason to check the validity of the fee-bump transaction at apply time. Therefore, the sequence number of the inner transaction is always consumed at apply time. The inner transaction, however, will still have its validity checked at apply time. Every fee-bump transaction result contains a complete inner transaction result. This inner-transaction result is exactly what would have been produced had there been no fee-bump transaction, except that the inner fee will always be 0. -## Example: implementing a fee-bump transaction {#example-implementing-a-fee-bump-transaction} +## Example: implementing a fee-bump transaction This example shows how to create and submit a fee-bump transaction on the Stellar network. Replace secret key values, `SECREY_KEY_1` and `SECREY_KEY_2` of keypairs of your choosing. This is not a production example, and you should take care to never expose your secret keys on the web. diff --git a/docs/learn/encyclopedia/transactions-specialized/memos.mdx b/docs/learn/encyclopedia/transactions-specialized/memos.mdx index 8c838f194..9ac512dad 100644 --- a/docs/learn/encyclopedia/transactions-specialized/memos.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/memos.mdx @@ -16,7 +16,7 @@ Memos can be one of the following types: `MEMO_HASH`: A 32-byte hash. `MEMO_RETURN`: A 32-byte hash intended to be interpreted as the hash of the transaction the sender is refunding. -## Memo content examples {#memo-content-examples} +## Memo content examples - Notifying that the transaction is a refund or reimbursement - Reference to an invoice the transaction is paying diff --git a/docs/learn/encyclopedia/transactions-specialized/path-payments.mdx b/docs/learn/encyclopedia/transactions-specialized/path-payments.mdx index 9c438ab8b..1b98630aa 100644 --- a/docs/learn/encyclopedia/transactions-specialized/path-payments.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/path-payments.mdx @@ -13,19 +13,19 @@ It is possible for path payments to fail if there are no viable exchange paths. For more information on the Stellar Decentralized Exchange and Liquidity Pools, see our [Liquidity on Stellar: SDEX and Liquidity Pools Encyclopedia Entry](../sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx) -## Operations {#operations} +## Operations Path payments use the Path Payment Strict Send or Path Payment Strict Receive operations. -### Path Payment Strict Send {#path-payment-strict-send} +### Path Payment Strict Send Allows a user to specify the amount of the asset to send. The amount received will vary based on offers in the order books and/or liquidity pools. -### Path Payment Strict Receive {#path-payment-strict-receive} +### Path Payment Strict Receive Allows a user to specify the amount of the asset received. The amount sent will vary based on the offers in the order books/liquidity pools. -## Path payments - more info {#path-payments---more-info} +## Path payments - more info - Path payments don’t allow intermediate offers to be from the source account as this would yield a worse exchange rate. You’ll need to either split the path payment into two smaller path payments or ensure that the source account’s offers are not at the top of the order book. - Balances are settled at the very end of the operation. diff --git a/docs/learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx b/docs/learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx index 8bcf06650..f12a6dfce 100644 --- a/docs/learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/pooled-accounts-muxed-accounts-memos.mdx @@ -11,13 +11,13 @@ You can create a Stellar account for each user, but most custodial services, inc Note that we used memos in the past for this purpose, however, using muxed accounts is better in the long term. At this time, there isn't support for muxed accounts by all wallets, exchanges, and anchors, so you may want to support both memos and muxed accounts, at least for a while. -## Pooled accounts {#pooled-accounts} +## Pooled accounts A pooled account allows a single Stellar account ID to be shared across many users. Generally, services that use pooled accounts track their customers in a separate, internal database and use the muxed accounts feature to map an incoming and outgoing payment to the corresponding internal customer. The benefits of using a pooled account are lower costs – no base reserves are needed for each account – and lower key complexity – you only need to manage one account keypair. However, with a single pooled account, it is now your responsibility to manage all individual customer balances and payments. You can no longer rely on the Stellar ledger to accumulate value, handle errors and atomicity, or manage transactions on an account-by-account basis. -## Muxed accounts {#muxed-accounts} +## Muxed accounts Muxed accounts are embedded into the protocol for convenience and standardization. They distinguish individual accounts that all exist under a single, traditional Stellar account. They combine the familiar `GABC…` address with a 64-bit integer ID. @@ -29,7 +29,7 @@ It is safe for all wallets to implement sending to muxed accounts. If you wish to receive deposits to muxed accounts please keep in mind that they are not yet supported by all wallets and exchanges. -### Address format {#address-format} +### Address format Muxed accounts have their own address format that starts with an M prefix. For example, from a traditional Stellar account address: `GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ`, we can create new muxed accounts with different IDs. The IDs are embedded into the address itself- when you parse the muxed account addresses, you get the G address from above plus another number. @@ -38,7 +38,7 @@ Muxed accounts have their own address format that starts with an M prefix. For e Both of these addresses will act on the underlying `GA7Q…` address when used with one of the supported operations. -### Supported operations {#supported-operations} +### Supported operations Not all operations can be used with muxed accounts. Here is what you can use them for: @@ -55,7 +55,7 @@ We will demonstrate some of these in the examples section. There’s no validation on IDs and as far as the Stellar network is concerned, all supported operations operate exactly as if you did not use a muxed account. For example, if you make two payments from two muxed accounts that share an underlying Stellar account (same G… address but different M… addresses) this is exactly the same as that single Stellar account sending two payments according to the ledger. Even though only the underlying `G…` account truly exists on the Stellar ledger, the Horizon API will make an effort to interpret and track the muxed accounts responsible for certain actions. -### Examples {#examples} +### Examples In this section, we’ll demonstrate how to create muxed accounts and how they interface with their supported operations. Since custodial account workarounds based on transaction memos are unnecessary now, we’ll use that as a skeleton for our example structure. @@ -67,7 +67,7 @@ Example 3: Fully muxed payments (i.e. M to M) But use a shared function for all of them that does the real work, highlighting the ease of implementing muxed account support. -#### Preamble {#preamble} +#### Preamble First, let’s create two accounts and then a handful of virtual accounts representing “custodial customers” that the parent account manages: @@ -127,7 +127,7 @@ Customers: With the accounts out of the way, let’s look at how we can manage the difference between traditional Stellar accounts (G...) and these virtual muxed accounts (M...). -#### Muxed Operations Model {#muxed-operations-model} +#### Muxed Operations Model The introduction of muxed addresses as a higher-level abstraction—and their experimental, opt-in nature—means there are mildly diverging branches of code depending on whether the source is a muxed account or not. We still need to, for example, load accounts by their underlying address, because the muxed versions don’t actually live on the Stellar ledger: @@ -151,7 +151,7 @@ function showBalance(acc) { For payments—our focus for this set of examples—the divergence only matters because we want to show the balances for the custodian account. -#### Payments {#payments} +#### Payments The actual code to build payments is almost exactly the same as it would be without the muxed situation: @@ -190,7 +190,7 @@ function doPayment(source, dest) { We can use this block to make a payment between normal Stellar accounts with ease: doPayment("GCIHA...", "GDS5N..."). The main divergence from the standard payments code—aside from the stubs to show XLM balances before and after—is the inclusion of the opt-in withMuxing flag. -#### Muxed to Unmuxed {#muxed-to-unmuxed} +#### Muxed to Unmuxed The codeblock above covers all payment operations, abstracting away any need for differentiating between muxed (M...) and unmuxed (G...) addresses. From a high level, then, it’s still trivial to make payments between one of our “customers” and someone outside of the “custodian’s” organization. @@ -220,7 +220,7 @@ GCIHA: 9509.9997600 XLM Of course, there’s also a fee charged for the transaction itself. -#### Muxed to Muxed {#muxed-to-muxed} +#### Muxed to Muxed As we’ve mentioned, muxed account actions aren’t represented in the Stellar ledger explicitly. When two muxed accounts sharing an underlying Stellar account communicate, it’s as if the underlying account is talking to itself. A payment between two such accounts, then, is essentially a no-op. @@ -250,11 +250,11 @@ Notice that the account’s balance is essentially unchanged, yet it was charged If we were to make a payment between two muxed accounts that had different underlying Stellar accounts, this would be equivalent to a payment between those two respective G... accounts. -#### More Examples {#more-examples} +#### More Examples As is the case for most protocol-level features, you can find more usage examples and inspiration in the relevant test suite for your favorite SDK. For example, [here](https://github.com/stellar/js-stellar-base/blob/master/test/unit/muxed_account_test.js) are some of the JavaScript test cases. -### FAQs {#faqs} +### FAQs **What happens if I pay a muxed address, but the recipient doesn’t support them?** @@ -329,13 +329,13 @@ namespace StrKey { There are also abstractions for constructing and managing both muxed and regular accounts; consult your SDK documentation for details. -## Memo - differentiated accounts {#memo---differentiated-accounts} +## Memo - differentiated accounts Prior to the introduction of muxed accounts, products and services that relied on pooled accounts often used transaction memos to differentiate between users. Supporting muxed accounts is better in the long term, but for now you may want to support both memos and muxed accounts as all exchanges, anchors, and wallets may not support muxed accounts. To learn about what other purposes memos can be used for, see our [Memos Encyclopedia Entry](./memos.mdx). -## Why are muxed accounts better in the long term? {#why-are-muxed-accounts-better-in-the-long-term} +## Why are muxed accounts better in the long term? Muxed accounts are a better approach to differentiating between individuals in a pooled account because they have better: diff --git a/docs/learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx b/docs/learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx index 812072fb5..489afa155 100644 --- a/docs/learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx +++ b/docs/learn/encyclopedia/transactions-specialized/sponsored-reserves.mdx @@ -13,9 +13,9 @@ Anything that increases the minimum balance can be sponsored (account creation, To learn about base reserves, see our section on [Lumens](../../fundamentals/lumens.mdx#base-reserves). -## Sponsored reserves operations {#sponsored-reserves-operations} +## Sponsored reserves operations -### Begin and end sponsorships {#begin-and-end-sponsorships} +### Begin and end sponsorships To create a sponsored reserve, you have to use a sandwich transaction that includes three operations. @@ -31,7 +31,7 @@ At the end of any transaction, there must be no ongoing is-sponsoring-future-res View operation details in our [List of Operations section](../../fundamentals/transactions/list-of-operations.mdx). -### Revoke sponsorship {#revoke-sponsorship} +### Revoke sponsorship Allows the sponsoring account to remove or transfer sponsorships of existing ledgerEntries and signers. If the ledgerEntry or signer is not sponsored, the owner of the ledgerEntry or signer can establish a sponsorship if it is the beneficiary of an is-sponsoring-future-reserves-for relationship. @@ -50,7 +50,7 @@ Operation logic View operation details in our [List of Operations section](../../fundamentals/transactions/list-of-operations.mdx#begin-sponsoring-future-reserves). -## Effect on minimum balance {#effect-on-minimum-balance} +## Effect on minimum balance Once sponsorships are introduced, the minimum balance calculation is: (2 base reserves + `numSubEntries` + `numSponsoring` - `numSponsored`) \* `baseReserve` + `liabilities.selling`. @@ -60,13 +60,13 @@ When a sponsored entry or subentry is removed, `numSponsoring` is decreased on t To learn more about minimum balance requirements, see our section on [Lumens](../../fundamentals/lumens.mdx#minimum-balance). -## Effect on claimable balances {#effect-on-claimable-balances} +## Effect on claimable balances All claimable balances are sponsored through built-in logic in the claimable balance operations. The account that creates the claimable balance pays the base reserve to get the claimable balance on the ledger. When the claimable balance is claimed by the claimant(s), the claimable balance is removed from the ledger, and the account that created it gets the base reserve back. Read more about claimable balances in our [Claimable Balances Encyclopedia Entry](./claimable-balances.mdx). -## Examples {#examples} +## Examples Each of the following examples builds on itself, referencing variables from previous snippets. The following examples will demonstrate: @@ -77,7 +77,7 @@ Each of the following examples builds on itself, referencing variables from prev For brevity in the Golang examples, we’ll assume the existence of a `SignAndSend`(...) method (defined below) which creates and submits a transaction with the proper parameters and basic error-checking. -### Preamble {#preamble} +### Preamble We’ll start by including the boilerplate of account and asset creation. @@ -169,7 +169,7 @@ func main() { -### 1. Sponsoring trustlines {#1-sponsoring-trustlines} +### 1. Sponsoring trustlines Now, let’s sponsor trustlines for Account A. Notice how the `CHANGE_TRUST` operation is sandwiched between the begin and end sponsoring operations and that all relevant accounts need to sign the transaction. @@ -310,7 +310,7 @@ console.log("Sponsored two trustlines of", A.publicKey()); -### 2. Transferring sponsorship {#2-transferring-sponsorship} +### 2. Transferring sponsorship Suppose that now Signer 1 wants to transfer the responsibility of sponsoring reserves for the trustline to Sponsor 2. This is accomplished by sandwiching the transfer between the `BEGIN/END_SPONSORING_FUTURE_RESERVES` operations. Both of the participants must sign the transaction, though either can submit it. @@ -381,7 +381,7 @@ console.log("Transferred sponsorship for", A.publicKey()); At this point, Signer 1 is only sponsoring the first asset (arbitrarily coded as ABCD), while Signer 2 is sponsoring the other two assets. (Recall that initially Signer 1 was also sponsoring EFGH.) -### 3. Sponsorship revocation {#3-sponsorship-revocation} +### 3. Sponsorship revocation Finally, we can demonstrate complete revocation of sponsorships. Below, Signer 2 removes themselves from all responsibility over the two asset trustlines. Notice that Account A is not involved at all, since revocation should be performable purely at the sponsor’s discretion. @@ -443,7 +443,7 @@ Finally, we can demonstrate complete revocation of sponsorships. Below, Signer 2 -### Sponsorship Source Accounts {#sponsorship-source-accounts} +### Sponsorship Source Accounts When it comes to the SourceAccount fields of the sponsorship sandwich, it's important to refer to the wisdom of [CAP-33](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#abstract): @@ -477,11 +477,11 @@ For example, the following is an identical expression of the earlier Golang exam -### Other examples {#other-examples} +### Other examples If you’d like other examples or want to view a more-generic pseudo-code breakdown of these sponsorship scenarios, you can refer to [CAP-0033](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#example-revoke-sponsorship) directly. -### Footnote {#footnote} +### Footnote For the above examples, an implementation of SignAndSend (Golang) and some (very) rudimentary error checking code (all languages) might look something like this: diff --git a/docs/learn/fundamentals/anchors.mdx b/docs/learn/fundamentals/anchors.mdx index ad3eab6db..1f94f3cad 100644 --- a/docs/learn/fundamentals/anchors.mdx +++ b/docs/learn/fundamentals/anchors.mdx @@ -13,7 +13,7 @@ You can set up an anchor by using the SDF-maintained [Anchor Platform](/platform Learn how to integrate anchor services into your blockchain-based application by viewing the [Build Apps section](../../build/apps/overview.mdx). If you’re looking specifically for MoneyGram Access, see the Integrate with MoneyGram Access tutorial. -### Stellar Ecosystem Proposals (SEPs) {#stellar-ecosystem-proposals-seps} +### Stellar Ecosystem Proposals (SEPs) Stellar is an open-source network that is designed to interoperate with traditional financial institutions, various types of assets, and other networks. Network participants implement Stellar Ecosystem Proposals (SEPs) to ensure they can interoperate with other products and services on the network. SEPs are publicly created, open-source documents that live in a [GitHub repository](https://github.com/stellar/stellar-protocol/tree/master/ecosystem#stellar-ecosystem-proposals-seps.mdx) and they define how anchors, asset issuers, applications, exchanges, and other service providers should interact and interoperate. diff --git a/docs/learn/fundamentals/fees-resource-limits-metering.mdx b/docs/learn/fundamentals/fees-resource-limits-metering.mdx index 9955c7705..9f2dd3c1d 100644 --- a/docs/learn/fundamentals/fees-resource-limits-metering.mdx +++ b/docs/learn/fundamentals/fees-resource-limits-metering.mdx @@ -5,7 +5,7 @@ sidebar_position: 70 import CanvasFeeGraphs from "@site/src/components/CanvasFeeGraphs"; -## Fees overview {#fees-overview} +## Fees overview Stellar requires a fee for all transactions to make it to the ledger. This helps prevent spam and prioritizes transactions during traffic surges. All fees are paid using the native Stellar token, the [lumen (or XLM)](./lumens.mdx). @@ -19,7 +19,7 @@ When competing for space on the ledger, smart contract transactions are _only_ c The lumens collected from transaction fees go into a locked account and are not given to or used by anyone. -## Resource fee {#resource-fee} +## Resource fee All smart contract transactions require a resource fee in addition to an inclusion fee: @@ -50,7 +50,7 @@ Find current resource fees in the [Resource Limits & Fees](../../networks/resour For help in analyzing smart contract cost and efficiency, see this [How-To Guide](../../build/guides/fees/analyzing-smart-contract-cost.mdx). -### Refundable and non-refundable resource fees {#refundable-and-non-refundable-resource-fees} +### Refundable and non-refundable resource fees The resource fee is calculated with a non-refundable fees portion and a refundable fees portion: `ResourceFee(sorobanData.resourceFee) = Non-refundable resource fee + Refundable resource fees`. @@ -58,11 +58,11 @@ The resource fee is calculated with a non-refundable fees portion and a refundab **Refundable fees:** calculated from rent, events, and return value. Refundable fees are charged from the source account before the transaction is executed and then refunded based on actual usage. However, the transaction will fail if `refundableFee` is not enough to cover the actual resource usage. -### Find a transaction’s resource fee {#find-a-transactions-resource-fee} +### Find a transaction’s resource fee The best way to find the required resource fee for any smart contract transaction is to use the [`simulateTransaction` endpoint](../encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx) from the RPC, which enables you to send a preflight transaction that will return the necessary resource values and resource fee. -### Resource limitations {#resource-limitations} +### Resource limitations :::note @@ -76,7 +76,7 @@ Resource limits are determined by a validator vote and can be adjusted based on Find current resource limits in the [Resource Limits & Fees](../../networks/resource-limits-fees.mdx) page in the Networks section. -## Inclusion fee {#inclusion-fee} +## Inclusion fee The inclusion fee is the maximum bid (a bid denotes a dynamic fee, meaning it varies based on certain network conditions) the submitter is willing to pay for the transaction to be included in the ledger. The inclusion fee equals the number of operations in the transaction multiplied by the effective base fee for the given ledger: `inclusion fee = # of operations * effective base fee` @@ -96,9 +96,9 @@ Alternatively, your transaction may not make it to the ledger if the effective b Fees are deducted from the source account unless there is a fee-bump transaction that states otherwise. Learn about fee-bump transactions in the [Fee-Bump Transaction section](../encyclopedia/transactions-specialized/fee-bump-transactions.mdx). -## Surge and dynamic pricing {#surge-and-dynamic-pricing} +## Surge and dynamic pricing -### Surge pricing {#surge-pricing} +### Surge pricing The network can enter surge pricing mode under two circumstances: 1. when the number of operations submitted to a ledger exceeds the network capacity (1,000 operations for transactions that do not execute smart contracts), or 2. if there is competition between smart contract transactions for a particular resource (instructions, ledger entry accesses (reads and writes), ledger IO (bytes read and bytes written), and the total size of transactions to be applied). During this time, the network uses market dynamics to decide which transactions to include in the ledger. Transactions that offer a higher maximum base fee bid make it to the ledger first. @@ -114,7 +114,7 @@ It is recommended to apply [ledger bounds](./transactions/operations-and-transac **You are more likely to pay a higher inclusion fee when submitting smart contract transactions.** Smart contract transactions have tighter ledger limits than transactions that don’t interact with smart contracts and will therefore experience surge pricing more often. You are more likely to pay your maximum inclusion fee bid or, at least, the minimum inclusion fee bid in your transaction set. So, you must plan your fee bidding strategy accordingly. -### Dynamic pricing for storage {#dynamic-pricing-for-storage} +### Dynamic pricing for storage Stellar’s storage database size is determined by two forces: the rate of additions (writes) and the rate of deletions (evictions). Stellar has set a ledger growth threshold to a constant value (the `BucketListTargetSizeBytes` network parameter, implemented to prevent explosive state growth and subject to change based on validator vote). Because there is a fixed capacity, write fees are based on the ledger size and can alter dynamically based on that size. @@ -122,7 +122,7 @@ When the ledger size is large, there is a higher demand for storage space, which Write fees will grow gradually over time when the database size is below the ledger growth threshold and will grow linearly, but with a 1,000x factor after exceeding that threshold. This is a safeguard against spam and is not anticipated under normal circumstances. -## Metering {#metering} +## Metering Metering is a mechanism in the host environment that accounts for the resource costs incurred during the execution of a smart contract. The outcomes of metering act as the canonical truth of a smart contract’s execution cost and serve as an input for fee computations. @@ -134,11 +134,11 @@ Consider two contracts: A and B, both comprising the same number of Wasm instruc Metering ensures fairness, thwarts resource manipulation and attacks, and generates a deterministic and reproducible measure of runtime resource costs. -### Methodology {#methodology} +### Methodology To maintain equivalence in metering between the host and guest, computation costs on both sides are expressed in terms of CPU instructions and memory bytes (representing CPU and RAM usage). Metering and limit-checking occur within the host environment, and pre-calibrated numerical models ensure results are deterministic. -### Cost types {#cost-types} +### Cost types Metering is segmented into host components, referred to as **cost types**. Each cost type can be viewed as a “meta instruction” symbolizing a specific host operation with a known complexity that depends on a runtime input. For instance, cost type `ComputeSha256Hash` represents the cost of computing the SHA256 hash of a byte array. @@ -150,7 +150,7 @@ Execution of Wasm instructions is accounted for as a host cost type `WasmInsnExe Find a complete list of host cost types and their definitions here: [`ContractCostType`](https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-contract-config-setting.x#L92-L155). -### Cost parameters {#cost-parameters} +### Cost parameters Cost types are carefully selected to: @@ -161,7 +161,7 @@ Each cost type has a separate model for both resource types (CPU and memory). The parameters for each model, `a` and `b`, are calibrated and fitted offline against inputs of various sizes. The collection of all model cost parameters from the network configurable entries (see [`ConfigSettingsEntry`](https://github.com/stellar/stellar-xdr/blob/e372df9f677961aac04c5a4cc80a3667f310b29f/Stellar-contract-config-setting.x#L223-L226) can be updated through network consensus. -### Metering process {#metering-process} +### Metering process Before contract execution, the host environment is prepared with the cost parameters and a budget defining the resource limits. Metering is then implemented to measure the cumulative resource consumption during host execution. @@ -169,7 +169,7 @@ During execution, whenever a component (a code block defining a cost type) is en If the contract execution concludes within the specified resource limits, the metered total of CPU instructions is recorded and utilized as the input for fee calculation. While memory usage is not included in the fee computation, it is nevertheless subject to the resource limits. -## Inclusion fee pricing strategies {#inclusion-fee-pricing-strategies} +## Inclusion fee pricing strategies For the past three hours, inclusion fee statistics on the Mainnet network can be seen below. @@ -180,13 +180,13 @@ There are two primary methods to deal with inclusion fee fluctuations and surge - [**Method 1:**](#set-the-highest-fee-youre-comfortable-paying) set the highest fee you’re comfortable paying. This does not mean that you’ll pay that amount on every transaction — you will only pay what’s necessary to get into the ledger. Under normal (non-surge) circumstances, you will only pay the standard fee even with a higher maximum fee set. This method is simple, convenient, and efficient but can still potentially fail. - [**Method 2:**](#fee-bumps-on-past-transactions) resubmit a transaction with a higher fee using a fee-bump transaction -### Set the highest fee you’re comfortable paying​ {#set-the-highest-fee-youre-comfortable-paying} +### Set the highest fee you’re comfortable paying​ In general, it’s a good idea to choose the highest fee you’re willing to pay per operation for your transaction to make it to the ledger. Wallet developers may want to offer users a chance to specify their own base fee, though it may make more sense to set a persistent global base fee that’s above the market rate since the average user probably doesn’t care if they’re paying 0.8 cents or 0.00008 cents. Remember that you’re more likely to pay your maximum fee bid with smart contract transactions. -### Fee-bumps on past transactions​ {#fee-bumps-on-past-transactions} +### Fee-bumps on past transactions​ Even with a liberal fee-paying policy, your transaction may fail to make it into the ledger due to insufficient funds or untimely surges. Fee-bump transactions can solve this problem. The following snippet shows you how to resubmit a transaction with a higher fee (as long as you have the original transaction envelope): diff --git a/docs/learn/fundamentals/lumens.mdx b/docs/learn/fundamentals/lumens.mdx index 0ca9bfdcb..7beaa964b 100644 --- a/docs/learn/fundamentals/lumens.mdx +++ b/docs/learn/fundamentals/lumens.mdx @@ -7,7 +7,7 @@ Lumens (XLM) are the native currency of the Stellar network. The lumen is the on To read up on the basics of lumens, head over to our Stellar Learn site: [Stellar Learn: Lumens](https://www.stellar.org/lumens) -## Transaction fees {#transaction-fees} +## Transaction fees Stellar requires a small fee for all transactions to prevent ledger spam and prioritize transactions during surge pricing. Transaction fees are paid in lumens. @@ -15,13 +15,13 @@ To learn about fees on Stellar, see our [Fees section](./fees-resource-limits-me Smart contract transactions on Stellar employ a different fee structure based on an inclusion fee and resource consumption (which includes [rent](#rent)). Read more in the [Fees and Metering section](./fees-resource-limits-metering.mdx). -## Base reserves {#base-reserves} +## Base reserves A unit of measurement used to calculate an account’s minimum balance. One base reserve is currently 0.5 XLM. Validators can vote to change the base reserve, but that’s uncommon and should only happen every few years. -## Minimum balance {#minimum-balance} +## Minimum balance Stellar accounts must maintain a minimum balance to exist, which is calculated using the base reserve. An account must always maintain a minimum balance of two base reserves (currently 1 XLM). Every subentry after that requires an additional base reserve (currently 0.5 XLM) and increases the account’s minimum balance. Subentries include trustlines (for both traditional assets and pool shares), offers, signers, and data entries. An account cannot have more than 1,000 subentries. @@ -33,11 +33,11 @@ For example, an account with one trustline, two offers, and a claimable balance When you close a subentry, the associated base reserve will be added to your available balance. An account must always pay its own minimum balance unless a subentry is being sponsored by another account. For information about this, see our [Sponsored Reserves Encyclopedia Entry](../encyclopedia/transactions-specialized/sponsored-reserves.mdx). -## Rent {#rent} +## Rent Smart contract data does not require any base reserves in order to live on the ledger, so every smart contract entry must pay rent instead. The rent charged for an entry to exist on the ledger is based on how big the entry is and how long the it should be live on the ledger before being archived. There are different rent requirements for each storage type `Persistent`, `Temporary`, and `Instance`, which you can read about in the [State Archival section](../encyclopedia/storage/state-archival.mdx). -## Lumen Supply Metrics {#lumen-supply-metrics} +## Lumen Supply Metrics import { CodeExample } from "@site/src/components/CodeExample"; @@ -49,7 +49,7 @@ Unlike many other blockchains, the native network currency is not created throug Please reference our [Ecosystem Horizon API Providers](../../data/horizon/horizon-providers.mdx) to access more Stellar network data via Horizon. -### Dashboard API {#dashboard-api} +### Dashboard API As of May 28th, 2024, the Dashboard API shows: @@ -72,7 +72,7 @@ As of May 28th, 2024, the Dashboard API shows: -### Definitions {#definitions} +### Definitions **originalSupply** One hundred billion lumens [were created](https://stellar.expert/explorer/public/ledger/2) when the Stellar network went live. That’s the Original Supply for the network. diff --git a/docs/learn/fundamentals/networks.mdx b/docs/learn/fundamentals/networks.mdx index 4d7dfe2a0..08006a16e 100644 --- a/docs/learn/fundamentals/networks.mdx +++ b/docs/learn/fundamentals/networks.mdx @@ -5,9 +5,9 @@ sidebar_position: 20 Stellar has three networks: the public network (Mainnet, also called Pubnet or the Public Network), the test network (Testnet), and a dev network (Futurenet). Mainnet is the main network used by applications in production. It connects to real financial rails and requires XLM to cover minimum balances, transaction fees, and rent. The Testnet is a smaller, free-to-use network maintained by SDF that functions like the Mainnet but doesn’t connect to real money. It has a built-in testnet XLM faucet (called Friendbot), and it resets on a regular cadence, so it's the best place for developers to test applications when they need a stable environment that mirrors Mainnet functionality. Futurenet is a dev network you can use to test more bleeding edge features that also has access to its own Friendbot. It resets whenever a reset is necessary, so it's not as predictable as Testnet, but it is where new features may be introduced before the are implemented in stable releases. -## Stats: Mainnet versus Testnet versus Futurenet {#stats-mainnet-versus-testnet-versus-futurenet} +## Stats: Mainnet versus Testnet versus Futurenet -### Mainnet {#mainnet} +### Mainnet - Validator nodes are run by the public - SDF offers free [Horizon Testnet and Futurenet Instances](../../data/horizon/horizon-providers.mdx#sdf-provided-horizon) to interact with the Testnet and Futurenet. The ecosystem has [Horizon providers](../../data/horizon/horizon-providers.mdx#ecosystem-horizon-providers) whom offer instances for Testnet and Mainnet. You can [run your own Horizon](../../data/horizon/admin-guide/overview.mdx) or use an instance offered by an [infrastructure provider](../../data/horizon/horizon-providers.mdx#ecosystem-horizon-providers). @@ -16,7 +16,7 @@ Stellar has three networks: the public network (Mainnet, also called Pubnet or t - See more detailed smart contract network settings in the section on [Fees and Metering](./fees-resource-limits-metering.mdx). - No publicly available RPC, see RPC service providers [here](../../data/rpc/rpc-providers.mdx) -### Testnet {#testnet} +### Testnet - SDF runs three core validator nodes - SDF offers a free [Horizon instance](https://horizon-testnet.stellar.org/) you can use to interact with the Testnet @@ -24,7 +24,7 @@ Stellar has three networks: the public network (Mainnet, also called Pubnet or t - Testnet is limited to 100 operations per ledger and one smart contract transaction per ledger - SDF offers free RPC endpoints, more information [here](../../data/rpc/rpc-providers.mdx#sdf-provided-rpc) -### Futurenet {#futurenet} +### Futurenet - SDF runs core validator nodes - SDF offers a free [Horizon instance](https://horizon-futurenet.stellar.org) you can use to interact with the Futurenet @@ -32,13 +32,13 @@ Stellar has three networks: the public network (Mainnet, also called Pubnet or t - Futurenet is limited to 100 operations per ledger and one smart contract transaction per ledger - SDF offers free RPC endpoints, more information [here](../../data/rpc/rpc-providers.mdx#sdf-provided-rpc) -## Friendbot {#friendbot} +## Friendbot Friendbot is a bot that funds accounts with fake XLM on Testnet or Futurenet. You can request XLM from Friendbot using the [Stellar Lab](../../tools/developer-tools/lab/account.mdx) or with various SDKs. Requests to Friendbot are rate limited, so use it wisely. Friendbot provides 10,000 fake XLM when funding a new account. If you are creating multiple accounts, you can fund your first account with Friendbot and then use that first account to fund your subsequent accounts using the Create Account operation. -## Testnet and Futurenet data reset {#testnet-and-futurenet-data-reset} +## Testnet and Futurenet data reset Testnet and Futurenet are reset periodically to the genesis ledger to declutter the network, remove spam, reduce the time needed to catch up on the latest ledger, and help maintain the system. Resets clear all ledger entries (accounts, trustlines, offers, smart contract data, etc.), transactions, and historical data from Stellar Core, Horizon, and the Stellar RPC- which is why developers should not rely on the persistence of accounts or the state of any balances when using Testnet or Futurenet. @@ -57,7 +57,7 @@ If you run a Testnet or Futurenet Horizon instance, you need to re-join and re-s Check out [this How-To Guide](../../build/guides/basics/automate-reset-data.mdx) on automating Testnet and Futurenet reset data. -## Test data automation {#test-data-automation} +## Test data automation It is recommended that you have testing infrastructure that can repopulate the Testnet and Futurenet with useful data after a reset. This will make testing more reliable and will help you scale your testing infrastructure to a private network if you choose to do so. For example, you may want to: @@ -70,16 +70,16 @@ If you maintain an application, you should think about creating a data set that A script can automate this entire process by creating an account with Friendbot and submitting a set of transactions that are predefined as a part of your testing infrastructure. -## What Testnet and Futurenet should and should not be used for {#what-testnet-and-futurenet-should-and-should-not-be-used-for} +## What Testnet and Futurenet should and should not be used for -### Testnet and Futurenet are good for {#testnet-and-futurenet-are-good-for} +### Testnet and Futurenet are good for - Creating test accounts (with funding from Friendbot); - Developing applications and contracts and exploring tutorials on Stellar without the potential to lose any assets; - Testing existing applications against new releases or release candidates of Stellar Core, Horizon, and the Stellar RPC; - Performing data analysis on a smaller, non-trivial data set compared to the Mainnet. -### Testnet and Futurenet are bad for {#testnet-and-futurenet-are-bad-for} +### Testnet and Futurenet are bad for - Load and stress testing; - High availability test infrastructure- SDF does not guarantee Testnet availability; @@ -88,7 +88,7 @@ A script can automate this entire process by creating an account with Friendbot - The ability to control the data reset frequency; - The need to secure private or sensitive data (before launching on the Mainnet). You can always run your own test network for use cases that don’t work well with SDF’s Testnet. -## Moving your project from Testnet or Futurenet to production {#moving-your-project-from-testnet-or-futurenet-to-production} +## Moving your project from Testnet or Futurenet to production Mainnet, Testnet, and Futurenet each have their own unique passphrase, which is used to validate signatures on a given transaction. diff --git a/docs/learn/fundamentals/stellar-consensus-protocol.mdx b/docs/learn/fundamentals/stellar-consensus-protocol.mdx index 25ef64580..68471c1f7 100644 --- a/docs/learn/fundamentals/stellar-consensus-protocol.mdx +++ b/docs/learn/fundamentals/stellar-consensus-protocol.mdx @@ -19,31 +19,31 @@ There are three desired properties of consensus mechanisms: fault tolerance, saf Consensus mechanisms can typically only prioritize two out of three of these properties. SCP prioritizes fault tolerance and safety over liveness. Because of prioritizing safety, blocks can sometimes get stuck while waiting for nodes to agree. -## SCP components {#scp-components} +## SCP components -### Quorum set {#quorum-set} +### Quorum set As mentioned above, each Core node decides on which other nodes it would like to trust to reach agreement. A node’s trusted set of nodes is called a **quorum set**. Validators might add each other to their quorum sets due to innate trust associated with real-world identities. -### Thresholds and quorum slices {#thresholds-and-quorum-slices} +### Thresholds and quorum slices In addition to choosing a quorum set, Core nodes must also choose a **threshold**. A threshold is the minimum number of nodes in a quorum set that must agree to reach consensus. For example, let’s say node B has nodes [A, C, D] in its quorum set and sets the threshold to 2. This means that any combination of 2 nodes in the quorum set agreeing is valid: either [A,C], [C,D], or [A,D] must agree for the node to proceed. The combination of agreeing nodes within the quorum set are called **quorum slices**. -### Node blocking sets {#node-blocking-sets} +### Node blocking sets Nodes can be blocked from reaching consensus by **node blocking sets**. Node blocking sets are any set of nodes in a quorum set that prevent a node from reaching agreement. For example, if a node requires 3 out of 4 of the nodes in its quorum set to agree, any combination of two nodes is considered a node blocking set. -### Quorum {#quorum} +### Quorum A **quorum** is a set of nodes sufficient to reach an agreement wherein each node is part of a quorum slice. -### Statement {#statement} +### Statement Valid **statements** on Stellar express the different opinions of nodes regarding transaction sets to agree on for a given ledger. For example: “I propose this transaction set for ledger number 800”. A node’s opinion on a statement depends on the opinions of its quorum set. -## Federated voting {#federated-voting} +## Federated voting In the SCP, agreement is achieved using federated voting. A node reasons about the state of the network based on what it learns from its quorum set- before a statement is 100% agreed upon by every honest node in the network, it goes through three steps of federated voting: (1) Vote, (2) Accept, and (3) Confirm. @@ -67,17 +67,17 @@ To transition between the states above, federated voting has the following rules - Confirm A if every node in a quorum slice accepted A -## Consensus rounds {#consensus-rounds} +## Consensus rounds Each consensus round is separated into two stages: -### Nomination protocol {#nomination-protocol} +### Nomination protocol In the nomination protocol, candidate transaction sets are selected to be included in a ledger. Once a node confirms its first candidate, it stops voting to nominate any new transaction sets. It may still accept or confirm previously nominated statements. This guarantees that at some point, all nodes will converge on a candidate set. If every node on the network stops introducing new values but continues to confirm what other nodes confirmed, eventually, everyone will end up with the same list of candidates. A node may start the ballot protocol as soon as it confirms a candidate. After it confirms its first candidate and starts the ballot protocol, nomination continues running in the background. -### Ballot protocol {#ballot-protocol} +### Ballot protocol The ballot protocol ensures that the network can unanimously confirm and apply nominated transaction sets. It consists of two steps: diff --git a/docs/learn/fundamentals/stellar-data-structures/accounts.mdx b/docs/learn/fundamentals/stellar-data-structures/accounts.mdx index 4649a227b..68659ae9c 100644 --- a/docs/learn/fundamentals/stellar-data-structures/accounts.mdx +++ b/docs/learn/fundamentals/stellar-data-structures/accounts.mdx @@ -21,15 +21,15 @@ Accounts are made up of the below fields. Click on the field to learn more about - [Signers](../../encyclopedia/security/signatures-multisig.mdx) - [Thresholds](../../encyclopedia/security/signatures-multisig.mdx#thresholds) -## Base reserves and subentries {#base-reserves-and-subentries} +## Base reserves and subentries Accounts store data in subentries, and each subentry increases the account’s required minimum balance. -### Base reserves {#base-reserves} +### Base reserves A base reserve is a unit of measurement used to calculate an account’s minimum balance. One base reserve is currently 0.5 XLM. -### Subentries {#subentries} +### Subentries Account data is stored in subentries, each of which increases an account’s minimum balance by one base reserve (0.5 XLM). An account cannot have more than 1,000 subentries. Possible subentries are: @@ -38,7 +38,7 @@ Account data is stored in subentries, each of which increases an account’s min - Additional signers - Data entries (includes data made with the `manageData` operation, not smart contract ledger entries) -## Trustlines {#trustlines} +## Trustlines Trustlines are an explicit opt-in for an account to hold and trade a particular asset. To hold a specific asset, an account must establish a trustline with the issuing account using the change_trust operation. Trustlines track the balance of an asset and can also limit the amount of an asset that an account can hold. diff --git a/docs/learn/fundamentals/stellar-data-structures/assets.mdx b/docs/learn/fundamentals/stellar-data-structures/assets.mdx index ab4e0e1b2..534dff81a 100644 --- a/docs/learn/fundamentals/stellar-data-structures/assets.mdx +++ b/docs/learn/fundamentals/stellar-data-structures/assets.mdx @@ -9,9 +9,9 @@ Accounts on the Stellar network can be used to track, hold, and transfer any typ Assets on Stellar have two identifying characteristics: the asset code and the issuer. Since more than one organization can issue a credit representing the same asset, asset codes often overlap (for example, multiple companies offer a USD token on Stellar). Assets are uniquely identified by the combination of their asset code and issuer. -## Asset components {#asset-components} +## Asset components -### Asset code {#asset-code} +### Asset code An asset’s identifying code. There are three different formats: Alphanumeric 4, Alphanumeric 12, and liquidity pool shares. @@ -19,13 +19,13 @@ Learn about liquidity pool shares in the [Liquidity Pool Encyclopedia Entry](../ Learn more about asset codes in the [Naming an Asset section](../../../tokens/control-asset-access.mdx#naming-an-asset) -### Issuer {#issuer} +### Issuer There is no dedicated operation to create an asset on Stellar. Instead, assets are created with a payment operation: an issuing account makes a payment using the asset it’s issuing, and that payment creates the asset on the network. The public key of the issuing account is linked on the ledger to the asset. Responsibility for and control over an asset resides with the issuing account. Since settings are stored at the account level on the ledger, the issuing account is where you use set_options operations to link to meta-information about an asset and set authorization flags. -## Using Stellar assets in smart contracts {#using-stellar-assets-in-smart-contracts} +## Using Stellar assets in smart contracts Assets issued on the Stellar network are accessible to smart contracts. Every Stellar asset has reserved a Stellar Asset Contract that can be deployed by anyone who wants to be able to interact with the asset from a contract. @@ -33,7 +33,7 @@ The Stellar CLI can deploy a Stellar Asset Contract for a Stellar asset. Deployi Learn more in the [SAC section](../../../tokens/stellar-asset-contract.mdx). -## Representation {#representation} +## Representation In Horizon, assets are represented in a JSON object: @@ -75,7 +75,7 @@ astro_dollar = Asset("AstroDollar", "GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGS -## Amount precision {#amount-precision} +## Amount precision Each asset amount is encoded as a signed 64-bit integer in the XDR structures that Stellar uses to encode transactions. The asset amount unit seen by end-users is scaled down by a factor of ten million (10,000,000) to arrive at the native 64-bit integer representation. @@ -85,14 +85,14 @@ The smallest non-zero amount unit, also known as a stroop, is 0.0000001 (one ten The numbers are represented as int64s. Amount values are stored as only signed integers to avoid bugs that arise from mixing signed and unsigned integers. -## Relevance in Horizon and Stellar Client Libraries {#relevance-in-horizon-and-stellar-client-libraries} +## Relevance in Horizon and Stellar Client Libraries In Horizon and client-side libraries such as js-stellar-sdk, the integer encoded value is abstracted away. Many APIs expect an amount in unit value (the scaled-up amount displayed to end-users). Some programming languages (such as JavaScript) have problems maintaining precision on a number amount. It is recommended to use “big number” libraries that can record arbitrary-precision decimal numbers without a loss of precision. -## Deleting or burning assets {#deleting-or-burning-assets} +## Deleting or burning assets To delete, or "burn", an asset, you must send it back to the account that issued it. -## Custom token contracts {#custom-token-contracts} +## Custom token contracts Custom token contracts can be deployed on Stellar by deploying a contract that implements the [Token Interface](../../../tokens/token-interface.mdx), which is the same interface implemented by the [Stellar Asset Contract (SAC)](../../../tokens/stellar-asset-contract.mdx) for Stellar assets. diff --git a/docs/learn/fundamentals/stellar-data-structures/contracts.mdx b/docs/learn/fundamentals/stellar-data-structures/contracts.mdx index 089f84bc1..dcfdeb858 100644 --- a/docs/learn/fundamentals/stellar-data-structures/contracts.mdx +++ b/docs/learn/fundamentals/stellar-data-structures/contracts.mdx @@ -11,11 +11,11 @@ Stellar has integrated a smart contracts platform called "[Soroban](../../../bui A smart contract is a programmed set of executable code and state that can be invoked or used on the Stellar network. -## Wasm {#wasm} +## Wasm Once a smart contract has been written by a developer and compiled into a WebAssembly (Wasm) executable file, it can then be "installed" onto the Stellar network. A `CONTRACT_DATA` [ledger entry](./ledgers.mdx) is created to store this binary data and its unique identifier is the hash of the executable file. This binary executable is stored independently from its deployed contract(s). When a Stellar transaction attempts to invoke a contract function, the Wasm bytecode is first retrieved from the ledger and a secure, isolated runtime virtual machine ("VM") is instantiated so it can run the bytecode for the contract and then exit. -## Contract Instances {#contract-instances} +## Contract Instances After the executable bytecode is installed on-chain, contract instances can be deployed that reference the aformentioned bytecode. A smart contract executable can have a one-to-many relationship with "contract instances" which function independently. This means the same executable code can be used by multiple contract instances that all behave identically (because of the shared executable code), while maintaining separate and distinct state data (because the data is tied to the contract instance). A contract instance is stored as its own ledger entry, and any of the contract's [instance storage](#instance-storage) is stored in that same ledger entry alongside the contract instance. @@ -24,18 +24,18 @@ flowchart LR A[my instance] & B[your instance]--> C[contract Wasm] ``` -## Contract Storage {#contract-storage} +## Contract Storage In addition to the ledger entries that are created during the contract install/deploy process, each contract can create and access its own set of ledger entries. These ledger entries (as well as the contract code and the contract instance ledger entries) are subject to [state archival](../../encyclopedia/storage/state-archival.mdx) lifetimes (a ledger entry's "TTL ledger"). While they all function similarly, each type has its own fee and TTL behavior. -### Temporary Storage {#temporary-storage} +### Temporary Storage - Cheapest fees. - Permanently deleted when its TTL ledger is reached, cannot be restored. - Suitable for time-bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data. - Unlimited amount of storage. -### Persistent Storage {#persistent-storage} +### Persistent Storage - Most expensive fees (same price as `Instance` storage). - Recoverable after archival, can be restored using the [`RestoreFootprintOp`](../transactions/list-of-operations.mdx#restore-footprint) operation. @@ -43,7 +43,7 @@ In addition to the ledger entries that are created during the contract install/d - Unlimited amount of storage. - Suitable for user data that cannot be `Temporary` (i.e. balances). -### Instance Storage {#instance-storage} +### Instance Storage :::info diff --git a/docs/learn/fundamentals/stellar-ecosystem-proposals.mdx b/docs/learn/fundamentals/stellar-ecosystem-proposals.mdx index 34420d56d..7dbb11863 100644 --- a/docs/learn/fundamentals/stellar-ecosystem-proposals.mdx +++ b/docs/learn/fundamentals/stellar-ecosystem-proposals.mdx @@ -11,13 +11,13 @@ SEPs define standards for building that infrastructure on top of the Stellar net SEPs are publicly-created, open-source documents that live in the [GitHub repository](https://github.com/stellar/stellar-protocol/tree/master/ecosystem) and have a lightweight approval process. New SEPs and upgrades are discussed constantly. We encourage participation in these discussions to help build new standards and make Stellar services more accessible. -## Notable SEPs {#notable-seps} +## Notable SEPs There are many SEPs, and they cover a wide variety of standards for interoperation. Whatever you're building, you may want to take a look at the complete list to see if there's a standard for your use case. Here, we'll cover a few notable SEPs that define the standards for the most common Stellar use cases. -### SEP-0001 - Stellar Info File {#sep-0001---stellar-info-file} +### SEP-0001 - Stellar Info File Defines how to create and host a stellar.toml file: a common place where the Internet can find information about your Stellar integration. You can store a lot of information in your stellar.toml file including organization information, currency information, and contact information. TOML is a simple and commonly used configuration file format designed to be readable by both humans and machines. @@ -27,7 +27,7 @@ Using the `set_options` operation, you can link your Stellar account to the doma [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md) -### SEP-0005 - Key Derivation Methods for Stellar Accounts {#sep-0005---key-derivation-methods-for-stellar-accounts} +### SEP-0005 - Key Derivation Methods for Stellar Accounts Describes methods for key derivation for Stellar, improving key storage and moving keys between wallets and applications. Guidance in this SEP improves the Stellar ecosystem by: @@ -40,7 +40,7 @@ Describes methods for key derivation for Stellar, improving key storage and movi [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md) -### SEP-0006 - Deposit and Withdrawal API {#sep-0006---deposit-and-withdrawal-api} +### SEP-0006 - Deposit and Withdrawal API Defines the standard way for anchors and wallets to interact on behalf of users. With this SEP’s guidance, wallets and other clients can interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. @@ -60,7 +60,7 @@ SEP-0024 is the alternative to SEP-0006 which supports hosted deposits and withd [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) -### SEP-0007 - URI Scheme to Facilitate Delegated Signing {#sep-0007---uri-scheme-to-facilitate-delegated-signing} +### SEP-0007 - URI Scheme to Facilitate Delegated Signing Defines the standard URI scheme that can be used to generate a URI that will serve as a request to sign a transaction. With this SEP’s guidance, non-wallet applications can have their their users sign a transaction without seeing the wallet user's secret key in any form since the URI (request) will typically be signed by the user’s trusted wallet where the secret keys are stored. @@ -75,7 +75,7 @@ This SEP defines a standard protocol enabling the following features within a wa [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md) -### SEP-0010 - Stellar Authentication {#sep-0010---stellar-authentication} +### SEP-0010 - Stellar Authentication Defines a standard way for clients (such as wallets or exchanges) to create authenticated web sessions for users holding a Stellar account. This SEP also supports authenticating users of shared or pooled Stellar accounts. Clients can use muxed accounts to distinguish users or sub-accounts of shared accounts. @@ -85,7 +85,7 @@ Proves that the user has a Stellar account and that they control the account wit [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) -### SEP-0012 - KYC API {#sep-0012---kyc-api} +### SEP-0012 - KYC API Allows for sharing of KYC data and defines a standard way for Stellar clients to upload KYC and other information to anchors and other services. This SEP was made with these goals in mind: @@ -100,7 +100,7 @@ Allows for sharing of KYC data and defines a standard way for Stellar clients to [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md) -### SEP-0020 - Self-Verification of Validator Nodes {#sep-0020---self-verification-of-validator-nodes} +### SEP-0020 - Self-Verification of Validator Nodes Defines how validators self-verify by setting the home domain of their Stellar account to their website, where they publish information on-chain about their node and organization in a stellar.toml file. This allows other participants to discover other nodes and add them to their quorum sets without needing a centralized database. @@ -108,7 +108,7 @@ Defines how validators self-verify by setting the home domain of their Stellar a [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0020.md) -### SEP-0024 - Hosted Deposit and Withdrawal {#sep-0024---hosted-deposit-and-withdrawal} +### SEP-0024 - Hosted Deposit and Withdrawal Defines the standard way for anchors and wallets to interact on behalf of users interactively. This means that the user’s application must open a webview hosted by a third-party anchor for the user to provide the information necessary to complete the transaction. @@ -120,7 +120,7 @@ SEP-0006 is the alternative to SEP-0024 that supports an API-style solution for [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md) -### SEP-0030 - Account Recovery: Multi-Party Recovery of Stellar Accounts {#sep-0030---account-recovery-multi-party-recovery-of-stellar-accounts} +### SEP-0030 - Account Recovery: Multi-Party Recovery of Stellar Accounts Defines the standard API that enables an individual (e.g., a user or wallet) to regain access to a Stellar account that it owns after the individual has lost its private key without providing any third-party control of the account. Using this protocol, the user or wallet will preregister the account and a phone number, email, or other form of authentication with one or more servers implementing the protocol and add those servers as signers of the account. If two or more servers are used with appropriate signer configuration no individual server will have control of the account, but collectively, they may help the individual recover access to the account. @@ -135,7 +135,7 @@ This SEP enables the following use cases for a user: [Link to GitHub](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0030.md) -### SEP-0031 - Cross-Border Payment API {#sep-0031---cross-border-payment-api} +### SEP-0031 - Cross-Border Payment API Defines the protocol for two financial accounts that exist outside the Stellar network (anchors) to interact with each other. diff --git a/docs/learn/fundamentals/stellar-stack.mdx b/docs/learn/fundamentals/stellar-stack.mdx index 282b217f1..f530a7431 100644 --- a/docs/learn/fundamentals/stellar-stack.mdx +++ b/docs/learn/fundamentals/stellar-stack.mdx @@ -7,13 +7,13 @@ The Stellar stack is made up of the following components: the networks (Mainnet, ![Stellar Stack](/assets/stellar-tech-stack.png) -## Networks {#networks} +## Networks Stellar has three networks: the public network (Mainnet, also called Pubnet or the Public Network), the test network (Testnet), and a dev network (Futurenet). Mainnet is the main network used by applications in production. The Testnet is a smaller, free-to-use network maintained by SDF that functions like the Mainnet but doesn’t connect to real money and is the best place for developers to test their applications. Futurenet is a dev network you can use to test more bleeding edge features. Read more about the different networks in the [Networks section](./networks.mdx). -## Stellar Core {#stellar-core} +## Stellar Core Stellar Core is the program used by the individual nodes (or computers) that make up the network. Stellar Core keeps a common distributed ledger and engages in consensus to validate and process transactions. Generally, nodes reach consensus, apply a transaction set, and update the ledger every 5-7 seconds. @@ -21,7 +21,7 @@ Nodes reach consensus using the Stellar Consensus Protocol, which can you can le Anyone can run a Stellar Core node, but you don’t have to in order to build on Stellar. We recommend you do so if you issue an asset and want to ensure the accuracy of the ledger, if you want to participate in network governance by voting on protocol version, minimum fees, and resource and ledger limits, and/or if you want to contribute to Stellar’s overall health and decentralization. Check out our tutorial on installing, configuring, and maintaining your own node here: [Run a Validator Node Tutorial](../../validators/README.mdx). -## Horizon {#horizon} +## Horizon Horizon is the client-facing RESTful HTTP API server in the platform layer which allows programmatic access to submit transactions and query the network’s historical data. It acts as the interface for applications that want to access the Stellar network. You can communicate with Horizon using an SDK, a web browser, or with simple command tools like cURL. @@ -29,7 +29,7 @@ You do not need to run your own Horizon instance — when you're getting started Learn all there is to know about using Horizon in the Horizon [documentation](../../data/horizon/README.mdx). -## RPC {#rpc} +## RPC Stellar's RPC is a JSON RPC server that provides an interface for users and applications to interact with smart contracts on the Stellar blockchain. When an application would like to interact with smart contracts, it sends a request to the RPC server. The server interprets these requests, translates them into a format understandable by the blockchain nodes, and forwards them. After processing the requests, the blockchain nodes send back the results. The RPC server receives these results and sends them back to the requesting application. @@ -37,7 +37,7 @@ SDF has RPC endpoints available for Futurenet and Testnet. These services are fr SDF does not provide a publicly available RPC endpoint for Mainnet. Developers should [select an ecosystem provider](../../data/rpc/rpc-providers.mdx) that works for their project before migrating to Mainnet. In some cases, projects may choose to run their own RPC instance. -## SDKs {#sdks} +## SDKs SDKs simplify some of the work of accessing Horizon and the Stellar RPC by converting the data into friendlier formats and allowing you to program in the language of your choice. Stellar’s SDKs show you how to request data and create and submit transactions. Soroban's SDKs allow you to write smart contracts in Rust and interact with smart contracts in a myriad of other languages. diff --git a/docs/learn/fundamentals/transactions/list-of-operations.mdx b/docs/learn/fundamentals/transactions/list-of-operations.mdx index 9f19ac592..c06a3a515 100644 --- a/docs/learn/fundamentals/transactions/list-of-operations.mdx +++ b/docs/learn/fundamentals/transactions/list-of-operations.mdx @@ -9,7 +9,7 @@ Learn more about transactions and operations in our [Operations and Transactions There are currently 26 operations you can use on the Stellar network, these operations, their definitions, SDKs, thresholds, parameters, and errors are listed below. -## Create account {#create-account} +## Create account Creates and funds a new account with the specified starting balance @@ -32,7 +32,7 @@ Creates and funds a new account with the specified starting balance | CREATE_ACCOUNT_LOW_RESERVE | -3 | This operation would create an account with fewer than the minimum number of XLM an account must hold. | | CREATE_ACCOUNT_ALREADY_EXIST | -4 | The `destination` account already exists. | -## Payment {#payment} +## Payment Sends an amount in a specific asset to a destination account @@ -60,7 +60,7 @@ Sends an amount in a specific asset to a destination account | PAYMENT_NOT_AUTHORIZED | -7 | The destination account is not authorized by the asset's issuer to hold the asset. | | PAYMENT_LINE_FULL | -8 | The destination account (receiver) does not have sufficient limits to receive `amount` and still satisfy its buying liabilities. | -## Path payment strict send {#path-payment-strict-send} +## Path payment strict send A payment where the asset sent can be different than the asset received; allows the user to specify the amount of the asset to send @@ -96,7 +96,7 @@ Learn more about path payments: [Path Payments Encyclopedia Entry](../../encyclo | PATH_PAYMENT_STRICT_SEND_OFFER_CROSS_SELF | -11 | The payment would cross one of its own offers. | | PATH_PAYMENT_STRICT_SEND_UNDER_DESTMIN | -12 | The paths that could send `destination amount` of `destination asset` would fall short of `destination min`. | -## Path payment strict receive {#path-payment-strict-receive} +## Path payment strict receive A payment where the asset received can be different from the asset sent; allows the user to specify the amount of the asset received @@ -132,7 +132,7 @@ Learn more about path payments: [Path Payments Encyclopedia Entry](../../encyclo | PATH_PAYMENT_STRICT_RECEIVE_OFFER_CROSS_SELF | -11 | The payment would cross one of its own offers. | | PATH_PAYMENT_STRICT_RECEIVE_OVER_SENDMAX | -12 | The paths that could send `destination amount` of `destination asset` would exceed `send max`. | -## Manage buy offer {#manage-buy-offer} +## Manage buy offer Creates, updates, or deletes an offer to buy a specific amount of an asset for another @@ -166,7 +166,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | MANAGE_BUY_OFFER_NOT_FOUND | -11 | An offer with that `offerID` cannot be found. | | MANAGE_BUY_OFFER_LOW_RESERVE | -12 | The account creating this offer does not have enough XLM to satisfy the minimum XLM reserve increase caused by adding a subentry and still satisfy its XLM selling liabilities. For every offer an account creates, the minimum amount of XLM that account must hold will increase. | -## Manage sell offer {#manage-sell-offer} +## Manage sell offer Creates, updates, or deletes an offer to sell a specific amount of an asset for another @@ -200,7 +200,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | MANAGE_SELL_OFFER_NOT_FOUND | -11 | An offer with that `offerID` cannot be found. | | MANAGE_SELL_OFFER_LOW_RESERVE | -12 | The account creating this offer does not have enough XLM to satisfy the minimum XLM reserve increase caused by adding a subentry and still satisfy its XLM selling liabilities. For every offer an account creates, the minimum amount of XLM that account must hold will increase. | -## Create passive sell offer {#create-passive-sell-offer} +## Create passive sell offer Creates an offer to sell one asset for another without taking a reverse offer of equal price @@ -233,7 +233,7 @@ Learn more about passive sell offers: [Liquidity on Stellar: SDEX and Liquidity | MANAGE_SELL_OFFER_NOT_FOUND | -11 | An offer with that `offerID` cannot be found. | | MANAGE_SELL_OFFER_LOW_RESERVE | -12 | The account creating this offer does not have enough XLM to satisfy the minimum XLM reserve increase caused by adding a subentry and still satisfy its XLM selling liabilities. For every offer an account creates, the minimum amount of XLM that account must hold will increase. | -## Set options {#set-options} +## Set options Set options for an account such as flags, inflation destination, signers, home domain, and master key weight @@ -272,7 +272,7 @@ Learn more about signers operations and key weight: [Signature and Multisignatur | SET_OPTIONS_BAD_SIGNER | -8 | Any additional signers added to the account cannot be the master key. | | SET_OPTIONS_INVALID_HOME_DOMAIN | -9 | Home domain is malformed. | -## Change trust {#change-trust} +## Change trust Creates, updates, or deletes a trustline @@ -301,7 +301,7 @@ Learn more about trustlines: [Trustlines section](../stellar-data-structures/acc | CHANGE_TRUST_CANNOT_DELETE | -7 | The asset trustline is still referenced by a liquidity pool. | | CHANGE_TRUST_NOT_AUTH_MAINTAIN_LIABILITIES | -8 | The asset trustline is deauthorized. | -## Allow trust {#allow-trust} +## Allow trust Updates the authorized flag of an existing trustline @@ -329,7 +329,7 @@ This operation is deprecated as of Protocol 17- prefer SetTrustlineFlags instead | ALLOW_TRUST_SELF_NOT_ALLOWED | -5 | The source account attempted to allow a trustline for itself, which is not allowed because an account cannot create a trustline with itself. | | ALLOW_TRUST_LOW_RESERVE | -6 | Claimable balances can't be created on revocation of asset (or pool share) trustlines associated with a liquidity pool due to low reserves. | -## Account merge {#account-merge} +## Account merge Transfers the XLM balance of an account to another account and removes the source account from the ledger @@ -354,7 +354,7 @@ Transfers the XLM balance of an account to another account and removes the sourc | ACCOUNT_MERGE_DEST_FULL | -6 | The `destination` account cannot receive the balance of the source account and still satisfy its lumen buying liabilities. | | ACCOUNT_MERGE_IS_SPONSOR | -7 | The source account is a sponsor. | -## Manage data {#manage-data} +## Manage data Sets, modifies, or deletes a data entry (name/value pair) that is attached to an account @@ -379,7 +379,7 @@ Learn more about entries and subentries: [Accounts section](../stellar-data-stru | MANAGE_DATA_LOW_RESERVE | -3 | This account does not have enough XLM to satisfy the minimum XLM reserve increase caused by adding a subentry and still satisfy its XLM selling liabilities. For every new DataEntry added to an account, the minimum reserve of XLM that account must hold increases. | | MANAGE_DATA_INVALID_NAME | -4 | Name not a valid string. | -## Bump sequence {#bump-sequence} +## Bump sequence Bumps forward the sequence number of the source account to the given sequence number, invalidating any transaction with a smaller sequence number @@ -398,7 +398,7 @@ Bumps forward the sequence number of the source account to the given sequence nu | --- | --- | --- | | BUMP_SEQUENCE_BAD_SEQ | -1 | The specified `bumpTo` sequence number is not a valid sequence number. It must be between 0 and `INT64_MAX` (9223372036854775807 or 0x7fffffffffffffff). | -## Create claimable balance {#create-claimable-balance} +## Create claimable balance Moves an amount of asset from the operation source account into a new ClaimableBalanceEntry @@ -425,7 +425,7 @@ Learn more about claimable balances: [Claimable Balances Encyclopedia Entry](../ | CREATE_CLAIMABLE_BALANCE_NOT_AUTHORIZED | -4 | The source account is not authorized to transfer this asset. | | CREATE_CLAIMABLE_BALANCE_UNDERFUNDED | -5 | The source account does not have enough funds to transfer amount of this asset to the ClaimableBalanceEntry. | -## Claim claimable balance {#claim-claimable-balance} +## Claim claimable balance Claims a ClaimableBalanceEntry that corresponds to the BalanceID and adds the amount of an asset on the entry to the source account @@ -450,7 +450,7 @@ Learn more about claimable balances and view more parameters: [Claimable Balance | CLAIM_CLAIMABLE_BALANCE_NO_TRUST | -4 | The source account does not trust the issuer of the asset it is trying to claim in the ClaimableBalanceEntry. | | CLAIM_CLAIMABLE_BALANCE_NOT_AUTHORIZED | -5 | The source account is not authorized to claim the asset in the ClaimableBalanceEntry. | -## Begin sponsoring future reserves {#begin-sponsoring-future-reserves} +## Begin sponsoring future reserves Allows an account to pay the base reserves for another account; sponsoring account establishes the is-sponsoring-future-reserves relationship @@ -475,7 +475,7 @@ Learn more about sponsored reserves: [Sponsored Reserves Encyclopedia Entry](../ | BEGIN_SPONSORING_FUTURE_RESERVES_ALREADY_SPONSORED | -2 | Source account is already sponsoring sponsoredID. | | BEGIN_SPONSORING_FUTURE_RESERVES_RECURSIVE | -3 | Either source account is currently being sponsored, or sponsoredID is sponsoring another account. | -## End sponsoring future reserves {#end-sponsoring-future-reserves} +## End sponsoring future reserves Terminates the current is-sponsoring-future-reserves relationship in which the source account is sponsored @@ -496,7 +496,7 @@ Learn more about sponsored reserves: [Sponsored Reserves Encyclopedia Entry](../ | --- | --- | --- | | END_SPONSORING_FUTURE_RESERVES_NOT_SPONSORED | -1 | Source account is not sponsored. | -## Revoke sponsorship {#revoke-sponsorship} +## Revoke sponsorship Sponsoring account can remove or transfer sponsorships of existing ledgerEntries and signers; the logic of this operation depends on the state of the source account @@ -527,7 +527,7 @@ Or | REVOKE_SPONSORSHIP_ONLY_TRANSFERABLE | -4 | Sponsorship cannot be removed from this ledgerEntry. This error will happen if the user tries to remove the sponsorship from a ClaimableBalanceEntry. | | REVOKE_SPONSORSHIP_MALFORMED | -5 | One or more of the inputs to the operation was malformed. | -## Clawback {#clawback} +## Clawback Burns an amount in a specific asset from a receiving account @@ -553,7 +553,7 @@ Learn more about clawbacks: [Clawback Encyclopedia Entry](../../encyclopedia/tra | CLAWBACK_NO_TRUST | -3 | The From account does not trust the issuer of the asset. | | CLAWBACK_UNDERFUNDED | -4 | The From account does not have a sufficient available balance of the asset (after accounting for selling liabilities). | -## Clawback claimable balance {#clawback-claimable-balance} +## Clawback claimable balance Claws back an unclaimed ClaimableBalanceEntry, burning the pending amount of the asset @@ -578,7 +578,7 @@ Learn more about claimable balances: [Claimable Balances Encyclopedia Entry](../ | CLAWBACK_CLAIMABLE_BALANCE_NOT_ISSUER | -2 | The source account is not the issuer of the asset in the claimable balance. | | CLAWBACK_CLAIMABLE_BALANCE_NOT_CLAWBACK_ENABLED | -3 | `The CLAIMABLE_BALANCE_CLAWBACK_ENABLED_FLAG` is not set for this trustline. | -## Set trustline flags {#set-trustline-flags} +## Set trustline flags Allows issuing account to configure authorization and trustline flags to an asset @@ -608,7 +608,7 @@ Learn more about flags: [Flags Glossary Entry](../../glossary.mdx#flags) | SET_TRUST_LINE_FLAGS_INVALID_STATE | -4 | If the final state of the trustline has both AUTHORIZED_FLAG (1) and AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG (2) set, which are mutually exclusive. | | SET_TRUST_LINE_FLAGS_LOW_RESERVE | -5 | Claimable balances can't be created on revocation of asset (or pool share) trustlines associated with a liquidity pool due to low reserves. | -## Liquidity pool deposit {#liquidity-pool-deposit} +## Liquidity pool deposit Deposits assets into a liquidity pool, increasing the reserves of a liquidity pool in exchange for pool shares @@ -643,7 +643,7 @@ Learn more about liquidity pools: [Liquidity Pools Encyclopedia Entry](../../enc | LIQUIDITY_POOL_DEPOSIT_BAD_PRICE | -6 | The deposit price is outside of the given bounds. | | LIQUIDITY_POOL_DEPOSIT_POOL_FULL | -7 | The liquidity pool reserves are full. | -## Liquidity pool withdraw {#liquidity-pool-withdraw} +## Liquidity pool withdraw Withdraw assets from a liquidity pool, reducing the number of pool shares in exchange for reserves of a liquidity pool @@ -673,7 +673,7 @@ Learn more about liquidity pools: [Liquidity Pools Encyclopedia Entry](../../enc | LIQUIDITY_POOL_WITHDRAW_LINE_FULL | -4 | The withdrawal would exceed the trustline limit for one of the assets. | | LIQUIDITY_POOL_WITHDRAW_UNDER_MINIMUM | -5 | Unable to withdraw enough to satisfy the minimum price. | -## Invoke Host Function {#invoke-host-function} +## Invoke Host Function Invoke and deploy Soroban smart contracts with `InvokeHostFunctionOp`. @@ -707,7 +707,7 @@ Learn more [here](../../encyclopedia/contract-development/contract-interactions/ | INVOKE_HOST_FUNCTION_ENTRY_ARCHIVED | -4 | A ledger entry required for this function's footprint is in an archived state, and must be restored. | | INVOKE_HOST_FUNCTION_INSUFFICIENT_REFUNDABLE_FEE | -5 | The refundable Soroban fee provided was not sufficient to pay for the compute resources required by this function invocation. | -## Extend Footprint TTL {#extend-footprint-ttl} +## Extend Footprint TTL Extend the time to live (TTL) of entries for Soroban smart contracts with the `ExtendFootprintTTLOp`. This operation extends the TTL of the entries specified in the `readOnly` footprint of the transaction so that they will live at least until the `extendTo` ledger sequence number is reached. @@ -733,7 +733,7 @@ Learn more in the [State Archival section](../../encyclopedia/storage/state-arch | EXTEND_FOOTPRINT_TTL_RESOURCE_LIMIT_EXCEEDED | -2 | The TTL extension could not be completed within the currently configured resource constraints of the network. | | EXTEND_FOOTPRINT_TTL_INSUFFICIENT_REFUNDABLE_FEE | -3 | The refundable Soroban fee provided was not sufficient to pay for TTL extension of the specified ledger entries. | -## Restore Footprint {#restore-footprint} +## Restore Footprint Make archived Soroban smart contract entries accessible again by restoring them with `RestoreFootprintOp`. This operation restores the archived entries specified in the `readWrite` footprint. diff --git a/docs/learn/fundamentals/transactions/operations-and-transactions.mdx b/docs/learn/fundamentals/transactions/operations-and-transactions.mdx index ddb4c0456..2692a3397 100644 --- a/docs/learn/fundamentals/transactions/operations-and-transactions.mdx +++ b/docs/learn/fundamentals/transactions/operations-and-transactions.mdx @@ -3,11 +3,11 @@ title: Operations and Transactions sidebar_position: 10 --- -## Operations and transactions: how they work {#operations-and-transactions-how-they-work} +## Operations and transactions: how they work To perform actions with an account on the Stellar network, you compose operations, bundle them into a transaction, and then sign and submit the transaction to the network. Smart contract transactions (those with `InvokeHostFunctionOp`, `ExtendFootprintTTLOp`, or `RestoreFootprintOp` operations) can only have one operation per transaction. -### Operations {#operations} +### Operations Operations are individual commands that modify the ledger. Operations are used to send payments, invoke a smart contract function, enter orders into the decentralized exchange, change settings on accounts, and authorize accounts to hold assets. @@ -17,7 +17,7 @@ To learn more about signature weight, see the [Signature and Multisignature Ency View a comprehensive list of Stellar operations and their threshold levels in the [List of Operations section](./list-of-operations.mdx). -### Transactions {#transactions} +### Transactions The Stellar network encodes transactions using a standardized protocol called External Data Representation (XDR). You can read more about this in our [XDR Encyclopedia Entry](../../encyclopedia/data-format/xdr.mdx). @@ -33,7 +33,7 @@ Operations are executed for the source account of the transaction unless an oper Smart contract transactions also go through a simulation process where developers can test how the transaction would be executed on the network using the RPC endpoint `simulateTransaction`. Read more in the [Soroban docs](../../encyclopedia/contract-development/contract-interactions/transaction-simulation.mdx). -#### Transaction attributes {#transaction-attributes} +#### Transaction attributes - [Fee](../fees-resource-limits-metering.mdx) - [List of operations](./list-of-operations.mdx) @@ -43,7 +43,7 @@ Smart contract transactions also go through a simulation process where developer - [Source account](../../glossary.mdx#source-account) - [Preconditions (optional)](#preconditions) -## Transaction and operation validity {#transaction-and-operation-validity} +## Transaction and operation validity Before being successfully submitted to the Stellar network, transactions go through several validity checks. These checks are grouped into three categories: @@ -53,7 +53,7 @@ Preconditions are checked first. All preconditions are optional. Time bounds are encouraged, but the other preconditions are used in more specialized circumstances. You can set multiple preconditions as long as the combination is logically sound. -#### Time bounds {#time-bounds} +#### Time bounds Valid if within set time bounds of the transaction @@ -63,7 +63,7 @@ Setting time bounds on transactions is highly encouraged, and many SDKs enforce If `maxTime` is 0, upper time bounds are not set. In this case, if a transaction does not make it to the transaction set, it is kept in memory and continuously tries to make it to the next transaction set. Because of this, we advise that all transactions are created with time bounds to invalidate transactions after a certain amount of time, especially if you plan to resubmit your transaction at a later time. -#### Ledger bounds {#ledger-bounds} +#### Ledger bounds Valid if within the set ledger bounds of the transaction @@ -73,7 +73,7 @@ The lower bound is inclusive (less than or equal to) while the upper bound is no If the upper bound is set to 0, this indicates there is no upper bound. -#### Minimum sequence number {#minimum-sequence-number} +#### Minimum sequence number If a minimum sequence number is set, the transaction will only be valid when its source account’s sequence number (call it S) is large enough. Specifically, it’s valid when S satisfies `minSeqNum <= S < tx.seqNum`. @@ -81,19 +81,19 @@ If this precondition is omitted, the default behavior applies: the transaction Note that after a transaction is executed, the account will always set its sequence number to the transaction’s sequence number. -#### Minimum sequence age {#minimum-sequence-age} +#### Minimum sequence age Transaction is valid after a particular duration (expressed in seconds) elapses since the account’s sequence number age. Minimum sequence age is a precondition relating to time, but unlike time bounds, which express absolute times, minimum sequence age is relative to when the transaction source account’s sequence number was touched. -#### Minimum sequence ledger gap {#minimum-sequence-ledger-gap} +#### Minimum sequence ledger gap Valid if submitted in a ledger meeting or exceeding the source account’s sequence number age This is similar to the minimum sequence age, except it is expressed as a number of ledgers rather than a duration of time. -#### Extra signers {#extra-signers} +#### Extra signers Valid if submitted with signatures that fulfill each of the extra signers @@ -101,52 +101,52 @@ A transaction can specify up to two extra signers as a precondition, meaning it The additional signers can be of any type besides the pre-authorized transaction signer since to pre-authorize a transaction, you need to know its hash, but be hash must include the extra signers. This Catch-22 relationship means including this type of extra signer will return an error. -### Operation validity {#operation-validity} +### Operation validity When a transaction is submitted to a node, the node checks the validity of each operation in the transaction before attempting to include it in a candidate transaction set. These initial operation validity checks are intended to be fast and simple, with more intensive checks coming after the fees have been consumed. For an operation to pass this validity check, it has to meet the following conditions: -#### The signatures on the transaction must be valid for the operation {#the-signatures-on-the-transaction-must-be-valid-for-the-operation} +#### The signatures on the transaction must be valid for the operation The signatures are from valid signers for the source account of the operation. The combined weight of all signatures for the source account of the operation meets the threshold for the operation. -#### The operation must be well-formed {#the-operation-must-be-well-formed} +#### The operation must be well-formed Typically this means checking the parameters for the operation to see if they’re in a valid format. For example, only positive values can be set for the amount of a payment operation. -#### The operation must be valid in the current protocol version of the network {#the-operation-must-be-valid-in-the-current-protocol-version-of-the-network} +#### The operation must be valid in the current protocol version of the network Deprecated operations, such as inflation, are invalid by design. -### Transaction validity {#transaction-validity} +### Transaction validity Finally, the following transaction checks take place: -#### Source account {#source-account} +#### Source account The source account must exist on the ledger. -#### Fee {#fee} +#### Fee The fee must be greater than or equal to the network minimum fee for the number of operations submitted as part of the transaction. This does not guarantee that the transaction will be applied, only that it is valid. In addition, the source account must be able to pay the fee specified. If multiple transactions are submitted but only a subset of them can be paid for, they are checked for validity in order of sequence number. -#### Fee-bump (if applicable) {#fee-bump-if-applicable} +#### Fee-bump (if applicable) See Validity of a [Fee-Bump Transaction section](../../encyclopedia/transactions-specialized/fee-bump-transactions.mdx#validity-of-a-fee-bump-transaction) -#### Sequence number {#sequence-number} +#### Sequence number The sequence number must be one greater than the sequence number stored in the source account entry when the transaction is applied unless sequence number preconditions are set. When checking the validity of multiple transactions with the same source account in a candidate transaction set, they must all be valid transactions and their sequence numbers must be offset by one. Then they are ordered and applied according to their sequence number. -#### List of operations {#list-of-operations} +#### List of operations Each operation must pass all the validity checks for an operation, described in the Operation Validity section above. -#### List of signatures {#list-of-signatures} +#### List of signatures - Meet signature requirements for each operation in the transaction - Appropriate network passphrase is part of the transaction hash signed by each signer - Combined weight of the signatures for the source account of the transaction meets the low threshold for the source account. -#### Memo (if applicable) {#memo-if-applicable} +#### Memo (if applicable) The memo type must be a valid type, and the memo itself must adhere to the formatting of the memo type. diff --git a/docs/learn/fundamentals/transactions/transaction-lifecycle.mdx b/docs/learn/fundamentals/transactions/transaction-lifecycle.mdx index c57866d06..43a006886 100644 --- a/docs/learn/fundamentals/transactions/transaction-lifecycle.mdx +++ b/docs/learn/fundamentals/transactions/transaction-lifecycle.mdx @@ -9,31 +9,31 @@ This is the transaction lifecycle for a classic Stellar transaction. Adding smar ::: -### 1. Creation (Transaction Creator) {#1-creation-transaction-creator} +### 1. Creation (Transaction Creator) A user creates a transaction by setting the source account, sequence number, list of operations and their respective parameters, fee or fee-bump, and optionally a memo and/or preconditions. -### 2. Signing (Transaction Signers) {#2-signing-transaction-signers} +### 2. Signing (Transaction Signers) Once the transaction is complete, it becomes a transaction envelope containing the transaction itself and a list of signers. All the required signatures must be collected and added to the transaction envelope’s list of signers. Commonly, it’s just the signature of the account doing the transaction, but more complicated setups can require collecting signatures from multiple parties. -### 3. Submitting (Transaction Submitter) {#3-submitting-transaction-submitter} +### 3. Submitting (Transaction Submitter) After signing, the transaction can now be submitted to the Stellar network. If the transaction is invalid, it will be rejected immediately by Stellar Core, the account’s sequence number will not be incremented, and no fee will be consumed from the source account. Multiple transactions for the same account can be submitted, provided each sequence number is off by one (unless minimum sequence number preconditions are set). If they are all valid, Stellar Core will craft a transaction set with each of those transactions applied in sequence number order. Transactions are typically submitted using Horizon, but you can also submit the transaction directly to an instance of Stellar Core. -### 4. Propagating (Validator) {#4-propagating-validator} +### 4. Propagating (Validator) Once Stellar Core has determined that a transaction is valid, it will propagate the transaction to all other servers to which it’s connected. This way, a valid transaction is flooded to the entire Stellar network. -### 5. Crafting a candidate transaction set (Validator) {#5-crafting-a-candidate-transaction-set-validator} +### 5. Crafting a candidate transaction set (Validator) When it’s time to close the ledger, each Stellar Core validator takes all valid transactions it is aware of since the last ledger close and collects them into a candidate transaction set. If it hears about any incoming transactions now, it puts them aside for the next ledger close. If the number of operations in the candidate transaction set is greater than the maximum number of operations per ledger, transactions will be prioritized by their fee for inclusion in the set. -### 6. Nominating a transaction set (Validator) {#6-nominating-a-transaction-set-validator} +### 6. Nominating a transaction set (Validator) Once each validator has crafted a candidate transaction set, the set is nominated to the network. -### 7. Stellar Consensus Protocol (SCP) determines the final transaction set (Validator Network) {#7-stellar-consensus-protocol-scp-determines-the-final-transaction-set-validator-network} +### 7. Stellar Consensus Protocol (SCP) determines the final transaction set (Validator Network) SCP resolves any differences between candidate transaction sets and ultimately determines a single transaction set to apply, the close time of the ledger, and any upgrades to the protocol that need to be applied network-wide at the apply time. @@ -41,18 +41,18 @@ If a transaction doesn’t make it into the transaction set, it is kept around i If a transaction is kept in memory after a certain number of ledger closes, it will be banned for several additional ledgers. This means no attempt will be made to include it in a candidate transaction set additional ledgers during this time. -### 8. Transaction apply order is determined (Validator Network) {#8-transaction-apply-order-is-determined-validator-network} +### 8. Transaction apply order is determined (Validator Network) Once SCP agrees on a particular transaction set, the apply order is computed for the transaction set. This shuffles the set's order to create uncertainty for competing transactions and maintains the order of sequence numbers for multiple transactions per account. -### 9. Fees are collected (Validator) {#9-fees-are-collected-validator} +### 9. Fees are collected (Validator) Fees are collected for all transactions simultaneously. -### 10. Application (Validator) {#10-application-validator} +### 10. Application (Validator) Each transaction is applied in the previously-determined order. For each transaction, the account’s sequence number is consumed (increased by 1), the transaction’s validity is rechecked, and each operation is applied in the order they occur in the transaction. Operations may fail at this stage due to errors that can occur outside of the transaction and operation validity checks. For example, an insufficient balance for a payment is not checked at submission and would fail at this time. The entire transaction will fail if any operation fails, and all previous operations will be rolled back. -### 11. Protocol Upgrades (Validator) {#11-protocol-upgrades-validator} +### 11. Protocol Upgrades (Validator) Finally, upgrades are run if an upgrade took place. This can include arbitrary logic to upgrade the ledger state for protocol upgrades, along with ledger header modifications, including the protocol version, base fee, maximum number of operations per ledger, etc. Once this has been completed, the life cycle begins anew. diff --git a/docs/learn/glossary.mdx b/docs/learn/glossary.mdx index 7a8d3bff9..b48cd736f 100644 --- a/docs/learn/glossary.mdx +++ b/docs/learn/glossary.mdx @@ -3,41 +3,41 @@ title: "Glossary" sidebar_position: 40 --- -### Account {#account} +### Account A central Stellar data structure to hold balances, sign transactions, and issue assets. See the [Accounts section](./fundamentals/stellar-data-structures/accounts.mdx) to learn more. -### Account ID {#account-id} +### Account ID The public key used to create an account. This key persists across different key assignments. It is [represented](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0023.md) in base32. -### Anchor {#anchor} +### Anchor The on and off-ramps on the Stellar network that facilitate one-to-one conversion of off-chain representations to and from tokenized assets, for example, digital tokens representing bank deposits. Read more in the [Anchor Encyclopedia entry](./fundamentals/anchors.mdx) -### Application (app) {#application-app} +### Application (app) A software program designed for users to carry out a specific task (other than operating the computer itself). -### Asset {#asset} +### Asset Fiat, physical, or other tokens of value that are tracked, held, or transferred by the Stellar distributed network. See the [Assets section](./fundamentals/stellar-data-structures/assets.mdx) to learn more. -### Balance {#balance} +### Balance The amount of a given asset an account holds. Each asset has its own balance and these balances are stored in trustlines for every asset except XLM, which is held directly by the account. -### BalanceID {#balanceid} +### BalanceID Parameter required when claiming a newly created entry via the Claim claimable balance operation. See [ClaimableBalanceID](#claimablebalanceid). -### Base fee {#base-fee} +### Base fee The fee you’re willing to pay per operation in a transaction. @@ -45,263 +45,263 @@ This differs from the Effective Base Fee which is the actual fee paid per operat Learn more in our [Fees section](./fundamentals/fees-resource-limits-metering.mdx). -### Base reserve {#base-reserve} +### Base reserve A unit of measurement used to calculate an account’s minimum balance. One base reserve is currently 0.5 XLM. Learn more in our [Lumens section](./fundamentals/lumens.mdx#base-reserves). -### Burn {#burn} +### Burn Remove an asset from circulation, which can happen in two ways: 1) a holder sends the asset back to the issuing account 2) an issuer claws back a clawback-enabled asset from a holder's account. -### Claim Predicate {#claim-predicate} +### Claim Predicate A recursive data structure used to construct complex conditionals with different values of ClaimPredicateType. -### ClaimableBalanceID {#claimablebalanceid} +### ClaimableBalanceID A SHA-256 hash of the OperationID for claimable balances. -### Claimant {#claimant} +### Claimant An object that holds both the destination account that can claim the ClaimableBalanceEntry and a ClaimPredicate that must evaluate to true for the claim to succeed. -### Clawback {#clawback} +### Clawback An amount of asset from a trustline or claimable balance removed (clawed back) from a recipient’s balance sheet. See the [Clawback](./encyclopedia/transactions-specialized/clawbacks.mdx) Encyclopedia Entry for more information. -### Core Advancement Proposals (CAPs) {#core-advancement-proposals-caps} +### Core Advancement Proposals (CAPs) Proposals of standards to improve the Stellar protocol- CAPs deal with changes to the core protocol of the Stellar network. -### Create account operation {#create-account-operation} +### Create account operation Makes a payment to a 0-balance public key (Stellar address), thereby creating the account. You must use this operation to initialize an account rather than a standard payment operation. -### Cross-asset payments {#cross-asset-payments} +### Cross-asset payments A payment that automatically handles the conversion of dissimilar assets. -### Decentralized exchange {#decentralized-exchange} +### Decentralized exchange A distributed exchange that allows the trading and conversion of assets on the network. Learn more in our [Liquidity on Stellar](./encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx#sdex) Encyclopedia Entry. -### External Data Representation (XDR) {#external-data-representation-xdr} +### External Data Representation (XDR) The type of encoding used operations and data running on stellar-core. -### Flags {#flags} +### Flags Flags control access to an asset on the account level. Learn more about flags in our [Controlling Access to an Asset section](../tokens/control-asset-access.mdx#controlling-access-to-an-asset-with-flags). -### Fuzzing {#fuzzing} +### Fuzzing An automated test that rapidly stuffs massive amounts of randomized, malformed data into a system to reveal adverse or unexpected results that indicate vulnerabilities. Read more in the [Fuzz Testing Tutorial](../build/smart-contracts/example-contracts/fuzzing.mdx). -### GitHub {#github} +### GitHub An online repository for documents that can be accessed and shared among multiple users; host for the Stellar platform’s source code, documentation, and other open-source repos. -### Home domain {#home-domain} +### Home domain A fully qualified domain name (FQDN) linked to a Stellar account, used to generate an on-chain link to a Stellar Info File, which holds off-chain metadata. See the Set Options operation. Can be up to 32 characters. -### Horizon {#horizon} +### Horizon The Stellar API, provides an HTTP interface to data in the Stellar network. -### JSON {#json} +### JSON A standardized human-readable and machine-readable format for the exchange of structured data. -### Keypair {#keypair} +### Keypair A combined public and private key used to secure transactions. You can use any Stellar wallet, SDK, or the Stellar Lab to generate a valid keypair. -### Keystore {#keystore} +### Keystore An encrypted store or file that serves as a repository of private keys, certificates, and public keys. -### Ledger {#ledger} +### Ledger A representation of the state of the Stellar universe at a given point in time, shared across all network nodes. Learn more in the [Ledgers section](./fundamentals/stellar-data-structures/ledgers.mdx). -### LedgerKey {#ledgerkey} +### LedgerKey LedgerKey holds information to identify a specific ledgerEntry. It is a union that can be any one of the LedgerEntryTypes (ACCOUNT, TRUSTLINE, OFFER, DATA, or CLAIMABLE_BALANCE). -### Liability {#liability} +### Liability A buying or selling obligation, required to satisfy (selling) or accommodate (buying) transactions. -### Lumen (XLM) {#lumen-xlm} +### Lumen (XLM) The native, built-in token on the Stellar network. Learn more about lumens in our [Lumens section](./fundamentals/lumens.mdx). -### Master key {#master-key} +### Master key The private key used in initial account creation. -### Minimum balance {#minimum-balance} +### Minimum balance The smallest permissible balance in lumens for a Stellar account, currently 1 lumen. Learn more in our [Lumens section](./fundamentals/lumens.mdx#minimum-balance). -### Network capacity {#network-capacity} +### Network capacity The maximum number of operations per ledger, as determined by validator vote. Currently 1,000 operations for the mainnet and 100 operations for the testnet. -### Number of subentries {#number-of-subentries} +### Number of subentries The number of entries owned by an account, used to calculate the account’s minimum balance. -### Operation {#operation} +### Operation An individual command that modifies the ledger. Learn more in our [Operations and Transactions](./fundamentals/transactions/operations-and-transactions.mdx) section. -### OperationID {#operationid} +### OperationID Contains the transaction source account, sequence number, and the operation index of the CreateClaimableBalance operation in a transaction. -### Order {#order} +### Order An offer to buy or sell an asset. Learn more in our [Liquidity on Stellar: SDEX and Liquidity Pools Encyclopedia Entry](./encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx#orders). -### Orderbook {#orderbook} +### Orderbook A record of outstanding orders on the Stellar network. Learn more in our [Liquidity on Stellar: SDEX and Liquidity Pools Encyclopedia Entry](./encyclopedia/sdex/liquidity-on-stellar-sdex-liquidity-pools.mdx#order-books). -### Passive order {#passive-order} +### Passive order An order that does not execute against a marketable counter order with the same price; filled only if the prices are not equal. -### Passphrase {#passphrase} +### Passphrase The Mainnet and Testnet each have their own unique passphrase, which are used to validate signatures on a given transaction. Learn more about network passphrases in the [Network Passphrases Encyclopedia Entry](./encyclopedia/network-configuration/network-passphrases.mdx). -### Pathfinding {#pathfinding} +### Pathfinding The process of determining the best path of a payment, evaluating the current orderbooks, and finding the series of conversions to achieve the best rate. -### Payment channel {#payment-channel} +### Payment channel Allows two parties who frequently transact with one another to move the bulk of their activity off-chain, while still recording opening balances and final settlement on-chain. -### Precondition {#precondition} +### Precondition Optional requirements you can add to control a transaction’s validity. See the [Operation and Transaction Validity section](./fundamentals/transactions/operations-and-transactions.mdx#preconditions) for more information. -### Price {#price} +### Price The ratio of the quote asset and the base asset in an order. -### Public key {#public-key} +### Public key The public part of a keypair that identifies a Stellar account. The public key is public- it is visible on the ledger, anyone can look it up, and it is used when sending payments to the account, identifying the issuer of an asset, and verifying that a transaction is authorized. -### Mainnet or Pubnet {#mainnet-or-pubnet} +### Mainnet or Pubnet The Stellar Public Network, aka mainnet, the main network used by applications in production. Read more in our [Networks section](./fundamentals/networks.mdx). -### Rate-limiting {#rate-limiting} +### Rate-limiting Horizon rate limits on a per-IP-address basis. By default, a client is limited to 3,600 requests per hour, or one request per second on average. -### Sequence number {#sequence-number} +### Sequence number Used to identify and verify the order of transactions with the source account. A transaction’s sequence number must always increase by one (unless minimum sequence number preconditions are set, or a bump sequence operation is used). SDKs and the Stellar Lab automatically increment the account’s sequence number by one when you build a transaction. -### Secret (private) key {#secret-private-key} +### Secret (private) key The private key is part of a keypair, which is associated with an account. Do not share your secret key with anyone. -### SEPs (Stellar Ecosystem Proposals) {#seps-stellar-ecosystem-proposals} +### SEPs (Stellar Ecosystem Proposals) Standards and protocols to allow the Stellar ecosystem to interoperate. Learn more in our [SEPs section](./fundamentals/stellar-ecosystem-proposals.mdx). -### Signer {#signer} +### Signer Refers to the master key or to any other signing keys added later. A signer is defined as the pair: public key + weight. Signers can be set with the Set Options operation. See our [Signature and Multisignature Encyclopedia Entry](./encyclopedia/security/signatures-multisig.mdx) for more information. -### Smart contract {#smart-contract} +### Smart contract Self-executing contracts with the terms of the agreement directly written into code, automatically enforceable without the need for intermediaries. -### Soroban {#soroban} +### Soroban The smart contract platform on the Stellar network. The name "Soroban" comes from the Japanese abacus, which is a traditional counting tool used for mathematical calculations. The Soroban abacus is a lightweight instrument known for its efficiency and accuracy in performing arithmetic operations. -### Source account {#source-account} +### Source account The account that originates a transaction. This account also provides the fee and sequence number for the transaction. -### Starlight {#starlight} +### Starlight Stellar’s layer 2 protocol that allows for bi-directional payment channels. -### Stellar {#stellar} +### Stellar A decentralized, federated peer-to-peer network that allows people to send payments in any asset anywhere in the world instantaneously, and with minimal fees. -### Stellar Consensus Protocol (SCP) {#stellar-consensus-protocol-scp} +### Stellar Consensus Protocol (SCP) Provides a way to reach consensus without relying on a closed system to accurately record financial transactions. See our [SCP section](./fundamentals/stellar-consensus-protocol.mdx) to learn more. -### Stellar Core {#stellar-core} +### Stellar Core A replicated state machine that maintains a local copy of a cryptographic ledger and processes transactions against it, in consensus with a set of peers; also, the reference implementation for the peer-to-peer agent that manages the Stellar network. -### Stellar Development Foundation (SDF) {#stellar-development-foundation-sdf} +### Stellar Development Foundation (SDF) A non-profit organization founded to support the development and growth of the Stellar network. -### Stellar.toml {#stellartoml} +### Stellar.toml A formatted configuration file containing published information about a node and an organization. For more, see the Stellar Info File spec (SEP-0001`) -### Stroop {#stroop} +### Stroop As cents are to dollars, stroops are to assets: the smallest unit of an asset, one ten-millionth. -### Testnet {#testnet} +### Testnet The Stellar Test Network is maintained by the Stellar Development Foundation, which developers can use to test applications. Testnet is free to use and provides the same functionality as the main (public) network. Read more in our [Networks](./fundamentals/networks.mdx). -### Threshold {#threshold} +### Threshold The level of access for an operation. @@ -311,56 +311,56 @@ Read more about operation thresholds in the [Operations and Transactions section Learn more about quorum set validators in our [Stellar Consensus Protocol section](./fundamentals/stellar-consensus-protocol.mdx). -### Time bounds {#time-bounds} +### Time bounds An optional feature you can apply to a transaction to enforce a time limit on the transaction; either the transaction makes it to the ledger or times out (fails) depending on your time parameters. Read more about time bounds in our [Operation and Transaction Validity section](./fundamentals/transactions/operations-and-transactions.mdx#transaction-and-operation-validity). -### Transaction {#transaction} +### Transaction A group of 1 to 100 operations that modify the ledger state. Read more in the [Operations and Transactions section](./fundamentals/transactions/operations-and-transactions.mdx#transactions). -### Transaction envelope {#transaction-envelope} +### Transaction envelope A wrapper for a transaction that carries signatures. -### Transaction fee {#transaction-fee} +### Transaction fee Stellar requires a small fee for all transactions to prevent ledger spam and prioritize transactions during surge pricing. Learn more in our [Lumens section](./fundamentals/lumens.mdx#transaction-fees). -### Trustline {#trustline} +### Trustline An explicit opt-in for an account to hold a particular asset that tracks liabilities, the balance of the asset, and can also limit the amount of an asset that an account can hold. Learn more in our [Accounts section](./fundamentals/stellar-data-structures/accounts.mdx#trustlines). -### TTL (Time To Live) {#ttl-time-to-live} +### TTL (Time To Live) A smart contract's TTL is how many ledgers remain until the data entry is no longer live. Read more in the [State Archival section](./encyclopedia/storage/state-archival.mdx#ttl). -### Type {#type} +### Type The classification of data that dictates the kind of data that can be stored and how it can be manipulated within a smart contract. -### UNIX timestamp {#unix-timestamp} +### UNIX timestamp An integer representing a given date and time, as used on UNIX and Linux computers. -### Validator {#validator} +### Validator A basic validator keeps track of the ledger and submits transactions for possible inclusion. It ensures reliable access to the network and sign-off on transactions. A full validator performs the functions of a basic validator, but also publishes a history archive containing snapshots of the ledger, including all network transactions and their results. -### XLM (lumens) {#xlm-lumens} +### XLM (lumens) The native currency of the Stellar network. -### Wallet {#wallet} +### Wallet An interface that gives a user access to an account stored on the ledger; that access is controlled by the account’s secret key. The wallet allows users to store and manage their assets. diff --git a/docs/learn/interactive/dapps/introduction.mdx b/docs/learn/interactive/dapps/introduction.mdx index 1a47ede80..909480c90 100644 --- a/docs/learn/interactive/dapps/introduction.mdx +++ b/docs/learn/interactive/dapps/introduction.mdx @@ -18,17 +18,17 @@ While the course specifically focuses on the Soroban platform, the knowledge you Through The Soroban Dapps Challenge, you'll have hands-on experience using Soroban's initial versions of the smart contracts environment, a Rust SDK, a CLI, and an RPC server. You'll learn how to write, test, and deploy smart contracts, and you'll get to see your code in action on Futurenet. -## What This Course Entails {#what-this-course-entails} +## What This Course Entails We've designed this course as a learning adventure. It's a way for developers from the Stellar ecosystem and other blockchain communities to experiment, provide feedback, and contribute to the Soroban development process. As you progress through The Soroban Dapps Challenge, anticipate your code to break and updates to shift things. We invite you to experiment and build but also remind you that changes are afoot as we prepare for the production release. -## Getting Started {#getting-started} +## Getting Started To get started, simply head over to the [Dashboard](/docs/learn/interactive/dapps/dashboard), [connect your wallet](../../../build/guides/freighter/connect-testnet.mdx), and see what challenges await you! -## Giving Your Feedback {#giving-your-feedback} +## Giving Your Feedback We value your input. Feel free to file issues in the Soroban repos or raise them in the soroban channel in the Stellar Developer [Discord](https://discord.gg/3qrBhbwE). diff --git a/docs/learn/interactive/dapps/scaffold-soroban.mdx b/docs/learn/interactive/dapps/scaffold-soroban.mdx index e8d5cdda7..0304ede10 100644 --- a/docs/learn/interactive/dapps/scaffold-soroban.mdx +++ b/docs/learn/interactive/dapps/scaffold-soroban.mdx @@ -10,23 +10,23 @@ The Dapps Challenge is undergoing updates. Thank you for your patience as we wor ::: -## Demonstrative Soroban Dapps {#demonstrative-soroban-dapps} +## Demonstrative Soroban Dapps import ReactPlayer from "react-player"; The **Soroban** team has invested considerable effort into contract implementation. They’ve built CLI’s and libraries, enabling contract builders to create and invoke using Rust, which forms the “backend” of Soroban. However, the “frontend”, which involves JS client libraries, required attention. -## Background {#background} +## Background During the Soroban Hackathon, we recognized that while the frontend libraries were functional, their user experience was far from ideal. Furthermore, the lack of clear examples made it harder for dapp creators to design and understand Soroban's UX. To tackle this, the **Wallet Engineering** team, in collaboration with the Soroban team, has decided to launch “Scaffold Soroban”, a collection of demo dapps. These dapps demonstrate basic functionalities in a structured, easy-to-follow manner, primarily focusing on how to construct/deploy Soroban contract invocations. -## Dapp Demos {#dapp-demos} +## Dapp Demos For easy accessibility, we have compiled the dapps into a [single repository](https://github.com/stellar/scaffold-soroban), which contains the following dapps: -### [1. Payment Dapp](https://github.com/stellar/soroban-react-payment) {#1-payment-dapp} +### [1. Payment Dapp](https://github.com/stellar/soroban-react-payment) This dapp mirrors the Soroban payment flow in Freighter by using the wallet’s Soroban token balances to invoke the `xfer` method on the token’s contract. @@ -37,7 +37,7 @@ See the [demo](https://github.com/stellar/soroban-react-payment/releases/tag/v1. url="https://user-images.githubusercontent.com/6789586/244450707-2ca53a9c-7493-47a1-aee6-cb126d6e32f8.mp4" /> -### [2. Mint Token Dapp](https://github.com/stellar/soroban-react-mint-token) {#2-mint-token-dapp} +### [2. Mint Token Dapp](https://github.com/stellar/soroban-react-mint-token) This dapp allows a token admin to mint tokens by using the admin account to invoke the `mint` method on the token’s contract. @@ -48,7 +48,7 @@ See the [demo](https://github.com/stellar/soroban-react-mint-token/releases/tag/ url="https://user-images.githubusercontent.com/6886006/246495488-1b02da2c-5119-47c6-ab38-fbaa73a26f12.mov" /> -### [3. Atomic Swap Dapp](https://github.com/stellar/soroban-react-atomic-swap) {#3-atomic-swap-dapp} +### [3. Atomic Swap Dapp](https://github.com/stellar/soroban-react-atomic-swap) This dapp demonstrates a simplified swap between two tokens by using the wallet’s Soroban token balances to invoke the `swap` method on the atomic swap contract. @@ -59,7 +59,7 @@ See the [demo](https://github.com/stellar/soroban-react-atomic-swap/releases/tag url="https://user-images.githubusercontent.com/6886006/258894451-19f4363b-e6e3-4d32-973a-6d99fd0d9847.mov" /> -## How To Explore the Dapps on Scaffold-Soroban {#how-to-explore-the-dapps-on-scaffold-soroban} +## How To Explore the Dapps on Scaffold-Soroban To begin using these examples, navigate to [Scaffold-Soroban](https://scaffold-soroban.stellar.org/) and choose the name of the dapp you're interested in from the "select demo" dropdown: @@ -69,7 +69,7 @@ To begin using these examples, navigate to [Scaffold-Soroban](https://scaffold-s Dive in and discover the power of Soroban! -## Functionality Behind the Dapps {#functionality-behind-the-dapps} +## Functionality Behind the Dapps With the introduction of these dapps, let's delve deeper into some of their [standout features](https://github.com/stellar/soroban-react-atomic-swap/blob/main/src/helpers/soroban.ts) that showcase the power and innovation behind the dapps: @@ -81,7 +81,7 @@ Other utilities such as `accountToScVal` and `numberToI128` are also provided to The code referenced showcases various functionalities including sending transactions, retrieving token information, simulating transactions, building swaps, and authorizing contract calls, all of which are ready to be cloned, customized, and expanded upon to suit your unique needs and ideas. -## Conclusion {#conclusion} +## Conclusion We hope these dapps will help you understand the Soroban ecosystem better and inspire you to build your own dapps using tools like [stellar-sdk](https://www.npmjs.com/package/@stellar/stellar-sdk) and [freighter-api](https://www.npmjs.com/package/@stellar/freighter-api). We look forward to seeing what you create! diff --git a/docs/learn/migrate/evm/introduction-to-solidity-and-rust.mdx b/docs/learn/migrate/evm/introduction-to-solidity-and-rust.mdx index 83a44e5f6..02b108c0c 100644 --- a/docs/learn/migrate/evm/introduction-to-solidity-and-rust.mdx +++ b/docs/learn/migrate/evm/introduction-to-solidity-and-rust.mdx @@ -8,21 +8,21 @@ description: Explore the fundamentals of Solidity, Rust, and Soroban. We are excited to introduce you to Soroban, a powerful smart contracts platform designed to be sensible, built-to-scale, and developer-friendly, with a focus on Rust's performance and safety benefits. With its user-friendly interface and powerful features, Soroban offers an ideal platform for developers who are seeking a more efficient and effective way to build decentralized applications and transition from Solidity to Rust. In this article, we will explore the fundamentals of Solidity, Rust, and Soroban, and guide you through setting up the development environment to start your journey with Soroban's Rust smart contract compatibility. -## Solidity and Dapp Development {#solidity-and-dapp-development} +## Solidity and Dapp Development Solidity is a high-level, statically-typed programming language primarily used for developing smart contracts on the Ethereum Virtual Machine (EVM). It enables the creation of decentralized applications (dapps) that can run on various blockchain platforms, automating complex transactions and interactions without the need for a central authority. -## Rust: Performance and Safety {#rust-performance-and-safety} +## Rust: Performance and Safety Rust is a systems programming language that emphasizes safety, concurrency, and performance. Its unique features, such as a strong static type system, ownership model, and memory safety guarantees, make it an ideal choice for developing high-performance, secure applications, including smart contracts. -## Soroban: Programmable Logic {#soroban-programmable-logic} +## Soroban: Programmable Logic Soroban, a sensible and built-to-scale smart contracts platform, offers a developer-friendly and batteries-included experience. While it shares the same principles of scalability and practicality as Stellar, Soroban can also function as a standalone platform and integrate with other transaction processors, such as L2s, permissioned ledgers, and even other blockchains. With Soroban, Classic Stellar gains the added functionality of programmable logic in the form of custom operations encapsulated within smart contracts. You can learn more about Soroban's features and benefits in the [Soroban Overview](../../../build/smart-contracts). -## Setting Up the Development Environment for Rust and Soroban {#setting-up-the-development-environment-for-rust-and-soroban} +## Setting Up the Development Environment for Rust and Soroban To get started with Rust and Soroban, follow the steps on the [Setup Page](../../../build/smart-contracts/getting-started/setup.mdx). diff --git a/docs/learn/migrate/evm/smart-contract-deployment.mdx b/docs/learn/migrate/evm/smart-contract-deployment.mdx index 072244fda..6d6fcee13 100644 --- a/docs/learn/migrate/evm/smart-contract-deployment.mdx +++ b/docs/learn/migrate/evm/smart-contract-deployment.mdx @@ -11,42 +11,42 @@ import TabItem from "@theme/TabItem"; In this tutorial, we will discover the similarities in smart contract deployment by examining workflows with Soroban and [Hardhat](https://hardhat.org/). We will dive into the intricacies of each framework, learn to write secure and efficient smart contract code, and harness the power of Rust and Soroban to create customized contract logic. -## Table of Contents {#table-of-contents} +## Table of Contents 1. [Soroban and Hardhat Comparison](#soroban-and-hardhat-comparison) 2. [Hardhat vs Soroban SDKs](#hardhat-vs-soroban-sdks) 3. [Using Rust and Soroban for Smart Contract Development](#developing-smart-contracts-with-rust-and-soroban) 4. [Vault Contract Deployment and Interaction](#vault-contract-deployment-and-interaction) -## Soroban and Hardhat Comparison {#soroban-and-hardhat-comparison} +## Soroban and Hardhat Comparison -### Introduction {#introduction} +### Introduction Soroban and Hardhat are both frameworks that enable developers to build, test, and deploy smart contracts. In this section, we will delve into the similarities and distinctions between these two frameworks. -### Soroban Framework {#soroban-framework} +### Soroban Framework Soroban is a Rust-based framework tailored for developing smart contracts on the Stellar network. Designed as a lightweight framework, with [tools to support developers](../../../tools/developer-tools/README.mdx), Soroban allows developers to develop smart contracts through a simple and intuitive workflow. -### Hardhat {#hardhat} +### Hardhat Hardhat serves as a development environment for compiling, deploying, testing, and debugging smart contracts for the EVM. It assists developers in managing and automating recurring tasks inherent to building smart contracts. -### Similarities {#similarities} +### Similarities Soroban and Hardhat are powerful frameworks designed to streamline the process of building, testing, and deploying smart contracts. Equipped with a comprehensive suite of tools, these frameworks facilitate the development of smart contracts and their deployment on their respective virtual machines. -### Differences {#differences} +### Differences Soroban, with its lightweight design, offers developers an exceptional platform for writing Rust-based smart contracts and deploying them effortlessly on the Stellar network. In contrast, Hardhat serves primarily as a development environment tailored for the Ethereum Virtual Machine, providing a different focus and target audience. -## Hardhat vs. Soroban SDKs {#hardhat-vs-soroban-sdks} +## Hardhat vs. Soroban SDKs Hardhat offers a streamlined workflow for deploying smart contracts on the Ethereum Virtual Machine, with key components such as `ethers.js`, `scripts`, and `testing` playing crucial roles. On the other hand, Soroban presents a compelling alternative, boasting powerful SDKs that facilitate smart contract development and deployment. In the upcoming section, we will delve into [Soroban's SDKs](../../../tools/sdks/library.mdx), drawing comparisons with Hardhat components, and highlighting the unique advantages each platform brings to the table. -### Ethers.js {#ethersjs} +### Ethers.js `Ethers.js` is a widely-used `JavaScript` library designed for seamless interaction with the EVM. It offers a user-friendly interface that simplifies connecting to Ethereum nodes, managing accounts, and sending transactions. Additionally, `Ethers.js` provides a robust API for efficient communication with smart contracts. This library is a core component of the Hardhat framework and can be imported into scripts to streamline the deployment of smart contracts. @@ -60,11 +60,11 @@ async function main() { } ``` -### Soroban Client {#soroban-client} +### Soroban Client Soroban offers a comparable library, [`stellar-sdk`](../../../tools/sdks/library.mdx#javascript-sdk), that enables seamless interaction smart contracts deployed on the Stellar Network. This library supplies a comprehensive networking layer API for Stellar RPC methods as well as the traditional Horizon API, simplifying the process of building and signing transactions. Additionally, `stellar-sdk` streamlines communication with RPC instances and supports submitting transactions or querying network state with ease. -### Scripts {#scripts} +### Scripts Hardhat scripts streamline the automation of routine tasks, such as deploying and managing smart contracts. Developers can create these scripts using either JavaScript or TypeScript, catering to their preferred programming style. They are stored in the `scripts` directory of a Hardhat project and can be executed using the `npx hardhat run` command. @@ -87,7 +87,7 @@ main() }); ``` -### Soroban Scripts {#soroban-scripts} +### Soroban Scripts Soroban offers an extensive collection of SDKs that include scripting capabilities, ensuring a smooth workflow for deploying and managing smart contracts. Developers can automate tasks such as compiling, deploying, and interacting with smart contracts using a variety of SDKs that support scripting in languages like [`JavaScript`, `TypeScript`, `Python`, and others](../../../tools/sdks/library.mdx). @@ -129,7 +129,7 @@ tx = ( ... ``` -### Testing {#testing} +### Testing Hardhat provides a testing framework that allows developers to write tests for their smart contracts. These tests can be written in JavaScript or TypeScript and run using the `npx hardhat test` command. @@ -149,7 +149,7 @@ describe("MyContract", function () { }); ``` -### Soroban Testing {#soroban-testing} +### Soroban Testing Soroban enables users to leverage the power of Rust's testing framework to write tests for their smart contracts. These tests can be written in Rust and run using the `cargo test` command. @@ -175,15 +175,15 @@ fn test() { In summary, while Hardhat provides an excellent environment for deploying smart contracts on the EVM, Soroban's Rust-based framework offers significant advantages in terms of performance, making it an ideal choice for building secure and efficient smart contracts. -## Developing Smart Contracts with Rust and Soroban {#developing-smart-contracts-with-rust-and-soroban} +## Developing Smart Contracts with Rust and Soroban -### Introduction {#introduction-1} +### Introduction Now that we've examined the deployment workflow with Hardhat, let's explore developing and deploying smart contracts with Rust and Soroban. The key advantage of using Soroban is its ability to leverage Rust's safety features and performance, making it an excellent choice for developing secure and efficient smart contracts. We've learned that Smart contracts are self-executing contracts that can be programmed to automatically enforce the rules and regulations of a particular agreement. They are a core component of decentralized applications (dApps) and blockchain technology. In this section, we will learn how to use Rust and Soroban to develop and deploy custom smart contract logic. -### Setup {#setup} +### Setup If you haven't already setup up the dev environment for Soroban, you can get started by following the steps on the [Setup Page](../../../build/smart-contracts/getting-started/setup.mdx). @@ -220,7 +220,7 @@ soroban-examples Once we have the Token, let's create a new smart contract that uses it. -### Writing a Smart Contract {#writing-a-smart-contract} +### Writing a Smart Contract Let's start by writing a simple example of a vault contract that allows users to deposit funds and withdraw their funds with generated yield. @@ -902,7 +902,7 @@ If the user were to call the `withdraw` method with 100 shares, the following wo - 100 shares would be burned. - 100 + (100/100) tokens would be transferred from the vault contract to the withdrawer. -### Testing {#testing-1} +### Testing To test the vault contract, we will can simply run the following command in our terminal from our vault contract directory: @@ -918,7 +918,7 @@ running 1 test test test::test ... ok ``` -### Vault Contract Deployment and Interaction {#vault-contract-deployment-and-interaction} +### Vault Contract Deployment and Interaction Now that we have a working vault contract, we can deploy it to a network and interact with it. diff --git a/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.mdx b/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.mdx index aae0e23db..480945ffd 100644 --- a/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.mdx +++ b/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.mdx @@ -11,16 +11,16 @@ import TabItem from "@theme/TabItem"; In this tutorial, we will cover advanced Solidity and Rust concepts such as inheritance, interfaces, libraries, and modifiers. Additionally, we will learn how to write safe and efficient Rust code for smart contracts. Finally, we will learn how to convert common Solidity concepts to Rust. -## Table of Contents {#table-of-contents} +## Table of Contents 1. [Advanced Solidity Concepts](#advanced-solidity-concepts) 2. [Advanced Rust Concepts](#advanced-rust-concepts) 3. [Writing Safe and Efficient Rust Code for Smart Contracts](#writing-safe-and-efficient-rust-code-for-smart-contracts) 4. [Solidity to Soroban: Common Concepts and Best Practices](#solidity-to-soroban-common-concepts-and-best-practices) -## Advanced Solidity Concepts {#advanced-solidity-concepts} +## Advanced Solidity Concepts -### Inheritance {#inheritance} +### Inheritance In Solidity, smart contracts can inherit properties and functions from other contracts. This is achieved using the `is` keyword. @@ -42,7 +42,7 @@ contract Child is Parent { In this example, the `Child` contract inherits the `messageFromParent` function from the `Parent` contract. The `Child` contract can then call the `messageFromParent` function directly. -### Interfaces {#interfaces} +### Interfaces Interfaces are similar to contracts, but they cannot have any function implementations. They only contain function signatures. Contracts can implement interfaces using the `is` keyword, similar to inheritance. @@ -65,7 +65,7 @@ contract SomeContract is SomeInterface { In this example, the `SomeContract` contract implements the `SomeInterface` interface. Its implementation returns a `u256` that is incremented each time the `doSomething` function is called. -### Libraries {#libraries} +### Libraries Libraries are similar to contracts, but they cannot have any state variables. They are used to store reusable code that can be used by other contracts. Libraries are deployed once and can be used by multiple contracts. They are defined using the `library` keyword. They are invoked by using the `using` keyword. @@ -92,7 +92,7 @@ contract MyContract { In this example, the `SafeMath` library is used in the `increment` function. The `increment` function uses the `add` function from the `SafeMath` library to increment the `value` variable. -### Modifiers {#modifiers} +### Modifiers Modifiers are used to change the behavior of functions in a declarative way. They are defined using the `modifier` keyword. Modifiers can be used to perform common checks such as validating inputs, checking permissions, and more. @@ -119,9 +119,9 @@ contract MyContract is Ownable { In this example, the `onlyOwner` modifier is used to restrict access to the `doSomething` function. The `doSomething` function can only be called by the `owner` of the contract which was defined during deployment as `msg.sender`. -## Advanced Rust Concepts {#advanced-rust-concepts} +## Advanced Rust Concepts -### Crates {#crates} +### Crates A crate in Rust is a collection of precompiled programs, scripts, or routines that can be easily reused by programmers when writing code. This allows them to avoid reinventing the wheel by not having to implement the same logic or program multiple times. There are two types of crates in Rust: [Binary crates and Library crates](https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html). @@ -172,7 +172,7 @@ In this example, the `alloc` crate is imported into the smart contract using the For more details on how to use the `alloc` crate, including a hands-on practical exercise, visit the [alloc example contract](../../../build/smart-contracts/example-contracts/alloc.mdx#how-it-works). -#### Inheriting Functionality from Other Crates {#inheriting-functionality-from-other-crates} +#### Inheriting Functionality from Other Crates We can illustrate another example of inheritance by importing functionality into a crate from other crates in the same project in the following example: @@ -255,7 +255,7 @@ fn mint(e: Env, to: Address, amount: i128) { As you can see, the `event.rs`, `admin.rs`, and `balance.rs` files are imported into the `contract.rs` file using the `use` keyword. This allows us to use the functions from those files in the `mint` function of our `contract.rs` file. -#### Inheriting Functionality using `contractimport!` {#inheriting-functionality-using-contractimport} +#### Inheriting Functionality using `contractimport!` The Soroban Rust SDK provides a powerful macro, [`contractimport`](https://docs.rs/soroban-sdk/latest/soroban_sdk/macro.contractimport.html), which allows a user to import a contract from its Wasm file, generating a client, types, and constant holding the contract file. @@ -294,11 +294,11 @@ impl LiquidityPoolTrait for LiquidityPool { In the above example, we use `contractimport` to interact with the token file via a `Client` that was generated for the `token` module. This `Client` was created using a Contract trait that matches the interface of the contract, a ContractClient struct that contains functions for each function in the contract, and types for all contract types defined in the contract. -#### A Note on Inheritance and Composability {#a-note-on-inheritance-and-composability} +#### A Note on Inheritance and Composability While we've been using the term "inheritance" to help make the transition from Solidity smoother, let's clarify an important aspect of Rust: it does not support inheritance as we traditionally understand it. Instead, Rust practices "composability", meaning it uses functions from different crates, which are akin to packages, in a modular fashion. So, when we discuss `contractimport!`, we're actually observing composability in action, not "inheritance". Rust does not foster the "is a" relationship inherent in OOP languages. Instead, it enables us to reuse and assemble code effectively across different scopes. This is a technical truth that is important to understand; however, it's worth noting that this fact doesn't impact the practical usage of Soroban throughout this guide. -### Modules {#modules} +### Modules In Rust, modules consist of a cohesive set of related functions and types that are often organized together for better organization and reusability. These modules can be reused across multiple projects by publishing them as crates. @@ -345,7 +345,7 @@ Notice that we use the `checked_add` function from the standard library to ensur Even when Rust code is compiled with the `#![no_std]` flag, it is still possible to use some of the standard library's features, such as the `checked_add` function. This is because Rust provides the option to selectively import modules and functions from the standard library, allowing developers to use only the specific features they need. -### Traits {#traits} +### Traits Rust does not have a built-in modifier system like Solidity. However, you can achieve similar functionality using `traits` and their implementations. @@ -405,7 +405,7 @@ Here's a breakdown of the code above: It's worth mentioning that the Soroban Rust SDK comes with several built-in requirements that developers can use, such as the [`require_auth`](https://docs.rs/soroban-sdk/latest/soroban_sdk/struct.Address.html#method.require_auth) method provided by the `Address` struct. -### Interfaces {#interfaces-1} +### Interfaces Interfaces are an essential part of building smart contracts with Soroban. @@ -417,7 +417,7 @@ There are many types of smart contract interfaces, and each has a specific purpo For more information on smart contract interfaces built with Soroban, including the Token Interface, visit the [tokens section](../../../tokens/README.mdx) of the documentation. -## Writing Safe and Efficient Rust Code for Smart Contracts {#writing-safe-and-efficient-rust-code-for-smart-contracts} +## Writing Safe and Efficient Rust Code for Smart Contracts When writing Rust code for smart contracts, it's important to focus on safety and efficiency. Some tips include: @@ -494,7 +494,7 @@ fn main() { } ``` -## Solidity to Soroban: Common Concepts and Best Practices {#solidity-to-soroban-common-concepts-and-best-practices} +## Solidity to Soroban: Common Concepts and Best Practices In this section we will explore key Solidity concepts and provide their Soroban equivalents. We will discuss the following topics: @@ -504,11 +504,11 @@ In this section we will explore key Solidity concepts and provide their Soroban - Function visibility specifiers - Time-based variables -### Message Properties {#message-properties} +### Message Properties The Soroban Rust SDK and Solidity provide a number of message properties that can be used to access information about the current transaction. These properties include: -#### Solidity {#solidity} +#### Solidity - `msg.sender`: The address of the account that sent the transaction. - `msg.value`: The amount of Ether sent with the transaction. @@ -536,7 +536,7 @@ contract SimpleContract { These are a part of Solidity's global variables, which are accessible from any function in the contract. -#### Soroban {#soroban} +#### Soroban In contrast to Solidity's global variables, Soroban relies on passing an [`Env`](https://docs.rs/soroban-sdk/latest/soroban_sdk/struct.Env.html) argument to all functions which provides access to the environment the contract is executing within. @@ -583,11 +583,11 @@ use soroban_sdk::{Env, Address}; } ``` -### Error Handling {#error-handling} +### Error Handling The Soroban Rust SDK and Solidity provide a number of ways to handle errors. These include: -#### Solidity {#solidity-1} +#### Solidity Solidity provides a `require` function that can be used to check for certain conditions and revert the transaction if they are not met. For example, the following code sets a minimum value for the amount of Ether sent with the transaction: @@ -599,7 +599,7 @@ function deposit() public payable { } ``` -#### Soroban {#soroban-1} +#### Soroban The [panic!](https://doc.rust-lang.org/book/ch09-00-error-handling.html) macro serves as Rust's error-handling mechanism, which closely resembles the `require` function in Solidity. @@ -612,11 +612,11 @@ pub fn simple_deposit(amount: u32) { } ``` -### Address-Related Functionality {#address-related-functionality} +### Address-Related Functionality Both Soroban and Solidity provide provide a number of functions for working with addresses. These functions include: -#### Solidity {#solidity-2} +#### Solidity - `address(this)`: Returns the address of the current contract. - `address payable(this)`: Returns the address of the current contract as a payable address. @@ -639,7 +639,7 @@ contract SimpleContract { There would be no difference in appearance between a regular address and a payable address in Solidity. -#### Soroban {#soroban-2} +#### Soroban - `e.current_contract_address()`: Returns the Address object corresponding to the current executing contract. @@ -664,7 +664,7 @@ impl SimpleContract { } ``` -#### Why Soroban Differs {#why-soroban-differs} +#### Why Soroban Differs Soroban has some differences from Solidity in terms of addresses and other functionalities. These differences arise due to the design principles and goals of Soroban. @@ -674,11 +674,11 @@ To further explain, the `Env` type offers a gateway to the environment where the Meanwhile, the `Address` object serves as a potent tool for authentication and [authorization](#authorization). For instance, it can be used to authorize token transfers, acting as a security gatekeeper within the system. This feature amplifies the functionality of addresses in Soroban, making them not just a means of identification or storage, but also a key player in verifying and authorizing transactions. -### Function Visibility Specifiers {#function-visibility-specifiers} +### Function Visibility Specifiers The Soroban Rust SDK and Solidity provide a number of function visibility specifiers that can be used to control who can call a function. These specifiers include: -#### Solidity {#solidity-3} +#### Solidity - `public`: Anyone can call the function. - `external`: Only other contracts can call the function. @@ -698,7 +698,7 @@ contract SimpleContract { } ``` -#### Soroban {#soroban-3} +#### Soroban - `pub`: The item (function, struct, etc.) is accessible from any module or scope. - `pub(crate)`: The item is accessible only within the current crate. @@ -763,11 +763,11 @@ impl OuterTrait for NewContract { } ``` -### Time-Based Variables {#time-based-variables} +### Time-Based Variables The Soroban Rust SDK and Solidity provide a number of time-based variables that can be used to access information about the current block(EVM) or ledger(Soroban). These variables include: -#### Solidity {#solidity-4} +#### Solidity - `block.timestamp`: The timestamp of the current block. - `block.number`: The number of the current block. @@ -788,7 +788,7 @@ contract SimpleContract { } ``` -#### Soroban {#soroban-4} +#### Soroban - `env.ledger().timestamp()`: Returns a unix timestamp for when the most recent ledger was closed. - `env.ledger().sequence()`: Returns the sequence number of the most recently closed ledger. @@ -811,11 +811,11 @@ impl SimpleContract { } ``` -### Authorization {#authorization} +### Authorization Soroban differs from Solidity in its approach to authorization and modifiers. While Solidity has a built-in modifier system, Sorotban does not. Instead, Soroban leverages traits, their implementations, and core features to achieve similar functionality. -#### Solidity {#solidity-5} +#### Solidity In Solidity, the ERC20 token standard includes the `approve` function, which allows a token holder to authorize another address to spend a certain amount of tokens on their behalf. This function is commonly used in decentralized exchanges and other token transfer scenarios. Furthermore, we're ensuring that the spender is authorized to spend the amount of tokens requested by the token holder. @@ -862,7 +862,7 @@ The approve function allows the token holder to authorize spender to spend amoun These Solidity examples illustrate some common authorization patterns used in Ethereum smart contracts. Soroban provides alternative approaches to achieve similar functionality, leveraging core functionality derived right from the soroban SDK. -#### Soroban {#soroban-5} +#### Soroban Soroban's design principles prioritize flexibility, security, and testability, which have led to differences in how authorization is handled compared to Solidity. @@ -900,7 +900,7 @@ Soroban's approach to authorization in this example offers several advantages ov Soroban authorization provides Contract-level Authorization, Account Abstraction Functionality, and more advanced Authorization checks. To learn more about these advantages, visit the [Authorization section](../../encyclopedia/security/authorization.mdx) of the documentation. -## Summary {#summary} +## Summary Overall the Soroban equivalents of Solidity concepts are very similar. However, there are notable differences worth highlighting. Soroban uses `env` instead of `msg` to access information about the entire contract execution environment, including the state of the contract, addresses involved, and more. Authorization is also handled differently in Soroban, as it is built into the core functionality of the SDK and is more robust than relying on smart contract code alone. diff --git a/docs/learn/migrate/evm/solidity-and-rust-basics.mdx b/docs/learn/migrate/evm/solidity-and-rust-basics.mdx index 0d535cd7e..c780469f0 100644 --- a/docs/learn/migrate/evm/solidity-and-rust-basics.mdx +++ b/docs/learn/migrate/evm/solidity-and-rust-basics.mdx @@ -8,13 +8,13 @@ description: Explore the fundamentals of Solidity and Rust Syntax, Data Types, a In this tutorial, we'll explore Rust and Solidity, two powerful programming languages. Rust, a systems programming language, is renowned for its safety, concurrency, and performance features, which can be advantageous when building smart contracts. On the other hand, Solidity is a high-level language specifically designed for creating smart contracts on the Ethereum Virtual Machine. This section aims to provide a high-level overview of the similarities and differences between the two languages. -## Table of Contents {#table-of-contents} +## Table of Contents 1. [Solidity Syntax, Data Types, and Basic Constructs](#solidity-syntax) 2. [Rust Syntax, Data Types, and Ownership Model](#rust-syntax) 3. [Writing and Interacting With Simple Smart Contracts](#writing-and-interacting-with-simple-smart-contracts) -### Solidity Syntax {#solidity-syntax} +### Solidity Syntax Solidity is a programming language designed specifically for creating smart contracts on the Ethereum Virtual Machine (EVM). It has a syntax similar to JavaScript and supports a variety of data types and constructs. @@ -28,7 +28,7 @@ contract HelloWorld { } ``` -### Data Types {#data-types} +### Data Types Solidity supports various data types, such as: @@ -97,7 +97,7 @@ contract DataTypesExample { } ``` -### Basic Constructs {#basic-constructs} +### Basic Constructs Some of the basic constructs in Solidity include: @@ -109,7 +109,7 @@ Some of the basic constructs in Solidity include: We will explore some of these constructs in more detail in the next article, [Advanced Solidity Concepts](./solidity-and-rust-advanced-concepts.mdx#advanced-solidity-concepts). -### Rust Syntax {#rust-syntax} +### Rust Syntax Rust is a programming language that is well-suited for building smart contracts due to its emphasis on safety, concurrency, and performance. It enforces strict ownership and borrowing rules to prevent data races and other common bugs. @@ -119,11 +119,11 @@ fn main() { } ``` -### Data Types {#data-types-1} +### Data Types The [Soroban Rust SDK](https://docs.rs/soroban-sdk/latest/soroban_sdk/index.html) supports a variety of [Built-In Types](../../encyclopedia/contract-development/types/built-in-types.mdx) which consist of both Primitive and [Custom Types](../../encyclopedia/contract-development/types/custom-types.mdx), such as: -#### Primitive Data Types {#primitive-data-types} +#### Primitive Data Types - 32-bit Integers: signed (`i32`) and unsigned (`u32`) - 64-bit Integers: signed (`i64`) and unsigned (`u64`) @@ -142,7 +142,7 @@ The [Soroban Rust SDK](https://docs.rs/soroban-sdk/latest/soroban_sdk/index.html Both are limited to the characters `a-zA-Z0-9_` and are encoded into 64-bit integers. -#### Custom Data Types {#custom-data-types} +#### Custom Data Types - `Structs` (with Named Fields): A custom type consisting of named fields stored on the ledger as a `map` of key-value pairs. - `Structs` (with Unnamed Fields): A custom type consisting of unnamed fields stored on the ledger as a vector of values. @@ -209,13 +209,13 @@ pub enum Enum { } ``` -### A Brief Introduction to Modules, Macros, Structs, Traits, and Attribute Macros {#a-brief-introduction-to-modules-macros-structs-traits-and-attribute-macros} +### A Brief Introduction to Modules, Macros, Structs, Traits, and Attribute Macros In this section, we will provide a concise introduction to some fundamental concepts in Rust: `Modules`, `Macros`, `Structs`, `Traits`, and `Attribute Macros`. These concepts are essential for understanding and writing efficient Rust code, and they will assist you on your journey as a smart contract developer. -#### 1. Modules {#1-modules} +#### 1. Modules Modules in Rust are used to organize and separate code into different namespaces. They enable better code organization, reusability, and encapsulation. To define a module, use the `mod` keyword followed by a block containing the module's contents. @@ -227,7 +227,7 @@ mod my_module { } ``` -#### 2. Macros {#2-macros} +#### 2. Macros [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html) in Rust are powerful tools that allow you to do metaprogramming, enabling you to build chunks of reusable code at compile time. @@ -245,7 +245,7 @@ fn main() { } ``` -#### 3. Structs {#3-structs} +#### 3. Structs Structs are custom data types in Rust that enable you to bundle data together. They provide a way to define and create more complex data structures. @@ -263,7 +263,7 @@ fn main() { } ``` -#### 4. Traits {#4-traits} +#### 4. Traits Traits in Rust define a shared set of behaviors that types can then either use as-is (default implementations) or implement themselves. They can be thought of as interfaces in other languages. Traits are defined with the `trait` keyword, and their methods can be implemented for different types using the `impl` keyword. @@ -281,7 +281,7 @@ impl MyTrait for MyStruct { } ``` -#### 5. Attribute Macros {#5-attribute-macros} +#### 5. Attribute Macros Attribute macros in Rust are a form of procedural macros that enable you to define custom attributes for various language elements such as functions, structs, and enums. They can modify or generate code based on the annotated items. @@ -309,7 +309,7 @@ impl HelloContract { } ``` -### Ownership Model {#ownership-model} +### Ownership Model Rust enforces [**strict ownership rules**](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html) to manage memory and resources: @@ -318,17 +318,17 @@ Rust enforces [**strict ownership rules**](https://doc.rust-lang.org/book/ch04-0 - [`Borrowing`](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html): Values can be borrowed as immutable or mutable references. - [`Lifetimes`](https://doc.rust-lang.org/rust-by-example/scope/lifetime.html): Used to ensure that references remain valid. -### Smart Contract Dialect {#smart-contract-dialect} +### Smart Contract Dialect Contract development in Rust involves certain restrictions due to either unavailable features in the deployment environment or high runtime costs. Thus, the code written for contracts can be seen as a distinct _dialect_ of Rust, focusing on deterministic behavior and minimized code size. To learn more about Rust's Contract Dialect, check out the [Contract Rust Dialect Page](../../encyclopedia/contract-development/rust-dialect.mdx). -## Writing and Interacting with Simple Smart Contracts {#writing-and-interacting-with-simple-smart-contracts} +## Writing and Interacting with Simple Smart Contracts In this section, we'll learn how to write and interact with simple smart contracts in Solidity and Rust. -### Writing a Smart Counter in Solidity {#writing-a-smart-counter-in-solidity} +### Writing a Smart Counter in Solidity Here's an example of a simple Solidity smart contract for a counter: @@ -391,7 +391,7 @@ function increment() public { This is a function called `increment()` that increments the counter by 1. It doesn't return anything, but it modifies the state of the contract. Like `getCount()`, it's marked as `public`, which means it can be called from both inside and outside the contract. -### Interacting with the Solidity Smart Counter {#interacting-with-the-solidity-smart-counter} +### Interacting with the Solidity Smart Counter We can interact with the smart contract using the `Remix IDE`. To do so, follow these steps: @@ -417,7 +417,7 @@ The contract should appear under the `Deployed Contracts` tab: Up to this point, we've covered the basics of writing, deploying to a sandbox EVM, and interacting with a simple smart contract using Solidity. In the following section, we will extend our knowledge by learning how to achieve the same outcomes using Rust. -### Writing a Smart Counter in Rust {#writing-a-smart-counter-in-rust} +### Writing a Smart Counter in Rust In this section, we'll create a Rust program that simulates the functionality of the Counter smart contract. Here's an example of a simple counter in Rust: @@ -543,7 +543,7 @@ This is a repeat of the code we saw earlier, which retrieves the value associate Now that we have written our smart contract, it's time to explore how we can interact with it using the [Stellar CLI](../../../tools/developer-tools/cli/stellar-cli.mdx), one of many robust [Developer Tools](../../../tools/developer-tools/README.mdx) available. This powerful command-line tool allows us to interact with the Soroban Virtual Machine from a local machine, providing us with an efficient and flexible way to manage our smart contract. -### Interacting with the Rust Smart Counter {#interacting-with-the-rust-smart-counter} +### Interacting with the Rust Smart Counter To interact with the Rust counter, create a new Rust library using the cargo new command. diff --git a/docs/networks/resource-limits-fees.mdx b/docs/networks/resource-limits-fees.mdx index e60e9bd02..b49a2296d 100644 --- a/docs/networks/resource-limits-fees.mdx +++ b/docs/networks/resource-limits-fees.mdx @@ -5,13 +5,13 @@ title: Resource Limits & Fees import CanvasFeeGraphs from "@site/src/components/CanvasFeeGraphs"; -## Current Inclusion Fees {#current-inclusion-fees} +## Current Inclusion Fees For the past three hours, inclusion fee statistics for smart contract transactions on the Mainnet network are: -## Resource Limits {#resource-limits} +## Resource Limits :::note @@ -37,7 +37,7 @@ Resource limitations and fees only apply to smart contract transactions. Read mo | Max txs size in bytes per ledger | 130 KiB | | Eviction scan size | 500 KB | -## Resource Fees {#resource-fees} +## Resource Fees | Network Setting | Cost (stroops) | | :--------------------------------------------- | :------------------------ | diff --git a/docs/networks/software-versions.mdx b/docs/networks/software-versions.mdx index 62646e577..f89fb8d22 100644 --- a/docs/networks/software-versions.mdx +++ b/docs/networks/software-versions.mdx @@ -12,9 +12,9 @@ Release candidates are software releases that are also released to the [Testnet] [testnet]: ./README.mdx -## Protocol 22 (Testnet, October , 2024) {#protocol-22-testnet-october--2024} +## Protocol 22 (Testnet, October , 2024) -### Software {#software} +### Software | Software | Version | | --- | --- | @@ -35,27 +35,27 @@ Release candidates are software releases that are also released to the [Testnet] | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Release notes {#release-notes} +### Release notes -#### Core {#core} +#### Core New features in Protocol 22: - Constructor support in Soroban: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0058.md. - Soroban host functions for BLS12-381: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0059.md. -#### Soroban Rust SDK {#soroban-rust-sdk} +#### Soroban Rust SDK Key protocol-related changes: - Support for constructors - Support for BLS12-381 host functions -#### Stellar CLI (Previously Soroban CLI) {#stellar-cli-previously-soroban-cli} +#### Stellar CLI (Previously Soroban CLI) -## Protocol 21 (Mainnet, June 18, 2024) {#protocol-21-mainnet-june-18-2024} +## Protocol 21 (Mainnet, June 18, 2024) -### Software {#software-1} +### Software | Software | Version | | --- | --- | @@ -79,9 +79,9 @@ Key protocol-related changes: | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Release notes {#release-notes-1} +### Release notes -#### Core {#core-1} +#### Core New features in Protocol 21: @@ -90,14 +90,14 @@ New features in Protocol 21: - Use refined cost model for VM instantiation in order to reduce the VM instantiation metered costs: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0054.md - Intra-transaction VM module caching for the further Soroban cost reduction: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0055.md, https://github.com/stellar/stellar-protocol/blob/master/core/cap-0056.md -#### Soroban Rust SDK {#soroban-rust-sdk-1} +#### Soroban Rust SDK Key protocol-related changes: - Support for secp256r1 signature verification - Support for extending TTL of contract instance and code separate from each other -#### Stellar CLI (Previously Soroban CLI) {#stellar-cli-previously-soroban-cli-1} +#### Stellar CLI (Previously Soroban CLI) Note: Soroban CLI has been renamed to Stellar CLI. @@ -127,9 +127,9 @@ Note: Soroban CLI has been renamed to Stellar CLI. - Remove lab xdr command - Add xdr command to root -## Protocol 21 (Testnet only, May 20, 2024) {#protocol-21-testnet-only-may-20-2024} +## Protocol 21 (Testnet only, May 20, 2024) -### Software {#software-2} +### Software | Software | Version | | --- | --- | @@ -153,9 +153,9 @@ Note: Soroban CLI has been renamed to Stellar CLI. | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Release notes {#release-notes-2} +### Release notes -#### Core {#core-2} +#### Core This is the first stable Core release supporting protocol 21. New features in protocol 21: @@ -164,16 +164,16 @@ This is the first stable Core release supporting protocol 21. New features in pr - Use refined cost model for VM instantiation in order to reduce the VM instantiation metered costs: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0054.md - Intra-transaction VM module caching for the further Soroban cost reduction: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0055.md, https://github.com/stellar/stellar-protocol/blob/master/core/cap-0056.md -#### Soroban Rust SDK {#soroban-rust-sdk-2} +#### Soroban Rust SDK This is the first version of the Soroban SDK that supports protocol 21. It is marked as 'preview' because contracts built with SDK v21 will only be compatible with the networks upgraded to protocol 21. Key protocol-related changes: - Support for secp256r1 signature verification - Support for extending TTL of contract instance and code separate from each other -## Protocol 21: Preview 1 (Testnet only, April 12, 2024) {#protocol-21-preview-1-testnet-only-april-12-2024} +## Protocol 21: Preview 1 (Testnet only, April 12, 2024) -### Software {#software-3} +### Software | Software | Version | | --- | --- | @@ -197,9 +197,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Release notes {#release-notes-3} +### Release notes -#### Core {#core-3} +#### Core This is the first Core release supporting protocol 21. New features in protocol 21: @@ -208,16 +208,16 @@ This is the first Core release supporting protocol 21. New features in protocol - Use refined cost model for VM instantiation in order to reduce the VM instantiation metered costs: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0054.md - Intra-transaction VM module caching for the further Soroban cost reduction: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0055.md, https://github.com/stellar/stellar-protocol/blob/master/core/cap-0056.md -#### Soroban Rust SDK {#soroban-rust-sdk-3} +#### Soroban Rust SDK This is the first version of the Soroban SDK that supports protocol 21. It is marked as 'preview' because contracts built with SDK v21 will only be compatible with the networks upgraded to protocol 21. The API itself may be considered stable. Key changes: - Support for secp256r1 signature verification - Support for extending TTL of contract instance and code separate from each other -## Protocol 20: Soroban Phase 2 (March 19, 2024) {#protocol-20-soroban-phase-2-march-19-2024} +## Protocol 20: Soroban Phase 2 (March 19, 2024) -### Software {#software-4} +### Software | Software | Version | | --- | --- | @@ -244,9 +244,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Changelog {#changelog} +### Changelog -#### Core {#core-4} +#### Core - Remove use of C99 that looks like Cxx20 designated initializers - Reduce scan size in phase1 @@ -270,7 +270,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Fix noisy eviction scan warnings - Early initialization of soroban metrics -#### Soroban Rust SDK {#soroban-rust-sdk-4} +#### Soroban Rust SDK - Display String contents in Debug implementation - Add Bytes to_buffer and to_alloc_vec @@ -278,9 +278,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Add option to disable test snapshots on Env - Bump version to 20.4.0 -## Protocol 20: Soroban Phase 1 (February 27, 2024) {#protocol-20-soroban-phase-1-february-27-2024} +## Protocol 20: Soroban Phase 1 (February 27, 2024) -### Software {#software-5} +### Software | Software | Version | | --- | --- | @@ -307,9 +307,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Changelog {#changelog-1} +### Changelog -#### Soroban RPC {#soroban-rpc} +#### Soroban RPC - (tag: v20.3.3) Bump version to 20.3.3 - Update Dockerfile and Makefile to refer rpc instead of tools @@ -325,7 +325,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Add prometheus hook to count different log levels - Remove build-test-wasms from makefile -#### Soroban CLI {#soroban-cli} +#### Soroban CLI - (tag: v20.3.1) Bump version to 20.3.1 - Update references in end-to-end tests to point to the latest releases @@ -342,9 +342,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Revert "[Epic] Separating soroban-rpc to prepare for repo change" - [Epic] Separating soroban-rpc to prepare for repo change -## Protocol 20: Soroban Phase 1 (Mainnet Edition) (February 5, 2024) {#protocol-20-soroban-phase-1-mainnet-edition-february-5-2024} +## Protocol 20: Soroban Phase 1 (Mainnet Edition) (February 5, 2024) -### Software {#software-6} +### Software | Software | Version | | --- | --- | @@ -371,16 +371,16 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Testnet Network Passphrase | `Test SDF Network ; September 2015` | | Mainnet Network Passphrase | `Public Global Stellar Network ; September 2015` | -### Changelog {#changelog-2} +### Changelog -#### XDR {#xdr} +#### XDR - Run CI for the msrv and latest rust version - Backfill changes to next for json rendering - Bump XDR - Bump version to 20.1.0 -#### Soroban Environment {#soroban-environment} +#### Soroban Environment - Allow small version-range wiggle room on curve25519-dalek to enable docs.rs nightly build - Bump version to 20.2.2 @@ -410,14 +410,14 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Bump wasmi to 0.31.1-soroban.20.0.1 - Bump version to 20.1.1 -#### Soroban Rust SDK {#soroban-rust-sdk-5} +#### Soroban Rust SDK - Update soroban-env-\* - Bump version to 20.3.2 - Update extend_ttl docs - Bug 1076 conversion error flattening -#### Soroban RPC {#soroban-rpc-1} +#### Soroban RPC - Migrate Soroban Tools to Soroban RPC - Use soroban-tools Crates @@ -433,7 +433,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Add diagnostic events to sendTransaction response - Remove panics from internal codebase -#### Soroban CLI {#soroban-cli-1} +#### Soroban CLI - feat: soroban init command - Bump dependencies for pubnet release @@ -447,9 +447,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Update typescript bindings for latest versions - Warn about RC versions only when using pubnet -## Stable v20.1.0 (January 11, 2024) {#stable-v2010-january-11-2024} +## Stable v20.1.0 (January 11, 2024) -### Software {#software-7} +### Software | Software | Version | | --- | --- | @@ -473,18 +473,18 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | | Testnet Network Passphrase | `Test SDF Network ; September 2015` | -### Changelog {#changelog-3} +### Changelog -#### Soroban Rust SDK {#soroban-rust-sdk-6} +#### Soroban Rust SDK - Fix bug with Timepoint/Duration as parameters/returns - Add storage update fns - Export functions for creating Timepoint/Duration - Allow `&Env` in contract fns -## Stable v20.0.0 (December 18, 2023) {#stable-v2000-december-18-2023} +## Stable v20.0.0 (December 18, 2023) -### Software {#software-8} +### Software | Software | Version | | --- | --- | @@ -509,13 +509,13 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | | Testnet Network Passphrase | `Test SDF Network ; September 2015` | -### Changelog {#changelog-4} +### Changelog -#### XDR {#xdr-1} +#### XDR - Update the docs for extendTTL/restore ops to match the threshold change -#### Soroban Environment {#soroban-environment-1} +#### Soroban Environment - Make RecordedAuthPayload consistently return None for invoker. - Expiration-related fixes @@ -743,7 +743,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Remaining host code review - Bump version to 20.0.0 -#### Soroban Rust SDK {#soroban-rust-sdk-7} +#### Soroban Rust SDK - Token events - Update rust-version @@ -842,7 +842,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Update env - Bump version to 20.0.0 -#### Soroban RPC {#soroban-rpc-2} +#### Soroban RPC - increased preflight instruction fee padding to 3 million - Enforce enabling diagnostics events @@ -885,7 +885,7 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Unify all ledger sequence types to uint32 and stop stringyfying integers < 53-bits wide - Restore CORS support -#### Soroban CLI {#soroban-cli-2} +#### Soroban CLI - Allow fetching contract from network - Each generated contract method adds -file-path @@ -907,9 +907,9 @@ This is the first version of the Soroban SDK that supports protocol 21. It is ma - Fix various typescript bindings - Make output consistent for all ways to get version -## Preview 11 (September 11, 2023): Testnet and Futurenet Edition {#preview-11-september-11-2023-testnet-and-futurenet-edition} +## Preview 11 (September 11, 2023): Testnet and Futurenet Edition -### Software {#software-9} +### Software | Software | Version | | --- | --- | @@ -940,9 +940,9 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te ::: -### Changelog {#changelog-5} +### Changelog -#### XDR {#xdr-2} +#### XDR - Generate for entry expired error - Bump XDR @@ -964,7 +964,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Bump XDR - Bump version to 20.0.0-rc1 -#### Soroban Environment {#soroban-environment-2} +#### Soroban Environment - Attach the auth in recording mode to any valid tracker when possible - Make RecordedAuthPayload consistently return None for invoker @@ -1054,7 +1054,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Update wasmi to 0.31.0-soroban - Bump version to 20.0.0-rc1 -#### Soroban Rust SDK {#soroban-rust-sdk-8} +#### Soroban Rust SDK - Implement deployer functions that return the deployed contract id - Add Vec::to_vals @@ -1097,7 +1097,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Adapt to removal of ConversionError from number type conversions - Bump version to 20.0.0-rc1 -#### Soroban RPC {#soroban-rpc-3} +#### Soroban RPC - List --network under RPC options - Enforce enabling diagnostics events @@ -1125,7 +1125,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Fix set_authorization_entries bug in transaction simulation - Restore CORS support -#### Soroban CLI {#soroban-cli-3} +#### Soroban CLI - Add multi-party authorization + signing support - Add two new output types for contract inspect @@ -1148,9 +1148,9 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Return an error once contract read is unable to read any entry - wrap token no longer fails with valid inputs in sandbox mode -## Preview 10 (July 13, 2023) {#preview-10-july-13-2023} +## Preview 10 (July 13, 2023) -### Software {#software-10} +### Software | Software | Version | | --- | --- | @@ -1172,9 +1172,9 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te | Soroban Mint Token dapp | `1.1.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog {#changelog-6} +### Changelog -#### XDR {#xdr-3} +#### XDR - Remove TransactionResultV2 - Regenerate for overhaul of error codes @@ -1197,7 +1197,7 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Generate rename - Update crate-git-revision -#### Soroban Environment {#soroban-environment-3} +#### Soroban Environment - Move a bunch of code out of host, reorg modules slightly. - Remove temp storage, fixes #758 @@ -1250,22 +1250,22 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te - Change `[IU]256` `[from,to]_bytes` functions to work with Val - Bump wasmi version -#### Soroban Rust SDK {#soroban-rust-sdk-9} +#### Soroban Rust SDK - Fix storage comment - Noop in instance bump for tests -#### Soroban RPC {#soroban-rpc-4} +#### Soroban RPC - Update js-soroban-client dependency from 0.9.0 to 0.9.1 -#### Soroban CLI {#soroban-cli-4} +#### Soroban CLI - Update js-soroban-client dependency from 0.9.0 to 0.9.1 -## Preview 9 (May 24th, 2023) {#preview-9-may-24th-2023} +## Preview 9 (May 24th, 2023) -### Software {#software-11} +### Software | Software | Version | | --- | --- | @@ -1285,31 +1285,31 @@ The Soroban RPC version for Preview 11 is presently in Stellar's unstable and te | Laboratory | `2.10.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog {#changelog-7} +### Changelog -#### XDR {#xdr-4} +#### XDR See https://github.com/stellar/rs-stellar-xdr/releases v0.0.16 for more details. -#### Soroban Environment {#soroban-environment-4} +#### Soroban Environment See https://github.com/stellar/rs-soroban-env/releases v0.0.16 for more details. -#### Soroban Rust SDK {#soroban-rust-sdk-10} +#### Soroban Rust SDK See https://github.com/stellar/rs-soroban-sdk/releases v0.8.4 for more details. -#### Soroban RPC {#soroban-rpc-5} +#### Soroban RPC See https://github.com/stellar/soroban-tools/releases v0.8.0 for more details. -#### Soroban CLI {#soroban-cli-5} +#### Soroban CLI See https://github.com/stellar/soroban-tools/releases v0.8.0 for more details. -## Preview 8 (April 4th, 2023) {#preview-8-april-4th-2023} +## Preview 8 (April 4th, 2023) -### Software {#software-12} +### Software | Software | Version | | --- | --- | @@ -1329,7 +1329,7 @@ See https://github.com/stellar/soroban-tools/releases v0.8.0 for more details. | Laboratory | `v2.8.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Breaking changes note {#breaking-changes-note} +### Breaking changes note This release includes a major overhaul of the value representation at the XDR level, which potentially breaks contracts that rely on the old type definitions, here is a summary of the changes: @@ -1342,9 +1342,9 @@ This release includes a major overhaul of the value representation at the XDR le SDK support has also been added/updated for these types. See [xdr](https://github.com/stellar/stellar-xdr/pull/70), [env](https://github.com/stellar/rs-soroban-env/pull/682) and [sdk](https://github.com/stellar/rs-soroban-sdk/pull/879) changes for more details. -### Changelog {#changelog-8} +### Changelog -#### XDR {#xdr-5} +#### XDR - Make types wrapping Strings no longer aliases - Value representation overhaul @@ -1352,7 +1352,7 @@ SDK support has also been added/updated for these types. See [xdr](https://githu See https://github.com/stellar/rs-stellar-xdr/releases v0.0.15 for more details. -#### Soroban Environment {#soroban-environment-5} +#### Soroban Environment - Remove the unnecessary error events that appeared in non-error scenarios. - Reform metering for value cloning and memory allocation. @@ -1375,7 +1375,7 @@ See https://github.com/stellar/rs-stellar-xdr/releases v0.0.15 for more details. See https://github.com/stellar/rs-soroban-env/releases v0.0.15 for more details. -#### Soroban Rust SDK {#soroban-rust-sdk-11} +#### Soroban Rust SDK - Add docs in specs for types. - Rename Serialize/Deserialize to To/FromXdr. @@ -1397,7 +1397,7 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.15 for more details. See https://github.com/stellar/rs-soroban-sdk/releases v0.7.0 for more details. -#### Soroban RPC {#soroban-rpc-6} +#### Soroban RPC - Set a maximum ledger latency in /health method. - Add resultMetaXdr and envelopeXdr back to getTransaction() response. @@ -1412,7 +1412,7 @@ See https://github.com/stellar/rs-soroban-sdk/releases v0.7.0 for more details. See https://github.com/stellar/soroban-tools/releases v0.7.0 for more details. -#### Soroban CLI {#soroban-cli-6} +#### Soroban CLI - Improved documentation, and `--help` text - feat: auto-generate comprehensive CLI docs. @@ -1432,9 +1432,9 @@ See https://github.com/stellar/soroban-tools/releases v0.7.0 for more details. See https://github.com/stellar/soroban-tools/releases v0.7.0 for more details. -## Preview 7 (February 16th, 2023) {#preview-7-february-16th-2023} +## Preview 7 (February 16th, 2023) -### Software {#software-13} +### Software | Software | Version | | --- | --- | @@ -1454,19 +1454,19 @@ See https://github.com/stellar/soroban-tools/releases v0.7.0 for more details. | Laboratory | `v2.7.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Breaking changes note {#breaking-changes-note-1} +### Breaking changes note This release comes with a revamp of authorization approach that is breaking for most of the contracts that did any sort of auth logic or used tokens. [example](../build/smart-contracts/example-contracts/auth.mdx) and [authorization overview](../learn/encyclopedia/security/authorization.mdx) for more details. -### Changelog {#changelog-9} +### Changelog -#### XDR {#xdr-6} +#### XDR - Update Rust XDR for Auth Next. See https://github.com/stellar/rs-stellar-xdr/releases v0.0.13 and v0.0.14 for more details. -#### Soroban Environment {#soroban-environment-6} +#### Soroban Environment - Allow for a custom budget outside tests - Restructure Event to be cheap to clone and allow it to be rolled back @@ -1484,7 +1484,7 @@ See https://github.com/stellar/rs-stellar-xdr/releases v0.0.13 and v0.0.14 for m See https://github.com/stellar/rs-soroban-env/releases v0.0.13 and v0.0.14 for more details. -#### Soroban Rust SDK {#soroban-rust-sdk-12} +#### Soroban Rust SDK - Support variants with multiple fields in UDTs - Error on UDT enums with 0-element tuple variants @@ -1504,7 +1504,7 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.13 and v0.0.14 for m See https://github.com/stellar/rs-soroban-sdk/releases v0.5.0 and v0.6.0 for more details. -#### Soroban RPC {#soroban-rpc-7} +#### Soroban RPC - Configure default limit, update cursor / startLedger validation, and include latest ledger for getEvents - Add support for AuthNext @@ -1518,7 +1518,7 @@ See https://github.com/stellar/rs-soroban-sdk/releases v0.5.0 and v0.6.0 for mor See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more details. -#### Soroban CLI {#soroban-cli-7} +#### Soroban CLI - Add option for running contract with unlimited budget - Add support for AuthNext @@ -1528,9 +1528,9 @@ See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more det See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more details. -## Preview 6 (January 9th, 2023) {#preview-6-january-9th-2023} +## Preview 6 (January 9th, 2023) -### Software {#software-14} +### Software | Software | Version | | --- | --- | @@ -1549,9 +1549,9 @@ See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more det | Stellar JS Soroban Client | `v0.3.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog {#changelog-10} +### Changelog -#### Soroban Environment {#soroban-environment-7} +#### Soroban Environment - Wasm instruction level calibration - Replace `im` containers with `Vec` @@ -1566,7 +1566,7 @@ See https://github.com/stellar/soroban-tools/releases v0.5.0 v0.6.0 for more det See https://github.com/stellar/rs-soroban-env/releases v0.0.12 for more details. -#### Soroban Rust SDK {#soroban-rust-sdk-13} +#### Soroban Rust SDK - Fix contractimpl for empty impl blocks - bump env and fix token interface @@ -1584,13 +1584,13 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.12 for more details. See https://github.com/stellar/rs-soroban-sdk/releases v0.4.0, v0.4.1, v0.4.2 for more details. -#### Soroban RPC {#soroban-rpc-8} +#### Soroban RPC - Add GitHub linting for GO code See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. -#### Soroban CLI {#soroban-cli-8} +#### Soroban CLI - Update rust version - StrValError --> Error and implemented using thiserror @@ -1601,9 +1601,9 @@ See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. -## Preview 5 (December 8th, 2022) {#preview-5-december-8th-2022} +## Preview 5 (December 8th, 2022) -### Software {#software-15} +### Software | Software | Version | | --- | --- | @@ -1621,9 +1621,9 @@ See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. | Stellar JS Soroban Client | `v0.2.0` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog {#changelog-11} +### Changelog -#### XDR {#xdr-7} +#### XDR - Remove BigInt from ScVal - Add u128 and i128 to ScVal @@ -1632,7 +1632,7 @@ See https://github.com/stellar/soroban-tools/releases v0.4.0 for more details. See https://github.com/stellar/stellar-xdr/compare/48d5e17ae63bba0aa9725cd9d18d7438f44c07b1...026c9cd074bdb28ddde8ee52f2a4502d9e518a09 for more details. -#### Soroban Environment {#soroban-environment-8} +#### Soroban Environment - Upgrade crate-git-revision to 0.0.4 (contribution by [@brson]) - Add Host::with_artificial_test_contract_frame @@ -1643,7 +1643,7 @@ See https://github.com/stellar/stellar-xdr/compare/48d5e17ae63bba0aa9725cd9d18d7 See https://github.com/stellar/rs-soroban-env/releases v0.0.10, v0.0.11 for more details. -#### Soroban Rust SDK {#soroban-rust-sdk-14} +#### Soroban Rust SDK - Rename data to storage by @leighmcculloch in #786 - Add ability to get current Budget from env in tests by @leighmcculloch in #789 @@ -1657,7 +1657,7 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.10, v0.0.11 for more See https://github.com/stellar/rs-soroban-sdk/releases v0.3.0, v0.3.1, v0.3.2 for more details. -#### Soroban RPC {#soroban-rpc-9} +#### Soroban RPC - Add soroban-rpc version subcommand - Add a new getLedgerEntry jsonrpc method, deprecating and replacing getContractData allowing an application to fetch any ledger entry @@ -1665,7 +1665,7 @@ See https://github.com/stellar/rs-soroban-sdk/releases v0.3.0, v0.3.1, v0.3.2 fo See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1 for more details. -#### Soroban CLI {#soroban-cli-9} +#### Soroban CLI - Fix apt-get install in publish workflow - Added type description to errors when using --arg (contribution by [@waldmatias]) @@ -1677,9 +1677,9 @@ See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1 for more de See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1, 0.3.3 for more details. -## Preview 4 (November 15th, 2022) {#preview-4-november-15th-2022} +## Preview 4 (November 15th, 2022) -### Software {#software-16} +### Software | Software | Version | | --- | --- | @@ -1694,13 +1694,13 @@ See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1, 0.3.3 for | Stellar Quickstart | `stellar/quickstart:soroban-dev@sha256:0993d3350148af6ffeab5dc8f0b835236b28dade6dcae77ff8a09317162f768d` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog {#changelog-12} +### Changelog -#### XDR {#xdr-8} +#### XDR - Trivial whitespace changes -#### Soroban Environment {#soroban-environment-9} +#### Soroban Environment - Vm tuning - Add token events @@ -1712,7 +1712,7 @@ See https://github.com/stellar/soroban-tools/releases v0.3.0, v0.3.1, 0.3.3 for See https://github.com/stellar/rs-soroban-env/releases v0.0.7, v0.0.8, v0.0.9 for more details. -#### Soroban Rust SDK {#soroban-rust-sdk-15} +#### Soroban Rust SDK - Add Logger::print in testutils - Add conversion from Address to Identifier @@ -1724,11 +1724,11 @@ See https://github.com/stellar/rs-soroban-env/releases v0.0.7, v0.0.8, v0.0.9 fo See https://github.com/stellar/rs-soroban-sdk/releases v0.2.0, v0.2.1 for more details. -#### Soroban RPC {#soroban-rpc-10} +#### Soroban RPC - Initial Release -#### Soroban CLI {#soroban-cli-10} +#### Soroban CLI - Strings and symbols are rendered as text in JSON output - Bytes are rendered as hex in JSON output @@ -1739,9 +1739,9 @@ See https://github.com/stellar/rs-soroban-sdk/releases v0.2.0, v0.2.1 for more d See https://github.com/stellar/soroban-cli/releases v0.2.0, v0.2.1 for more details. -## Preview 3 (October 11th, 2022) {#preview-3-october-11th-2022} +## Preview 3 (October 11th, 2022) -### Software {#software-17} +### Software | Software | Version | | --- | --- | @@ -1756,15 +1756,15 @@ See https://github.com/stellar/soroban-cli/releases v0.2.0, v0.2.1 for more deta | Stellar Quickstart | `stellar/quickstart:soroban-dev@sha256:e58d83f92a61f43406087f488dd1cba110a92646dca85f14b3a416163609e853` | | Futurenet Network Passphrase | `Test SDF Future Network ; October 2022` | -### Changelog {#changelog-13} +### Changelog See https://www.stellar.org/blog/soroban-a-new-smart-contract-standard. -## Preview 2 (September 13th, 2022) {#preview-2-september-13th-2022} +## Preview 2 (September 13th, 2022) See https://www.stellar.org/developers-blog/soroban-preview-release-2. -## Preview 1 (August 1st, 2022) {#preview-1-august-1st-2022} +## Preview 1 (August 1st, 2022) See https://www.stellar.org/blog/project-jump-cannon-soroban-preview-release. diff --git a/docs/tokens/README.mdx b/docs/tokens/README.mdx index a850a049f..f55a3aaa3 100644 --- a/docs/tokens/README.mdx +++ b/docs/tokens/README.mdx @@ -12,11 +12,11 @@ Several factors can help you determine whether to issue an asset on Stellar or c However: -### TL;DR {#tldr} +### TL;DR If possible, we recommend issuing a Stellar asset and using the SAC to interact with that asset in smart contracts or to send to contract addresses. More on why below. -## Issuing assets on Stellar {#issuing-assets-on-stellar} +## Issuing assets on Stellar Stellar has first-class support for asset tokenization — issuing an asset can be done using a [built-in transaction](./quickstart.mdx) without the development of a smart contract. @@ -36,7 +36,7 @@ Note that while these items are also possible with custom smart contract tokens, Assets issued on the Stellar network are accessible to smart contracts with the use of that asset’s Stellar Asset Contract (SAC). -### Stellar Asset Contract {#stellar-asset-contract} +### Stellar Asset Contract The Stellar Asset Contract (SAC) is compiled into the protocol layer and allows smart contracts to interact with assets issued on Stellar. An instance of the SAC can be deployed for every Stellar asset by anyone who wants to interact with the asset from a contract. The SAC has access to all account balances (for XLM) and trustline balances (for all other assets) as well as smart contract token balances. @@ -55,7 +55,7 @@ Learn how to deploy a Stellar Asset Contract for an asset in [this How-To Guide] - Other than the customization noted above, it is not possible to modify the behavior of Stellar assets or their SAC. If you’re looking to use assets in a way not supported by Stellar assets, you can create your own custom smart contract token using the token interface and all applications that interact with tokens using the token interface will be able to interact with the custom token. -## Custom tokens {#custom-tokens} +## Custom tokens If you have a unique use case where the capabilities Stellar Assets are not sufficient, you can create a custom token that implements the [token interface][ti]. The token interface specifies the functions and events a contract must implement to be compatible with applications that use tokens. @@ -72,7 +72,7 @@ Smart contracts cannot use Stellar assets unless that Stellar asset has a deploy - As the creator of a new token, you decide to implement a feature within your custom token smart contract that enables you to receive a 1% fee from every transaction involving your token. Whenever someone transfers your token to another user, 1% of the transferred amount is automatically deducted and sent to a designated wallet address that you control. - You want to develop a factory contract that automates the creation of instances of a specific token. This contract serves as a centralized and standardized way to deploy new token contracts on demand without manual intervention each time a new instance is needed. -## Helpful links {#helpful-links} +## Helpful links - [Issue an asset tutorial][how-to-issue] - [Stellar Asset Contract][sac] diff --git a/docs/tokens/anatomy-of-an-asset.mdx b/docs/tokens/anatomy-of-an-asset.mdx index cf36371d9..a1569f1b6 100644 --- a/docs/tokens/anatomy-of-an-asset.mdx +++ b/docs/tokens/anatomy-of-an-asset.mdx @@ -11,7 +11,7 @@ Issuing an asset on Stellar is easy and only takes a few operations. However, th Assets issued on the Stellar network are accessible to smart contracts. Every Stellar asset has reserved a [Stellar Asset Contract](./stellar-asset-contract.mdx) that can be deployed by anyone who wants to be able to interact with the asset from a contract. -## Stablecoins {#stablecoins} +## Stablecoins One major category of assets is the stablecoin. A stablecoin is a blockchain-based token whose value is tied to another asset, such as the US dollar, other fiat currencies, commodities like gold, or even cryptocurrencies. There are two types of stablecoin: 1) reserve-backed stablecoins that must have a mechanism for redeeming the asset backing them, and 2) algorithmic stablecoins that don’t have assets backing them and instead rely on an algorithm to control the stablecoin supply. When discussing stablecoins, our documentation will focus on reserve-backed stablecoins. @@ -19,11 +19,11 @@ Reserve-backed stablecoins are pegged to a real-world asset at a 1:1 ratio. Beca Currently, one of Stellar's most significant use cases is the tokenization of fiat currency for processes like cross-border payments. With anchors, users can connect Stellar tokens to existing rails that allow for the deposit of real-world assets in exchange for digital currency and vice versa. Learn more about anchors in our [Anchors section](../learn/fundamentals/anchors.mdx). -### Treasury management {#treasury-management} +### Treasury management When issuing a reserve-backed stablecoin, you must set up its off-chain reserve, which securely stores the asset backing the stablecoin. When users wish to redeem their stablecoin, they can receive an equivalent amount of the underlying reserve asset from the issuer. -## Compliance {#compliance} +## Compliance As an asset issuer, you may need to comply with regulatory requirements that vary based on jurisdiction. Stellar has built-in features that can help meet these requirements, such as: diff --git a/docs/tokens/control-asset-access.mdx b/docs/tokens/control-asset-access.mdx index 4ac48de84..537b8e941 100644 --- a/docs/tokens/control-asset-access.mdx +++ b/docs/tokens/control-asset-access.mdx @@ -6,7 +6,7 @@ sidebar_position: 40 import { CodeExample } from "@site/src/components/CodeExample"; import { Alert } from "@site/src/components/Alert"; -## Issuing and distribution accounts {#issuing-and-distribution-accounts} +## Issuing and distribution accounts It is best practice on the Stellar network to create two accounts when issuing an asset: 1) the issuing account and 2) the distribution account. @@ -18,17 +18,17 @@ Note that you can also issue an asset by creating an offer or liquidity pool dep It is best practice to issue an asset by sending it from the issuing account to a distribution account for two main reasons: security and auditing. -### Security {#security} +### Security The distribution account will be a hot account, meaning that some web service out there has direct access to sign its transactions. For example, if the account you're distributing from is also the issuing account and it is compromised by a malicious actor, the actor can now issue as much of the asset as they want. If the malicious actor redeems the newly issued tokens with an anchor service, the anchor may not have the liquidity to support the customer withdrawals. Stakes are lower if you use a distribution account- if the distribution account is compromised, you can freeze the account’s asset balance and start with a new distribution account without changing the issuing account. -### Auditing {#auditing} +### Auditing Using a distribution account is better for auditing because an issuing account can’t actually hold a balance of its own asset. Sending an asset back to its issuing account burns (deletes) the asset. If you have a standing inventory of the issued asset in a separate account, it’s easier to track and can help with bookkeeping. -## Naming an asset {#naming-an-asset} +## Naming an asset One thing you must decide when issuing an asset is what to call it. An asset code is the asset’s identifying code. There are three possible formats: Alphanumeric 4, Alphanumeric 12, and liquidity pool shares. @@ -40,17 +40,17 @@ Learn about liquidity pool shares in the [Liquidity Pool Encyclopedia Entry](../ Provided it falls into one of these buckets, you can choose any asset code you like. That said, if you’re issuing a currency, you should use the appropriate ISO 4217 code, and if you’re issuing a stock or bond, the appropriate ISIN number. Doing so makes it easier for Stellar interfaces to properly display and sort your token in their listings and allows potential token holders to understand what your token represents. -## Controlling access to an asset with flags {#controlling-access-to-an-asset-with-flags} +## Controlling access to an asset with flags When you issue an asset on Stellar, anyone can hold it by default. In general, that’s a good thing: easy access means better reach and better liquidity. However, if you need to control access to an asset to comply with regulations (or for any other reason), you can easily do so by enabling flags on your issuing account. Flags are created on the account level using a `set_options` operation. They can be set at any time in the life cycle of an asset, not just when you issue it. -### Flag types {#flag-types} +### Flag types The (0xn) next to each flag type denotes the bit settings for each flag. -#### Authorization Required (0x1) {#authorization-required-0x1} +#### Authorization Required (0x1) When `AUTH_REQUIRED_FLAG` is enabled, an issuer must approve an account before that account can hold its asset. This setting allows issuers to vet potential token holders and to approve trustlines. @@ -61,7 +61,7 @@ There are two levels of authorization an asset issuer can grant using the `Set_T - `AUTHORIZED_FLAG`: signifies complete authorization allowing an account to transact freely with the asset to make and receive payments, place orders, and deposit into a liquidity pool. - `AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG`: denotes limited authorization that allows an account to maintain current orders, withdraw from a liquidity pool, or cancel current orders - but not to otherwise transact with the asset. -#### Authorization Revocable (0x2) {#authorization-revocable-0x2} +#### Authorization Revocable (0x2) When `AUTH_REVOCABLE_FLAG` is enabled, an issuer can revoke an existing trustline’s authorization, thereby freezing the asset held by an account. Doing so prevents that account from transferring or trading the asset and cancels the account’s open orders for the asset. @@ -75,21 +75,21 @@ There are three levels of authorization an asset issuer can remove using the `Se - `AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG`: denotes limited authorization that allows an account to maintain current orders but not to otherwise transact with the asset. - `CLAWBACK_ENABLED`: enables the issuing account to take back (burning) all of the asset. See our [section on Clawbacks](../learn/encyclopedia/transactions-specialized/clawbacks.mdx) for more information. -#### Clawback Enabled (0x8) {#clawback-enabled-0x8} +#### Clawback Enabled (0x8) With the `AUTH_CLAWBACK_ENABLED_FLAG` flag set, any _subsequent_ trustlines established with this account will have clawbacks enabled. You can read more about clawbacks (and selectively controlling them on a per-trustline basis) [here](../learn/encyclopedia/transactions-specialized/clawbacks.mdx). Note that this flag requires that revocable is also set. -#### Authorization Immutable (0x4) {#authorization-immutable-0x4} +#### Authorization Immutable (0x4) With this setting, none of the other authorization flags (`AUTH_REQUIRED_FLAG`, `AUTH_REVOCABLE_FLAG`) can be set, and the issuing account can’t be merged. You set this flag to signal to potential token holders that your issuing account and its assets will persist on the ledger in an open and accessible state. -### Set Trustline Flag operation {#set-trustline-flag-operation} +### Set Trustline Flag operation The issuing account can configure various authorization and trustline flags for individual trustlines to an asset. The asset parameter is of the TrustLineAsset type. If you are modifying a trustline to a regular asset (i.e. one in a Code:Issuer format), this is equivalent to the asset type. If you are modifying a trustline to a pool share, this is the liquidity pool’s unique ID. -### Example flow {#example-flow} +### Example flow Let’s look at how an issuer of a regulated asset might use the `AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG` flag. @@ -107,7 +107,7 @@ Here’s a payment from A to B sandwiched between `set_trust_line_flags` operati The authorization sandwich allows the issuer to inspect the specific payment and to grant authorization for it and it alone. Since operations bundled in a transaction are simultaneous, A and B are only authorized for the specific, pre-approved payment operation. Complete authorization does not extend beyond the specific transaction. -### Sample code {#sample-code} +### Sample code In the following code samples, proper error checking is omitted. However, you should always validate your results, as there are many ways that requests can fail. Refer to the [Error Handling](/data/horizon/api-reference/errors/error-handling.mdx) page for tips on error management strategies. @@ -214,7 +214,7 @@ except BaseHorizonError as e: -## Limiting the supply of an asset {#limiting-the-supply-of-an-asset} +## Limiting the supply of an asset :::danger Warning diff --git a/docs/tokens/how-to-issue-an-asset.mdx b/docs/tokens/how-to-issue-an-asset.mdx index c7ea3edd7..e3c073416 100644 --- a/docs/tokens/how-to-issue-an-asset.mdx +++ b/docs/tokens/how-to-issue-an-asset.mdx @@ -14,7 +14,7 @@ If you'd like to interact with an asset issued on the Stellar network in smart c ::: -## Prerequisites {#prerequisites} +## Prerequisites You must ensure you have the required amount of XLM to create your issuing and distribution accounts and cover the minimum balance and transaction fees. If you’re issuing an asset on the testnet, you can fund your account by getting test XLM from friendbot. If you’re issuing an asset in production, you will need to acquire XLM from another wallet or exchange. @@ -24,9 +24,9 @@ Learn about the testnet and mainnet in our [Networks section](../learn/fundament Learn more about fees in our [Fees, Resource Limits, and Metering section](../learn/fundamentals/fees-resource-limits-metering.mdx). -## Foundational tools {#foundational-tools} +## Foundational tools -### Issuer account keypair {#issuer-account-keypair} +### Issuer account keypair First, you must generate a unique keypair. The public key will act as your [issuing identity](../learn/fundamentals/stellar-data-structures/assets.mdx#issuer) on the network, while you use the secret key to sign transactions. @@ -81,13 +81,13 @@ Many users secure their issuing account with cold storage techniques, such as a ::: -### Distribution account keypair {#distribution-account-keypair} +### Distribution account keypair Your asset can be issued and transferred between accounts through a payment, contract, or claimable balance. Although it is not required to create a distribution account, it is best practice, so we will do so in this example. Read more in our [Issuing and Distribution Accounts section](./control-asset-access.mdx#issuing-and-distribution-accounts). -#### Three Operations {#three-operations} +#### Three Operations -##### Generate a new keypair {#generate-a-new-keypair} +##### Generate a new keypair @@ -109,7 +109,7 @@ distributorKeypair := keypair.MustRandom() -##### Import an existing keypair {#import-an-existing-keypair} +##### Import an existing keypair @@ -131,7 +131,7 @@ distributorKeypair := keypair.MustParseFull("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U -##### Employ [multiple signatures](../learn/encyclopedia/security/signatures-multisig.mdx) {#employ-multiple-signatures} +##### Employ [multiple signatures](../learn/encyclopedia/security/signatures-multisig.mdx) :::danger @@ -139,7 +139,7 @@ Be careful when working with raw secret keys. If you don't have issuer trustline ::: -### Local asset object {#local-asset-object} +### Local asset object The asset object is a combination of your [code](./control-asset-access.mdx#naming-an-asset) and your issuing public key. After your issuance, anyone can search the network for your unique asset. @@ -185,9 +185,9 @@ You’ll want to make sure you publish information about your asset to establish ::: -## Network transactions {#network-transactions} +## Network transactions -### Establish distributor trustline {#establish-distributor-trustline} +### Establish distributor trustline Accounts must establish a [trustline](../learn/fundamentals/stellar-data-structures/accounts.mdx#trustlines) with the issuing account to hold that issuer’s asset. This is true for all assets except for the network’s native token, [Lumens](../learn/fundamentals/lumens.mdx). @@ -284,7 +284,7 @@ transaction, _ := txnbuild.NewTransaction( -### Issuer payment to distributor {#issuer-payment-to-distributor} +### Issuer payment to distributor Payments are the most popular operation to actually issue (or mint) your asset, compared to [other issuances](../learn/fundamentals/transactions/list-of-operations.mdx#path-payment-strict-send). A payment creates the amount of an asset specified, up to [the maximum 64-bit integer](../learn/fundamentals/stellar-data-structures/assets.mdx#amount-precision). Relevantly, you do not need to scale up the issuing amount of your asset by the XDR [minimum increment](../learn/fundamentals/stellar-data-structures/assets.mdx#amount-precision). @@ -359,9 +359,9 @@ You can also create a market directly from the issuing account and issue tokens ::: -### Optional transactions {#optional-transactions} +### Optional transactions -#### Configure maximum supply {#configure-maximum-supply} +#### Configure maximum supply :::danger @@ -416,7 +416,7 @@ lockAccountTransaction, _ := txnbuild.NewTransaction( -#### Approve distributor trustline {#approve-distributor-trustline} +#### Approve distributor trustline If you enable the [authorization flag](./control-asset-access.mdx#authorization-required-0x1), the issuing account also needs to approve the distributor account's trustline request before the issuing payment. You will need to do this for all new accounts when set for your asset. @@ -490,7 +490,7 @@ transaction, _ := txnbuild.NewTransaction( -## Full Code Sample {#full-code-sample} +## Full Code Sample diff --git a/docs/tokens/publishing-asset-info.mdx b/docs/tokens/publishing-asset-info.mdx index ea4d226ee..0466e224a 100644 --- a/docs/tokens/publishing-asset-info.mdx +++ b/docs/tokens/publishing-asset-info.mdx @@ -12,7 +12,7 @@ The most successful asset issuers give exchanges, wallets, and potential buyers Completing your Stellar info file is not a step you can skip. -## What is a Stellar info file? {#what-is-a-stellar-info-file} +## What is a Stellar info file? A Stellar info file is a common place where the Internet can find information about your organization’s Stellar integration. You write it in TOML, a simple and widely used configuration file format designed to be readable by both humans and machines, and publish it at `https://YOUR_DOMAIN/.well-known/stellar.toml`. @@ -20,7 +20,7 @@ That way, everyone knows where to find it, anyone can look it up, and it proves Using a `set_options` operation, you can link your Stellar account to the domain that hosts your Stellar info file, thereby creating a definitive on-chain connection between this information and that account. -## Completing your `stellar.toml` {#completing-your-stellartoml} +## Completing your `stellar.toml` The first Stellar Ecosystem Proposal (SEP) is [SEP-0001: Stellar Info File](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md) and specifies everything you would ever need to include in your Stellar info file. This section will walk through the sections of SEP-0001 that relate to asset issuers. Use this section in conjunction with the SEP to ensure you complete your `stellar.toml` correctly. @@ -35,7 +35,7 @@ For each of those sections, we’ll let you know which fields are required, mean **Note:** it's a good idea to keep the sections in the order presented in SEP-0001: Stellar Info File, which is also the order they're presented here. TOML requires arrays to be at the end, so if you scramble the order, you may cause errors for TOML parsers. -### 1. General Information {#1-general-information} +### 1. General Information Required field for all asset issuers: @@ -45,7 +45,7 @@ Listing your public keys lets users confirm that you own them. For example, when There are several fields where you list information about your Stellar integration to aid in discoverability. If you are an anchor service, and you have set up infrastructure to interoperate with wallets and allow for in-app deposit and withdrawal of assets, make sure to include the locations of your servers on your `stellar.toml` file so those wallets know where to find relevant endpoints to query. In particular, list these: -#### Suggested fields for asset issuers: {#suggested-fields-for-asset-issuers} +#### Suggested fields for asset issuers: - `TRANSFER_SERVER` if you support [SEP-0006: Deposit and Withdrawal API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) - `TRANSFER_SERVER_SEP0024` if you support [SEP-0024: Interactive Deposit and Withdrawal](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md) @@ -55,11 +55,11 @@ There are several fields where you list information about your Stellar integrati If you support other Stellar Ecosystem Proposals — such as federation or delegated signing — or host a public Horizon instance that other people can use to query the ledger, you should also add the location of those resources to [General Information](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md#general-information) so they're discoverable. -### 2. Organization Documentation {#2-organization-documentation} +### 2. Organization Documentation Basic information about your organization goes into a TOML table called [`DOCUMENTATION`]. Organization Documentation is your chance to inform exchanges and buyers about your business and to demonstrate that your business is legitimate and trustworthy. -#### Required field for all asset issuers: {#required-field-for-all-asset-issuers} +#### Required field for all asset issuers: - `ORG_NAME` The legal name of your organization, and if your business has one, its official ORG_DBA. - `ORG_URL` The HTTPS URL of your organization's official website. In order to prove the website is yours, you must host your `stellar.toml` on the same domain you list here. That way, exchanges and buyers can view the SSL certificate on your website and feel reasonably confident that you are who you say you are. @@ -68,7 +68,7 @@ Basic information about your organization goes into a TOML table called [`DOCUME - `ORG_OFFICIAL_EMAIL` The best business email address for your organization. This should be hosted at the same domain as your official website. - `ORG_SUPPORT_EMAIL` The best email for support requests. -#### Suggested fields for asset issuers: {#suggested-fields-for-asset-issuers-1} +#### Suggested fields for asset issuers: - `ORG_GITHUB` Your organization's official Github account. - `ORG_KEYBASE` Your organization's official Keybase account. Your Keybase account should contain proof of ownership of any public online accounts you list here, including your organization's domain. @@ -77,28 +77,28 @@ Basic information about your organization goes into a TOML table called [`DOCUME Issuers that list verified information including phone/address attestations and Keybase verifications are prioritized by Stellar clients. -### 3. Point of Contact Documentation {#3-point-of-contact-documentation} +### 3. Point of Contact Documentation Information about the primary point(s) of contact for your organization goes into a TOML [array of tables](https://github.com/toml-lang/toml#array-of-tables) called `[[PRINCIPALS]]`. You need to put contact information for at least one person in your organization. If you don't, exchanges can't verify your offering, and it is unlikely that buyers will be interested. Multiple principals can be added with additional `[[PRINCIPALS]]` entries. -#### Required field for all asset issuers: {#required-field-for-all-asset-issuers-1} +#### Required field for all asset issuers: - `name` The name of the primary contact. - `email` The primary contact's official email address. This should be hosted at the same domain as your organization's official website. -#### Suggested fields for asset issuers: {#suggested-fields-for-asset-issuers-2} +#### Suggested fields for asset issuers: - `github` The personal Github account of the point of contact. - `twitter` The personal Twitter handle of the point of contact. - `keybase` The personal Keybase account for the point of contact. This account should contain proof of ownership of any public online accounts listed here and may contain proof of ownership of your organization's domain. -### 4. Currency Documentation {#4-currency-documentation} +### 4. Currency Documentation Information about the asset(s) you issue goes into a TOML [array of tables](https://github.com/toml-lang/toml#array-of-tables) called `[[CURRENCIES]]`. If you issue multiple assets, you can include them all in one `stellar.toml`. Each asset should have its own `[[CURRENCIES]]` entry. (These entries are also used for assets you support but don’t issue, but as this section focuses on issuing assets the language will reflect that.) -#### Required field for all asset issuers: {#required-field-for-all-asset-issuers-2} +#### Required field for all asset issuers: - `code` The asset code. This is one of two key pieces of information that identify your token. Without it, your token cannot be listed anywhere. - `issuer` The Stellar public key of the issuing account. This is the second key piece of information that identifies your token. Without it, your token cannot be listed anywhere. @@ -111,13 +111,13 @@ If you're issuing anchored (tethered, stablecoin, asset-backed) tokens, there ar - `redemption_instructions` Instructions to redeem your token for the underlying asset. - `attestation_of_reserve` A URL to attestation or other proof, evidence, or verification of reserves, such as third-party audits, which all issuers of stablecoins should offer to adhere to best practices. -#### Suggested fields for asset issuers: {#suggested-fields-for-asset-issuers-3} +#### Suggested fields for asset issuers: - `desc` A description of your token and what it represents. This is a good place to clarify what your token does and why someone might want to own it. - `conditions` Any conditions you place on the redemption of your token. - `image` A URL to a PNG or GIF image with a transparent background representing your token. Without it, your token will appear blank on many exchanges. -## How to publish your Stellar info file {#how-to-publish-your-stellar-info-file} +## How to publish your Stellar info file After you've followed the steps above to complete your Stellar info file, post it at the following location: `https://YOUR_DOMAIN/.well-known/stellar.toml` @@ -158,7 +158,7 @@ server { } ``` -## Sample code to set the home domain of your issuing account {#sample-code-to-set-the-home-domain-of-your-issuing-account} +## Sample code to set the home domain of your issuing account @@ -298,7 +298,7 @@ func main() { -## Sample `stellar.toml` {#sample-stellartoml} +## Sample `stellar.toml` diff --git a/docs/tokens/stellar-asset-contract.mdx b/docs/tokens/stellar-asset-contract.mdx index 61af1795e..73d6874dc 100644 --- a/docs/tokens/stellar-asset-contract.mdx +++ b/docs/tokens/stellar-asset-contract.mdx @@ -18,7 +18,7 @@ The Stellar Asset Contract (SAC) is an implementation of [CAP-46-6 Smart Contrac See examples of how to use the SAC in the [Tokens How-To Guides](../build/guides/tokens/README.mdx). -## Overview {#overview} +## Overview :::note @@ -48,7 +48,7 @@ The SAC implements the [SEP-41 Token Interface], which is similar to the widely Some functionality available on the Stellar network in transaction operations, such as the order book, do not have any functions exposed on the Stellar Asset Contract in the current protocol. -## Deployment {#deployment} +## Deployment Every Stellar asset on Stellar has reserved a contract address that the Stellar Asset Contract can be deployed to. Anyone can initiate the deploy and the Stellar asset issuer does not need to be involved. @@ -62,7 +62,7 @@ Anyone can deploy the instances of Stellar Asset Contract. Note, that the initia [stellar cli]: ../tools/developer-tools/cli/stellar-cli.mdx [stellar sdk]: ../tools/sdks/library.mdx -## Interacting with classic Stellar assets {#interacting-with-classic-stellar-assets} +## Interacting with classic Stellar assets The Stellar Asset Contract is the only way for contracts to interact with Stellar assets, either the native XLM asset, or those issued by Stellar accounts. @@ -82,15 +82,15 @@ After the contract has been deployed, users can use their classic account (for l - Balances are stored in a 128-bit signed integer. - A balance can only be clawed back if the issuer account had the `AUTH_CLAWBACK_ENABLED_FLAG` set when the balance was created. A balance is created when either an `Address::Contract` is on the receiving end of a successful transfer, or if the admin sets the authorization state. Read more about `AUTH_CLAWBACK_ENABLED_FLAG` [here](./control-asset-access.mdx#clawback-enabled-0x8). -### Balance Authorization Required {#balance-authorization-required} +### Balance Authorization Required In the `Address::Contract` case, if the issuer has `AUTH_REQUIRED_FLAG` set, then the specified `Address::Contract` will need to be explicitly authorized with `set_auth` before it can receive a balance. This logic lines up with how trustlines interact with the `AUTH_REQUIRED_FLAG` issuer flag, allowing asset issuers to have the same control in Soroban as they do in Stellar classic. Read more about `AUTH_REQUIRED_FLAG` [here](./control-asset-access.mdx#authorization-required-0x1). -### Revoking Authorization {#revoking-authorization} +### Revoking Authorization The admin can only revoke authorization from an `Address`, if the issuer of the asset has `AUTH_REVOCABLE_FLAG` set. The deauthorization will fail if the issuer is missing. This requirement is true for both the trustline balances of `Address::Account` and contract balances of `Address:Contract`. Note that when a trustline is deauthorized from Soroban, `AUTHORIZED_FLAG` is cleared and `AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG` is set to avoid having to pull offers and redeeming pool shares. -## Authorization semantics {#authorization-semantics} +## Authorization semantics See the [authorization overview](../learn/encyclopedia/security/authorization.mdx) and [auth example](../build/smart-contracts/example-contracts/auth.mdx) for general information about authorization in Soroban. @@ -106,7 +106,7 @@ Unprivileged mutators require authorization from the `Address` that spends or al Priviliged mutators require authorization from a specific privileged identity, known as the "administrator". For example, only the administrator can `mint` more of the token. Similarly, only the administrator can appoint a new administrator. -## Contract Interface {#contract-interface} +## Contract Interface This interface can be found in the [SDK]. It extends the common [SEP-41 Token Interface]. diff --git a/docs/tokens/token-interface.mdx b/docs/tokens/token-interface.mdx index c1a13ff39..08c673937 100644 --- a/docs/tokens/token-interface.mdx +++ b/docs/tokens/token-interface.mdx @@ -10,7 +10,7 @@ Tokens deployed on Soroban can implement any interface they choose, however, the Note, that in the specific cases the interface doesn't have to be fully implemented. For example, the custom token may not implement the administrative interface compatible with the Stellar Asset Contract - it won't stop it from being usable in the contracts that only perform the regular user operations (transfers, allowances, balances etc.). -### Compatibility Requirements {#compatibility-requirements} +### Compatibility Requirements For any given contract function, there are 3 requirements that should be consistent with the interface described here: @@ -18,7 +18,7 @@ For any given contract function, there are 3 requirements that should be consist - Authorization - the users have to authorize the token function calls with all the arguments of the invocation (see the interface comments). If this is inconsistent, then the custom token may have issues with getting the correct signatures from the users and may also confuse the wallet software. - Events - the token has to emit the events in the specified format. If inconsistent, then the token may not be handled correctly by the downstream systems such as block explorers. -### Code {#code} +### Code The interface below uses the Rust [soroban-sdk](../tools/sdks/library.mdx#soroban-rust-sdk) to declare a trait that complies with the [SEP-41](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0041.md) token interface. @@ -152,11 +152,11 @@ The `approve` function overwrites the previous value with `amount`, so it is pos ::: -### Metadata {#metadata} +### Metadata Another requirement for complying with the token interface is to write the standard metadata (`decimal`, `name`, and `symbol`) for the token in a specific format. This format allows users to directly read constant data from the ledger instead of invoking a Wasm function. The [token example](https://github.com/stellar/soroban-examples/blob/main/token/src/metadata.rs) demonstrates how to use the Rust [soroban-token-sdk](https://github.com/stellar/rs-soroban-sdk/blob/main/soroban-token-sdk/src/lib.rs) to write the metadata, and we strongly encourage token implementations to follow this approach. -### Handling Failure Conditions {#handling-failure-conditions} +### Handling Failure Conditions In the token interface, there are several instances where function calls can fail due to various reasons such as lack of proper authorization, insufficient allowance or balance, etc. To handle these failure conditions, it is important to specify the expected behavior when such situations arise. @@ -168,21 +168,21 @@ More details on Authorization can be found [here](../learn/encyclopedia/security For the functions in the token interface, [trapping](https://doc.rust-lang.org/book/ch09-00-error-handling.html) should be used as the standard way to handle failure conditions since the interface is not designed to return error codes. This means that when a function encounters an error, it will halt execution and revert any state changes that occurred during the function call. -### Failure Conditions {#failure-conditions} +### Failure Conditions Here is a list of basic failure conditions and their expected behavior for functions in the token interface: -#### Admin functions: {#admin-functions} +#### Admin functions: - If the admin did not authorize the call, the function should trap. - If the admin attempts to perform an invalid action (e.g., minting a negative amount), the function should trap. -#### Token functions: {#token-functions} +#### Token functions: - If the caller is not authorized to perform the action (e.g., transferring tokens without proper authorization), the function should trap. - If the action would result in an invalid state (e.g., transferring more tokens than available in the balance or allowance), the function should trap. -### Example: Handling Insufficient Allowance in `burn_from` function {#example-handling-insufficient-allowance-in-burn_from-function} +### Example: Handling Insufficient Allowance in `burn_from` function In the `burn_from` function, the token contract should check whether the spender has enough allowance to burn the specified amount of tokens from the `from` address. If the allowance is insufficient, the function should trap, halting execution and reverting any state changes. diff --git a/docs/tools/README.mdx b/docs/tools/README.mdx index 54480d287..11a228bc5 100644 --- a/docs/tools/README.mdx +++ b/docs/tools/README.mdx @@ -5,20 +5,20 @@ sidebar_position: 0 This section of the docs will provide links to the SDKs and developer tools for use when developing on Stellar as well as documentation for various SDF-maintained platforms such as the Anchor Platform and Stellar Disbursement Platform (SDP). -## [SDKs](./sdks/library.mdx) {#sdks} +## [SDKs](./sdks/library.mdx) Stellar’s Software Development Kits (SDKs) provide devs with the tools, libraries, and documentation to interact with and develop on the blockchain. They simplify tasks such as creating and deploying smart contracts and sending transactions while also offering APIs to access data and integrate functionalities into applications. -## [Developer Tools](./developer-tools/README.mdx) {#developer-tools} +## [Developer Tools](./developer-tools/README.mdx) Find SDF and ecosystem-maintained developer tools that help streamline the development process for applications and smart contracts on Stellar. -## SDF Platforms {#sdf-platforms} +## SDF Platforms -### [Anchor Platform](/platforms/anchor-platform) {#anchor-platform} +### [Anchor Platform](/platforms/anchor-platform) The Anchor Platform is a set of tools and APIs that enable developers and businesses to build their own on and off-ramp services for the Stellar network. It provides a standardized interface, including the implementation of several Stellar Ecosystem Proposals (SEPs), to make it easy for businesses to integrate with Stellar-based wallets and exchanges. -### [Stellar Disbursement Platform (SDP)](/platforms/stellar-disbursement-platform) {#stellar-disbursement-platform-sdp} +### [Stellar Disbursement Platform (SDP)](/platforms/stellar-disbursement-platform) The Stellar Disbursement Platform (SDP) is a tool built for organizations to make bulk payments to a group of recipients over the Stellar network. diff --git a/docs/tools/developer-tools/IDEs.mdx b/docs/tools/developer-tools/IDEs.mdx index 6ac363b1b..07dcf971b 100644 --- a/docs/tools/developer-tools/IDEs.mdx +++ b/docs/tools/developer-tools/IDEs.mdx @@ -7,10 +7,10 @@ sidebar_position: 70 # IDEs -### [Okashi](https://okashi.dev) {#okashi} +### [Okashi](https://okashi.dev) A web IDE for building, deploying, and testing contracts. -### [Sorobix](https://sorobix.vercel.app/) {#sorobix} +### [Sorobix](https://sorobix.vercel.app/) An IDE and a web GUI where you can write, deploy, and invoke contracts on the Stellar network using Soroban. diff --git a/docs/tools/developer-tools/analytics-platforms.mdx b/docs/tools/developer-tools/analytics-platforms.mdx index b73670370..184ffb81f 100644 --- a/docs/tools/developer-tools/analytics-platforms.mdx +++ b/docs/tools/developer-tools/analytics-platforms.mdx @@ -9,10 +9,10 @@ sidebar_position: 65 There's a wide range of analytics platforms that make exploring Stellar network data easy and fun! The following platforms allow you to easily create aggregates, visualizations, and dashboards to figure out exactly the story you want to tell, with Stellar data.. -### [Dune](https://dune.com/) {#dune} +### [Dune](https://dune.com/) Dune is a web-based platform that allows you to query Stellar network data and aggregate it into beautiful dashboards. -### [Ortege](https://www.ortege.ai/) {#ortege} +### [Ortege](https://www.ortege.ai/) Ortege is an AI-powered blockchain analytics & insights tool for Stellar, making complex data simple and accessible. Access for free by signing up [here](https://app.ortege.ai/login/). diff --git a/docs/tools/developer-tools/anchor-tools.mdx b/docs/tools/developer-tools/anchor-tools.mdx index 79a59a15c..9df1d8830 100644 --- a/docs/tools/developer-tools/anchor-tools.mdx +++ b/docs/tools/developer-tools/anchor-tools.mdx @@ -7,14 +7,14 @@ sidebar_position: 20 # Anchor Tools -### [Anchor Directory](https://anchors.stellar.org/?) {#anchor-directory} +### [Anchor Directory](https://anchors.stellar.org/?) View all anchors on Stellar, their currencies, and where they operate. -### [Demo Wallet](https://demo-wallet.stellar.org/) {#demo-wallet} +### [Demo Wallet](https://demo-wallet.stellar.org/) An application for interactively testing anchor services. Lets financial application developers test their integrations and learn how Stellar ecosystem protocols (SEPs) work; use the demo wallet to test Regulated Assets (SEP-8), Hosted Deposit and Withdrawal (SEP-24), and Cross-Border Payments (SEP-31) with any home domain that has a Stellar Info File (also known as SEP-1, or a stellar.toml file). -### [Polaris](https://django-polaris.readthedocs.io/en/stable/) {#polaris} +### [Polaris](https://django-polaris.readthedocs.io/en/stable/) An extendable django app that makes it easy for anchors to facilitate cross-border payments and enable deposits and withdrawals; run a web server supporting any combination of SEP-1, 6, 10, 12, and 24. diff --git a/docs/tools/developer-tools/asset-tools.mdx b/docs/tools/developer-tools/asset-tools.mdx index 3120f6e6a..a25773df0 100644 --- a/docs/tools/developer-tools/asset-tools.mdx +++ b/docs/tools/developer-tools/asset-tools.mdx @@ -7,6 +7,6 @@ sidebar_position: 30 # Asset Sandbox -### [Asset Sandbox](https://stellar.cheesecakelabs.com/?utm_source=stellar&utm_medium=landing-page&utm_campaign=stellar-asset-sandbox) {#asset-sandbox} +### [Asset Sandbox](https://stellar.cheesecakelabs.com/?utm_source=stellar&utm_medium=landing-page&utm_campaign=stellar-asset-sandbox) A sandbox supported by SDF and Cheesecake Labs for businesses to experiment with asset issuance on Stellar's test network. diff --git a/docs/tools/developer-tools/block-explorers.mdx b/docs/tools/developer-tools/block-explorers.mdx index c7a3d851f..69e9780f8 100644 --- a/docs/tools/developer-tools/block-explorers.mdx +++ b/docs/tools/developer-tools/block-explorers.mdx @@ -9,18 +9,18 @@ sidebar_position: 40 Block explorers exist to publicly display blockchain data in an easily digestbible way. They can be browsed with an ordinary web browser, and do not require any special developer skills to use. The block explorers available for Soroban index data related to payments, accounts, deployed contracts, transaction history, and more. -### [StellarExpert](https://stellar.expert/explorer/public) {#stellarexpert} +### [StellarExpert](https://stellar.expert/explorer/public) Explore transactions and network activity with StellarExpert. Check stats specific to an asset code, transaction hash, account address, or ledger sequence number. Not available for Futurenet. -### [StellarChain](https://stellarchain.io/) {#stellarchain} +### [StellarChain](https://stellarchain.io/) Explore transactions and network activity for Stellar’s networks, including Futurenet. -### [Soroban Explorer](https://soroban.nownodes.io/) {#soroban-explorer} +### [Soroban Explorer](https://soroban.nownodes.io/) Built specifically for Soroban, you can explore transactions and network activity for Stellar’s Testnet and Futurenet (Mainnet coming soon). -### [Stellar Explorer](https://steexp.com/) {#stellar-explorer} +### [Stellar Explorer](https://steexp.com/) Check data related to payments, accounts, deployed contracts, and more for Stellar’s Futurenet, Testnet, and Mainnet. diff --git a/docs/tools/developer-tools/cli/README.mdx b/docs/tools/developer-tools/cli/README.mdx index 17e6f52b6..25b7f9675 100644 --- a/docs/tools/developer-tools/cli/README.mdx +++ b/docs/tools/developer-tools/cli/README.mdx @@ -6,7 +6,7 @@ sidebar_position: 50 # CLI -### [Stellar CLI](https://github.com/stellar/stellar-cli) {#stellar-cli} +### [Stellar CLI](https://github.com/stellar/stellar-cli) The command line interface to Soroban smart contracts. It allows you to build, deploy, and interact with smart contracts; configure identities; generate key pairs; manage networks; and more. @@ -14,6 +14,6 @@ Install Stellar CLI as explained in [Setup](../../../build/smart-contracts/getti The auto-generated comprehensive reference documentation is available [here](stellar-cli.mdx). -### [Sora](https://github.com/tolgayayci/sora) {#sora} +### [Sora](https://github.com/tolgayayci/sora) Sora is a cross platform GUI designed to simplify use of Stellar CLI. It offers a user-friendly interface for managing projects, identities, networks, contract methods, events, logs and so more in ease. diff --git a/docs/tools/developer-tools/cli/install-cli.mdx b/docs/tools/developer-tools/cli/install-cli.mdx index 3d0f06594..621f0efa4 100644 --- a/docs/tools/developer-tools/cli/install-cli.mdx +++ b/docs/tools/developer-tools/cli/install-cli.mdx @@ -6,7 +6,7 @@ sidebar_position: 50 # Install the Stellar CLI -### [Stellar CLI](https://github.com/stellar/stellar-cli) {#stellar-cli} +### [Stellar CLI](https://github.com/stellar/stellar-cli) There are a few ways to install the latest released version of Stellar CLI. @@ -22,7 +22,7 @@ Install with cargo from source: cargo install --locked stellar-cli --features opt ``` -## Set up Autocomplete {#set-up-autocomplete} +## Set up Autocomplete The Stellar CLI supports some autocompletion. To set up, run the following commands: @@ -44,6 +44,6 @@ To enable autocomplete permanently, run: echo "source <(stellar completion --shell bash)" >> ~/.bashrc ``` -## See Video Tutorial {#see-video-tutorial} +## See Video Tutorial Video Tutorial: https://developers.stellar.org/meetings/2024/06/27 diff --git a/docs/tools/developer-tools/data-indexers.mdx b/docs/tools/developer-tools/data-indexers.mdx index 26c2ae33a..40e7a7ee7 100644 --- a/docs/tools/developer-tools/data-indexers.mdx +++ b/docs/tools/developer-tools/data-indexers.mdx @@ -9,26 +9,26 @@ sidebar_position: 60 To power your applications, a range of data services will be available from data indexers with query interfaces. These indexers will allow you to easily store and retrieve decoded ledger data, contract event emissions, and more. You can focus more energy on making your project successful, and waste less time figuring out precisely how to get the important data from the network. -### [Ankr](https://www.ankr.com/) {#ankr} +### [Ankr](https://www.ankr.com/) Also offers RPC and Horizon instances. -### [BlockEden](https://blockeden.xyz/stellar-soroban/) {#blockeden} +### [BlockEden](https://blockeden.xyz/stellar-soroban/) An all-in-one Stellar RPC, indexer GraphQL API, and data analytics web portal. -### [Goldsky](https://goldsky.com/) {#goldsky} +### [Goldsky](https://goldsky.com/) Mirror and indexer coming soon. -### [Mercury](https://mercurydata.app/) {#mercury} +### [Mercury](https://mercurydata.app/) A network indexing service that provides a toolkit to help get you started working with Stellar network data. -### [SubQuery](https://subquery.network/) {#subquery} +### [SubQuery](https://subquery.network/) An open-source data indexer for Stellar that enables custom API creation for dapps and smart contracts with clean, indexed data. It supports indexing ledgers, transactions, operations, and effects from Stellar, as well as transactions and events from Soroban into a Postgres database. -### [ZettaBlock](https://zettablock.com/) {#zettablock} +### [ZettaBlock](https://zettablock.com/) ZettaBlock offers real-time enterprise-grade data indexing infrastructure services to blockchain ecosystems through customizable, low latency APIs. diff --git a/docs/tools/developer-tools/jupyter-notebooks.mdx b/docs/tools/developer-tools/jupyter-notebooks.mdx index a16a3a477..932e197a3 100644 --- a/docs/tools/developer-tools/jupyter-notebooks.mdx +++ b/docs/tools/developer-tools/jupyter-notebooks.mdx @@ -17,7 +17,7 @@ Rust support in Jupyter Notebooks is experimental. You might run into bugs, or u ::: -## Getting Started {#getting-started} +## Getting Started 1. Install [Visual Studio Code] (VSCode) 2. Install the [Jupyter Notebook extension] in VSCode @@ -65,11 +65,11 @@ client.add(&1, &2) Congratulations you have a Jupyter Notebook with contract code that should look something like the screenshot below, ready for hacking and experimenting. -## Screenshot {#screenshot} +## Screenshot ![A running Jupyter notebook](/assets/jupyter-notebooks.png) -## Community {#community} +## Community Have ideas for how to improve Soroban contracts in Jupyter Notebooks? Join the community on [Discord]. diff --git a/docs/tools/developer-tools/lab/README.mdx b/docs/tools/developer-tools/lab/README.mdx index 27a4e831a..464b1f58c 100644 --- a/docs/tools/developer-tools/lab/README.mdx +++ b/docs/tools/developer-tools/lab/README.mdx @@ -7,13 +7,13 @@ sidebar_position: 80 # Lab -### [Stellar Lab](https://lab.stellar.org) {#stellar-lab} +### [Stellar Lab](https://lab.stellar.org) Stellar Lab is our new go-to tool for development, experimenting, and testing, as well as exploring APIs developers use to interact with the Stellar network. Whether you're a developer seeking to test transactions, explore RPC methods or Horizon endpoints, or dive deeper into the ecosystem, Stellar Lab provides a modern and user-friendly interface that makes the process smooth and intuitive. ![Lab: Homepage](/assets/lab/lab.png) -### Features of Stellar Lab {#features-of-stellar-lab} +### Features of Stellar Lab - Easily Create Accounts: Create Accounts on Mainnet, Testnet, and Futurenet using a web UI. You can use Friendbot to fund those accounts directly on Lab for Testnet and Futurenet. - Access RPC Methods and Horizon Endpoints: Leverage powerful Stellar RPC methods and Stellar Horizon endpoints in a web UI to interact with the Stellar network and obtain crucial data. Try RPC methods to get states from the ledger like accounts, trustlines, contract wasm, and more. @@ -26,10 +26,10 @@ Stellar Lab is our new go-to tool for development, experimenting, and testing, a These are the features that are available now. There will be more upcoming features to support smart contracts. We look forward to showing you the future of Stellar Lab. -### What About the Old Lab? {#what-about-the-old-lab} +### What About the Old Lab? In case you need it, the previous version of Stellar Lab is still accessible [here](https://old-lab.stellar.org). However, it will no longer be actively maintained. We encourage you to explore the new Lab and if you think there is anything that’s missing, please reach out to us Stellar Github. -### Help Us Improve! {#help-us-improve} +### Help Us Improve! We’re committed to making Stellar Lab even better. If you have any feature requests, please submit them on [Github](https://github.com/stellar/laboratory/issues). Your feedback is important to us with product iterations and in shaping the future of Stellar Lab. diff --git a/docs/tools/developer-tools/lab/account.mdx b/docs/tools/developer-tools/lab/account.mdx index 2d43ffe7a..86150cbf8 100644 --- a/docs/tools/developer-tools/lab/account.mdx +++ b/docs/tools/developer-tools/lab/account.mdx @@ -1,6 +1,6 @@ # Account -## [Create Account Keypair](https://lab.stellar.org/account/create) {#create-account-keypair} +## [Create Account Keypair](https://lab.stellar.org/account/create) ![Lab: Create Account](/assets/lab/lab-account-create.png) @@ -25,7 +25,7 @@ The Friendbot can be used for new account or accounts with balance under a start 4. Optionally, to save the generated keypair, click the "Save Keypair" button. Enter the name in the pop-up and click the "Save" button to save the keypair in the browser's local storage. Click the "Saved Keypairs" link on the left-side menu to view saved keypairs. The save feature is available only on Testnet and Futurenet networks. -## [Fund Account](https://lab.stellar.org/account/fund) {#fund-account} +## [Fund Account](https://lab.stellar.org/account/fund) ![Lab: Fund Account](/assets/lab/lab-account-fund.png) @@ -42,7 +42,7 @@ You can also create an account using a Stellar SDK. Follow a guide [here](../../ ::: -## [Saved Keypairs](https://lab.stellar.org/account/saved) {#saved-keypairs} +## [Saved Keypairs](https://lab.stellar.org/account/saved) ![Lab: Saved Keypairs](/assets/lab/lab-account-saved.png) diff --git a/docs/tools/developer-tools/lab/quickstart-with-lab.mdx b/docs/tools/developer-tools/lab/quickstart-with-lab.mdx index 480adccfc..9cd587866 100644 --- a/docs/tools/developer-tools/lab/quickstart-with-lab.mdx +++ b/docs/tools/developer-tools/lab/quickstart-with-lab.mdx @@ -1,15 +1,15 @@ # Using Lab with Quickstart -## Overview {#overview} +## Overview [Quickstart](https://github.com/stellar/quickstart) provides an easy way to set up a local Stellar network environment. Specifically, Quickstart docker image bundles Stellar Core with Horizon, RPC, Friendbot, and the necessary PostgreSQL databases. Now it is possible to use Stellar Lab as an interface on Quickstart. -## Prerequisites {#prerequisites} +## Prerequisites - [Stellar CLI](/docs/tools/developer-tools/cli/install-cli) - [Docker](https://www.docker.com/) -## Start Quickstart {#start-quickstart} +## Start Quickstart Quickstart can be started for different networks. In this example, we will start Quickstart for `testnet`. Start Quickstart with the Stellar CLI using the following command: @@ -19,7 +19,7 @@ stellar network container start testnet Quickstart will usually start on `http://localhost:8000`. With this information, we can now configure Stellar Lab to use the local network. -## Configure Stellar Lab to use Local Horizon and Local RPC {#configure-stellar-lab-to-use-local-horizon-and-local-rpc} +## Configure Stellar Lab to use Local Horizon and Local RPC ![Lab: Network selector](/assets/lab/lab-custom-network.png) diff --git a/docs/tools/developer-tools/lab/transactions.mdx b/docs/tools/developer-tools/lab/transactions.mdx index 4239ee3a0..761b7d3f2 100644 --- a/docs/tools/developer-tools/lab/transactions.mdx +++ b/docs/tools/developer-tools/lab/transactions.mdx @@ -1,12 +1,12 @@ # Transactions -## [Build Transaction](https://lab.stellar.org/transaction/build) {#build-transaction} +## [Build Transaction](https://lab.stellar.org/transaction/build) ![Lab: Build Transaction](/assets/lab/lab-transactions-build.png) You can access the "Build Transaction" page by clicking the "Transactions" link in the Lab's top navigation. The transaction builder UI has helpful messages, links, and input validation to make learning how to build transactions on the Stellar network easier. There are three main sections: params, operations, and transaction validation (error or success). -### Params {#params} +### Params A Stellar transaction requires a source account, transaction sequence number, and a base fee. Memo and time bounds are optional. @@ -14,7 +14,7 @@ Once you enter a valid public address in the "Source Account" input, you can aut The base fee is 100 by default, but you may need to increase the fee if the network is congested. -### Operations {#operations} +### Operations ![Lab: Transaction operations](/assets/lab/lab-transactions-ops.png) @@ -28,7 +28,7 @@ You can also save a valid transaction by clicking the save button at the bottom Clicking the share button (right next to the save button) allows you to share a link with all the transaction information provided. You can share any transaction, even if it's invalid or incomplete. -### Transaction Validation {#transaction-validation} +### Transaction Validation ![Lab: Transaction validation success](/assets/lab/lab-transactions-response-success.png) @@ -38,7 +38,7 @@ If there are errors in this transaction, you will see them grouped by section (p ![Lab: Transaction validation error](/assets/lab/lab-transactions-response-error.png) -## [Saved Transactions](https://lab.stellar.org/transaction/saved) {#saved-transactions} +## [Saved Transactions](https://lab.stellar.org/transaction/saved) ![Lab: Saved Transactions](/assets/lab/lab-transactions-saved.png) diff --git a/docs/tools/developer-tools/network-insights.mdx b/docs/tools/developer-tools/network-insights.mdx index d414410e5..51a2edc5e 100644 --- a/docs/tools/developer-tools/network-insights.mdx +++ b/docs/tools/developer-tools/network-insights.mdx @@ -7,6 +7,6 @@ sidebar_position: 85 # Network Insights -### [StellarFee](https://stellarfee.expert/) {#stellarfee} +### [StellarFee](https://stellarfee.expert/) A GUI tool which is a useful fee estimator, transaction simulator to find the resources consumed and the expected fees for a transaction. diff --git a/docs/tools/developer-tools/network-status.mdx b/docs/tools/developer-tools/network-status.mdx index e30685028..e2bc57b7b 100644 --- a/docs/tools/developer-tools/network-status.mdx +++ b/docs/tools/developer-tools/network-status.mdx @@ -7,14 +7,14 @@ sidebar_position: 90 # Network Status -### [Dashboard](https://dashboard.stellar.org/) {#dashboard} +### [Dashboard](https://dashboard.stellar.org/) Displays the current status of the Testnet and Mainnet. Monitor fee stats, recent operations, lumen supply, and more. -### [Stellarbeat](https://stellarbeat.io/) {#stellarbeat} +### [Stellarbeat](https://stellarbeat.io/) View Stellar network nodes and visualize consensus. -### [Status Page](https://status.stellar.org/) {#status-page} +### [Status Page](https://status.stellar.org/) Tracks network incidents and scheduled maintenance for the Testnet and Mainnet. Subscribe to updates to be notified about important events, including protocol upgrades and Testnet resets. diff --git a/docs/tools/developer-tools/node-operator-tools.mdx b/docs/tools/developer-tools/node-operator-tools.mdx index 37ad5ef9a..afba032bb 100644 --- a/docs/tools/developer-tools/node-operator-tools.mdx +++ b/docs/tools/developer-tools/node-operator-tools.mdx @@ -7,6 +7,6 @@ sidebar_position: 100 # Node Operator Tools -### [GitHub Repository](https://github.com/stellar/go/tree/master/tools) {#github-repository} +### [GitHub Repository](https://github.com/stellar/go/tree/master/tools) A GitHub repository with tools like Stellar Archivist (for Stellar Core archive maintenance) and Horizon cmp (compares responses of two Horizon servers). diff --git a/docs/tools/developer-tools/security-tools.mdx b/docs/tools/developer-tools/security-tools.mdx index 6254891ef..307691d48 100644 --- a/docs/tools/developer-tools/security-tools.mdx +++ b/docs/tools/developer-tools/security-tools.mdx @@ -7,6 +7,6 @@ sidebar_position: 115 # Security Tools -### [Scout: Bug Fighter](https://www.coinfabrik.com/products/scout/) {#scout-bug-fighter} +### [Scout: Bug Fighter](https://www.coinfabrik.com/products/scout/) A static code analysis tool built to assist Soroban developers and auditors in identifying potential security threats and applying best practices. diff --git a/docs/tools/developer-tools/smart-contract-resources.mdx b/docs/tools/developer-tools/smart-contract-resources.mdx index 728f1b53a..d7ee8b36a 100644 --- a/docs/tools/developer-tools/smart-contract-resources.mdx +++ b/docs/tools/developer-tools/smart-contract-resources.mdx @@ -7,18 +7,18 @@ sidebar_position: 120 # Smart Contract Resources -### [Keizai](https://keizai.dev/) {#keizai} +### [Keizai](https://keizai.dev/) Keizai is an open-source postman-inspired application, designed to simplify and elevate the testing process for developers working with Soroban smart contracts. -### [Soroban Copilot](https://github.com/mootz12/soroban-copilot) {#soroban-copilot} +### [Soroban Copilot](https://github.com/mootz12/soroban-copilot) A collection of no_std Rust packages focused on making Soroban development easier. -### [Soroban React](https://github.com/esteblock/soroban-react) {#soroban-react} +### [Soroban React](https://github.com/esteblock/soroban-react) A simple, powerful framework for building modern Soroban dapps using React. -### [Soroban Dev](https://sorobandev.com/) {#soroban-dev} +### [Soroban Dev](https://sorobandev.com/) A web developer's guide to Soroban. Contains guides for learning Soroban and Rust, developer tools, example applications, and more. diff --git a/docs/tools/developer-tools/wallets.mdx b/docs/tools/developer-tools/wallets.mdx index f06cab618..3a5392547 100644 --- a/docs/tools/developer-tools/wallets.mdx +++ b/docs/tools/developer-tools/wallets.mdx @@ -7,18 +7,18 @@ sidebar_position: 130 # Wallets -### [Stellar Wallet Kit](https://github.com/Creit-Tech/Stellar-Wallets-Kit/) {#stellar-wallet-kit} +### [Stellar Wallet Kit](https://github.com/Creit-Tech/Stellar-Wallets-Kit/) A wallet kit to handle integration to multiple Stellar ecosystem wallets with a simple API. Learn more about how to integrate this library from [the Stellar Wallet Kit Docs](https://stellarwalletskit.dev/). -### [Account Viewer](https://accountviewer.stellar.org/) {#account-viewer} +### [Account Viewer](https://accountviewer.stellar.org/) A stripped-down wallet where you can check an account’s XLM balance and send simple payments on Testnet and Mainnet. -### [Albedo](https://albedo.link/) {#albedo} +### [Albedo](https://albedo.link/) A web-based wallet for Stellar transaction signing and identity verification. -### [Freighter](https://www.freighter.app/) {#freighter} +### [Freighter](https://www.freighter.app/) SDF’s flagship non-custodial wallet extension that allows users to sign Stellar transactions via their browser. diff --git a/docs/tools/sdks/build-your-own.mdx b/docs/tools/sdks/build-your-own.mdx index 41a784166..5f5a5a308 100644 --- a/docs/tools/sdks/build-your-own.mdx +++ b/docs/tools/sdks/build-your-own.mdx @@ -15,22 +15,22 @@ To build SDKs for other languages a few things need to be included in the SDK to Below is a list of functionality a Soroban SDK needs to support those things, as well as some details on what an SDK can provide in regards to testing capabilities. -## Functionality {#functionality} +## Functionality -### Value Conversions {#value-conversions} +### Value Conversions - [Val] encode/decode - [Object] encode/decode - [Symbol] encode/decode - [Error] encode/decode -### Host Functions {#host-functions} +### Host Functions The host functions defined in [env.json] are functions callable from within the Wasm Guest environment. These need to be available to contracts to call, in some form, ideally wrapped so that contracts have a nicer interface. Host functions have friendly names in the file above, such as `get_ledger_version`, however in the Wasm they are only importable via short names, such as `x.4`. The letter proceeding the dot is the module, and the value after the dot is the function name. The mappins are available in env.rs. -### SDK Types {#sdk-types} +### SDK Types All the types in [soroban-sdk](https://docs.rs/soroban-sdk) should be supported. Notably: @@ -38,43 +38,43 @@ All the types in [soroban-sdk](https://docs.rs/soroban-sdk) should be supported. - [Vec] - [Bytes] -### User Defined Types {#user-defined-types} +### User Defined Types Contracts should be able to create user defined types, such as structs, unions, or enums, and have them be transmitted to the host for storing and transmitted back for loading. SDKs do this by converting objects to and from a `Val`. In the [soroban-sdk] this is referred to as a [Val]. -#### Structs {#structs} +#### Structs Structs with named fields should be translated into a `Map` with keys as `Symbol`s and the values as the field value, i.e. `Map`. Structs with unnamed fields should be translated into a `Vec` with the values as the elements. i.e. `Vec`. -#### Unions {#unions} +#### Unions Unions (or enums in some languages) with named variants and unit or tuple values should be translated into a `Vec` with the first element as a `Symbol` of the name of the variant, and zero or more additional elements representing a value stored with the variant. -#### Enums {#enums} +#### Enums Enums with integer values should be translated into a `u32`. -### User Defined Errors {#user-defined-errors} +### User Defined Errors Errors are `u32` values that are translated into a [Error]. -### Environment Meta Generation {#environment-meta-generation} +### Environment Meta Generation Contracts must contain a Wasm custom section with name `contractenvmetav0` and containing a serialized [`SCEnvMetaEntry`]. The interface version stored within should match the version of the host functions supported. -### Contract Spec Generation {#contract-spec-generation} +### Contract Spec Generation Contracts should contain a Wasm custom section with name `contractspecv0` and containing a serialized stream of [`SCSpecEntry`]. There should be a `SCSpecEntry` for every function, struct, and union exported by the contract. -### Contract Meta Generation {#contract-meta-generation} +### Contract Meta Generation Contracts may optionally contain a Wasm custom section with name `contractmetav0` and containing a serialized [`SCMetaEntry`]. Contracts may store any metadata in the entries that can be used by applications and tooling off-network. -## Testing {#testing} +## Testing Any Soroban SDK ideally provides a test environment for executing contract functions in the context of a Soroban runtime environment. The [soroban-sdk] does this by embedding the Soroban environment Rust library, [soroban-env-host]. diff --git a/docs/tools/sdks/library.mdx b/docs/tools/sdks/library.mdx index e2b4e50a9..f7684fa02 100644 --- a/docs/tools/sdks/library.mdx +++ b/docs/tools/sdks/library.mdx @@ -7,7 +7,7 @@ Interact with the Stellar network using the SDK in your preferred language. The Each SDK has its own source code and documentation. Learn how to use a specific SDK by referring to the documentation- most docs offer practical examples that demonstrate how to construct and submit transactions and interact with Horizon endpoints. -### Soroban Rust SDK {#soroban-rust-sdk} +### Soroban Rust SDK [Rust SDK](https://github.com/stellar/rs-soroban-sdk) | [Docs](https://docs.rs/soroban-sdk) @@ -27,7 +27,7 @@ soroban-sdk = $VERSION soroban-sdk = { version = $VERSION, features = ["testutils"] } ``` -### AssemblyScript SDK {#assemblyscript-sdk} +### AssemblyScript SDK [AssemblyScript SDK](https://github.com/Soneso/as-soroban-sdk) @@ -35,7 +35,7 @@ The `as-soroban-sdk` is an open source SDK that supports writing programs for th The AssemblyScript Soroban SDK is maintained by dedicated community developer, Soneso. Report issues and share feedback [here](https://github.com/Soneso/as-soroban-sdk/issues/new). -### JavaScript SDK {#javascript-sdk} +### JavaScript SDK [JavaScript SDK](https://github.com/stellar/js-stellar-sdk) | [Docs](https://stellar.github.io/js-stellar-sdk/) | [NPM](https://www.npmjs.com/package/@stellar/stellar-sdk) @@ -46,7 +46,7 @@ It provides: - A networking layer API for Stellar RPC methods and the Horizon API. - Facilities for building and signing transactions, for communicating with an RPC instance, for communicating with a Horizon instance, and for submitting transactions or querying network state. -### Python SDK {#python-sdk} +### Python SDK [Python SDK](https://github.com/StellarCN/py-stellar-base) | [Docs](https://stellar-sdk.readthedocs.io/en/latest/) | [Examples](https://github.com/StellarCN/py-stellar-base/tree/master/examples) @@ -59,7 +59,7 @@ It provides: - A networking layer API for Horizon endpoints. - Facilities for building and signing transactions, for communicating with a Stellar Horizon instance, and for submitting transactions or querying network history. -### iOS SDK {#ios-sdk} +### iOS SDK [iOS SDK](https://github.com/Soneso/stellar-ios-mac-sdk) | [Docs](https://github.com/Soneso/stellar-ios-mac-sdk/tree/master/docs) | [Smart Contract Docs](https://github.com/Soneso/stellar-ios-mac-sdk/blob/master/soroban.md) @@ -67,7 +67,7 @@ The `stellar-ios-mac-sdk` is an open source Stellar SDK for iOS & Mac. It provid The iOS SDK is maintained by dedicated community developer, Soneso. -### Flutter SDK {#flutter-sdk} +### Flutter SDK [Flutter SDK](https://github.com/Soneso/stellar_flutter_sdk) | [Docs](https://github.com/Soneso/stellar_flutter_sdk/blob/master/soroban.md) @@ -75,7 +75,7 @@ The `stellar-flutter-sdk` is an open source Stellar SDK for Flutter developers. The Flutter Stellar SDK is maintained by dedicated community developer, Soneso. -### PHP SDK {#php-sdk} +### PHP SDK [PHP SDK](https://github.com/Soneso/stellar-php-sdk) | [Docs](https://github.com/Soneso/stellar-php-sdk/blob/main/soroban.md) @@ -83,37 +83,37 @@ The `stellar-php-sdk` is an open source Stellar SDK for PHP developers. It provi The PHP Stellar SDK is maintained by dedicated community developer, Soneso. -### Elixir SDK {#elixir-sdk} +### Elixir SDK [Soroban Elixir SDK](https://github.com/kommitters/soroban.ex) & [Docs](https://github.com/kommitters/soroban.ex#documentation)| [Stellar Elixir SDK](https://github.com/kommitters/stellar_sdk) & [Docs](https://hexdocs.pm/stellar_sdk/readme.html#documentation) | [Examples](https://github.com/kommitters/stellar_sdk/tree/main/docs) This SDK is maintained by dedicated community developers, kommitters Open Source. -### Java SDK {#java-sdk} +### Java SDK [Java SDK](https://github.com/lightsail-network/java-stellar-sdk) | [Docs](https://lightsail-network.github.io/java-stellar-sdk/) `java-stellar-sdk` provides APIs to build transactions and connect to Horizon and also provides functionality to deploy and invoke Soroban smart contracts and communicates with the Stellar RPC Server. -### Go {#go} +### Go This SDK is split up into separate packages, all of which you can find in the [Go monorepo README](https://github.com/stellar/go/blob/master/docs/reference/readme.md). The two key libraries for interacting with Horizon are `txnbuild`, which enables the construction, signing, and encoding of Stellar transactions, and `horizonclient`, which provides a web client for interfacing with Horizon server REST endpoints to retrieve ledger information and submit transactions built with `txnbuild`. - txnbuild: [SDK](https://github.com/stellar/go/tree/master/txnbuild) | [Docs](https://godoc.org/github.com/stellar/go/txnbuild) - Horizonclient: [SDK](https://github.com/stellar/go/tree/master/clients/horizonclient) | [Docs](https://godoc.org/github.com/stellar/go/clients/horizonclient) -### Ruby {#ruby} +### Ruby [Ruby SDK](https://github.com/astroband/ruby-stellar-sdk) | [Base Source](https://github.com/astroband/ruby-stellar-sdk/blob/master/base/README.md) | [SDK Source](https://github.com/astroband/ruby-stellar-sdk/blob/master/sdk/README.md) | [Docs](https://www.rubydoc.info/gems/stellar-sdk) | [Base Examples](https://github.com/astroband/ruby-stellar-sdk/tree/master/base/examples) | [SDK Examples](https://github.com/astroband/ruby-stellar-sdk/tree/master/sdk/examples) -### C# .NET {#c-net} +### C# .NET [C# .NET SDK](https://github.com/Beans-BV/dotnet-stellar-sdk) | [Docs](https://elucidsoft.github.io/dotnet-stellar-sdk/) -### Scala {#scala} +### Scala [Scala SDK](https://github.com/Synesso/scala-stellar-sdk) | [Docs](https://synesso.github.io/scala-stellar-sdk/) -### Qt/C++ {#qtc} +### Qt/C++ [Qt/C++ SDK](https://github.com/bnogalm/StellarQtSDK) | [Docs](https://github.com/bnogalm/StellarQtSDK/wiki) diff --git a/docs/validators/README.mdx b/docs/validators/README.mdx index 2671c23bb..848b0f179 100644 --- a/docs/validators/README.mdx +++ b/docs/validators/README.mdx @@ -16,11 +16,11 @@ If you are interested in Horizon or RPC nodes, please explore those docs. If you are interested in running a validator node — because you issue an asset that you would like to help secure through transaction validation, because you want to help increase network health and decentralization, or because you want to participate in network governance — then this section of the docs is for you. It explains the technical and operational aspects of installing, configuring, and maintaining a Stellar Core validator node, and should help you figure out the best way to set up your Stellar integration. -## Node Setup Process {#node-setup-process} +## Node Setup Process The basic flow, which you can navigate through using the "Admin Guide" on the left, goes (roughly) like this: -### Initial Setup {#initial-setup} +### Initial Setup 1. Use the information on this _Introduction_ page to determine which [type of node](#types-of-nodes) you want to run. 2. [Prerequisite](./admin-guide/prerequisites.mdx) software must be installed (and configured according to your needs). @@ -30,13 +30,13 @@ The basic flow, which you can navigate through using the "Admin Guide" on the le 6. [Start your node](./admin-guide/running-node.mdx) and join the network. 7. [Logging](./admin-guide/logging.mdx) and [monitoring](./admin-guide/monitoring.mdx) should be appropriately set up and used to meet your needs. -### Ongoing Requirements {#ongoing-requirements} +### Ongoing Requirements 8. [Maintenance](./admin-guide/maintenance.mdx) is required from time to time to keep your node up-to-date and participating in the network. 9. [Network upgrades](./admin-guide/network-upgrades.mdx) require validator consensus, and you will need to consider casting a vote in the event of a protocol upgrade. 10. [Soroban settings](./admin-guide/soroban-settings.mdx) are network-wide, configurable, and changes can be proposed by anyone. Similar to protocol upgrades, changes to these settings will require validator consensus, so you should be prepared to participate. -### Other Information {#other-information} +### Other Information - Stellar Core uses a robust [command line](./admin-guide/commands.mdx) tool to control and operate a node. We've gathered information on some of the most-used commands, and linked to further, more comprehensive CLI documentation. - We've collected some miscellaneous helpful and [advanced](./admin-guide/advanced.mdx) information that could be useful as you understand and implement your core node. @@ -53,17 +53,17 @@ This architecture was **deprecated** as of [Horizon 2.0](https://www.stellar.org -### Basic Validator {#basic-validator} +### Basic Validator -#### Validating, no public archive {#validating-no-public-archive} +#### Validating, no public archive A Basic Validator keeps track of the ledger and submits transactions for possible inclusion, but it is _not_ configured to publish history archives. It does require a secret key, and is [configured to participate in consensus](./admin-guide/configuring.mdx#validating-node) by voting on — and signing off on — changes to the ledger, meaning it supports the network and increases decentralization. The advantage: signatures can serve as official endorsements of specific ledgers in real time. That’s important if, for instance, you issue an asset on Stellar that represents a real-world asset: you can let your customers know that you will only honor transactions and redeem assets from ledgers signed by your validator, and in the unlikely scenario that something happens to the network, you can use your node as the final arbiter of truth. Setting up your node as a validator allows you to resolve any questions _up front and in writing_ about how you plan to deal with disasters and disputes. -### Full Validator {#full-validator} +### Full Validator -#### Validating, offers public archive {#validating-offers-public-archive} +#### Validating, offers public archive A Full Validator is the same as a Basic Validator except that it also publishes a [History Archive](./admin-guide/environment-preparation.mdx) containing snapshots of the ledger, including all transactions and their results. A Full Validator writes to an internet-facing blob store — such as AWS or Azure — so it's a bit more expensive and complex to run, but it also does the most to support the network’s resilience and decentralization. diff --git a/docs/validators/admin-guide/advanced.mdx b/docs/validators/admin-guide/advanced.mdx index 3256fe508..a681feb3d 100644 --- a/docs/validators/admin-guide/advanced.mdx +++ b/docs/validators/admin-guide/advanced.mdx @@ -5,11 +5,11 @@ sidebar_position: 130 This page contains information that is useful to know but that should not stop somebody from running a node. -## Creating Your Own Private Network {#creating-your-own-private-network} +## Creating Your Own Private Network The [stellar-core GitHub repository] holds [a `testnet.md` file] which contains a short tutorial demonstrating how to configure and run a short-lived, isolated test network. -## Runtime Information: Start and Stop {#runtime-information-start-and-stop} +## Runtime Information: Start and Stop Stellar-core can be started directly from the command line, or through a supervision system such as `init`, `upstart`, or `systemd`. @@ -17,11 +17,11 @@ Stellar-core can be gracefully exited at any time by delivering `SIGINT` or pres Stellar-core can also be packaged in a container system such as Docker, so long as `BUCKET_DIR_PATH` and the database are stored on persistent volumes. For an example, see [`stellar/quickstart`]. -## In-depth Architecture {#in-depth-architecture} +## In-depth Architecture The [stellar-core GitHub repository] also contains [the `architecture.md` file], which describes how stellar-core is structured internally, how it is intended to be deployed, and the collection of servers and services needed to get the full functionality and performance. -## Reproducible Performance Testing With Stellar Supercluster {#reproducible-performance-testing-with-stellar-supercluster} +## Reproducible Performance Testing With Stellar Supercluster [Stellar Supercluster] is a tool that enables running simulated networks of stellar-core nodes on Kubernetes clusters. One use case for Supercluster is running reproducible performance tests. The Supercluster GitHub repository contains a few documents to help users run theoretical maximum Transaction Per Second (TPS) tests: @@ -29,7 +29,7 @@ The [stellar-core GitHub repository] also contains [the `architecture.md` file], - [`doc/eks.md`] details how to build a supercluster-compatible EKS cluster on AWS. - [`doc/theoretical-max-tps.md`] explains how to run the theoretical max TPS test on an EKS cluster. It also contains a table of results from SDF's own theoretical max TPS runs, as well as the configurations used to achieve those results. -### Other Supercluster Resources {#other-supercluster-resources} +### Other Supercluster Resources Supercluster is useful beyond reproducible performance testing. Some helpful resources to learn more about Supercluster include: diff --git a/docs/validators/admin-guide/commands.mdx b/docs/validators/admin-guide/commands.mdx index d15ba895c..ed5eb7b07 100644 --- a/docs/validators/admin-guide/commands.mdx +++ b/docs/validators/admin-guide/commands.mdx @@ -15,7 +15,7 @@ Additionally, while the commands on this page are _CLI_ commands, there is an ad -## Get `--help` Anywhere {#get---help-anywhere} +## Get `--help` Anywhere The `--help` (aliases: `-h` or `-?`) option can be specified at _any place_ in the command line. It will show you the help message for the relevant command. Some example useage is as follows: @@ -26,23 +26,23 @@ stellar-core --help new-db stellar-core catchup --help ``` -## Essential Commands {#essential-commands} +## Essential Commands For all stellar-core commands, options can _only_ by placed after the command. -### `new-db` {#new-db} +### `new-db` The **`new-db`** command creates or restores the local database to the genesis ledger. -#### `new-db` Options {#new-db-options} +#### `new-db` Options - `--minimal-for-in-memory-mode`: Reset the special database used only for in-memory mode. (see the `--in-memory` flag in [`run` options](#run-options)) -### `run` {#run} +### `run` The **`run`** command will run the `stellar-core` node. -#### `run` Options {#run-options} +#### `run` Options - `--disable-bucket-gc`: Keeps all, even old, buckets on disk. - `--metadata-output-stream `: Filename or file-descriptor number `fd:N` to stream metadata to. @@ -50,11 +50,11 @@ The **`run`** command will run the `stellar-core` node. Certain features, such as `in-memory` mode options, have been deprecated, so they aren't listed here. -### `catchup` {#catchup} +### `catchup` The **`catchup`** command will execute a catchup from history archives without connecting to the network. -#### `catchup` Options {#catchup-options} +#### `catchup` Options - ``: (required) Destination ledger is any valid number or `current` and ledger count is any valid number or `max`. - `--archive `: Archive name to be used for catchup. Use `any` to select randomly. diff --git a/docs/validators/admin-guide/configuring.mdx b/docs/validators/admin-guide/configuring.mdx index 580072ec9..af49e996e 100644 --- a/docs/validators/admin-guide/configuring.mdx +++ b/docs/validators/admin-guide/configuring.mdx @@ -11,7 +11,7 @@ Before attempting to configure stellar-core, it is highly recommended to first t -## Configuration Basics {#configuration-basics} +## Configuration Basics After you've [installed](./installation.mdx) Stellar Core, your next step is to complete a configuration file that specifies crucial things about your node — like whether it connects to the Testnet or the Mainnet public network, what database it writes to, and which other nodes are in its [quorum set](#choosing-your-quorum-set). @@ -31,7 +31,7 @@ This page attempts (as strictly as is possible) to focus on the specific fields -### Example Configurations {#example-configurations} +### Example Configurations While we're looking at some of the config basics on this page, we've written this content to work best in conjunction with concrete config examples, so as you read through it, you may want to review the following: @@ -43,7 +43,7 @@ While we're looking at some of the config basics on this page, we've written thi Auditing of the P2P network is enabled by default, see the [overlay topology](./monitoring.mdx#overlay-topology-survey) section for more detail if you'd like to disable it -### Network Passphrase {#network-passphrase} +### Network Passphrase Use the `NETWORK_PASSPHRASE` field to specify whether your node connects to the Testnet or the Mainnet [network](../../learn/fundamentals/networks.mdx). @@ -52,15 +52,15 @@ Use the `NETWORK_PASSPHRASE` field to specify whether your node connects to the For more about the Network Passphrase and how it works, check out the [encyclopedia entry](../../learn/encyclopedia/network-configuration/network-passphrases.mdx). -### Database {#database} +### Database You specify your node's database by using the aptly named `DATABASE` field of your config file, which you can can read more about in the [complete example config][complete-example-database]. It defaults to an in-memory database, but you can specify a path as per the example. -### Buckets {#buckets} +### Buckets The flat XDR files of Stellar Core are placed in a directory specified in the config file as `BUCKET_DIR_PATH`, which defaults to `buckets`. -## Validating Node {#validating-node} +## Validating Node :::note @@ -102,7 +102,7 @@ If you run multiple validators, make sure to set a common `HOME_DOMAIN` for them If you want other validators to add your node to their quorum sets, you should also share your public key (`GDMTUTQ...`) by publishing a `stellar.toml` file on your home domain following specifications laid out by [SEP-20]. -## Choosing Your Quorum Set {#choosing-your-quorum-set} +## Choosing Your Quorum Set To create your quorum set, Stellar Core relies on two arrays of tables: `[[HOME_DOMAINS]]` and `[[VALIDATORS]]`. Check out the example config's [`HOME_DOMAINS` array] and [`VALIDATORS` array] to see them in action. @@ -130,7 +130,7 @@ To generate a quorum set, stellar core: While this does not absolve you of all responsibility — you still need to pick trustworthy validators and keep an eye on them to ensure that they're consistent and reliable — it does make your life easier and reduces the chances for human error. -### Validator Discovery {#validator-discovery} +### Validator Discovery When you add a validating node to your quorum set, it's generally because you trust the _organization_ running the node: you trust SDF, not some anonymous Stellar public key. @@ -140,7 +140,7 @@ As a result of that link, you can look up a node by its Stellar public key and c When you look at that list, you will discover that the most reliable organizations actually run more than one validator, and adding all of an organization's nodes to your quorum set creates the redundancy necessary to sustain arbitrary node failure. When an organization with a trio of nodes takes one down for maintenance, for instance, the remaining two nodes vote on the organization's behalf, and the organization's network presence persists. -### Home Domains Array {#home-domains-array} +### Home Domains Array `[[HOME_DOMAINS]]` defines a superset of validators: when you add nodes hosted by the same organization to your configuration, they share a home domain, and the information in the `[[HOME_DOMAINS]]` table, specifically the quality rating, will automatically apply to every one of those validators. @@ -163,7 +163,7 @@ HOME_DOMAIN="some-other-domain" QUALITY="LOW" ``` -### Validators Array {#validators-array} +### Validators Array For each node you would like to add to your quorum set, complete a `[[VALIDATORS]]` table with the following fields: @@ -209,11 +209,11 @@ Your quorum set is automatically configured based on the information you provide ::: -### Validator Quality {#validator-quality} +### Validator Quality `QUALITY` is a required field for each node you add to your quorum set. Whether you specify it for a suite of nodes in a `[[HOME_DOMAINS]]` table, or for a single node in a `[[VALIDATORS]]` table, it means the same thing, and you have the same three rating options: `HIGH`, `MEDIUM`, or `LOW`. -#### HIGH Quality {#high-quality} +#### HIGH Quality **HIGH** quality validators are given the most weight in automatic quorum set configuration. Before assigning a high quality rating to a node, make sure it has low latency and good uptime, and that the organization running the node is reliable and trustworthy. @@ -224,15 +224,15 @@ A high quality validator: Choosing redundant nodes is good practice. The archive requirement is programmatically enforced. -#### MEDIUM Quality {#medium-quality} +#### MEDIUM Quality **MEDIUM** quality validators are nested below high quality validators, and their combined weight is equivalent to a _single high quality entity_. If a node doesn't publish an archive, but you deem it reliable, or have an organizational interest in including it in your quorum set, give it a medium quality rating. -#### LOW Quality {#low-quality} +#### LOW Quality **LOW** quality validators are nested below medium quality validators, and their combined weight is equivalent to a _single medium quality entity_. Should they prove reliable over time, you can upgrade their rating to medium to give them a bigger role in your quorum set configuration. -### Automatic Quorum Set Generation {#automatic-quorum-set-generation} +### Automatic Quorum Set Generation :::info Important Note @@ -253,7 +253,7 @@ Once you add validators to your configuration, stellar core automatically genera _Diagram: Depiction of the nested quality levels and how they interact._ -### Quorum and Overlay Network {#quorum-and-overlay-network} +### Quorum and Overlay Network In order to get in sync and run consensus, your validator needs to be able to connect to the Stellar Network. In most cases, it is sufficient to simply rely on node's built-in peer discovery. However, your validator can be configured to connect to specific peers via `KNOWN_PEERS` and `PREFERRED_PEERS` in the config file. These can be either domain names or IPs. This can be useful for troubleshooting. @@ -261,7 +261,7 @@ Additionally, configuring `PREFERRED_PEER_KEYS` with the keys from your quorum s Without those settings, your validator depends on other nodes on the network to forward you the right messages, which is typically done as a best effort. -### Impact of Validator Quality on Nomination {#impact-of-validator-quality-on-nomination} +### Impact of Validator Quality on Nomination The Stellar Consensus Protocol uses validator quality levels in determining which validator should nominate the next transaction set for inclusion in a ledger. This process of choosing the validator that will nominate the next transaction set is called _leader election_. To start, the leader election algorithm assigns organizations and validators weights as follows: @@ -278,7 +278,7 @@ The leader election algorithm then assigns each validator a probability of winni 1. Higher quality organizations have a greater chance of winning leader election than lower quality organizations. 2. Organizations of equal quality have an equal chance of winning leader election. -#### Validator Nomination Weight Example {#validator-nomination-weight-example} +#### Validator Nomination Weight Example Let there be 3 `HIGH` quality organizations, 2 `MEDIUM` quality organizations, and 1 `LOW` quality organization. The weight of each organization is as follows: diff --git a/docs/validators/admin-guide/environment-preparation.mdx b/docs/validators/admin-guide/environment-preparation.mdx index b3fce1e46..9c0aaa9ab 100644 --- a/docs/validators/admin-guide/environment-preparation.mdx +++ b/docs/validators/admin-guide/environment-preparation.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { Alert } from "@site/src/components/Alert"; -## Initialize the Database and Local State {#initialize-the-database-and-local-state} +## Initialize the Database and Local State After configuring your [database](./configuring.mdx#database) and [buckets](./configuring.mdx#buckets) settings, before running Stellar Core for the first time, you must initialize the database: @@ -15,7 +15,7 @@ stellar-core new-db This command will initialize the database, as well as the bucket directory, and then exit. You can also use this command if your database gets corrupted and you want to restart it from scratch. -### Automatic Maintenance {#automatic-maintenance} +### Automatic Maintenance Some tables in stellar-core are used to publish ledger data to history archives. @@ -35,7 +35,7 @@ If this happens, database performance can be restored. The node will require som 1. run the `maintenance` http command manually with a large number of ledgers, and 2. perform a database maintenance operation such as `VACUUM FULL` to reclaim/rebuild the database as needed. -### Metadata Snapshots and Restoration {#metadata-snapshots-and-restoration} +### Metadata Snapshots and Restoration Some deployments of Stellar Core and Horizon will want to retain metadata for the _entire history_ of the network. This metadata can be quite large and computationally expensive to regenerate anew by replaying ledgers in stellar-core from an empty initial database state, as described in the previous section. @@ -51,13 +51,13 @@ Some operators therefore prefer to shut down their stellar-core (and/or Horizon) Any reasonably recent state will do — if such a snapshot is a little old, stellar-core will replay ledgers from whenever the snapshot was taken to the current network state anyways — but this procedure can greatly accelerate restoring validator nodes, or cloning them to create new ones. -## History Archives {#history-archives} +## History Archives Stellar Core normally interacts with one or more history archives, which are configurable facilities where [Full Validators](../README.mdx#full-validator) store flat files containing history checkpoints: bucket files and history logs. History archives are usually off-site commodity storage services such as Amazon S3, Google Cloud Storage, Azure Blob Storage, or custom SCP/SFTP/HTTP servers. Use command templates in the config file to give the specifics of which services you will use and how to access them. The [example config] will demonstrate how to configure a history archive through command templates. -### Configuring to Get Data from an Archive {#configuring-to-get-data-from-an-archive} +### Configuring to Get Data from an Archive No matter what kind of node you're running, you should configure it to `get` history from one or more public archives. You can configure any number of archives to download from: Stellar Core will automatically round-robin between them. @@ -69,7 +69,7 @@ If you notice a lot of errors related to downloading archives, you should ensure ::: -### Configuring to Publish Data to an Archive {#configuring-to-publish-data-to-an-archive} +### Configuring to Publish Data to an Archive Archive sections can also be configured with `put` and `mkdir` commands to cause the instance to publish to that archive (for nodes configured as [full validators](../README.mdx#full-validator)). @@ -89,7 +89,7 @@ More detailed guidance and strategies for publishing history archives can be fou ::: -## Other Preparation {#other-preparation} +## Other Preparation In addition, your should ensure that your operating environment is also functional. This means you will have considered and prepared the following. diff --git a/docs/validators/admin-guide/installation.mdx b/docs/validators/admin-guide/installation.mdx index c11c4afa7..3df480a67 100644 --- a/docs/validators/admin-guide/installation.mdx +++ b/docs/validators/admin-guide/installation.mdx @@ -13,7 +13,7 @@ There are three common ways to install and run Stellar Core: 3. **Use a [Docker image](#docker-based-installation).** Using a Docker image is the quickest and easiest method, so it's a good choice for a lot of developers. -## Release Version {#release-version} +## Release Version Whichever method you use, you should make sure to install the latest [release](https://github.com/stellar/stellar-core/releases) since these builds are backwards compatible and are cumulative. @@ -23,19 +23,19 @@ The version number scheme that we follow is `protocol_version.release_number.pat - `release_number` is bumped when a set of new features or bug fixes not impacting the protocol are included in the release, and - `patch_number` is used when a critical fix has to be deployed. -## Package-Based Installation {#package-based-installation} +## Package-Based Installation If you are using a recent LTS version of Ubuntu, we provide the latest stable releases of [`stellar-core`](https://github.com/stellar/stellar-core) and [`stellar-horizon`](https://github.com/stellar/go/tree/master/services/horizon) in Debian binary package format. You may choose to install these packages individually, which offers the greatest flexibility, but requires **manual** creation of the relevant configuration files and configuration of a **PostgreSQL** database. -## Installing From Source {#installing-from-source} +## Installing From Source The Stellar Core source code repository contains extensive and thorough instructions to build the software from source. Please [check out `INSTALL.md`](https://github.com/stellar/stellar-core/blob/master/INSTALL.md) for more information. -## Docker-Based Installation {#docker-based-installation} +## Docker-Based Installation -### Development Environments {#development-environments} +### Development Environments SDF maintains a [quickstart image](https://github.com/stellar/quickstart) that bundles Stellar's "Captive Core" with Horizon and the necessary PostgreSQL databases. It's a quick way to set up a default, non-validating, ephemeral configuration that should work for most developers. Additionally, the quickstart image can be spun up pre-configured for use as a Mainnet, Testnet, Futurenet, or Local network node. @@ -45,7 +45,7 @@ The quickstart image is not intended to serve as a production-level instance nod -### Production Environments {#production-environments} +### Production Environments SDF also maintains a Stellar-Core-only standalone image, [`stellar/stellar-core`](https://hub.docker.com/r/stellar/stellar-core). diff --git a/docs/validators/admin-guide/maintenance.mdx b/docs/validators/admin-guide/maintenance.mdx index 6f454254d..135b89934 100644 --- a/docs/validators/admin-guide/maintenance.mdx +++ b/docs/validators/admin-guide/maintenance.mdx @@ -13,7 +13,7 @@ If you are changing some settings that may impact network wide settings such as If you're changing your quorum set configuration, also read the [section on what to do](#special-considerations-during-quorum-set-updates). -## Recommended Steps to Perform as Part of a Maintenance {#recommended-steps-to-perform-as-part-of-a-maintenance} +## Recommended Steps to Perform as Part of a Maintenance We recommend performing the following steps in order (repeat sequentially as needed if you run multiple nodes). @@ -23,7 +23,7 @@ We recommend performing the following steps in order (repeat sequentially as nee 4. When done, start your instance that should rejoin the network 5. The instance will be completely caught up when it's both `Synced` and _there is no backlog in uploading history_. -## Special Considerations During Quorum Set Updates {#special-considerations-during-quorum-set-updates} +## Special Considerations During Quorum Set Updates When you join the ranks of node operators, it's also important to join the conversation. The best way to do that: follow the`#validators` channel on the [Stellar Developer Discord](https://discord.gg/stellardev). If you can't do that for some reason, sign up for the [Stellar Validators Google Group](https://groups.google.com/forum/#!forum/stellar-validators). diff --git a/docs/validators/admin-guide/monitoring.mdx b/docs/validators/admin-guide/monitoring.mdx index 7867cf715..1c063e9be 100644 --- a/docs/validators/admin-guide/monitoring.mdx +++ b/docs/validators/admin-guide/monitoring.mdx @@ -17,7 +17,7 @@ You can access this information using commands and inspecting Stellar Core's out However you decide to monitor, the most important thing is that you have a system in place to ensure that your integration keeps ticking. -## General Node Information {#general-node-information} +## General Node Information If you run `$ stellar-core http-command 'info'`, the output will look something like this: @@ -83,7 +83,7 @@ Some notable fields from this `info` endpoint are: - `state`: the node's synchronization status relative to the network - `quorum`: summary of the state of the SCP protocol participants, which is the same information returned by the `quorum` command ([see below](#quorum-health)). -## Peer Information {#peer-information} +## Peer Information The `peers` command returns information on the peers your node is connected to. @@ -167,7 +167,7 @@ The output will look something like: } ``` -## Overlay Topology Survey {#overlay-topology-survey} +## Overlay Topology Survey There is a survey mechanism in the overlay that allows a validator to request connection information from other nodes on the network. The survey can be triggered from a validator, and will flood through the network like any other message, but will request information from other nodes about which nodes it is connected to and a brief summary of their per-connection traffic volumes. @@ -181,7 +181,7 @@ Additionally, the "stop/start collecting" messages contain a `nonce` field ident During the reporting phase, the surveyor sends `TimeSlicedSurveyRequestMessage`s to individual nodes to gather the information the node recorded during the collecting phase. -### Overlay Survey Script {#overlay-survey-script} +### Overlay Survey Script To simplify running an overlay survey, stellar-core ships with a script [`OverlaySurvey.py`](https://github.com/stellar/stellar-core/blob/master/scripts/OverlaySurvey.py) in the [`scripts` directory](https://github.com/stellar/stellar-core/tree/master/scripts). This script walks the network using the overlay survey HTTP endpoints to build a graph containing the topology of the overlay network. The script outputs this graph both in JSON format, as well as GraphML. You can analyze the GraphML file using a GraphML viewer such as [Gephi](https://gephi.org/). @@ -201,7 +201,7 @@ The arguments this example uses are: Therefore, this example will run a survey from a stellar-core node running on the local machine with a collecting phase duration of 20 minutes and output the results to `sr.json` and `gmlw.graphml`. -#### Attaching to a Running Survey {#attaching-to-a-running-survey} +#### Attaching to a Running Survey Use the `--startPhase` option to attach the script to an already running survey. This may be necessary if something happened during the running of the script that caused the script to terminate early (such as losing connection with the surveyor node). `--startPhase` has three possible values: @@ -209,7 +209,7 @@ Use the `--startPhase` option to attach the script to an already running survey. - `stopCollecting`: Immediately broadcast a `TimeSlicedSurveyStopCollectingMessage` for the currently running survey and begin surveying individual nodes for results. Use this option if your survey is currently in the collecting phase and you'd like to move it to the reporting phase. - `surveyResults`: Begin surveying individual nodes for results. Use this option if your survey is in the reporting phase. -#### More Survey Script Options {#more-survey-script-options} +#### More Survey Script Options The survey script contains additional subcommands and options to further analyze the survey results. You can find a complete list of subcommands by running: @@ -225,7 +225,7 @@ $ python3 OverlaySurvey.py -h for more info about any given subcommand. -### Example Survey Command Using HTTP Endpoints {#example-survey-command-using-http-endpoints} +### Example Survey Command Using HTTP Endpoints This section walks through an example of running an overlay survey by calling the survey HTTP endpoints directly. We highly recommend using the overlay survey script instead. This section may be useful to anyone who wants to modify the survey script, or anyone who is curious about the lower-level details of how the survey works and the data it includes. @@ -339,11 +339,11 @@ Some notable fields from this `getsurveyresult` endpoint are: - `lostSyncCount`: The number of times this node lost sync. - `isValidator`: Is this node a validator? -## Quorum Health {#quorum-health} +## Quorum Health To help node operators monitor their quorum sets and maintain the health of the overall network, Stellar Core also provides metrics on other nodes in your quorum set. You should monitor them to make sure they're up and running, and that your quorum set is maintaining good overlap with the rest of the network. -### Quorum Set Diagnostics {#quorum-set-diagnostics} +### Quorum Set Diagnostics The `quorum` command allows you to diagnose problems with the quorum set of the local node. @@ -402,7 +402,7 @@ The output will look something like: This output has two main sections: `qset` and `transitive`. The former describes the node and its quorum set. The latter describes the transitive closure of the node's quorum set. -### Per-node Quorum-set Information {#per-node-quorum-set-information} +### Per-node Quorum-set Information Entries to watch for in the `qset` section, which describe the node and its quorum set, are: @@ -436,7 +436,7 @@ stellar-core http-command 'quorum?node=@GABCDE' Overall network health can be evaluated by walking through all nodes and looking at their health. Note that this is only an approximation, as remote nodes may not have received the same messages (in particular: `missing` for other nodes is not reliable). -### Transitive Closure Summary Information {#transitive-closure-summary-information} +### Transitive Closure Summary Information When showing quorum-set information about the local node rather than some other node, a summary of the transitive closure of the quorum set is also provided in the `transitive` field. This has several important sub-fields: @@ -447,7 +447,7 @@ When showing quorum-set information about the local node rather than some other - `potential_split`: this will contain a pair of lists of validator IDs, which is a potential pair of disjoint quorums allowed by the current configuration. In other words, a possible split in consensus allowed by the current configuration. This may help narrow down the cause of the misconfiguration: likely it involves too-low a consensus threshold in one of the two potential quorums, and/or the absence of a mandatory trust relationship that would bridge the two. - `critical`: an "advance warning" field that lists nodes that _could cause_ the network to fail to enjoy quorum intersection, if they were misconfigured sufficiently badly. In a healthy transitive network configuration, this field will be `null`. If it is non-`null` then the network is essentially "one misconfiguration" (of the quorum sets of the listed nodes) away from no longer enjoying quorum intersection, and again, corrective action should be taken: careful adjustment to the quorum sets of _nodes that depend on_ the listed nodes, typically to strengthen quorums that depend on them. -### Detailed Transitive Quorum Analysis {#detailed-transitive-quorum-analysis} +### Detailed Transitive Quorum Analysis The quorum endpoint can also retrieve detailed information about the transitive quorum. This is a format that's easier to process than what `scp` returns, as it doesn't contain all SCP messages. @@ -528,17 +528,17 @@ Notable fields contained in this response are: - `value_id`: a unique ID for what the node is voting for (allows you to quickly tell if nodes are voting for the same thing) - `value`: what the node is voting for -## Using Prometheus {#using-prometheus} +## Using Prometheus Monitoring `stellar-core` using Prometheus is by far the simplest solution, especially if you already have a Prometheus server within your infrastructure. Prometheus is a free and open source time-series database with a simple yet incredibly powerful query language `PromQL`. Prometheus is also tightly integrated with Grafana, so you can render complex visualisations with ease. In order for Prometheus to scrape `stellar-core` application metrics, you will need to install the stellar-core-prometheus-exporter (`apt-get install stellar-core-prometheus-exporter`) and configure your Prometheus server to scrape this exporter (default port: `9473`). On top of that grafana can be used to visualize metrics. -### Install a Prometheus Server Within your Infrastructure {#install-a-prometheus-server-within-your-infrastructure} +### Install a Prometheus Server Within your Infrastructure Installing and configuring a Prometheus server is out of scope of this document, however it is a fairly simple process: Prometheus is a single Go binary which you can download from https://prometheus.io/docs/prometheus/latest/installation/. -### Install the `stellar-core-prometheus-exporter` {#install-the-stellar-core-prometheus-exporter} +### Install the `stellar-core-prometheus-exporter` The stellar-core-prometheus-exporter is an exporter that scrapes the `stellar-core` metrics endpoint (`http://localhost:11626/metrics`) and renders these metrics in the Prometheus text-based format available for Prometheus to scrape and store in its time series database. @@ -550,11 +550,11 @@ apt-get install stellar-core-prometheus-exporter You will need to open up port `9473` between your Prometheus server and all your Stellar Core nodes for your Prometheus server to be able to scrape metrics. -### Point Prometheus to stellar-core-prometheus-exporter {#point-prometheus-to-stellar-core-prometheus-exporter} +### Point Prometheus to stellar-core-prometheus-exporter Pointing your Prometheus instance to the exporter can be achieved by manually configuring a scrape job; however, depending on the number of hosts you need to monitor this can quickly become unwieldy. Luckily, the process can also be automated using Prometheus' various "service discovery" plugins. For example with AWS hosted instance you can use the `ec2_sd_config` plugin. -#### Manual {#manual} +#### Manual ```yaml - job_name: "stellar-core" @@ -569,7 +569,7 @@ Pointing your Prometheus instance to the exporter can be achieved by manually co application: "stellar-core" ``` -#### Using Service Discovery (EC2) {#using-service-discovery-ec2} +#### Using Service Discovery (EC2) ```yaml - job_name: stellar-core @@ -601,7 +601,7 @@ Pointing your Prometheus instance to the exporter can be achieved by manually co target_label: application ``` -### Create Alerting Rules {#create-alerting-rules} +### Create Alerting Rules Once Prometheus scrapes metrics we can add alerting rules. Recommended rules are [**here**](https://github.com/stellar/packages/blob/master/docs/stellar-core-alerting.rules) (require Prometheus 2.0 or later). Copy rules to _/etc/prometheus/stellar-core-alerting.rules_ on the Prometheus server and add the following to the prometheus configuration file to include the file: @@ -612,7 +612,7 @@ rule_files: Rules are documented in-line,and we strongly recommend that you review and verify all of them as every environment is different. -### Configure Notifications Using Alertmanager {#configure-notifications-using-alertmanager} +### Configure Notifications Using Alertmanager Alertmanager is responsible for sending notifications. Installing and configuring an Alertmanager server is out of scope of this document, however it is a fairly simple process. Official documentation is [here](https://github.com/prometheus/alertmanager/). @@ -654,14 +654,14 @@ receivers: In the above examples alerts with severity "critical" are sent to pagerduty and warnings are sent to slack. -### Useful Exporters {#useful-exporters} +### Useful Exporters You may find the below exporters useful for monitoring your infrastructure as they provide incredible insight into your operating system and database metrics. Installing and configuring these exporters is out of the scope of this document but should be relatively straightforward. - [node_exporter](https://prometheus.io/docs/guides/node-exporter/) can be used to track all operating system metrics. - [postgresql_exporter](https://github.com/wrouesnel/postgres_exporter) can be used to monitor the local stellar-core database. -### Visualize Metrics Using Grafana {#visualize-metrics-using-grafana} +### Visualize Metrics Using Grafana Once you've configured Prometheus to scrape and store your stellar-core metrics, you will want a nice way to render this data for human consumption. Grafana offers the simplest and most effective way to achieve this. Installing Grafana is out of scope of this document but is a very simple process, especially when using the [prebuilt apt packages](https://grafana.com/docs/installation/debian/#apt-repository) diff --git a/docs/validators/admin-guide/network-upgrades.mdx b/docs/validators/admin-guide/network-upgrades.mdx index a7f650c0c..86a3e6556 100644 --- a/docs/validators/admin-guide/network-upgrades.mdx +++ b/docs/validators/admin-guide/network-upgrades.mdx @@ -23,7 +23,7 @@ When a validator is armed to change network values, the output of `info` will co For a new value to be adopted, the same level of consensus between nodes needs to be reached as for transaction sets. -## Important Notes on Network Wide Settings {#important-notes-on-network-wide-settings} +## Important Notes on Network Wide Settings Changes to network wide settings have to be orchestrated properly between validators as well as non validating nodes. The general process validators have used to propose and vote on network settings is as follows: @@ -38,7 +38,7 @@ This careful orchestration plays an important part in the Stellar network's func For more information, take a look at how versioning takes into account network upgrades in [the `versioning.md` document](https://github.com/stellar/stellar-core/blob/master/docs/versioning.md) in the stellar-core GitHub repository. -## Upgrading Soroban Settings {#upgrading-soroban-settings} +## Upgrading Soroban Settings The mechanism to update Soroban settings is more complex than updating something like the `baseReserve`. The `upgrades` endpoint in stellar-core will require validators to vote on a serialized `ConfigUpgradeSetKey`, which contains a contractID and the SHA-256 hash of the `ConfigUpgradeSet` that will be applied to the existing settings. The serialized `ConfigUpgradeSet` must exist in the ledger as `Temporary` `ContractData` under the contractID specified earlier and with the `SCVal` `Bytes` key that contains the SHA-256 hash of the `ConfigUpgradeSet`. @@ -46,7 +46,7 @@ This means that someone wishing to propose a setting upgrade will need to create We have much more detail on the [next page](./soroban-settings.mdx) about _how_ to craft an upgrade proposal for these settings. Be sure to read and understand that. -## Example Upgrade Command {#example-upgrade-command} +## Example Upgrade Command By way of example, here is the `upgrades` command used to upgrade the protocol version to version 9 on January-31-2018. diff --git a/docs/validators/admin-guide/prerequisites.mdx b/docs/validators/admin-guide/prerequisites.mdx index 81a82a171..abaab5d32 100644 --- a/docs/validators/admin-guide/prerequisites.mdx +++ b/docs/validators/admin-guide/prerequisites.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 You can install Stellar Core a [number of different ways](./installation.mdx), and once you do, you can [configure](./configuring.mdx) it to participate in the network on a several [different levels](../README.mdx#types-of-nodes): it can be either a Basic Validator or a Full Validator. No matter how you install Stellar Core or what kind of node you run, however, you need to set up and connect to the peer-to-peer network and store the state of the ledger in a SQL [database](./configuring.mdx#database). -## Hardware Requirements {#hardware-requirements} +## Hardware Requirements :::info @@ -23,23 +23,23 @@ Stellar Core is designed to run on relatively modest hardware so that a whole ra _\* Assuming a 30-day retention window for data storage._ -## Network Access {#network-access} +## Network Access Stellar Core interacts with the peer-to-peer network to keep a distributed ledger in sync, which means that your node needs to make certain [TCP ports](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_ports) available for inbound and outbound communication. -### Inbound {#inbound} +### Inbound A Stellar Core node needs to allow all IPs to connect to its `PEER_PORT` over TCP. You can specify a port when you [configure] Stellar Core, but most people use the default, which is **11625**. -### Outbound {#outbound} +### Outbound A Stellar Core node needs to connect to other nodes on the internet via their `PEER_PORT` over TCP. You can find information about other nodes' `PEER_PORT`s on a network explorer like [Stellarbeat](https://stellarbeat.io/), but most use the default port for this as well, which is (again) **11625**. -## Internal System Access {#internal-system-access} +## Internal System Access Stellar Core also needs to connect to certain internal systems, though exactly how this is accomplished can vary based on your setup. -### Inbound {#inbound-1} +### Inbound - Stellar Core exposes an _unauthenticated_ HTTP endpoint on its `HTTP_PORT`. You can specify a port when you [configure] Stellar Core, but most people use the default, which is **11626**. - The `HTTP_PORT` is used by other systems (such as Horizon) to submit transactions, so this port may have to be exposed to the rest of your internal IP addresses. @@ -53,16 +53,16 @@ If you need to expose this endpoint to other hosts in your local network, we str ::: -### Outbound {#outbound-1} +### Outbound - Stellar Core requires access to a database (PostgreSQL, for example). If that database resides on a different machine on your network, you'll need to allow that connection. You'll specify the database when you [configure] Stellar Core. - You can safely block all other connections. -## Storage {#storage} +## Storage Most storage needs come from stellar-core's database backend, which needs to store the entire ledger state. For the most part, the contents of both the database and related directories (such as `buckets`) can be ignored, since they are completely managed by Stellar Core. In terms of storage space, 100 GB is enough (as of April 2024). -### Database {#database} +### Database The database is consulted during consensus, and modified atomically when a transaction set is applied to the ledger. It's random access, fine-grained, and fast. @@ -78,7 +78,7 @@ If you're using PostgreSQL, we recommend you configure your local database to be # max_connections = 150 ``` -### Buckets {#buckets} +### Buckets Stellar-core stores ledger state in the form of flat XDR files called "buckets." The bucket files are used for hashing and transmission of ledger differences to history archives. If BucketListDB is used, the `buckets` directory is also used as a primary database backend. If SQL is used, the `buckets` directory is only used for hashing and history archives, and simply represents a copy of the ledger state stored in SQL. diff --git a/docs/validators/admin-guide/publishing-history-archives.mdx b/docs/validators/admin-guide/publishing-history-archives.mdx index 18a93864a..69770bd28 100644 --- a/docs/validators/admin-guide/publishing-history-archives.mdx +++ b/docs/validators/admin-guide/publishing-history-archives.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 If you want to run a [Full Validator](../README.mdx#full-validator), you need to set up your node to publish a history archive. You can host an archive using a blob store such as Amazon's S3 or Digital Ocean's spaces, or you can simply serve a local archive directly via an HTTP server such as Nginx or Apache. If you're setting up a [Basic Validator](../README.mdx#basic-validator), you can skip this section. No matter what kind of node you're planning to run, make sure to set it up to `get` history, which is covered in [Environment Preparation](./environment-preparation.mdx). -## Caching and History Archives {#caching-and-history-archives} +## Caching and History Archives The _primary_ cost of running a validator will very likely be egress bandwidth. A crucial part of your strategy to manage those costs should be caching. You can significantly reduce these data transfer costs by using common caching techniques or a CDN. Three simple rules apply to caching the History archives: @@ -13,7 +13,7 @@ The _primary_ cost of running a validator will very likely be egress bandwidth. 2. Do not cache HTTP 4xx responses (`Cache-Control: no-cache`) 3. Cache everything else for as long as possible (**> 1 day**) -## Local History Archive Using nginx {#local-history-archive-using-nginx} +## Local History Archive Using nginx Here, we'll demonstrate how you can configure your node to store its history files in the local filesystem, and then publish that history using nginx for our webserver software. @@ -78,7 +78,7 @@ server { } ``` -## Amazon S3 History Archive {#amazon-s3-history-archive} +## Amazon S3 History Archive Now, let's demonstrate a configuration where your node stores its history files using Amazon's S3 service. You can then publish that history using an Amazon S3 static site, or again use nginx for your webserver software. This time, using nginx, we'll include some proxy and CDN configuration, as well. @@ -150,7 +150,7 @@ server { } ``` -## Backfilling a History Archive {#backfilling-a-history-archive} +## Backfilling a History Archive Given the choice, it's best to configure your history archive _prior to_ your node's initial sync with an existing network. That way your validator's history publishes as you join, and subsequently sync with, the network. @@ -189,7 +189,7 @@ As you allow your node to join the network again, you can watch it start publish At this stage your validator is successfully publishing its history, which enables other users to join the network using your archive. -## Complete History Archive {#complete-history-archive} +## Complete History Archive The [stellar-archivist](https://github.com/stellar/go/tree/master/tools/stellar-archivist) command line tool can be used to mirror, scan, and repair existing archives. Using the [SDF package repositories](https://github.com/stellar/packages), you can install `stellar-archivist` by running: diff --git a/docs/validators/admin-guide/running-node.mdx b/docs/validators/admin-guide/running-node.mdx index 0d02e8579..8d5145df0 100644 --- a/docs/validators/admin-guide/running-node.mdx +++ b/docs/validators/admin-guide/running-node.mdx @@ -3,7 +3,7 @@ title: Running sidebar_position: 60 --- -## Starting Your Node {#starting-your-node} +## Starting Your Node Once you've [set up your environment](./prerequisites.mdx), [configured your node](./configuring.mdx), set up your [quorum set](./configuring.mdx#choosing-your-quorum-set), and selected archives to `get` [history from](./environment-preparation.mdx#history-archives), you're ready to start Stellar Core. @@ -17,7 +17,7 @@ At this point, you're ready to observe your core node's activity as it joins the You may want to skip ahead and review the [Logging](./logging.mdx) page to familiarize yourself with Stellar Core's output. -## Interacting With Your Instance {#interacting-with-your-instance} +## Interacting With Your Instance When your node is running, you can interact with Stellar Core via an administrative HTTP endpoint. Commands can be issued using command-line HTTP tools such as `curl`, or by running a CLI command such as @@ -29,11 +29,11 @@ The HTTP endpoint is [not intended to be exposed to the public internet](./prere Details of available _HTTP_ endpoint commands can be found in the [stellar-core-GitHub repo](https://github.com/stellar/stellar-core/blob/master/docs/software/commands.md#http-commands). Additionally, [the commands page](./commands.mdx) contains an overview of some of the most useful _CLI_ commands (non-HTTP commands) for managing a running core node. -## Joining the Network {#joining-the-network} +## Joining the Network Your node will go through the following phases as it joins the network, and you can query for the output below by using the info endpoint mentioned [here](./monitoring.mdx#general-node-information) : -### Establish Connection to Other Peers. {#establish-connection-to-other-peers} +### Establish Connection to Other Peers. You should see `authenticated_count` increase. @@ -44,7 +44,7 @@ You should see `authenticated_count` increase. }, ``` -### Observing Consensus {#observing-consensus} +### Observing Consensus Until the node sees a quorum, it will say: @@ -77,7 +77,7 @@ After observing consensus, a new field `quorum` will display information about n "state" : "Catching up", ``` -### Catching up {#catching-up} +### Catching up This is a phase where the node downloads data from any configured archives. This phase begins with something like: @@ -101,7 +101,7 @@ The `CATCHUP_COMPLETE` and `CATCHUP_RECENT` config fields are mutually exclusive ::: -### Synced {#synced} +### Synced When the node is done catching up, its state will change to: diff --git a/docs/validators/admin-guide/soroban-settings.mdx b/docs/validators/admin-guide/soroban-settings.mdx index d433ee175..3ff065f85 100644 --- a/docs/validators/admin-guide/soroban-settings.mdx +++ b/docs/validators/admin-guide/soroban-settings.mdx @@ -7,7 +7,7 @@ import { Alert } from "@site/src/components/Alert"; Soroban has a large collection of settings stored on-ledger that can be modified through a validator vote. Here you can find out how to propose a new settings upgrade as well as how to examine a proposed upgrade. You can also look at the [Commands page](./commands.mdx) for more details on the stellar-core commands used below. -## Propose a Settings Upgrade {#propose-a-settings-upgrade} +## Propose a Settings Upgrade This section will describe how to propose a settings upgrade, but take a look at the [Upgrading the Network page](./network-upgrades.mdx#upgrading-soroban-settings) for more information on how the settings upgrade mechanism works internally. @@ -17,11 +17,11 @@ If you are being asked to vote for an upgrade, please move on to the [Examine a -## Helper Script {#helper-script} +## Helper Script A script to help you create the transactions below is available [in the stellar-core GitHub repo](https://github.com/stellar/stellar-core/blob/master/scripts/settings-helper.sh), with usage details [also available](https://github.com/stellar/stellar-core/blob/master/scripts/README.md). We've saved the information below for now, because it's important to be aware of how the underlying process to generate the transactions works in case the script has some issues. -### 1. Create an Upgrade Set {#1-create-an-upgrade-set} +### 1. Create an Upgrade Set The `stellar` CLI tool allows for the use of a JSON input file to encode a collection of Soroban settings into an base64-encoded string representing the XDR type `ConfigUpgradeSet`. You can use the [`pubnet_phase1.json`] and [`pubnet_phase2.json`] files as a starting point to formulate your upgrade proposal. You can also pull directly from a running core node using `http-command 'sorobaninfo?format=upgrade_xdr' | stellar-xdr decode --type ConfigUpgradeSet --output json-formatted`. This will allow you to get the exact settings running on that core node in JSON format, making it easier to change only the value you want to. Once you have your JSON file with updated values, use the following command to create the required upgrade set XDR: @@ -49,7 +49,7 @@ You can also download a [precompiled binary] of the latest release for your syst -### 2. Generate Settings Upgrade Transactions {#2-generate-settings-upgrade-transactions} +### 2. Generate Settings Upgrade Transactions You can use stellar-core's `get-settings-upgrade-txs` command to create a series of transactions that will: @@ -100,7 +100,7 @@ AAAAAgAAAABi/B0L0JGythwN1lY0aypo19NHxvLCyO5tBEc...F9wX14QAAAAARAAAAAwAAAAAAAAAAA nfyIVkHBNlHcyKH+8oKgrgJmA/MnLCW3E4Fhg4XYTkqZa2MyqzRdB2+mN3DOKUFKtZIAXp6o3DHrkgR0mo7rUw== ``` -### 3. Submit Settings Upgrade Transactions {#3-submit-settings-upgrade-transactions} +### 3. Submit Settings Upgrade Transactions These four transactions can then be submitted to the network through your node. Replace the blob placeholders below with the `TransactionEnvelope`s in lines 1, 3, 5, and 7. @@ -117,7 +117,7 @@ http-command 'tx?blob=' http-command 'tx?blob=' ``` -### 4. Verify Proposed Upgrades {#4-verify-proposed-upgrades} +### 4. Verify Proposed Upgrades You can verify that the proposed upgrades have been set up using stellar-core's `dumpproposedsettings` command, providing the `ConfigUpgradeSetKey` XDR string from line 9 above: @@ -125,7 +125,7 @@ You can verify that the proposed upgrades have been set up using stellar-core's http-command 'dumpproposedsettings?blob=' ``` -### 5. Schedule the Upgrades {#5-schedule-the-upgrades} +### 5. Schedule the Upgrades Now you can schedule the upgrade on all the required validators using stellar-core's `upgrades` command, providing the `ConfigUpgradeSetKey` output from line 9 above and an agreed upon time in the future: @@ -133,13 +133,13 @@ Now you can schedule the upgrade on all the required validators using stellar-co http-command 'upgrades?mode=set&upgradetime=YYYY-MM-DDTHH:MM:SSZ&configupgradesetkey=' ``` -### 6. Update Stellar Expert {#6-update-stellar-expert} +### 6. Update Stellar Expert One of the most-used methods of "watching" an upgrade take place for the network's Soroban settings is the [Protocol History page] on [stellar.expert]. In order to make sure that page gets updated with the proposed upgrades, please fill out a PR against [this repository]. -### Debugging {#debugging} +### Debugging Once the four transactions are run, you should see the proposed upgrade when running the `dumpproposedsettings` command ([see step 4 above](#4-verify-proposed-upgrades)). If you don't, then either one or more of the transactions above failed during application, or the upgrade is invalid. @@ -153,7 +153,7 @@ You should confirm what caused the failure by looking at the `TransactionResult` If the transactions succeeded but the `dumpproposedsettings` command still returns an error, then the upgrade is invalid. The error reporting here needs to be improved, but the validity checks happen [here](https://github.com/stellar/stellar-core/blob/3007c595c2fe9b53502aa0daf8089d119a9c37cb/src/herder/Upgrades.cpp#L1451). -## Examine a Proposed Upgrade {#examine-a-proposed-upgrade} +## Examine a Proposed Upgrade You can use stellar-core's `dumpproposedsettings` command along with a base64-encoded `ConfigUpgradeSetKey` XDR string to query a proposed upgrade: @@ -161,7 +161,7 @@ You can use stellar-core's `dumpproposedsettings` command along with a base64-en http-command 'dumpproposedsettings?blob=A6MvjFLujnqaZa5hacafWyYwhpk4cgRpyu0z6ilZ0pm1S7fmjSNnsyjGwGodLGiD8ss8S1AHiOBBb6GQbOeMbw==' ``` -## Examine Current Settings {#examine-current-settings} +## Examine Current Settings You can also get the current Soroban settings to compare against by using stellar-core's `sorobaninfo`. diff --git a/docs/validators/tier-1-orgs.mdx b/docs/validators/tier-1-orgs.mdx index 025a1adee..95c27b760 100644 --- a/docs/validators/tier-1-orgs.mdx +++ b/docs/validators/tier-1-orgs.mdx @@ -11,7 +11,7 @@ To become a Tier 1 organization, a team running validators must convince enough As a steward of the Stellar network, the SDF works closely with Tier 1 organizations to ensure the health of the network, maintain robust quorum intersection, and build in redundancy to minimize network disruptions. This guide outlines the minimum requirements recommended by the SDF in order to be a Tier 1 organization. However, in the end, the SDF on its own cannot add or remove a Tier 1 organization; this depends on the quorum sets of many other organizations in the network. -## Why Three Validators {#why-three-validators} +## Why Three Validators The most important recommendation for a Tier 1 organization is to set up and maintain three full validators. Why three? @@ -19,13 +19,13 @@ On Stellar, validators choose to trust organizations when they configure their q Here’s what else Tier 1 organizations should expect of one another: -## Publish History Archives {#publish-history-archives} +## Publish History Archives In addition to participating in the Stellar Consensus Protocol, a full validator publishes an archive of network transactions. To do that, you need to configure Stellar Core to record history to a publicly accessible archive, and add the location of that archive to your stellar.toml. We recommend that, as a Tier 1 organization, you should set each of your nodes to record history to a separate archive. Public archives make the network more resilient: when new nodes come online, or when existing nodes lose synch, they need to consult an archive to figure out what they missed. Sharing snapshots of the ledger, which detail transactions and their results, allows those nodes to catch up, and more archives mean more redundancy and greater decentralization. Plus, sharing history keeps everyone honest. -## Set Up a Safe Quorum Set {#set-up-a-safe-quorum-set} +## Set Up a Safe Quorum Set For simplicity, we’re recommending that every Tier 1 node use the same quorum set configuration, which is made up of inner quorum sets representing each Tier 1 organization. @@ -33,13 +33,13 @@ To configure a quorum set for your validator, we recommend including several Tie To see what the current recommended quorum set looks like, check out the [example Full Validator config file](https://github.com/stellar/packages/blob/master/docs/examples/pubnet-validator-full/stellar-core.cfg). -## Declare Your Node {#declare-your-node} +## Declare Your Node [SEP-20](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0020.md) is an open spec that explains how self-verification of validator nodes works. The fields it specifies are pretty simple: you set the home domain of your validator’s Stellar account to your website, where you publish information about your node and your organization in a stellar.toml file. It’s an easy way to propagate information, and it harnesses the network to allow other participants to discover your node and add it to their quorum sets without the need for a centralized database. -## Keep Your Nodes Up To Date {#keep-your-nodes-up-to-date} +## Keep Your Nodes Up To Date Running a validator requires vigilance. You need to keep an eye on your nodes, keep them up to date with the latest version of Stellar Core, and check in on public channels for information about what’s currently happening with other validators. As organizations join or leave the network, you might need to update the quorum set configuration of your validators to ensure that your validators have robust quorum intersection with Tier 1 and robust quorum availability. @@ -52,7 +52,7 @@ We always announce new Stellar Core releases in those channels. You can also fin It’s also critical that you pay attention to information about what those updates mean: often, you’ll need to set your validators to vote on something timely, such as when to vote to upgrade to a new protocol version, or how high to set the operations-per-ledger limit. -## Coordinate With Other Validators {#coordinate-with-other-validators} +## Coordinate With Other Validators Whether you run a trio of validators or a single node, it’s important that you coordinate with other validators when you make a significant change or notice something wrong. You should let them know when you plan to: @@ -63,7 +63,7 @@ Letting other validators know when you plan to take your node down for maintenan Letting other validators know when you plan to change your quorum set allows them to respond, adjust, and think through the implications of the change. For the Stellar network to expand safely, the SDF recommends that validators coordinate off-chain to maintain good quorum intersection. -## Monitor your quorum set {#monitor-your-quorum-set} +## Monitor your quorum set We recommend using Prometheus to scrape and store your stellar-core metrics, and Grafana to render that data for human consumption. You can find step-by-step instructions for setting up monitoring and alerts in [Monitoring and Diagnostics](./admin-guide/monitoring.mdx), along with links to Grafana dashboards we’ve created to make things easier. @@ -71,7 +71,7 @@ You can also use [Stellarbeat](https://stellarbeat.io) to view validators’ quo You should do regular check-ins on your quorum set. If nodes have bad uptime or prove otherwise unreliable, you may need to remove them from your quorum set so that you don’t get stuck and so that the network doesn’t halt. You may also want to add new organizations that come online and prove reliable. If you plan to do either of those things, remember to communicate and coordinate with other validators. -## Get in touch {#get-in-touch} +## Get in touch If you think you can be a Tier 1 organization, let us know on the `#validators` channel on the [Stellar Developers' Discord](https://discord.gg/stellardev). Community members can help you through the process, and once you’re up and running, SDF team members will help you join Tier 1, so that you can take your rightful place as a pillar of the network. Once you’ve proven that you are responsive, reliable, and maintain good uptime, the SDF may recommend that other validators adjust their quorum set to include your validators. diff --git a/platforms/anchor-platform/CONTRIBUTING.md b/platforms/anchor-platform/CONTRIBUTING.md index c274105f3..f246fd3bc 100644 --- a/platforms/anchor-platform/CONTRIBUTING.md +++ b/platforms/anchor-platform/CONTRIBUTING.md @@ -11,7 +11,7 @@ We're super glad to have you here, and hopefully this document will help you understand how (and more importantly _where_) to make the needed changes to our documentation. Let's start off with a bit of Docusaurus vocabulary, shall we? -## TL;DR {#tldr} +## TL;DR - For _unreleased_ versions of Anchor Platform: - Add and edit docs in `/platforms/anchor-platform` @@ -38,7 +38,7 @@ want to be judicious about which files you add to your commit. yarn ap:versions:regen ``` -## Table of Contents {#table-of-contents----omit-in-toc---} +## Table of Contents - [TL;DR](#tldr) - [More About Docusaurus than You Ever Wanted to Know](#more-about-docusaurus-than-you-ever-wanted-to-know) @@ -59,12 +59,12 @@ yarn ap:versions:regen - [Update Documentation Pages](#update-documentation-pages) - [Update API Specification](#update-api-specification) -## More About Docusaurus than You Ever Wanted to Know {#more-about-docusaurus-than-you-ever-wanted-to-know} +## More About Docusaurus than You Ever Wanted to Know I know it can feel a bit mysterious, but here's some knowledge and context to help your understanding of what's ahead. -### Versions Nomenclature {#versions-nomenclature} +### Versions Nomenclature This is how Docusaurus defines these terms, so that's what I'll use in this document, as well. @@ -79,7 +79,7 @@ document, as well. available at the `/platforms/anchor-platform` URL. This is the "stable" set of docs. -### Plugins {#plugins} +### Plugins There are two Docusaurus plugins at play here: @@ -95,7 +95,7 @@ Both of these plugin configurations have been broken out into a `/config/anchorPlatform.config.ts` file, to ease management of them and de-clutter somewhat the main `docusaurus.config.ts` file. -### Instances {#instances} +### Instances This is where it gets a bit more "in the weeds," but I promise this part is helpful to know. Both of the [plugins](#plugins) I mentioned above are really @@ -104,7 +104,7 @@ elsewhere in our docs site for Horizon, SDP, and just "regular" docs. It's not _generally_ important to consider different plugin instances, but it _is_ **quite relevant** when we discuss links. So... -### Links {#links} +### Links Most often, **especially in versioned docs**, it's important to [link to other docs by _relative_ file paths](https://docusaurus.io/docs/versioning#link-docs-by-file-paths). @@ -120,7 +120,7 @@ So, in practical terms: convention, we use _absolute_ paths for this, too, to make it a little more obvious when this behavior is taking place. -#### Examples {#examples} +#### Examples This should help to make it a bit clearer. @@ -167,12 +167,12 @@ This should help to make it a bit clearer. Read more about links [here](https://docusaurus.io/docs/markdown-features/links) (especially toward the bottom of the page). -## Directories to Know {#directories-to-know} +## Directories to Know There are a few directories that _all_ feed into the end product that is our versioned AP documentation. -### Directories You Already Know About {#directories-you-already-know-about} +### Directories You Already Know About - `/platforms/anchor-platform` This is where you are now, and traditionally has been the place to modify any of the markdown content that becomes our AP docs @@ -219,7 +219,7 @@ versioned AP documentation. "old" versions will likely just need to be made in those versioned specfiles for now (more on that in the next section). -### New Shiny Directories {#new-shiny-directories} +### New Shiny Directories - `/ap_versioned_sidebars` We can pretty well breeze right past this one. When you make a new version of the docs, Docusaurus stores a copy of the sidebar at @@ -235,13 +235,13 @@ versioned AP documentation. or update in a released version of the docs, you'll need to update accordingly here. -## Making New Versions {#making-new-versions} +## Making New Versions As noted in the [TL;DR](#tldr), this process is automated with the `VERSION=3.0.0 yarn ap:versions:new` script. However, here's what's happening under the hood of that script. -### Use Docusaurus to "Tag" a New Release {#use-docusaurus-to-tag-a-new-release} +### Use Docusaurus to "Tag" a New Release It's actually pretty simple! Use the Docusaurus CLI to make a new release: @@ -255,13 +255,13 @@ well "work" to get the new version displayed on the site. Any future changes to the 3.0.0 version of the docs should be made within the `/ap_versioned_docs` directory. -### Configure the OpenAPI plugin {#configure-the-openapi-plugin} +### Configure the OpenAPI plugin We'll also want to be able to modify/update/re-generate the API documentation if the need arises. So, we'll need to configure that `docusaurus-plugin-openapi-docs` plugin instance accordingly. -#### Copy the (bundled) OpenAPI Specfiles to the Versioned Directory {#copy-the-bundled-openapi-specfiles-to-the-versioned-directory} +#### Copy the (bundled) OpenAPI Specfiles to the Versioned Directory At the moment, it's just as simple as copying the files: @@ -274,7 +274,7 @@ cp openapi/anchor-platform/bundled-custody.yaml openapi/anchor-platform/versions > Notice how we're copying the _bundled_ file, not the _main_ file. This makes > sure the versioned file contains everything it needs. -#### Add Configuration to the OpenAPI Plugin Instance {#add-configuration-to-the-openapi-plugin-instance} +#### Add Configuration to the OpenAPI Plugin Instance > _Note_: These `versions` parts of the configuration are now generated > dynamically, using a `makeVersions()` function, so these manual config steps @@ -308,9 +308,9 @@ ap_platform: { } ``` -## Updating Old Versions {#updating-old-versions} +## Updating Old Versions -### Update Documentation Pages {#update-documentation-pages} +### Update Documentation Pages Let's say I find a misspelling in the `v2.8.4` Admin Guide documentation. Find the relevant file in the `/ap_versioned_docs/version-2.8.4` directory, fix it @@ -321,7 +321,7 @@ and commit. Content updates are pretty easy here. > here: > `/ap_versioned_docs/version-2.8.4/api-reference/platform/rpc/anchor-platform.openrpc.json` -### Update API Specification {#update-api-specification} +### Update API Specification This is a little more involved, but not much. Find and change the relevant part(s) of the diff --git a/platforms/anchor-platform/admin-guide/architecture.mdx b/platforms/anchor-platform/admin-guide/architecture.mdx index 7e1fd14b7..d9abf6435 100644 --- a/platforms/anchor-platform/admin-guide/architecture.mdx +++ b/platforms/anchor-platform/admin-guide/architecture.mdx @@ -3,21 +3,21 @@ title: "Architecture" sidebar_position: 20 --- -## Architecture {#architecture} +## Architecture Before starting with the Anchor Platform, let's get familiar with the architecture. This section will describe the components involved and how they interact. -### Fundamental Architecture {#fundamental-architecture} +### Fundamental Architecture The following architectural components are required for all deployments of the Anchor Platform. [![fundamental anchor platform architecture](../assets/anchor-platform-architecture-1.png)](../assets/anchor-platform-architecture-1.png) -#### Client {#client} +#### Client The client is an application, such as a wallet or remittance sender, that acts on behalf of a user and makes requests to the system. Clients make requests to the SEP server component of the Anchor Platform using sets of standards called [SEPs][seps] (Stellar Ecosystem Proposals). -#### SEP Server {#sep-server} +#### SEP Server The SEP server is a client-facing server and therefore needs to be accessible from an external network. The SEP server processes user requests and manages the state of transactions they initiate. When the SEP server needs to provide information it doesn't have to the client, such as the exchange rate for an asset pair or the KYC status of a customer, it makes synchronous [callback][callback-api] requests to the business server and returns the information in a SEP-compliant format. @@ -27,29 +27,29 @@ The SEP server will never store any sensitive information, such as KYC (PII), in ::: -#### Business Server {#business-server} +#### Business Server The business server is a service that you (the business) must implement to connect the Anchor Platform with your internal systems. The business server responds to callback requests sent by the SEP server, such as requests for a quote, receives events sent by event service, such as notification of a received payment to your Stellar account, and provides updates to the platform server when off-chain events occur, such as the initiation of a bank transfer to a customer. -#### Platform Server {#platform-server} +#### Platform Server The platform server is an internal component. It should be hosted in a private network and should not be accessible from the Internet. This server enables the business to fetch and update the state of transactions using its [API][platform-api]. -#### Database {#database} +#### Database The Anchor Platform uses a PostgreSQL database to store Stellar events and entities. It is primary used to store transactions. -### Complete Architecture {#complete-architecture} +### Complete Architecture In addition to the components described above, the Anchor Platform includes several other components that offer additional functionality. Your business can chose to which of the additional components to use, but the diagram below visualizes the architecture of the system if all components are utilized. [![complete anchor platform architecture](../assets/anchor-platform-architecture-2.png)](../assets/anchor-platform-architecture-2.png) -#### Event Service {#event-service} +#### Event Service The event service enables the Anchor Platform to send HTTP webhooks to registered clients and your business server when the state of transactions change, removing the need for clients and/or your business server to poll the Anchor Platform's APIs. It works by reading events from published to a Kafka topic by the other Anchor Platform components. [Read more][events] about using the event service. -#### Custody Server {#custody-server} +#### Custody Server The custody server connects to enterprise wallet providers, such as Fireblocks, to send and receive payments for transactions initiated via the Anchor Platform. This service is an alternative to the Stellar Observer for businesses who use one of the supported providers. In addition to the functionality offered by the Stellar Observer, the Custody Server can also facilitate outbound payments to client's Stellar accounts. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. @@ -57,7 +57,7 @@ If you already have an integration with your wallet provider, then this componen Currently the only supported provider is Fireblocks. -#### Stellar Observer {#stellar-observer} +#### Stellar Observer The Stellar observer, an alternative to the custody server pictured above, monitors the Stellar blockchain using Horizon, automatically detects user payments sent to the business, and updates the corresponding transactions in the Anchor Platform's database. If you also use the [events] service, payments to your accounts will trigger a HTTP callback made to your business server. diff --git a/platforms/anchor-platform/admin-guide/custody-services/configuration.mdx b/platforms/anchor-platform/admin-guide/custody-services/configuration.mdx index 4a45bf803..05483f0f6 100644 --- a/platforms/anchor-platform/admin-guide/custody-services/configuration.mdx +++ b/platforms/anchor-platform/admin-guide/custody-services/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 10 import { CodeExample } from "@site/src/components/CodeExample"; -## Custody Server Configuration {#custody-server-configuration} +## Custody Server Configuration If you want to use an external custody service to store and manage your wallets, then you need to deploy one more service - the Custody Server. @@ -66,7 +66,7 @@ docker run stellar/anchor-platform:latest --custody-server -## Anchor Platform Configuration {#anchor-platform-configuration} +## Anchor Platform Configuration Update the configuration file of the Anchor Platform with the deposit info generator type for SEP-24 and SEP-31. Also, you need to configure a trustline check, if you use JSON-RPC. @@ -114,7 +114,7 @@ custody: ::: -## Kotlin Reference Server Configuration {#kotlin-reference-server-configuration} +## Kotlin Reference Server Configuration Update the configuration file of the Kotlin Reference Server to enable custody integration. diff --git a/platforms/anchor-platform/admin-guide/custody-services/fireblocks/example.mdx b/platforms/anchor-platform/admin-guide/custody-services/fireblocks/example.mdx index 9b3b8bf30..613d31bca 100644 --- a/platforms/anchor-platform/admin-guide/custody-services/fireblocks/example.mdx +++ b/platforms/anchor-platform/admin-guide/custody-services/fireblocks/example.mdx @@ -8,7 +8,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; [comment]: # "Sequence diagram definitions are located in /static/definitions folder" [comment]: # "To updated them, use https://sequencediagram.org" -### SEP-24 deposit flow with webhook: {#sep-24-deposit-flow-with-webhook} +### SEP-24 deposit flow with webhook: - request_offchain_funds - notify_offchain_funds_received @@ -16,7 +16,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_webhook](../../../assets/sequence_diagram_sep24_deposit_webhook.png)](../../../assets/sequence_diagram_sep24_deposit_webhook.png)
-### SEP-24 deposit flow with reconciliation job: {#sep-24-deposit-flow-with-reconciliation-job} +### SEP-24 deposit flow with reconciliation job: - request_offchain_funds - notify_offchain_funds_received @@ -24,27 +24,27 @@ import { CodeExample } from "@site/src/components/CodeExample"; - notify_onchain_funds_sent [![sequence_diagram_sep24_deposit_job](../../../assets/sequence_diagram_sep24_deposit_job.png)](../../../assets/sequence_diagram_sep24_deposit_job.png)
-### SEP-24 withdrawal flow with webhook: {#sep-24-withdrawal-flow-with-webhook} +### SEP-24 withdrawal flow with webhook: - do_stellar_payment - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_webhook](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)](../../../assets/sequence_diagram_sep24_withdrawal_webhook.png)
-### SEP-24 withdrawal flow with reconciliation job: {#sep-24-withdrawal-flow-with-reconciliation-job} +### SEP-24 withdrawal flow with reconciliation job: - request_onchain_funds - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep24_withdrawal_job](../../../assets/sequence_diagram_sep24_withdrawal_job.png)](../../../assets/sequence_diagram_sep24_withdrawal_job.png)
-### SEP-31 receive flow with webhook: {#sep-31-receive-flow-with-webhook} +### SEP-31 receive flow with webhook: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_webhook](../../../assets/sequence_diagram_sep31_receive_webhook.png)](../../../assets/sequence_diagram_sep31_receive_webhook.png)
-### SEP-31 receive flow with reconciliation job: {#sep-31-receive-flow-with-reconciliation-job} +### SEP-31 receive flow with reconciliation job: - notify_onchain_funds_received - notify_offchain_funds_sent [![sequence_diagram_sep31_receive_job](../../../assets/sequence_diagram_sep31_receive_job.png)](../../../assets/sequence_diagram_sep31_receive_job.png) diff --git a/platforms/anchor-platform/admin-guide/events/delivery.mdx b/platforms/anchor-platform/admin-guide/events/delivery.mdx index 3c5f30142..cd6d3148e 100644 --- a/platforms/anchor-platform/admin-guide/events/delivery.mdx +++ b/platforms/anchor-platform/admin-guide/events/delivery.mdx @@ -3,7 +3,7 @@ title: "Delivery Guarantees" sidebar_position: 30 --- -## Delivery Guarantees {#delivery-guarantees} +## Delivery Guarantees Depending on the messaging system you use, there will be different delivery guarantees. the event service uses Kafka as the messaging system, so the delivery guarantees will depend on the producer configuration and the broker configuration that you use. Depending on the number of partitions configured for the `TRANSACTION` topic, the events may be delivered out of order. @@ -15,11 +15,11 @@ Any transaction logic that depends on the order should use the transaction `stat Next subsections will describe the delivery guarantees from the client and the business server perspective. -### Client Delivery Guarantees {#client-delivery-guarantees} +### Client Delivery Guarantees For each client, the event service will attempt to deliver each event up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the client is not reachable after three attempts, the event service will no longer attempt to deliver any events to that client. -### Business Server Delivery Guarantees {#business-server-delivery-guarantees} +### Business Server Delivery Guarantees The event service will attempt to deliver each event to the businesss server up to three times with an exponential backoff. If the event is not delivered after three attempts due to HTTP 4xx or 5xx errors, the event will be skipped. If the business server is not reachable after three attempts, the event service will no longer attempt to deliver any events to the business server. diff --git a/platforms/anchor-platform/admin-guide/events/integration.mdx b/platforms/anchor-platform/admin-guide/events/integration.mdx index 10c0951f6..98c919e72 100644 --- a/platforms/anchor-platform/admin-guide/events/integration.mdx +++ b/platforms/anchor-platform/admin-guide/events/integration.mdx @@ -7,11 +7,11 @@ This guide will walk you through integrating with the event service to start rec It assumes familiarity with Kafka and will not cover how to set up a Kafka cluster. -## Requirements {#requirements} +## Requirements Anchor Platform will send events to the `TRANSACTION` Kafka topic. The event service will consume events from this topic and send them to the appropriate endpoints. -## Configuration {#configuration} +## Configuration First, the event service's Kafka producer need to be configured using the `event.queue` section of the configuration file or setting the environment variables. The following is the set of required environment variables needed to configure the event service's Kafka producer: @@ -61,11 +61,11 @@ event_processor: This will enable the event processor to start processing events from `TRANSACTION` topic. In this example, the event processor will send events to client and business server callback endpoints. -## Receiving Events {#receiving-events} +## Receiving Events The event service can be used to send events to client and business server callback endpoints. The event service will send events to these endpoints as HTTP POST requests with the event data in the request body. -### As a Client Application {#as-a-client-application} +### As a Client Application Client applications can receive updates about their users' transactions and customer information. The schema of the event data will depend on the type of event being sent. @@ -73,7 +73,7 @@ To receive events as a client application, you will need to expose callback URLs Anchor Platform will only send events to clients listed in the client configuration. See the [client configuration documentation][clients-config] for more information. -#### Callback Signing {#callback-signing} +#### Callback Signing Anchor Platform signs the callback requests it sends to client applications. The signature is included in the `Signature` header of the request. The callback URL signature specification can be found in the corresponding SEP protocol specifications. @@ -82,13 +82,13 @@ Anchor Platform signs the callback requests it sends to client applications. The - [SEP-0024](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#url-callback-signature) - [SEP-0031](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#url-callback-signature) -### As a Business Server {#as-a-business-server} +### As a Business Server In addition to SEP transaction status updates, business servers can receive events about SEP-31 quote creation or SEP-12 customer information updates. The schema of the event data will depend on the type of event being sent. Visit the [Event API documentation](../../api-reference/callbacks/post-event.api.mdx) for more information about the schema of the event data. To receive events as a business server, you will need to expose a callback URL that the event service can send events to. The event service will send a POST request to this endpoint with the event data in the request body. -#### Configuration {#configuration-1} +#### Configuration The event service's callback API can be configured using the `callback_api` section of the Anchor Platform configuration file or setting the environment variables. diff --git a/platforms/anchor-platform/admin-guide/getting-started.mdx b/platforms/anchor-platform/admin-guide/getting-started.mdx index b2bbcc22e..baf963cda 100644 --- a/platforms/anchor-platform/admin-guide/getting-started.mdx +++ b/platforms/anchor-platform/admin-guide/getting-started.mdx @@ -3,7 +3,7 @@ title: "Getting Started" sidebar_position: 30 --- -## Installation {#installation} +## Installation import { CodeExample } from "@site/src/components/CodeExample"; @@ -17,7 +17,7 @@ docker pull stellar/anchor-platform:latest
-## Set Up the Development Environment {#set-up-the-development-environment} +## Set Up the Development Environment In this guide we'll use [docker compose][docker-compose] for simplicity, but you can run the Anchor Platform using other tools that support docker as well, such as [minikube] or a full-blown [kubernetes] cluster. @@ -54,7 +54,7 @@ The `--sep-server` option tells the Anchor Platform to make the API endpoints de The `--platform-sever` option makes the Platform API available, which is the backend API your service(s) will use to communicate with the Anchor Platform. It will be available on port 8085 -## Configuration {#configuration} +## Configuration The Anchor Platform supports two approaches for configuration: @@ -112,7 +112,7 @@ version: 1 -### Changing Port of the Platform Server {#changing-port-of-the-platform-server} +### Changing Port of the Platform Server For example, let's change port of the platform server. @@ -139,7 +139,7 @@ platform_server: -### Specify Your Service's Assets {#specify-your-services-assets} +### Specify Your Service's Assets Lets add the assets your Anchor Platform deployment will utilize. This configuration is specified in a YAML file. If you're only using the Anchor Platform for hosting a SEP-1 stellar.toml file or for running SEP-10 Stellar Authentication, you can skip this step. @@ -194,7 +194,7 @@ assets: -### Add Data Persistence {#add-data-persistence} +### Add Data Persistence The Anchor Platform supports [PostgreSQL][postgresql] and [Aurora PostgreSQL][aurora-postgresql] for use in production, but also supports [H2][h2] or [SQLite][sqlite] for use in development. For managing migrations, the Anchor Platform uses [Flyway][flyway]. The latest version of PostgreSQL supported by Flyway is PostgreSQL 14. @@ -308,7 +308,7 @@ docker compose up You should see the logs reporting a successful connection to the postgres database. -### Configure Platform API Authentication {#configure-platform-api-authentication} +### Configure Platform API Authentication To facilitate cross-border payments or deposit & withdrawal transactions, your business will need to fetch and update transaction records from the Anchor Platform's internal API. Currently, the `--sep-server` option makes public SEP APIs, while internal Platform API available on the Platform server, started by `--platform-server` option. Business should make Platform Server accessible only in the internal network, however it's possible to add authentication for accessing the internal Platform API. @@ -329,7 +329,7 @@ When making requests to the Platform API, add a JWT signed by the secret defined `PLATFORM_API_BASE_URL` uses `platform` instead of `localhost` as the host because you'll be making requests to the Platform API within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls. -### Passing JVM flags {#passing-jvm-flags} +### Passing JVM flags Anchor Platform uses JVM to run. Sometimes, it's desired to change JVM flags to run the service. To do so, set environmental variable `JVM_FLAGS` to appropriate value diff --git a/platforms/anchor-platform/admin-guide/sep10/README.mdx b/platforms/anchor-platform/admin-guide/sep10/README.mdx index d0acf0529..9d30c9f53 100644 --- a/platforms/anchor-platform/admin-guide/sep10/README.mdx +++ b/platforms/anchor-platform/admin-guide/sep10/README.mdx @@ -5,7 +5,7 @@ sidebar_position: 50 import { CodeExample } from "@site/src/components/CodeExample"; -## Enable Stellar Authentication {#enable-stellar-authentication} +## Enable Stellar Authentication Stellar-based wallet applications create authenticated sessions with Stellar anchors by proving they, or their users, have sufficient control over a Stellar account. Once authenticated, the wallet application uses a session token provided by the anchor in subsequent requests to the anchor's standardized services. @@ -35,7 +35,7 @@ By default, the Anchor Platform allows anyone with a Stellar account to authenti ::: -## Config With Client Attribution {#config-with-client-attribution} +## Config With Client Attribution `SEP10_CLIENT_ATTRIBUTION_REQUIRED` informs the Anchor Platform whether it should allow users of noncustodial wallets to authenticate without the wallet also identifying itself. @@ -127,7 +127,7 @@ CLIENTS[3]_DOMAINS=noncustodial-client2.com `CLIENTS` is the list of outside wallet servers or clients for the Anchor server to safely communicate with. -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-10 functionality is supported by your business. diff --git a/platforms/anchor-platform/admin-guide/sep24/configuration.mdx b/platforms/anchor-platform/admin-guide/sep24/configuration.mdx index b8d012f90..41ea33561 100644 --- a/platforms/anchor-platform/admin-guide/sep24/configuration.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Next, let's modify `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-24 functionality is supported by your business, and they also need to know all currencies you support. @@ -46,7 +46,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -## Enable Hosted Deposits & Withdrawals {#enable-hosted-deposits--withdrawals} +## Enable Hosted Deposits & Withdrawals Now you're ready to enable hosted deposits and withdrawals via the SEP-24 API. Specify the following in your `dev.assets.yaml` file, and change the values depending on your preferences. This example asset file will enable support for Circle's USDC and a fiat USD. @@ -115,7 +115,7 @@ SEP24_INITIAL_USER_DEADLINE_SECONDS=1209600 `SEP24_INITIAL_USER_DEADLINE_SECONDS` is an optional param that defines the time in seconds a user has to act before the transaction moves to the next status. It determines the `user_action_required_by` field, which indicates the deadline. Check [JSON-RPC Methods][json-rpc-methods] for usage examples. -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/platforms/anchor-platform/admin-guide/sep24/example.mdx b/platforms/anchor-platform/admin-guide/sep24/example.mdx index eeb212f6a..303368354 100644 --- a/platforms/anchor-platform/admin-guide/sep24/example.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/example.mdx @@ -9,11 +9,11 @@ Integrating with the Anchor Platform involves three key areas: - Providing transaction status updates to the Anchor Platform - Fetching transaction status updates from the Anchor Platform -## Building a Web-Based User Experience {#building-a-web-based-user-experience} +## Building a Web-Based User Experience The Anchor Platform does not offer a white-label UI that your business can utilize, and instead expects the business to build their own UI and backend system. We won't build an entire on & off-ramp user experience in this guide, but will cover the ways in which your existing product should be updated to be compatible with the Anchor Platform. -### Authentication {#authentication} +### Authentication If your business has an existing on & off-ramp product, you likely have an existing system for user authentication. However, because the Anchor Platform authenticates the user prior to providing the business's URL, requiring the user to go through another form of authentication is actually unnecessary. In this way, the Anchor Platform can be thought of as providing an alternative form of authentication. @@ -210,7 +210,7 @@ curl \ -## Providing Updates to the Platform {#providing-updates-to-the-platform} +## Providing Updates to the Platform Let's create an endpoint for our business server that accepts the information collected in our UI. @@ -321,7 +321,7 @@ At this time, the Anchor Platform does not send notifications to the wallet appl ::: -## Fetching Updates from the Platform {#fetching-updates-from-the-platform} +## Fetching Updates from the Platform If you only use the Anchor Platform to expose the SEP APIs to wallet applications, then you won't have a strong reason for fetching transaction status updates from the Anchor Platform, mostly because it won't update the transaction status until you make `JSON-RPC API` requests. @@ -408,7 +408,7 @@ async function getPlatformTransaction(transactionId) { -## Full Example Implementation {#full-example-implementation} +## Full Example Implementation Stellar provides an example business server implementation for SEP-24. It's split into two parts: 1) a web UI, accessible for the end user; and 2) a back-end implementation, used to get and push updates from/to the Anchor Platform. diff --git a/platforms/anchor-platform/admin-guide/sep24/faq.mdx b/platforms/anchor-platform/admin-guide/sep24/faq.mdx index ee5eb71da..5972a06cf 100644 --- a/platforms/anchor-platform/admin-guide/sep24/faq.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/faq.mdx @@ -3,7 +3,7 @@ title: "FAQ" sidebar_position: 50 --- -### How To Use JWTs? {#how-to-use-jwts} +### How To Use JWTs? As part of the flow, once a user makes a request, i.e. an interactive withdrawal/deposit request, it will be processed by the Anchor Platform and forwarded to your service. The Anchor Platform will make a `GET` call to `?token=`. @@ -14,7 +14,7 @@ This JWT token will contain: 3. `jti` is the hash of the transaction. 4. `data` is the extra payload that has been set by the user. It will always contain the Stellar `asset` wants to deposit or withdraw. If provided by the client, it will also contain the `amount` the user wants to transact, the `client_domain` of the wallet verified during SEP-10 authentication, and `client_name` (defined as 'name' in [clients] configuration if provided), and the `lang` (language) preference of the user. -### How To Provide Fees? {#how-to-provide-fees} +### How To Provide Fees? Currently, it's recommended to provide fees/exchange rates in the iFrame/web view of your application. @@ -26,11 +26,11 @@ Currently, it's recommended to provide fees/exchange rates in the iFrame/web vie ::: -### How to identify the user account? {#how-to-identify-the-user-account} +### How to identify the user account? You should use the `sub` field of the JWT token. For custodial wallets, this value will be in the format `account:memo`. Use the memo to identity the user. For noncustodial wallets, simply use the `sub` value itself, which will be equal to the user account. -### How to identify the wallet? {#how-to-identify-the-wallet} +### How to identify the wallet? Utilize the `data.client_domain` attributes within the JWT token. In the presence of [clients] configuration, the JWT token will additionally incorporate the `data.client_name` field, enabling wallet identification. diff --git a/platforms/anchor-platform/admin-guide/sep24/getting-started.mdx b/platforms/anchor-platform/admin-guide/sep24/getting-started.mdx index e77894428..ce1d1dbf4 100644 --- a/platforms/anchor-platform/admin-guide/sep24/getting-started.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-24, businesses make their on Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-24: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap] -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience a deposit and withdrawal goes something like this: diff --git a/platforms/anchor-platform/admin-guide/sep24/integration.mdx b/platforms/anchor-platform/admin-guide/sep24/integration.mdx index e41a3c5ed..4fae1b17e 100644 --- a/platforms/anchor-platform/admin-guide/sep24/integration.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/integration.mdx @@ -33,43 +33,43 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-24 protocol document][sep-24] -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about quotes. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit Transaction Via JSON-RPC {#updating-deposit-transaction-via-json-rpc} +## Updating Deposit Transaction Via JSON-RPC SEP-24 deposit flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -85,7 +85,7 @@ Statuses in red mean the transaction is in a ::: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds The first step of the deposit flow after starting the deposit itself is collecting KYC. It's usually done in the web-app, but can also be optionally provided by the wallet application, using [SEP-9]. Once the necessary KYC is collected, a `request_offchain_funds` JSON-RPC request should be made. @@ -146,7 +146,7 @@ When the KYC process is long (for example, ID verification), it's advised to fir ::: -### Processing KYC Information {#processing-kyc-information} +### Processing KYC Information :::tip @@ -202,7 +202,7 @@ To execute this, you need to run: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide an updated transaction information. @@ -254,7 +254,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In a real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -289,7 +289,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill a user request. After the transaction completion, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -327,7 +327,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as Fireblocks. To make a payment via custody service, it's necessary to make the following JSON-RPC request: @@ -370,7 +370,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, it's necessary to make the following JSON-RPC request: @@ -409,7 +409,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -451,7 +451,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service There is a possibility to send funds back to the user (refund). You can refund the whole sum(full refund) or do a set of partial refunds. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -501,11 +501,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending It's similar to [Refund sent](#refund-sent), but it handles a case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -544,7 +544,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to handle abandoned transactions by expiring those have remained inactive for a certain period. To achieve this, check the transaction status using the `GET /transactions` endpoint and sort the results by the `user_action_required_by` timestamp. If the timestamp has passed, manually execute the appropriate logic, such as expiring the transaction or initiating an auto-refund, based on the transaction's current status. For example, to expire transaction business should change the transaction status to `expired`: @@ -583,7 +583,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### On-Hold Transaction {#on-hold-transaction} +### On-Hold Transaction In rare cases, you may want to pause current transaction and request more information from the user (after the transfer has been received). This could be used for compliance use cases. @@ -616,7 +616,7 @@ To execute this, you need to run: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, it's necessary to make the following JSON-RPC request: @@ -649,7 +649,7 @@ To execute this, you need to run: -## Updating Withdrawal Transaction Via JSON-RPC {#updating-withdrawal-transaction-via-json-rpc} +## Updating Withdrawal Transaction Via JSON-RPC This diagram defines a sequence/rules of transaction's status transition for SEP-24 withdrawal flow. @@ -669,7 +669,7 @@ Once the deposit flow is finished, implementing the withdrawal is straightforwar The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similar to deposit, the next step is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the update will look differently. @@ -740,11 +740,11 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Processing KYC Information {#processing-kyc-information-1} +### Processing KYC Information This step is optional, and it's similar to [Processing KYC Information](#processing-kyc-information) of the deposit flow. -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -793,7 +793,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `fee_details` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -838,7 +838,7 @@ Only `amount_out` and `fee_details` can be updated using this JSON-RPC request, ::: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -873,7 +873,7 @@ To execute this, you need to run: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -907,7 +907,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -941,11 +941,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service-1} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -994,23 +994,23 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### On-Hold Transaction {#on-hold-transaction-1} +### On-Hold Transaction Works in the same manner as for the deposit flow. For more details, see [On-Hold Transaction](#on-hold-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/platforms/anchor-platform/admin-guide/sep24/setting-up-production-server.mdx b/platforms/anchor-platform/admin-guide/sep24/setting-up-production-server.mdx index 68c15d0bb..f631e5dbf 100644 --- a/platforms/anchor-platform/admin-guide/sep24/setting-up-production-server.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/setting-up-production-server.mdx @@ -7,7 +7,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities. -## Deploying a Secure Environment {#deploying-a-secure-environment} +## Deploying a Secure Environment Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions. @@ -38,7 +38,7 @@ STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org -## Connecting to Real KYC {#connecting-to-real-kyc} +## Connecting to Real KYC Most anchors need to collect [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number. @@ -50,7 +50,7 @@ KYC information should be linked to the session created through [Stellar Web Aut Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location. -## Pre-Filling the KYC Form {#pre-filling-the-kyc-form} +## Pre-Filling the KYC Form Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the `/transactions/deposit/interactive` and `/transactions/withdraw/interactive` endpoints. @@ -58,7 +58,7 @@ All fields from [SEP-9](https://github.com/stellar/stellar-protocol/blob/master/ All SEP-9 data that was sent from the wallet is a part of the [Interactive JWT](./faq.mdx#how-to-use-jwts), send by the Anchor Platform -## Connecting to Real Banking Rails {#connecting-to-real-banking-rails} +## Connecting to Real Banking Rails Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process. @@ -71,33 +71,33 @@ There are many ways to identify that a specific bank transfer relates to a speci Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours. -## Testing Edge Cases {#testing-edge-cases} +## Testing Edge Cases Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases: -### General Tests {#general-tests} +### General Tests - Test the interactive flow usability - Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting -### KYC Tests {#kyc-tests} +### KYC Tests - Check that KYC appears with a new wallet SK - Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible - Check that you can use the same KYC information (email, phone number, username, etc) multiple times - Check that you can go through KYC multiple times with the same Stellar SK. -### Interactive Test {#interactive-test} +### Interactive Test - Check that the deposit flow goes through, and that the banking rails are working - Check that you cannot make a withdrawal with a value higher than the current balance - Check that the withdrawal flow goes through, and that the banking rails are working -### Security Tests {#security-tests} +### Security Tests - Make sure platform endpoints are secured -## Polishing and Internationalization {#polishing-and-internationalization} +## Polishing and Internationalization Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations. @@ -105,7 +105,7 @@ You can support multiple languages in your webapp by using the `Accept-Language` Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product. -## Connecting to Wallets {#connecting-to-wallets} +## Connecting to Wallets All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs. diff --git a/platforms/anchor-platform/admin-guide/sep31/configuration.mdx b/platforms/anchor-platform/admin-guide/sep31/configuration.mdx index d0c9892ee..177b40c42 100644 --- a/platforms/anchor-platform/admin-guide/sep31/configuration.mdx +++ b/platforms/anchor-platform/admin-guide/sep31/configuration.mdx @@ -5,7 +5,7 @@ sidebar_position: 20 import { CodeExample } from "@site/src/components/CodeExample"; -## Modify a Stellar Info File {#modify-a-stellar-info-file} +## Modify a Stellar Info File Let's start by modifying our `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support. @@ -37,7 +37,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes. -## Enable Cross Border Payments {#enable-cross-border-payments} +## Enable Cross Border Payments Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your `dev.assets.yaml` file. @@ -122,7 +122,7 @@ You should get the following. -## Enable the Customer KYC API {#enable-the-customer-kyc-api} +## Enable the Customer KYC API Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -229,7 +229,7 @@ You should get the following: -## Enable the RFQ API {#enable-the-rfq-api} +## Enable the RFQ API Businesses need to provide their send-side counterparts with a [Rate][get-rates-api] API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time. @@ -348,7 +348,7 @@ You should get the following: -## Configure Callback API Authentication {#configure-callback-api-authentication} +## Configure Callback API Authentication Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well. diff --git a/platforms/anchor-platform/admin-guide/sep31/integration.mdx b/platforms/anchor-platform/admin-guide/sep31/integration.mdx index b4ce186a5..41e948f32 100644 --- a/platforms/anchor-platform/admin-guide/sep31/integration.mdx +++ b/platforms/anchor-platform/admin-guide/sep31/integration.mdx @@ -16,7 +16,7 @@ The following may also be required depending on your use case: - [`DELETE /customer`][delete-customer] if your business wants or is required to allow senders to request deletion of customer data -## Create a Business Server {#create-a-business-server} +## Create a Business Server First, lets create a business server and add it to our docker compose file. @@ -69,11 +69,11 @@ Next, create a simple web server using your preferred programming language and a This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the [Anchor Platform API Reference][ap-api], and the sections below will expand on concepts important to understand when implementing the endpoints. -## Customer Callback Endpoints {#customer-callback-endpoints} +## Customer Callback Endpoints The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the [SEP-12 KYC API specification][sep12]. -### Identifying Customers {#identifying-customers} +### Identifying Customers Customers can be identified using two approaches. @@ -132,13 +132,13 @@ Or, the sending organziation could use the identifier you returned when they ori Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate. -### Customer Types {#customer-types} +### Customer Types Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your `dev.assets.yaml` file, and your sending organizations will need to understand which label to use when registering or querying the status of customers. In `PUT /customer` requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In `GET /customer` requests, you should use the type to determine the customer's status. -### Test with the Demo Wallet {#test-with-the-demo-wallet} +### Test with the Demo Wallet You can test your implementation with the [Stellar Demo Wallet][demo-wallet] following the steps below. @@ -155,33 +155,33 @@ You should see the demo wallet find your service URLs, authenticate, and check w Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail. -## Rate Callback Endpoint {#rate-callback-endpoint} +## Rate Callback Endpoint Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the [`GET /rate` endpoint][get-rate]. -### Firm vs. Indicative Quotes {#firm-vs-indicative-quotes} +### Firm vs. Indicative Quotes Requests for quotes will have a `type` parameter that is either [`indicative`][indicative] or [`firm`][firm]. If `type=firm`, your response must include the `id` & `expires_at` date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If `type=indicative`, do not return `id` or `expires_at` fields because the rate provided will not be used in a transaction. Note that the client may request that the quote expires after a specific date-time using the `expires_after` parameter. Your business must honor this request by returning an `expires_at` value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client. -### Using the Client ID {#using-the-client-id} +### Using the Client ID Requests may include a `client_id` parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates. `client_id` may not be present for indicative requests, in which case your market price should be returned. Currently `client_id` will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform. -### Delivery Methods {#delivery-methods} +### Delivery Methods It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your `asset.yaml` file, clients will always provide the payment rail they want your business to use for firm quote requests. Because this endpoint is currently only used paying out remittances in off-chain assets, the `buy_delivery_method` will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then `sell_delivery_method` may also be passed for business that support these types of transactions. -## Fetching Transaction Status Updates {#fetching-transaction-status-updates} +## Fetching Transaction Status Updates To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil. The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the `GET /transactions` Platform API endpoint. -### Running the Stellar Observer {#running-the-stellar-observer} +### Running the Stellar Observer The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file. @@ -201,7 +201,7 @@ services: -### Polling for Received Payments {#polling-for-received-payments} +### Polling for Received Payments The Stellar Observer makes JSON-RPC requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, thus updating the transaction's `transfer_received_at` date-time. @@ -217,7 +217,7 @@ curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&ord The response will include a list of cross-border payment transactions initiated by sending organizations. This list will be ordered according to the time a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s). -## Updating Transaction Via JSON-RPC {#updating-transaction-via-json-rpc} +## Updating Transaction Via JSON-RPC SEP-31 flow diagram defines sequence/rules of the transaction's status transition and a set of JSON-RPC methods that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in the request. If the request doesn't contain required attributes, the Anchor Platform will return an error and won't change the status of the transaction. @@ -237,7 +237,7 @@ You can create a [template][sep24-integration-make-json-rpc-request] for making This chapter also contains information about the format of [request][sep24-integration-rpc-request]/[response][sep24-integration-rpc-response] and [error codes][sep24-integration-error-codes] that might be returned by the Anchor Platform. -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds SEP-31 Transactions should initially be in the `pending_receiver` status. To request funds from the Sending Anchor, the Receiving Anchor should change the transaction status to `pending_sender` by making the following RPC request: @@ -275,7 +275,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_sender`. -### Funds Received {#funds-received} +### Funds Received If the Sending Anchor has sent the funds, the Receiving Anchor should change the transaction status to `pending_receiver` by making the following JSON-RPC request: @@ -320,7 +320,7 @@ To execute this, you need to run: The transaction status will be changed to `pending_receiver`. -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make a `notify_offchain_funds_sent` JSON-RPC request. @@ -355,7 +355,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that payment has been submitted to external network, but it is not yet confirmed. @@ -389,7 +389,7 @@ To execute this, you need to run: -### Verifying Customer Information {#verifying-customer-information} +### Verifying Customer Information In some cases, the Receiving Anchor might need to request an updated information from the Sending Anchor. For example, the bank tells the Receiving Anchor that the provided Receiving Client's name is incorrect or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` status until the Sending Anchor makes another SEP-12 `PUT /customer` request to update. The Sending Anchor can check which fields need to be updated by making a SEP-12 `GET /customer` request including the id or account & memo parameters. The Receiving Anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described. @@ -426,7 +426,7 @@ To execute this, you need to run: -### Do Stellar Refund {#do-stellar-refund} +### Do Stellar Refund Integration with the custody service allows you to do refund via custody service, such as Fireblocks. @@ -475,7 +475,7 @@ You can't do multiple refunds in the SEP-31 flow. For this reason, the total ref ::: -### Refund Sent {#refund-sent} +### Refund Sent There is a possibility to send all funds back to the `Sending Anchor` (refund). You need to refund the whole sum(full refund). @@ -525,7 +525,7 @@ You can't do multiple refunds in SEP-31 flow. For this reason, the amount to ref ::: -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the details of the error. @@ -564,7 +564,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to expire those transactions that have been abandoned by the user after some time. It's a good practice to clean up inactive transactions in the `incomplete` status. To do so, simply change the transaction's status to `expired`. @@ -603,7 +603,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery The transaction status can be changed from `error/expired` to `pending-anchor`. After recovery, you can refund the received assets or proceed with the processing of the transaction. To recover the transaction, it's necessary to make the following JSON-RPC request: @@ -636,7 +636,7 @@ To execute this, you need to run: -### Configuration {#configuration} +### Configuration You can enable these types of transactions by updating your `assets.yaml` file configuration: diff --git a/platforms/anchor-platform/admin-guide/sep6/configuration.mdx b/platforms/anchor-platform/admin-guide/sep6/configuration.mdx index fb15490cd..69bee9ae5 100644 --- a/platforms/anchor-platform/admin-guide/sep6/configuration.mdx +++ b/platforms/anchor-platform/admin-guide/sep6/configuration.mdx @@ -13,7 +13,7 @@ To enable SEP-6 deposits and withdraws, the Anchor Platform must be configured t - Provide information about the on & off-chain assets, as well as the payment rails, supported by your business via SEP-6 and SEP-38 `/info` endpoints - Support the endpoints and callbacks required to request KYC information and provide exchange rates -## Enable Programmatic Deposits & Withdrawals {#enable-programmatic-deposits--withdrawals} +## Enable Programmatic Deposits & Withdrawals Add the following variables to your environment file. @@ -28,7 +28,7 @@ SEP38_ENABLED=true -### Modify a Stellar Info File {#modify-a-stellar-info-file} +### Modify a Stellar Info File Let's modify the `stellar.toml` file created [earlier][sep1-ap]. Wallets need to know that SEP-6 functionality is supported by your business, and they also need to know all the Stellar assets you support. @@ -63,7 +63,7 @@ ORG_DESCRIPTION = "A description of your organization" Note that you will need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your Mainnet distribution accounts and signing key, as well as the Mainnet issuing accounts of the assets your service utilizes. -### Modify the Assets Configuration File {#modify-the-assets-configuration-file} +### Modify the Assets Configuration File Now you're ready to specify the following in your `dev.assets.yaml` file, and change the values depending on your use case. This example asset file enables support for Circle's USDC and a fiat USD to deposit from and withdraw to. @@ -112,7 +112,7 @@ assets: -### Managing Distribution Accounts {#managing-distribution-accounts} +### Managing Distribution Accounts Note that the example above lists a `distribution_account` attribute for the USDC entry. If specified, this account will be provided along with a randomly generated and unique-per-transaction memo to clients as the address to send funds to for withdrawal transactions. The transaction's memo is how you or the Anchor Platform will match the funds received with a transaction record in the Anchor Platform's database. @@ -140,7 +140,7 @@ SEP6_DEPOSIT_INFO_GENERATOR_TYPE=custody -### Enable Callbacks to the Business Server {#enable-callbacks-to-the-business-server} +### Enable Callbacks to the Business Server Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients ask your business what KYC information needs to be collected and sends that information via the SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server. @@ -165,7 +165,7 @@ The above tells the Anchor Platform to include a [JWT][how-to-use-jwt], signed w See the [KYC API][platform-api-kyc] and [Rates API][get-rates-api] for details on the endpoints that must be implemented on your business server. -### Additional Optional Configuration {#additional-optional-configuration} +### Additional Optional Configuration `more_info_url` is an optional URL provided by your business server for wallet applications to display information about previously initiated transactions. This URL is typically used by wallets in their transaction history views, and your business can specify the information to be displayed about the transaction. @@ -190,7 +190,7 @@ SEP6_INITIAL_USER_DEADLINE_SECONDS=1209600 -## Test With the Demo Wallet {#test-with-the-demo-wallet} +## Test With the Demo Wallet Wallets should now be able to discover, authenticate, and initiate transactions with your service! Your project and source files should now look something like this. diff --git a/platforms/anchor-platform/admin-guide/sep6/getting-started.mdx b/platforms/anchor-platform/admin-guide/sep6/getting-started.mdx index fb4e1293c..3a1d875e9 100644 --- a/platforms/anchor-platform/admin-guide/sep6/getting-started.mdx +++ b/platforms/anchor-platform/admin-guide/sep6/getting-started.mdx @@ -9,7 +9,7 @@ By leveraging the Anchor Platform's support for SEP-6, businesses make their own Before continuing with this section, make sure that you have already [installed][installation-ap] the Anchor Platform, and configured necessary features, required by SEP-6: [SEP-1 (Stellar Info File)][sep1-ap] and [SEP-10 (Stellar Authentication)][sep10-ap]. -## The Basic User Experience {#the-basic-user-experience} +## The Basic User Experience The complete customer experience for a deposit or withdrawal using SEP-6 is as follows: diff --git a/platforms/anchor-platform/admin-guide/sep6/integration.mdx b/platforms/anchor-platform/admin-guide/sep6/integration.mdx index cc9ea0942..7627af2e8 100644 --- a/platforms/anchor-platform/admin-guide/sep6/integration.mdx +++ b/platforms/anchor-platform/admin-guide/sep6/integration.mdx @@ -34,47 +34,47 @@ Communication from the Anchor Platform about transaction updates, customer updat You can find out more about transaction flow and statuses in the [SEP-6 protocol document][sep-6]. -## Callbacks {#callbacks} +## Callbacks The Anchor Platform relies on the business server to provide and store information about customers and quotes. -### Customer Information {#customer-information} +### Customer Information The Anchor Platform does not store customer information. Instead, it forwards all SEP-12 customer requests to the business server. The business server is responsible for storing and managing this information. Therefore, your business server must implement the [customer APIs][customer-callback] to handle KYC updates. -### Quotes and Fees {#quotes-and-fees} +### Quotes and Fees To support the exchange of non-equivalent assets, the Anchor Platform exposes a SEP-38 compliant API to provide quotes for the exchange. The quote API is used to provide the user with the expected amount of the asset they will receive in exchange for the asset they are sending. The quote API is also used to provide the user with the expected fees for the transaction. Therefore, your business server must implement the [rate API][rate-callback] to provide quotes to the Anchor Platform. -## Securing Platform API {#securing-platform-api} +## Securing Platform API -### Using API Key {#using-api-key} +### Using API Key -### Using JWT {#using-jwt} +### Using JWT -## Making JSON-RPC Requests {#making-json-rpc-requests} +## Making JSON-RPC Requests -### JSON-RPC Request {#json-rpc-request} +### JSON-RPC Request -### JSON-RPC Response {#json-rpc-response} +### JSON-RPC Response -### Error Codes {#error-codes} +### Error Codes -## Updating Deposit (Exchange) Transaction Via JSON-RPC {#updating-deposit-exchange-transaction-via-json-rpc} +## Updating Deposit (Exchange) Transaction Via JSON-RPC SEP-6 deposit flow diagram defines sequences/rules of the transaction's status transition and a set of JSON-RPC method that should be called to change that status. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -92,7 +92,7 @@ Statuses in red mean the transaction is in a ::: -### Verifying KYC Information {#verifying-kyc-information} +### Verifying KYC Information Although Anchor Platform does not require a customer to have their KYC information collected before initiating a deposit, your business may want to collect this information before the customer makes a transfer. By listening to transaction created events, or by polling the [`GET /transactions`][get-transactions] endpoint, you can require determine if a transaction requires the customer to update their information. The required SEP-9 fields can be communicated to the user by returning a `NEEDS_INFO` status with the required fields in the `fields` attribute. @@ -129,7 +129,7 @@ To execute this, you need to run: -### Ready to Receive Funds {#ready-to-receive-funds} +### Ready to Receive Funds After the user has submitted their KYC information, the anchor can notify the Platform that they are ready to receive funds. The anchor should use the `request_offchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -201,7 +201,7 @@ For exchange deposits with a firm quote (the request is associated with a `quote ::: -### Funds Received {#funds-received} +### Funds Received If offchain funds were received, you'll want to provide updated transaction information. @@ -253,7 +253,7 @@ To execute this, you need to run: -### Waiting For User Funds {#waiting-for-user-funds} +### Waiting For User Funds In the real world, the transfer confirmation process may take time. In such cases, transactions should be set to a new status indicating that the confirmation of the transfer has been received but the funds themselves have not been received yet. @@ -288,7 +288,7 @@ To execute this, you need to run: -### Sending Onchain Funds {#sending-onchain-funds} +### Sending Onchain Funds Next, send a transaction on the Stellar network to fulfill the user deposit. After the Stellar transaction has been submitted, it's necessary to send the `notify_onchain_funds_sent` JSON-RPC request to notify a user that the funds were successfully sent. @@ -326,7 +326,7 @@ To execute this, you need to run: After this JSON-RPC request, the transaction will be transferred to the `completed` status. -### Sending Payment Via Custody Service {#sending-payment-via-custody-service} +### Sending Payment Via Custody Service The Anchor Platform provides a possibility to send a payment via custody services, such as [Fireblocks](../custody-services/fireblocks/README.mdx). To make a payment via a custody service, make the following JSON-RPC request. @@ -369,7 +369,7 @@ If custody integration is enabled, the Anchor Platform will do this validation f ::: -### Pending Trust {#pending-trust} +### Pending Trust This status has to be set if a payment requires an asset trustline that wasn't configured by the user. There are two ways of how the transaction may be moved to the `pending_trust` status. The first one is processing of a payment via custody service in case it detected that the trustline isn't configured. The second one is when the business itself detects that the trustline is missing and wants to notify the user that it has to be configured. To move the transaction to the `pending_trust` status, make the following JSON-RPC request. @@ -408,7 +408,7 @@ Payment via custody service periodically checks if the trustline was configured. ::: -### Trust Set {#trust-set} +### Trust Set This status has to be set if the business has detected that the trustline was or wasn't configured by user. @@ -450,7 +450,7 @@ Depending on the `success` flag, the status of the transaction will be changed t ::: -### Refund Sent {#refund-sent} +### Refund Sent Sometimes, funds need to be sent back to the user (refund). You can refund the whole sum (full refund) or do a set of partial refunds back to the `source_account` using the `refund_memo` and `refund_memo_type` associated with the transaction if present. Also, if user sent more money than expected, you can refund a part of the sum back to the user and send the rest as onchain funds. @@ -500,11 +500,11 @@ If a sum of refunds is less than `amount_in`, the status of the transaction will ::: -### Refund Pending {#refund-pending} +### Refund Pending This is similar to [Refund Sent](#refund-sent), but it handles the case when a refund has been submitted to external network but is not yet confirmed. The status of the transaction is set to `pending_external`. This is the status that will be set when waiting for Bitcoin or other external crypto network to complete a transaction, or when waiting for a bank transfer. -### Transaction Error {#transaction-error} +### Transaction Error If you encounter an unrecoverable error when processing the transaction, it's required to set the transaction status to `error`. You can use the message field to describe the error details. @@ -543,7 +543,7 @@ If a user has made a transfer, you should do a transaction recovery, and then yo ::: -### Expired Transaction {#expired-transaction} +### Expired Transaction Your business may want to handle abandoned transactions by expiring those have remained inactive for a certain period. To achieve this, check the transaction status using the `GET /transactions` endpoint and sort the results by the `user_action_required_by` timestamp. If the timestamp has passed, manually execute the appropriate logic, such as expiring the transaction or initiating an auto-refund, based on the transaction's current status. @@ -582,7 +582,7 @@ This JSON-RPC method can't be used after the user has made a transfer. ::: -### Transaction Recovery {#transaction-recovery} +### Transaction Recovery Transaction status can be changed from `error/expired` to `pending_anchor`. After recovery, you can refund the received assets or proceed with processing of the transaction. To recover a transaction, make the following JSON-RPC request. @@ -615,7 +615,7 @@ To execute this, you need to run: -## Updating Withdrawal (Exchange) Transaction Via JSON-RPC {#updating-withdrawal-exchange-transaction-via-json-rpc} +## Updating Withdrawal (Exchange) Transaction Via JSON-RPC The SEP-6 withdrawal flow diagram defines the sequence/rules of the transaction's status transition. You can't define the status you want to set for a specific transaction in your requests. Each JSON-RPC method defines data structures that it expects in request. If request doesn't contain a required attributes, the Anchor Platform will return and error and won't change status of the transaction. @@ -637,7 +637,7 @@ Once the withdrawal flow is finished, implementing the withdrawal is straightfor The starting point both for withdrawal and for deposit is the same. -### Ready to Receive Funds {#ready-to-receive-funds-1} +### Ready to Receive Funds Similarly to deposit, the step after KYC has been collected is to notify the user that the anchor is ready to receive funds. However, as your service will be receiving transactions over the Stellar network, the RPC request will be different. The anchor should use the `request_onchain_funds` RPC to provide the final amounts to the user. To do so, make the following JSON-RPC request. @@ -718,7 +718,7 @@ The Stellar account that will be used to receive funds should be configured. ::: -### Funds Received {#funds-received-1} +### Funds Received If onchain funds were received, you need to provide amounts and change the status of the transaction to `pending_anchor`. @@ -767,7 +767,7 @@ This method will be called automatically by the custody server if the custody in ::: -### Amount Updated {#amount-updated} +### Amount Updated If onchain funds were received, but for some reason the `amount_in` differs from specified in the interactive flow (`amount_expected`), you can update `amount_out` and `fee_details` to make them correspond to the actual `amount_in`. The status of the transaction in this case won't be changed and will be equal to `pending_anchor`. @@ -812,7 +812,7 @@ Only `amount_out` and `fee_details` can be updated using this JSON-RPC request, ::: -### Offchain Funds Available {#offchain-funds-available} +### Offchain Funds Available You can move transaction status to `pending_user_transfer_complete` if offchain funds were sent, and if it's ready for the user / recipient to pick it up. @@ -846,7 +846,7 @@ To execute this, you need to run: -### Offchain Funds Pending {#offchain-funds-pending} +### Offchain Funds Pending Another option is to move the transaction's status to `pending_external`. This status means that the payment has been submitted to an external network, but is not yet confirmed. @@ -880,7 +880,7 @@ To execute this, you need to run: -### Offchain Funds Sent {#offchain-funds-sent} +### Offchain Funds Sent To complete the transaction and change its status to `completed`, you need to make the `notify_offchain_funds_sent` JSON-RPC request. @@ -915,11 +915,11 @@ To execute this, you need to run: -### Refund Sent {#refund-sent-1} +### Refund Sent The refund logic works in the same way as for the deposit flow. For more details, see [Refund Sent](#refund-sent) of the deposit flow. -### Sending Refund Via Custody Service {#sending-refund-via-custody-service} +### Sending Refund Via Custody Service Integration with a custody service allows you to do a refund via a custody service, such as Fireblocks. @@ -968,19 +968,19 @@ Similarly to the deposit flow, you can make a full refund or a set of partial re ::: -### Transaction Error {#transaction-error-1} +### Transaction Error Works in the same manner as for the deposit flow. For more details, see [Transaction Error](#transaction-error) of the deposit flow. -### Expired Transaction {#expired-transaction-1} +### Expired Transaction Works in the same manner as for the deposit flow. For more details, see [Expired Transaction](#expired-transaction) of the deposit flow. -### Transaction Recovery {#transaction-recovery-1} +### Transaction Recovery Works in the same manner as for the deposit flow. For more details, see [Transaction Recovery](#transaction-recovery) of the deposit flow. -## Tracking Stellar Transactions {#tracking-stellar-transactions} +## Tracking Stellar Transactions diff --git a/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx b/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx index b437d2198..7436ecf55 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/anchor-platform-integration-points.mdx @@ -9,13 +9,13 @@ For that reason, there are some connection points between the two instances that Please note that for the default deployment of the Stellar Disbursement Platform, that relies on default Helm values and default Wallets and Assets, no extra configuration is needed. This guide is for those who want to customize the deployment by changing the Wallets and Assets available in their SDP instance. -## Role of the Anchor Platform in SDP {#role-of-the-anchor-platform-in-sdp} +## Role of the Anchor Platform in SDP The Wallet Registration flow kicks off within the recipient's wallet app. This app interacts with the [Anchor Platform] to initiate the [SEP-24] deposit process through the SDP (Stellar Disbursement Platform). The SDP collects the necessary recipient information to ultimately execute the payment to them. The Anchor Platform (AP) is used to handle the implementation of interoperability protocols such as [SEP-1], [SEP-10], and [SEP-24], making their endpoints available to wallet apps. The [Anchor Platform] is pre-configured in both [the repo]'s Helm chart, and in the Docker Compose file available in the `dev` directory. -## Steps for Configuring SDP-AnchorPlatform Integration {#steps-for-configuring-sdp-anchorplatform-integration} +## Steps for Configuring SDP-AnchorPlatform Integration To ensure a seamless integration between the SDP and the [Anchor Platform], make sure to follow these steps: @@ -26,7 +26,7 @@ To ensure a seamless integration between the SDP and the [Anchor Platform], make By following these steps, you'll ensure a secure and efficient integration between your SDP and Anchor Platform systems. -## Manual Synchronization of Custom Assets and Wallets {#manual-synchronization-of-custom-assets-and-wallets} +## Manual Synchronization of Custom Assets and Wallets Currently, some configurations within the Anchor Platform are static and loaded via environment variables. On the other hand, the SDP reads these same configurations from its database and allows an owner user to modify them. This dynamic pertains particularly to the lists of supported assets and wallets. diff --git a/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx b/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx index 67f3e2914..7b12f2f3a 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx @@ -15,7 +15,7 @@ In this section we will discuss the different configuration options available fo - These configurations are valid for version 2.x of the SDP. - All configurations can be passed in as either environment variables or CLI flags. For instance, the env var `BASE_URL` could be passed in through the `--base-url` flag. CLI flags take priority over env vars, even though env vars are more convenient. -## SDP Core Service {#sdp-core-service} +## SDP Core Service For the most up-to-date configuration, you can run the following command in the [stellar-disbursement-platform-backend git repository](https://github.com/stellar/stellar-disbursement-platform-backend): @@ -27,7 +27,7 @@ For the most up-to-date configuration, you can run the following command in the -### Operational Configuration {#operational-configuration} +### Operational Configuration Operational Configuration allows controlling metrics, logging, and other operational aspects of the SDP Core Service. @@ -42,14 +42,14 @@ Operational Configuration allows controlling metrics, logging, and other operati - `BASE_URL` - The SDP backend server's base URL. Default: "http://localhost:8000". Tenant-specific URLs will be configured during the [tenant provisioning process](tenant-provisioning#creating-tenants). - `SDP_UI_BASE_URL` - The SDP UI/dashboard Base URL used to send the invitation link when a new user is created. Tenant-specific URLs will be configured during the [tenant provisioning process](tenant-provisioning#creating-tenants). -### Messaging Configuration {#messaging-configuration} +### Messaging Configuration Messaging Configuration allows configuring the messaging service used to send messages to recipients and sdp dashboard users. The default configuration is set to "DRY_RUN" which means no messages will be sent and the messages will be logged to the console. This is recommended for testing purposes only. - `EMAIL_SENDER_TYPE`: The messenger type used to send invitations to new dashboard users. Options: "DRY_RUN", "TWILIO_EMAIL", "AWS_EMAIL". Default: "DRY_RUN". - `SMS_SENDER_TYPE`: The messenger type used to send SMS messages to recipients. Options: "DRY_RUN", "TWILIO_SMS", "AWS_SMS". Default: "DRY_RUN". -#### AWS Configuration {#aws-configuration} +#### AWS Configuration The following configurations are required when using AWS SES or SNS to send emails or SMS messages. @@ -59,7 +59,7 @@ The following configurations are required when using AWS SES or SNS to send emai - `AWS_SES_SENDER_ID` - The email that AWS SES will use as the sender when sending emails. Required when `EMAIL_SENDER_TYPE` is set to "AWS_EMAIL". - `AWS_SNS_SENDER_ID` - The sender ID to use when sending SMS messages using AWS SNS. Required when `SMS_SENDER_TYPE` is set to "AWS_SMS". -#### Twilio Configuration {#twilio-configuration} +#### Twilio Configuration The following configurations are required when `SMS_SENDER_TYPE=TWILIO_SMS`. @@ -72,11 +72,11 @@ The following configurations are required when `EMAIL_SENDER_TYPE=TWILIO_EMAIL`. - `TWILIO_SENDGRID_API_KEY` - 🔑 The API key for the Twilio SendGrid (email) service. - `TWILIO_SENDGRID_SENDER_ADDRESS` - The email address used to send emails via Twilio SendGrid. -#### General Messaging Configuration {#general-messaging-configuration} +#### General Messaging Configuration - `MAX_INVITATION_RESEND_ATTEMPTS` - The maximum number of attempts to (auto) resend the invitation to the Receiver Wallets. Default: 3. -### Stellar Configuration {#stellar-configuration} +### Stellar Configuration Stellar Configuration allows configuring accounts, transactions, and other Stellar-related settings. @@ -88,14 +88,14 @@ Stellar Configuration allows configuring accounts, transactions, and other Stell The remaining configurations related to distribution accounts are detailed in the `Stellar accounts configuration` section of [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). -### Security Configuration {#security-configuration} +### Security Configuration Security Configuration allows configuring the security aspects of the SDP Core Service. - `CORS_ALLOWED_ORIGINS` - Specifies the domains allowed to make cross-origin requests. "_" means all domains are allowed. Domains can contain wildcards, e.g., "https://_.example.com". - `SEP24_JWT_SECRET` - 🔑 The secret used to sign the JWT token for SEP-24 transactions. This secret is used during the receiver wallet registration flow. -#### Dashboard Authentication Configuration {#dashboard-authentication-configuration} +#### Dashboard Authentication Configuration The following configurations are related to dashboard user authentication and authorization. @@ -105,14 +105,14 @@ The following configurations are related to dashboard user authentication and au - `DISABLE_MFA` - Disables Multi-Factor Authentication (MFA) for the SDP dashboard users. - `DISABLE_RECAPTCHA` - Disables Google reCAPTCHA v2 for the SDP dashboard users. This flag doesn't affect the reCAPTCHA used during the SEP-24 flow. -#### Recaptcha Configuration {#recaptcha-configuration} +#### Recaptcha Configuration The following configurations are required when using Google reCAPTCHA v2 to protect the SDP Core Service from bots. ReCaptcha is used both for dashboard users and receivers of funds during the SEP-24 flow. - `RECAPTCHA_SITE_KEY` - The Google reCAPTCHA v2 - I'm not a robot site key. - `RECAPTCHA_SITE_SECRET_KEY` - 🔑 The reCAPTCHA site secret key used to validate reCAPTCHA responses. -### Anchor Platform Configuration {#anchor-platform-configuration} +### Anchor Platform Configuration Anchor Platform Configuration allows configuring the anchor platform used by the SDP Core Service. @@ -120,17 +120,17 @@ Anchor Platform Configuration allows configuring the anchor platform used by the - `ANCHOR_PLATFORM_BASE_SEP_URL` - The base URL of the anchor platform's SEP-24 implementation. - `ANCHOR_PLATFORM_OUTGOING_JWT_SECRET` - 🔑 The JWT secret used to create a JWT token used to send requests to the anchor platform. -### Event Broker and Scheduled Jobs Configuration {#event-broker-and-scheduled-jobs-configuration} +### Event Broker and Scheduled Jobs Configuration For asynchronous processing, the SDP Core Service gives user the choice to use either the Event Broker or Scheduled Jobs. The configurations for this section are detailed in the `Event Broker and Scheduler Configurations` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). -### Multi-tenancy Configuration {#multi-tenancy-configuration} +### Multi-tenancy Configuration The configurations for this section are detailed in `General Environment Variables` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). -## Transaction Submission Service (TSS) {#transaction-submission-service-tss} +## Transaction Submission Service (TSS) For the most up-to-date configuration, you can run the following command in the [stellar-disbursement-platform-backend git repository](https://github.com/stellar/stellar-disbursement-platform-backend): @@ -142,11 +142,11 @@ For the most up-to-date configuration, you can run the following command in the -### General Configuration {#general-configuration} +### General Configuration - `QUEUE_POLLING_INTERVAL` - Polling interval (seconds) to query the database for pending transactions to process. Default: 6. -### Operational Configuration {#operational-configuration-1} +### Operational Configuration Operational Configuration allows controlling metrics, logging, and other operational aspects of the Transaction Submission Servic (TSS) @@ -158,7 +158,7 @@ Operational Configuration allows controlling metrics, logging, and other operati - `ENVIRONMENT` - The environment where the application is running. Example: "development", "staging", "production". Default: "development". - `DATABASE_URL` - 🔑 The connection string for the PostgreSQL database. Format is `postgres://username:password@host:port/database?sslmode=disable`. Default: "postgres://localhost:5432/sdp?sslmode=disable". -### Stellar Configuration {#stellar-configuration-1} +### Stellar Configuration Stellar Configuration allows configuring accounts, transactions, and other Stellar-related settings. @@ -166,14 +166,14 @@ Stellar Configuration allows configuring accounts, transactions, and other Stell - `HORIZON_URL` - The URL of the Horizon server to use for submitting transactions. Default "https://horizon-testnet.stellar.org/". - `MAX_BASE_FEE` - The max base fee for submitting a Stellar transaction. Default: 10000. -#### Channel Accounts Configuration {#channel-accounts-configuration} +#### Channel Accounts Configuration The following configurations are required for using channel accounts to submit transactions to the Stellar network. - `NUM_CHANNEL_ACCOUNTS` - Number of channel accounts to utilize for transaction submission. Default: 2. - `CHANNEL_ACCOUNT_ENCRYPTION_PASSPHRASE` - 🔑 A Stellar-compliant ed25519 private key used to encrypt/decrypt the channel accounts' private keys. When not set, it will default to the value of the 'DISTRIBUTION_SEED' option. -#### Distribution Accounts Configuration {#distribution-accounts-configuration} +#### Distribution Accounts Configuration The following configurations are related to the distribution accounts used to send funds to recipients. This configuration should match the configuration in the SDP Core Service. For more details, refer to the `Stellar accounts configuration` section of [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). @@ -181,7 +181,7 @@ The following configurations are related to the distribution accounts used to se - `DISTRIBUTION_PUBLIC_KEY` - The public key of the HOST's Stellar distribution account, used to create channel accounts. - `DISTRIBUTION_SEED` - 🔑 The private key of the HOST's Stellar distribution account, used to create channel accounts. -### Event Broker Configuration {#event-broker-configuration} +### Event Broker Configuration If an Event Broker is used for asynchronous processing, the TSS will need to be configured to use it. For more details, refer to the `Event Broker and Scheduler Configurations` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). @@ -194,11 +194,11 @@ If an Event Broker is used for asynchronous processing, the TSS will need to be - `KAFKA_SSL_ACCESS_CERTIFICATE` - 🔑 Kafka SSL Access Certificate in PEM format that matches with the Kafka Access Key. - `KAFKA_SSL_ACCESS_KEY` - 🔑 The Kafka Access Key (keystore) in PEM format. -## Dashboard {#dashboard} +## Dashboard The SDP Dashboard is a web application that allows users to manage their accounts, view transaction history, and more. Environment variables can be set either on a global `window._env_` object or as `process.env` variables. All environment variables used in this repo are in `src/constants/envVariables.ts` file, including types. The default location of the `window._env_` object is `public/settings/env-config.js`. -### General Configuration {#general-configuration-1} +### General Configuration - `API_URL` - The base URL of the SDP Core Service. Default: "http://localhost:8000". - `STELLAR_EXPERT_URL` - The base URL of the Stellar Expert explorer. Default: "https://stellar.expert/explorer/testnet". diff --git a/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx b/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx index 91c421803..065ed096f 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/deploy-the-sdp.mdx @@ -9,15 +9,15 @@ This option is recommended for persistent deployments of production or staging i Please note that configuring deployment details like ingress, TLS, resource limits, and so on are out of scope for this guide. This guide assumes that you have a Kubernetes cluster with a Postgres database deployed in the same cluster and that you have the necessary permissions to deploy the SDP. It also assumes that you have the operational knowledge to manage the cluster and the database. -## Prerequisites {#prerequisites} +## Prerequisites - Kubernetes 1.19+ - Helm 3.2.0+ - Postgres 14.0+ -## Installing the Chart {#installing-the-chart} +## Installing the Chart -### Add the Helm repository {#add-the-helm-repository} +### Add the Helm repository Before you can install the chart, you need to add the Stellar Helm repository. @@ -26,7 +26,7 @@ helm repo add stellar https://helm.stellar.org/charts helm repo update ``` -### Customize the values {#customize-the-values} +### Customize the values The SDP Helm chart has a number of configurable values. You can customize these values by creating a values file and passing it to the `helm install` command. @@ -40,13 +40,13 @@ You can find the full list of configurable values in the [SDP GitHub repository] There is a more detailed explanation of how to configure the SDP in the [Configuring the SDP Guide](configuring-sdp). -### Multi-tenant considerations {#multi-tenant-considerations} +### Multi-tenant considerations When running the SDP in a multi-tenant configuration, you will need to acquire wildcard TLS certificates to facilitate tenant provisioning as the SDP relies on subdomains to differentiate between tenants. This will allow you to provision tenants without having to manually configure TLS certificates for each tenant. You can use a service like [Let's Encrypt](https://letsencrypt.org/) or [Namecheap](https://www.namecheap.com/security/ssl-certificates/) to acquire these certificates. For more information about multi-tenancy in the SDP, see the [Design and Architecture Guide](design-and-architecture#multi-tenancy). -### Install the chart {#install-the-chart} +### Install the chart To install the chart with the release name `sdp` and the values file `myvalues.yaml`: diff --git a/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx b/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx index 631c144a7..458303421 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/design-and-architecture.mdx @@ -24,7 +24,7 @@ The Stellar Disbursement Platform consists of four services deployed together: - Distribution Account: the SDP requires access to at least one funded Stellar account to make payments to the recipient - SEP-10 Auth Account: the SDP requires a Stellar account for the mutual authentication protocol [SEP-10: Stellar Web Authentication](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) used to connect to wallet applications -## Architecture Diagram {#architecture-diagram} +## Architecture Diagram ![Architecture Diagram](/assets/SDP/SDP2.png) diff --git a/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx b/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx index bbdd95ea9..a9c999634 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/getting-started.mdx @@ -19,7 +19,7 @@ By the end of this guide, you'll have a clear understanding of the Stellar Disbu Note that while we'll be using USDC and the [Demo Wallet][demo-wallet] in this guide, other Stellar assets and wallets can be used in development or production. -## Create and Fund a Host Distribution Account {#create-and-fund-a-host-distribution-account} +## Create and Fund a Host Distribution Account You'll need a minimum of two accounts when using the Stellar Disbursement Platform, a distribution and receiver account. We'll create the distribution account now and will create the receiver account while making our first disbursment. @@ -53,15 +53,15 @@ You can also acquire USDC through the [Stellar Lab](https://lab.stellar.org) if USDC will arrive in your demo wallet account within seconds! Refresh the account on the demo wallet page to see the new balance. -## Run the SDP Locally {#run-the-sdp-locally} +## Run the SDP Locally -### Prerequisites {#prerequisites} +### Prerequisites -#### Docker {#docker} +#### Docker Make sure you have Docker installed on your system. If not, you can download it from [here](https://docs.docker.com/get-docker/). -#### Stellar Accounts {#stellar-accounts} +#### Stellar Accounts We will need two Stellar accounts to set up the SDP, one of which you already created above. @@ -70,7 +70,7 @@ We will need two Stellar accounts to set up the SDP, one of which you already cr The public and private key of these two accounts will be used to configure the SDP in the next step. -### Run the SDP {#run-the-sdp} +### Run the SDP First you'll need to clone the project. @@ -126,7 +126,7 @@ This will bring up the following services: - `kafka-init`: Initial workflow to exec into the Kafka container and create topics. - `demo-wallet`: The demo wallet client that will be used as a receiver wallet, running on port 4000. -## New Tenant Provisioning Process {#new-tenant-provisioning-process} +## New Tenant Provisioning Process When you ran `main.sh` file, you've already created new tenants: `tenants=("redcorp" "bluecorp")`. To add more tenants, simply append them separated by spaces to that variable like so: `tenants=("redcorp" "bluecorp" "greencorp")` and run main.sh again. @@ -137,7 +137,7 @@ Be sure that the added tenant hosts are included in the host configuration file. 127.0.0.1 redcorp.sdp.local ``` -## Setup Owner User Password for each tenant {#setup-owner-user-password-for-each-tenant} +## Setup Owner User Password for each tenant Go through the forgot password flow to be able to login as an owner user. @@ -145,13 +145,13 @@ Go to Forgot Password page on `http://${tenant}.stellar.local:3000/forgot-passwo A token will be generated, and it's possible to check it on `sdp-api` logs. This token will be needed to Reset Password on `http://${tenant}.stellar.local:3000/reset-password`. -## Log In {#log-in} +## Log In Once the password for your target org user has been reset to one of your choice, navigate to the dashboard by opening a browser to localhost:3000 and login with the user account. ![Login](/assets/SDP/SDP26.png) Click the Sign in button and the SDP Dashboard will open. You will have no disbursements data at this point. ![Dashboard](/assets/SDP/SDP27.png) -## Create Your First Disbursement {#create-your-first-disbursement} +## Create Your First Disbursement Navigate to the frontend service by opening a browser and going to http://bluecorp.stellar.local:3000. @@ -164,7 +164,7 @@ Navigate to the frontend service by opening a browser and going to http://blueco You also have the option of modifying the message in the receiver invite. ![Disbursment Details 2](/assets/SDP/SDP29.png) -## Deposit Money {#deposit-money} +## Deposit Money To deposit money into your account: @@ -179,9 +179,9 @@ To deposit money into your account: - Enter the birthday that matches the phone number in the CSV. - Keep an eye on the dashboard until the payment status reaches `Success`. If everything was set up correctly, your money should be disbursed successfully. -## Troubleshooting {#troubleshooting} +## Troubleshooting -### Distribution account out of funds {#distribution-account-out-of-funds} +### Distribution account out of funds Payments will start failing if the distribution account runs out of funds. To fix this, you can either write a script that funds the distribution account or use the tools available to add more funds to the distribution account by following these steps: @@ -193,7 +193,7 @@ Payments will start failing if the distribution account runs out of funds. To fi - Click on `Send` and enter the distribution account public key and the amount you want to send. - Using Freighter or [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=testnet&label=Testnet&horizonUrl=https:////horizon-testnet.stellar.org&rpcUrl=https:////soroban-testnet.stellar.org&passphrase=Test%20SDF%20Network%20/;%20September%202015;;), swap the XLM for USDC if you wish to test with USDC. -## Verify Your Identity {#verify-your-identity} +## Verify Your Identity When a disbursement is created, the SDP attempts to send a message to receivers using either Twilio/AWS for SMS or email, according to the contact type associated with the user. This message includes a link to the wallet application selected when creating the disbursement, and should direct the receiver to install the wallet app, go through the wallet's onboarding flow, and finally register with the SDP. @@ -207,11 +207,11 @@ Check out the [Email and SMS Messages](#email-and-sms-messages) section to learn ::: -## Create a Receiver Account {#create-a-receiver-account} +## Create a Receiver Account Clicking on initation message link will take the receiver to the [demo-wallet], where they'll need to create an account to be used to receive the USDC payment. Follow the same process described earlier to create the account and add a USDC trustline. -## Initiate SEP-24 Webflow {#initiate-sep-24-webflow} +## Initiate SEP-24 Webflow Now we'll need to connect the demo wallet to the SDP instance running locally. To do that, select the pencil icon next to "centre.io" below your USDC balance and enter "localhost:8080". @@ -235,7 +235,7 @@ The webflow provides a message indicating your successful registration, which is ![Message](/assets/SDP/SDP16.png) -## Check Your Balance {#check-your-balance} +## Check Your Balance Refresh your account. The Demo Wallet should now show a balance of 2 USDC sent from the SDP (or however much was defined in the CSV file). @@ -245,17 +245,17 @@ Keep an eye on the dashboard until the payment status reaches Success. If everyt ![Disbursement](/assets/SDP/SDP18.png) -## Next Up: Updating Application Secrets {#next-up-updating-application-secrets} +## Next Up: Updating Application Secrets Now that you've been able to make a disbursement, let's go back to our docker compose files and update some values. **This is an important step before going to production. We'll be updating encryption keys and application secrets.** -### Email and SMS Messages {#email-and-sms-messages} +### Email and SMS Messages The Stellar Disbursement Platform sends emails to users and SMS/emails to receivers. For SMS messages, the Stellar Disbursement Platform supports Twilio, AWS SNS, and a dry run mode that just logs the messages. For emails, it supports AWS SES, Twilio SendGrid, and dry run. These services can be selected through the `SMS_SENDER_TYPE` and `EMAIL_SENDER_TYPE` configurations. When selecting Twilio or AWS services, you'll need to fill their service-specific configuration as well. Below there are some example configurations, and you can mix and match the services as you see fit. -#### Dry Run Configuration {#dry-run-configuration} +#### Dry Run Configuration Dry run mode is useful for testing the SDP without sending real messages. It will log the messages to the console instead of sending them to the receiver. This is the default configuration and it works for both SMS and Email. @@ -268,7 +268,7 @@ SMS_SENDER_TYPE: DRY_RUN -#### Twilio SMS Configuration {#twilio-sms-configuration} +#### Twilio SMS Configuration @@ -283,7 +283,7 @@ TWILIO_SERVICE_SID: -#### Twilio Email (Send Grid) Configuration {#twilio-email-send-grid-configuration} +#### Twilio Email (Send Grid) Configuration @@ -297,7 +297,7 @@ TWILIO_SENDGRID_SENDER_ADDRESS: -#### AWS SMS Configuration {#aws-sms-configuration} +#### AWS SMS Configuration @@ -316,7 +316,7 @@ AWS_SNS_SENDER_ID: -#### AWS Email Configuration {#aws-email-configuration} +#### AWS Email Configuration @@ -335,7 +335,7 @@ AWS_SES_SENDER_ID: -### Authentication {#authentication} +### Authentication Wallets authenticate with the Stellar Disbursement Platform using a mutual authentication protocol, where both the SDP and wallet prove they are in possession of their Stellar accounts by signing a payload exchanged between themselves. Once this process is complete, a JWT is provided to the wallet to use in future requests. Additionally, the SDP's microservices uses authentication tokens to communicate between themselves, and to encrypt user passwords. We need to provide updated values for all these use cases. @@ -385,13 +385,13 @@ EC256_PRIVATE_KEY: There are many other configuration values to update when moving to a production environment, such as database credentials, URLs, and more. -## Level Up {#level-up} +## Level Up -### Custom Assets and Wallets {#custom-assets-and-wallets} +### Custom Assets and Wallets The SDP contains a list of assets and wallets available for disbursements out-of-the-box. You might want to customize these, either to limit/expand options or to prepare for going live in production. Now that you've made a disbursement and added application secrets, let's look at how to customize the new disbursement options. -#### Assets {#assets} +#### Assets You can add and remove assets easily in the SDP dashboard. The SDP backend handles the request seamlessly, including checking for outstanding balance and adding/removing trustlines on the Stellar network. When assets are removed, the record is still retained in the database to preserve a full history. However, the asset will no longer be available for disbursements or holding a balance in the distribution account. @@ -403,11 +403,11 @@ Please make sure to update the appropriate configuration on the Anchor Platform ::: -#### Wallets {#wallets} +#### Wallets For a full overview on how to add wallets and how to make a wallet SDP-compatible, check out the [Making Your Wallet SDP-Ready](making-your-wallet-sdp-ready) guide. -### Wallet Address Registration {#wallet-address-registration} +### Wallet Address Registration Since version [`3.0.0`](https://github.com/stellar/stellar-disbursement-platform-backend/releases/tag/3.0.0), the SDP can pay directly to Stellar wallet addresses rather than directing the receivers through the registration flow. This is useful for organizations that are paying receivers who already have Stellar wallets and don't need to create a new one. diff --git a/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx b/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx index 47a8347e0..5fe6ab80b 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/making-your-wallet-sdp-ready.mdx @@ -9,7 +9,7 @@ Remember that any SDP instance will need an agreement with a wallet provider bef In this page, we will cover the technical aspects of the SDP-Wallet integration, including how to add a Wallet in the SDP database, how to validate and support the registration links using mobile app's [deep linking], how to start the user registration flow in the wallet using [SEP-24], and a recommended approach for handling [deferred deep linking]. -## Adding a Wallet to an SDP {#adding-a-wallet-to-an-sdp} +## Adding a Wallet to an SDP The default list of SDP wallets depends on which network is being used (testnet or pubnet). The network is passed as an environment variable and then the list of wallets can be seeded appropriately on SDP startup through the CLI command `./stellar-disbursement-platform db setup-for-network`, according with a hardcoded list of known wallets. Alternatively, wallets can be inserted directly into the SDP database through a SQL command. Both methods require adding the wallet name, homepage, SEP-10 client domain, and deep link schema. @@ -63,7 +63,7 @@ Please make sure to update the appropriate configuration on the Anchor Platform ::: -## Recipient Registration Experience {#recipient-registration-experience} +## Recipient Registration Experience The recipient registration experience is paramount to make this application smooth and easy to use. this requires the wallet to support [deferred deep linking], which will be discussed in a later section. A good description of the registration experience is as follows: @@ -75,7 +75,7 @@ The recipient registration experience is paramount to make this application smoo 1. The user receives the payment within seconds -## Registration Deep Link {#registration-deep-link} +## Registration Deep Link Once the user has installed the wallet application, the wallet should be able to interpret a [deep link] that follows the format registered in the SDP in order to kick off the [Wallet Registration Procedure](#wallet-registration-procedure). The deep link format supported by the SDP follows this format: @@ -138,7 +138,7 @@ console.log( ); ``` -### Wallet Registration Procedure {#wallet-registration-procedure} +### Wallet Registration Procedure When opening registration [deep link], these are the steps the wallet should follow in order to enforce the security and privacy measures expected in this flow, and to allow the user to input their information directly with the SDP: @@ -163,7 +163,7 @@ Additionally, the wallet should save the link and/or link attributes and associa 1. Saving the data is useful for reporting and troubleshooting, especially if the wallet needs to justify the source of funds for regulatory or tax purposes. 1. If the payer org wants to pay any cashout fees charged by the wallet or offramp, the wallet will need to know which users and transactions should be invoiced upstream. -### Deferred Deep Links {#deferred-deep-links} +### Deferred Deep Links Most likely, the intended recipient will not have the necessary wallet application installed on their device. For this reason, wallets should support the concept of [deferred deep linking], which enables the following flow: diff --git a/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx b/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx index 41c66bee4..ac7029ce6 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/secure-operation-manual.mdx @@ -7,7 +7,7 @@ This manual outlines the security measures implemented in the Stellar Disburseme Security is a critical aspect of the SDP. The measures outlined in this document are designed to mitigate risks and enhance the security of the platform. Users are strongly encouraged to follow these guidelines to protect their accounts and operations. -### Implementation of reCAPTCHA {#implementation-of-recaptcha} +### Implementation of reCAPTCHA Google's reCAPTCHA has been integrated into the SDP to prevent automated attacks and ensure that interactions are performed by humans, not bots. @@ -15,7 +15,7 @@ ReCAPTCHA is enabled by default and can be disabled in the development environme **Note:** Disabling reCAPTCHA is not supported for production environments due to security risks. -### Enforcement of Multi-Factor Authentication {#enforcement-of-multi-factor-authentication} +### Enforcement of Multi-Factor Authentication Multi-Factor Authentication (MFA) provides an additional layer of security to user accounts. It is enforced by default on the SDP and it relies on OTPs sent to the account's email. @@ -23,21 +23,21 @@ MFA is enabled by default and can be disabled in the development environment by **Note:** Disabling MFA is not supported for production environments due to security risks. -### Best Practices for Wallet Management {#best-practices-for-wallet-management} +### Best Practices for Wallet Management The SDP wallet should be used primarily as a hot wallet with a limited amount of funds to minimize potential losses. -#### Hot and Cold Wallets {#hot-and-cold-wallets} +#### Hot and Cold Wallets - A hot wallet is connected to the internet and allows for quick transactions. - A cold wallet is offline and used for storing funds securely. - Learn more about these concepts at [Investopedia](https://www.investopedia.com/hot-wallet-vs-cold-wallet-7098461). -### Distribution of Disbursement Responsibilities {#distribution-of-disbursement-responsibilities} +### Distribution of Disbursement Responsibilities To enhance security, disbursement responsibilities should be distributed among multiple financial controller users. -#### Recommended Configuration {#recommended-configuration} +#### Recommended Configuration 1. **Approval Flow**: Enable the approval flow on the organization page to require two users for the disbursement process. The owner can do that at _Profile > Organization > ... > Edit details > Approval flow > Confirm_. 2. **Financial Controller Role**: Create two users with the _Financial Controller_ role on the organization page to enforce separation of duties. The owner can do hat at _Settings > Team Members_. diff --git a/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx b/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx index be072bc81..a5c5e5d53 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/single-tenant-to-multi-tenant-migration.mdx @@ -10,7 +10,7 @@ import { CodeExample } from "@site/src/components/CodeExample"; Here you will find the required steps to migrate an existing single-tenant (`1.x`) Stellar Disbursement Platform application (SDP) to a multi-tenant (`2.x+`) version. -## Why Migrate? {#why-migrate} +## Why Migrate? Starting with version `2.x`, the SDP provides a multi-tenant architecture, where multiple organizations can manage disbursements under a unified infrastructure while maintaining separate datasets and funds management. @@ -26,13 +26,13 @@ You have the option of using the `2.1.0` version to perform this migration, and ::: -## Preparing for the Migrations {#preparing-for-the-migrations} +## Preparing for the Migrations -### Halt the Single-Tenant Version 🚧 {#halt-the-single-tenant-version-} +### Halt the Single-Tenant Version 🚧 Before proceeding with the migration, ensure that the single-tenant version of the SDP is not running. This is crucial to prevent any data inconsistencies or conflicts during the migration process. -### Double-Spending Prevention 🚨 {#double-spending-prevention-} +### Double-Spending Prevention 🚨 To avoid double-spending, ensure that no payment is in the `PENDING` state, otherwise this could result in having the same payment submitted independently by both single-tenant and multi-tenant instances. You can do that by checking the `payments` table for any payment in the `PENDING` state: @@ -56,7 +56,7 @@ SELECT * FROM public.submitter_transactions WHERE status = ANY(array['PROCESSING If there are any payments in the `PENDING` state or transactions in the `PROCESSING` state, you should wait for them to be processed and transitioned to either `SUCCESS` or `FAILED` before proceeding with the migration. -### Remove Channel Accounts 🧹 {#remove-channel-accounts-} +### Remove Channel Accounts 🧹 In version `2.x`, the channel accounts are encrypted using the `CHANNEL_ACCOUNT_ENCRYPTION_PASSPHRASE`, which is a different env from the one used in the single-tenant version (`DISTRIBUTION_SEED`). To avoid any issues, let's remove all existing channel accounts in the single-tenant version priot to the migration: @@ -68,7 +68,7 @@ In version `2.x`, the channel accounts are encrypted using the `CHANNEL_ACCOUNT_ -### Database Backup & Setup 💾 {#database-backup--setup-} +### Database Backup & Setup 💾 Backup your single-tenant database before proceeding with the migration. At this point, the single-tenant instance should be halted, and there shouldn't be any `PENDING` payments nor `PROCESSING` submitter_transactions. @@ -86,7 +86,7 @@ psql --dbname=$multiTenantDB < sdp-singleTenant.sql -## Changes Explained {#changes-explained} +## Changes Explained Among the changes introduced in the multi-tenant version, the most significant ones are: @@ -96,19 +96,19 @@ Among the changes introduced in the multi-tenant version, the most significant o 1. **CLI Commands**: some CLI commands have been revised to be tenant-aware, while others have been included to support new multi-tenant features. 1. **Database Structure**: the database structure has been revised to accommodate multi-tenancy and the tables are now distributed across multiple schemas, providing isolation between tenants. -### Infrastructure {#infrastructure} +### Infrastructure For the infrastructure setup, SDP Multi-tenant offers flexible operational modes. -#### Event Broker vs Scheduled Jobs {#event-broker-vs-scheduled-jobs} +#### Event Broker vs Scheduled Jobs Administrators can choose between using an event broker for event-driven operations, or scheduled jobs for periodic operations. Event brokers are recommended for multi-tenant setups, as they provide a scalable and reliable way to handle events, while scheduled jobs are recommended for local setups or single-tenant SDPs. Also, event-brokers provide faster communication between services. -#### Anchor Platform Version {#anchor-platform-version} +#### Anchor Platform Version While the single-tenant used [`stellar/anchor-platform:2.1.3`](https://hub.docker.com/layers/stellar/anchor-platform/2.1.3/images/sha256-e6ef4b17a8d3e5d1455fa3d8f5f7e2a2b9534ad749584ff5446d685eb07837e9?context=explore), the multi-tenant version requires [`stellar/anchor-platform:2.6.0`](https://hub.docker.com/layers/stellar/anchor-platform/2.6.0/images/sha256-913fa2461d36d5150724a172ca46f8c76284a3890b60a9d5709fe0c606af78b9) or later. -### Environment Variables {#environment-variables} +### Environment Variables Below are the environment variables that have been added or modified in the multi-tenant version. @@ -149,17 +149,17 @@ On the Anchor Platform side, we must set the following envs: - `SEP10_HOME_DOMAIN=""`: this should be an empty string for the Multi-tenant version. - `SEP10_WEB_AUTH_DOMAIN=`: the home domain of the anchor platform instance. -### Seggregation of Funds {#seggregation-of-funds} +### Seggregation of Funds In the multi-tenant version, tenants funds are isolated from each other **unless the tenant is created with `"distribution_account_type": "DISTRIBUTION_ACCOUNT.STELLAR.ENV"`**. For more information on the distribution account types, please refer to the [Tenant Provisioning](./tenant-provisioning.mdx#creating-tenants) section. The channel accounts on the other hand are shared between tenants, and they are created by the HOST distribution account, set in the `DISTRIBUTION_SEED` environment variable. The channel accounts are encrypted using the `CHANNEL_ACCOUNT_ENCRYPTION_PASSPHRASE` environment variable, or the `DISTRIBUTION_SEED` if the former is not set. In the single-tenant version, the channel accounts were encrypted by the `DISTRIBUTION_SEED`. -### CLI Commands {#cli-commands} +### CLI Commands The following CLI commands were updated to become tenant-aware: -#### Database Migrations & Population {#database-migrations--population} +#### Database Migrations & Population The single-tenant commands for DB migration and pre-population used to be: @@ -192,7 +192,7 @@ Please notice that some commands require a tenant-aware flag, that can be either - `--all`: to execute these migrations in all tenants. - `--tenant-id`: to specify the tenant ID to execute the migrations. -#### Channel Accounts {#channel-accounts} +#### Channel Accounts The ensure command was updated from using the `--num-channel-accounts-ensure` flag to using a positional argument: @@ -205,7 +205,7 @@ The ensure command was updated from using the `--num-channel-accounts-ensure` fl -### Database Structure {#database-structure} +### Database Structure In the updated version, the database structure has been revised to accommodate multi-tenancy. As a result, the tables are now distributed across multiple schemas, and new tables have been introduced to support the multi-tenant architecture. The following schemas are used in the multi-tenant version: @@ -215,7 +215,7 @@ In the updated version, the database structure has been revised to accommodate m These changes allow for the isolation of tenant data per schema, ensuring that each tenant's data is kept separate from other tenants. -## Step-by-Step Migration Guide {#step-by-step-migration-guide} +## Step-by-Step Migration Guide :::tip @@ -225,11 +225,11 @@ The project has a [script](https://github.com/stellar/stellar-disbursement-platf Using the new database created from the single-tenant database dump as a starting point (as described in the [Database Backup & Setup](#database-backup--setup-) section), we can now proceed with the migration steps below. -### Deploy the New Version {#deploy-the-new-version} +### Deploy the New Version To transaction to a multi-tenant setup, deploy the latest version of the SDP `2+` version. If you're using helm charts, you can get the helm chart from the [SDP Helm Chart repository](https://github.com/stellar/helm-charts/pull/80). -### Executing Initial Database Migrations {#executing-initial-database-migrations} +### Executing Initial Database Migrations Following the deployment of the multi-tenant SDP, the next step is to perform the initial **database migrations**. It does not include the tenant-specific tables yet, they will be created later. @@ -246,13 +246,13 @@ Migration Commands: These commands will create the tenant admin tables on the **admin** schema and the Transaction Submitter Service tables on the **tss** schema, respectively. -### New Tenant Provisioning Process {#new-tenant-provisioning-process} +### New Tenant Provisioning Process After successfully applying the database migrations, the next step is to provision a new tenant. This is achieved by making an HTTP request to the **Admin API**. Be aware that it will provision the tenants with all the per-tenant migrations included. -#### Starting the SDP API server {#starting-the-sdp-api-server} +#### Starting the SDP API server To facilitate tenant provisioning, initiate the SDP Server using the command: @@ -264,7 +264,7 @@ To facilitate tenant provisioning, initiate the SDP Server using the command: -#### Posting to the Admin API {#posting-to-the-admin-api} +#### Posting to the Admin API - **API port**: The Admin API is accessible on port `8003` by default. This port setting can be adjusted by altering the `ADMIN_PORT` environment variable. - **Authentication**: Admin API employs Basic Authentication for securing access. To authenticate, populate the request "Authorization" header with `"Authorization: Basic ${Base64(ADMIN_ACCOUNT:ADMIN_API_KEY)}"`. @@ -307,7 +307,7 @@ In the SDP Multi-tenant, certain configurations previously managed through envir The field **name** is important because it's the tenant identifier. The other fields can be set to the same values used on the environment variables used on the non-tenant version. -### Importing your data {#importing-your-data} +### Importing your data Now that we've provisioned a new tenant, we can import our data into it. We need to copy our old tables' data to the new tenant schema. @@ -329,7 +329,7 @@ To help with the import process, we added a function to the `admin` schema that This concludes the migration of the SDP data to the multi-tenant version. The next step is to drop the old tables that are no longer needed. -### Drop Old Tables {#drop-old-tables} +### Drop Old Tables Now, the only missing step is to drop the single-tenant tables that should not be in the multi-tenant database: @@ -361,7 +361,7 @@ COMMIT; -### Conclusion 🎉 {#conclusion-} +### Conclusion 🎉 This should conclude the data migration from the single-tenant version to the multi-tenant version of the SDP. Please, make sure to run an e2e test to ensure that everything is working as expected. diff --git a/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx b/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx index c771dd584..5c0ad4e4f 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/tenant-provisioning.mdx @@ -10,13 +10,13 @@ This section covers the steps to provision a new tenant in the Stellar Disbursem The endpoints needed to manage tenants can be found in the [Admin (Tenant Management)](../api-reference/admin.tag.mdx) docs. -## Creating Tenants {#creating-tenants} +## Creating Tenants Tenants can be created through the [POST /tenants](../api-reference/create-tenant.api.mdx) endpoint. As a quickstart, you can execute the [main.sh](https://github.com/stellar/stellar-disbursement-platform-backend/blob/develop/dev/main.sh) script from our repository and make sure to replace it with the desired values. The following sections detail how each field is used on the provisioning process and, so you can ensure the tenants are provisioned as expected: -### `distribution_account_type` {#distribution_account_type} +### `distribution_account_type` This is by far the most important field, as it determines the source of funds (distribution account) for the tenant, as well as how the secret for this distribution account is stored. The possible values are described below: @@ -51,29 +51,29 @@ Once a tenant is created, the `distribution_account_type` cannot be changed. If ::: -### `name` {#name} +### `name` This is the name of the tenant in the admin database. It is used to generate the per-tenant database schema, and is also used in the dashboard to identify the tenant. It cannot be changed once the tenant is created. -### `base_url`, and `sdp_ui_base_url` {#base_url-and-sdp_ui_base_url} +### `base_url`, and `sdp_ui_base_url` These are the URLs that the tenant will use to access the API and the dashboard, respectively. They are used to generate the tenant-specific URLs that are used in the dashboard and the user-targeted or receiver-targeted messages. They are important to allow the SDP backend to route the unauthenticated requests to the correct tenant, and to generate the correct URLs in the dashboard. -### `owner_email`, `owner_first_name`, and `owner_last_name` {#owner_email-owner_first_name-and-owner_last_name} +### `owner_email`, `owner_first_name`, and `owner_last_name` This is the information of the first user in the tenant organization. This user will have the `OWNER` role, which grants them full access & control to the tenant. The email, first name, and last name can be updated by the user themselvses once they sign up and access the dashboard. -### `organization_name` {#organization_name} +### `organization_name` This fields is used to populate the tenant's name in the dashboard. It can be updated by the owner user through the dashboard. -## Single-tenant Mode {#single-tenant-mode} +## Single-tenant Mode The platform is designed for multi-tenant mode, but it can also be used in single-tenant mode. This is the only case when setting `DISTRIBUTION_ACCOUNT.STELLAR.ENV` is acceptable, while the other modes are still advised. @@ -88,15 +88,15 @@ Once this `SINGLE_TENANT_MODE` env is enabled, all tenant-related requests will ::: -## Fetching Tenants {#fetching-tenants} +## Fetching Tenants The tenants can be fetched through the [GET /tenants](../api-reference/get-all-tenants.api.mdx) and [GET /tenants/:id-or-name](../api-reference/retrieve-a-tenant.api.mdx) endpoints. -## Deleting Tenants {#deleting-tenants} +## Deleting Tenants Tenants can be deleted through the [DELETE /tenants/:id](../api-reference/soft-delete-a-tenant.api.mdx) endpoint. This is a soft deletion though and despite the system not providing a way to ubdelete it, the tenant information won't be deleted from the database with the current implementation. -## Updating Tenants {#updating-tenants} +## Updating Tenants Some fields of a tenant can be updated through the [PATCH /tenants/:id](../api-reference/update-a-tenant.api.mdx) endpoint. The API documentation provides more details on which fields can be updated. diff --git a/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx b/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx index 21c4f94ae..28c9e8599 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/user-interface/wallets.mdx @@ -14,6 +14,6 @@ The Wallets page includes the following: - USDC, EUROC, etc: This is the current balance available for making payments within a disbursement. - XLM: This is the balance of Stellar Lumens. This is used to fund the distribution account (base reserve) and transaction fees associated with making payments. This is for informational purposes and is not the source of funds for disbursements. In general, you do not need to worry about maintaining this, as Stellar network fees are very low. -### Adding Funds {#adding-funds} +### Adding Funds Add funds to your distribution account: You can deposit Stellar-based digital assets into your distribution account by sending them to the provided public key. Make sure your account has a trustline to the asset before you send funds. As a general principle, do not use your distribution account as a long-term holding place for money. It is meant to be a pass-through wallet to fund disbursements. diff --git a/src/pages/docs/learn/interactive/dapps/challenges/challenge-0-crowdfund.mdx b/src/pages/docs/learn/interactive/dapps/challenges/challenge-0-crowdfund.mdx index 7690b72dc..fbdb33ad9 100644 --- a/src/pages/docs/learn/interactive/dapps/challenges/challenge-0-crowdfund.mdx +++ b/src/pages/docs/learn/interactive/dapps/challenges/challenge-0-crowdfund.mdx @@ -30,7 +30,7 @@ This challenge will guide you through the process of building and shipping a cro In this challenge, you will learn how to deploy smart contracts to Futurenet, and how to interact with them through a web frontend. In this context, the term "ship" refers to finalizing the development process of your dapp, ensuring that it functions as expected, and is accessible for user interaction and testing through a hosted frontend. However, it's crucial to clarify that despite its functionality, the dapp is not promoted nor intended for deployment in a production-level setting on Futurenet. The challenge is designed for educational purposes, helping you understand how a dapp can be built and interacted with, with further customization and development, it has the potential to evolve into a full-fledged, ready-to-use crowdfunding solution. -## Checkpoint 0: 📦 Install 📚 {#checkpoint-0--install-} +## Checkpoint 0: 📦 Install 📚 Start by installing the required dependencies. You'll also want to be sure you have the most updated version of Rust installed. @@ -56,7 +56,7 @@ cargo install_soroban Soroban CLI is the command line interface to Soroban. It allows you to build, deploy, and interact with smart contracts, configure identities, generate key pairs, manage networks, and more. The soroban-cli (alias) that is used in this challenge is a pinned version of the soroban-cli that is used in the Soroban Dapps Challenge. This ensures that the challenge is reproducible and that all participants are using the same version of Soroban. -## Checkpoint 1: 🎬 Deploy Smart Contracts {#checkpoint-1--deploy-smart-contracts} +## Checkpoint 1: 🎬 Deploy Smart Contracts Now that you have the Crowdfund branch checked out, it's time to deploy the smart contracts to a Sandbox environment. Deploying a smart contract in a production setting involves submitting the contract code to the blockchain's main network ( Mainnet ), where it becomes part of the chain's immutable ledger. Deploying smart contracts to a Sandbox environment simulates that process without actually affecting Mainnet. When you deploy the smart contracts, you'll instead deploy to Futurenet, a test network with more cutting-edge features that have not yet been implemented in the Mainnet. @@ -92,7 +92,7 @@ Please, save your deployed contract ID. You will need it to complete the challen {/* */} -## Checkpoint 2: 🤝 Connect the Frontend to the Backend {#checkpoint-2--connect-the-frontend-to-the-backend} +## Checkpoint 2: 🤝 Connect the Frontend to the Backend Now that you have deployed the smart contract, it's time to check out the frontend of your dapp. The frontend is the browser interface where contributors to your crowdfund campaign will connect their digital wallets and pledge assets to the campaign's cause. @@ -110,7 +110,7 @@ Now that you have the frontend running, it's time to connect it with the backend You will need to add some Futurenet network lumens to your wallet to interact with the dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create and or fund an account on Futurenet. Remember, these are test lumens for use on Futurenet and cannot be used on Mainnet. -## Checkpoint 3: 🌟 Powering the Campaign {#checkpoint-3--powering-the-campaign} +## Checkpoint 3: 🌟 Powering the Campaign Fuel the vision! In this step, you will learn how to mint tokens and fund the crowdfunding campaign. Minting tokens in a crowdfund dapp, while not always required, serves as a bootstrapping mechanism for the campaign, allowing the campaign to be funded with the minted tokens. @@ -129,7 +129,7 @@ Fuel the vision! In this step, you will learn how to mint tokens and fund the cr -#### Open Dapp and Mint {#open-dapp-and-mint} +#### Open Dapp and Mint Open the dapp frontend and click on the "Mint 100 ABND" button. @@ -139,7 +139,7 @@ Open the dapp frontend and click on the "Mint 100 ABND" button. -#### Approve Transaction {#approve-transaction} +#### Approve Transaction You should see a popup from Freighter asking you to sign the transaction. Click on "Approve" and wait for the transaction to be confirmed. @@ -149,7 +149,7 @@ You should see a popup from Freighter asking you to sign the transaction. Click -#### Check Updated Balance {#check-updated-balance} +#### Check Updated Balance You should see an updated balance in the pledge component. @@ -171,7 +171,7 @@ You should see an updated balance in the pledge component. -#### Fund the Campaign {#fund-the-campaign} +#### Fund the Campaign Now that you have your wallet set up, let's fund the crowdfunding campaign. Open the frontend and click on the "Back this project" button. You should see a popup from Freighter asking you to sign the transaction. @@ -181,7 +181,7 @@ Now that you have your wallet set up, let's fund the crowdfunding campaign. Open -#### Approve Transaction {#approve-transaction-1} +#### Approve Transaction Click on "Approve" and wait for the transaction to be confirmed. Once the transaction is confirmed, you should see a success message. @@ -191,7 +191,7 @@ Click on "Approve" and wait for the transaction to be confirmed. Once the transa -#### Check Updated Pledged Amount {#check-updated-pledged-amount} +#### Check Updated Pledged Amount You should see an updated balance reflecting the amount you have pledged in the pledge component. @@ -209,7 +209,7 @@ You should see an updated balance reflecting the amount you have pledged in the {/* Funding completed */} -## Checkpoint 4: 🚢 Ship it! 🚁 {#checkpoint-4--ship-it-} +## Checkpoint 4: 🚢 Ship it! 🚁 Now that your dapp is fully functional, its time to deploy it to a production environment. In this step, you will learn how to deploy your dapp to Vercel, a cloud platform for static sites that offers a quick and effective way to deploy the frontend of your dapp. This section requires that you have a [Vercel account] and the Vercel cli installed. @@ -271,7 +271,7 @@ You can now visit the preview link to see your deployed dapp! 🎉 Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create your Freighter account on Futurenet. -## Checkpoint 5: 💪 Pass the Challenge! {#checkpoint-5--pass-the-challenge} +## Checkpoint 5: 💪 Pass the Challenge! Now it's time to submit your work! @@ -285,7 +285,7 @@ Join [our Community in Discord](https://discord.gg/stellardev) in case you have ::: -## Checkpoint 6: ✅ Check your work! {#checkpoint-6--check-your-work} +## Checkpoint 6: ✅ Check your work! In order to successfully complete this challenge, your work needs to be checked. Please, follow the steps below: @@ -308,7 +308,7 @@ Public Key: GBSXUXZSA2VEXN5VGOWE5ODAJLC575JCMWRJ4FFRDWSTRCJ123456789 Invite a friend to try out your dapp and ask them to provide feedback! -## ⚔️ Side Quests {#️-side-quests} +## ⚔️ Side Quests 🌐 Explore [Stellar Lab] to inspect your account assets on Futurenet. @@ -333,7 +333,7 @@ You should see something like this: [stellar lab]: https://lab.stellar.org/?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;; -## 📚 User Workflows Checklist {#-user-workflows-checklist} +## 📚 User Workflows Checklist During this exercise you should be able to: @@ -352,6 +352,6 @@ Then via the web UI, you should be able to: - See your deposit(s) appear on the page as the transactions are confirmed. - "Live"-Update the page with the total amount with the new amount -## 🛡️🗡️ Take On More Challenges {#️️-take-on-more-challenges} +## 🛡️🗡️ Take On More Challenges View your progress and take on more challenges by visiting your [User Dashboard!](../dashboard) diff --git a/src/pages/docs/learn/interactive/dapps/challenges/challenge-1-payment.mdx b/src/pages/docs/learn/interactive/dapps/challenges/challenge-1-payment.mdx index d6128db8e..ed8e2634b 100644 --- a/src/pages/docs/learn/interactive/dapps/challenges/challenge-1-payment.mdx +++ b/src/pages/docs/learn/interactive/dapps/challenges/challenge-1-payment.mdx @@ -37,7 +37,7 @@ import "./styles.css"; This challenge will guide you through the process of setting up, customizing, and deploying a Soroban Payment dapp, a blockchain-powered payment application designed to work with the Freighter wallet. Payment dapps are powerful because they offer users equitable and accessible means to send and receive payments. Transactions via a payment dapp are peer-to-peer, which means that no central authority, third-party, or bank oversees or controls the payment. This decentralization reduces payment fees, which are comparatively minimal on a blockchain, and transaction time, which is, via a payment dapp, almost instantaneous. What's more, the wallet integration in a payment dapp, like Freighter in this case, means that anyone with a smartphone and the wallet installed can use the payment dapp, no matter where they are in the world. -## Checkpoint 0: 📦 Install Dependencies {#checkpoint-0--install-dependencies} +## Checkpoint 0: 📦 Install Dependencies Before you begin, ensure you have the following installed on your system. You'll also want to be sure you have the most updated versions of Rust and Soroban installed. @@ -48,7 +48,7 @@ Before you begin, ensure you have the following installed on your system. You'll Node and Yarn are package managers that let you install and manage dependencies during the dapp development process. Freighter is the wallet you will integrate into your payment dapp. -## Checkpoint 1: 🚀 Clone the Repository {#checkpoint-1--clone-the-repository} +## Checkpoint 1: 🚀 Clone the Repository Clone and set up the Soroban Dapps Challenge repository, which contains the Soroban Payment Dapp files. Then run yarn to install the dependencies. @@ -59,7 +59,7 @@ git checkout payment yarn ``` -## Checkpoint 2: 🎬 Deploy Smart Contracts {#checkpoint-2--deploy-smart-contracts} +## Checkpoint 2: 🎬 Deploy Smart Contracts For this step you will need to clone and deploy the Soroban token smart contract from the [Soroban Examples repository](https://github.com/stellar/soroban-examples/tree/v21.6.0/token). This Soroban token smart contract, broken into several smaller modules (as is the custom for complex smart contracts like this one), enables you to create and manage tokens on Soroban. @@ -145,7 +145,7 @@ soroban contract invoke \ {/* */} -## Checkpoint 3: 🖥️ Launch the Frontend {#checkpoint-3-️-launch-the-frontend} +## Checkpoint 3: 🖥️ Launch the Frontend In this checkpoint, you will make sure that the frontend of the Payment Dapp successfully communicates with the backend, allowing transactions to be created, signed, and submitted to the network. @@ -170,7 +170,7 @@ Now open your browser and navigate to [`http://localhost:9000`](http://localhost connect -## Checkpoint 4: 🚀 Token Transfer Odyssey {#checkpoint-4--token-transfer-odyssey} +## Checkpoint 4: 🚀 Token Transfer Odyssey Strap in and get ready to send some tokens! In this step, you will use the Payment Dapp to send Soroban tokens to another account. @@ -188,7 +188,7 @@ Strap in and get ready to send some tokens! In this step, you will use the Payme -#### Add Soroban Token {#add-soroban-token} +#### Add Soroban Token To add the newly minted DT token type to your wallet, open your Freighter wallet and click on the `Manage Assets` button at the bottom of the screen. @@ -204,7 +204,7 @@ Then click on the `Add Soroban token ` button and enter the token contract ID th -#### Check Token Addition {#check-token-addition} +#### Check Token Addition You should now see the Soroban token in your Freighter wallet. @@ -223,7 +223,7 @@ You should now see the Soroban token in your Freighter wallet. -#### Connect Freighter and Select Account {#connect-freighter-and-select-account} +#### Connect Freighter and Select Account Back on your dapp's frontend webpage, make sure Freighter is connected and then select the account that will be used to send Soroban tokens. Click "next" to continue. @@ -232,7 +232,7 @@ Back on your dapp's frontend webpage, make sure Freighter is connected and then -#### Provide Token Transfer Details {#provide-token-transfer-details} +#### Provide Token Transfer Details To send DT tokens via the Payment dapp, provide the public key of the account that will receive the Soroban tokens. (This could be another of your own Freighter accounts.) @@ -253,7 +253,7 @@ Confirm the payment settings, which include the option to add a memo and show th -#### Confirm and Submit Transaction {#confirm-and-submit-transaction} +#### Confirm and Submit Transaction Review the transaction details to ensure accuracy and then click "Sign with Freighter". Freighter will prompt you to sign the transaction with your wallet's private key. @@ -297,7 +297,7 @@ Output: {/* Tokens Sent */} -## Checkpoint 5: 🚢 Ship it! 🚁 {#checkpoint-5--ship-it-} +## Checkpoint 5: 🚢 Ship it! 🚁 In this step, you will deploy your dapp to a hosting platform so that it can be accessed by anyone with an internet connection. You can use any hosting platform you like, but for demonstration purposes, this section will use [Vercel](https://vercel.com/). Vercel is a cloud platform for static sites and serverless functions that offers a free tier for developers. It also has a built-in integration with GitHub, which makes it easy to deploy your dapp directly from your GitHub repository. @@ -418,7 +418,7 @@ You can now visit the preview link to see your deployed dapp! 🎉 Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create your Freighter account on Futurenet. -## Checkpoint 6: ✅ Complete the Challenge! {#checkpoint-6--complete-the-challenge} +## Checkpoint 6: ✅ Complete the Challenge! Now it's time to submit your work! @@ -432,11 +432,11 @@ Join [our Community in Discord](https://discord.gg/stellardev) in case you have ::: -## Checkpoint 7: 💪 Share Your Accomplishment with the Community {#checkpoint-7--share-your-accomplishment-with-the-community} +## Checkpoint 7: 💪 Share Your Accomplishment with the Community Don't forget to share your work with the community. Let others see what you've accomplished, receive feedback, and inspire others! -## ⚔️ Side Quests {#️-side-quests} +## ⚔️ Side Quests 🍴[Fork the Example Soroban Payment Dapp repo] and make your own changes to your Dapp. @@ -444,7 +444,7 @@ Consider customizing the code and submitting a pull request for the challenge. Y [fork the example soroban payment dapp repo]: https://github.com/stellar/soroban-react-payment -## 📚 User Workflows Checklist {#-user-workflows-checklist} +## 📚 User Workflows Checklist To ensure that you've covered all the key user actions during the challenge, follow this checklist: @@ -459,6 +459,6 @@ To ensure that you've covered all the key user actions during the challenge, fol - Deploy the site with Vercel - Submit your public key and URL -## 🛡️🗡️ Take On More Challenges {#️️-take-on-more-challenges} +## 🛡️🗡️ Take On More Challenges View your progress and take on more challenges by visiting your [User Dashboard!](../dashboard) diff --git a/src/pages/docs/learn/interactive/dapps/challenges/challenge-2-liquidity-pool.mdx b/src/pages/docs/learn/interactive/dapps/challenges/challenge-2-liquidity-pool.mdx index 115865495..8a7ea90ad 100644 --- a/src/pages/docs/learn/interactive/dapps/challenges/challenge-2-liquidity-pool.mdx +++ b/src/pages/docs/learn/interactive/dapps/challenges/challenge-2-liquidity-pool.mdx @@ -32,7 +32,7 @@ A liquidity pool is a collection of tokens or digital assets deposited by users The functionality of this liquidity pool dapp will allow users to mint tokens, deposit liquidity, swap between asset types, and withdraw funds from the liquidity pool. This dapp challenge will walk you through the step-by-step process of creating and launching a liquidity pool dapp on Stellar using Soroban smart contracts. You will learn how to deploy smart contracts to a sandbox environment and interact with them through a web frontend. In this context, the term "ship" refers to finalizing the development process of your dapp, ensuring that it functions as expected and is accessible for user interaction and testing through a hosted frontend. Despite the end-to-end functionality of this challenge, this dapp is not promoted nor intended for deployment in a production-level setting on Futurenet, but rather is designed for educational purposes. -## Checkpoint 0: 📦 Install 📚 {#checkpoint-0--install-} +## Checkpoint 0: 📦 Install 📚 Start by installing the required dependencies. You'll also want to be sure you have the most updated version of Rust installed. @@ -58,7 +58,7 @@ cargo install_soroban Soroban CLI is the command line interface to Soroban. It allows you to build, deploy, and interact with smart contracts, configure identities, generate key pairs, manage networks, and more. The soroban-cli alias that is used in this challenge is a pinned version of the soroban-cli that is used in the Soroban Dapps Challenge. Using the soroban-cli alias ensures that the challenge is reproducible and that all participants are using the same version of Soroban. -## Checkpoint 1: 🎬 Deploy Smart Contracts {#checkpoint-1--deploy-smart-contracts} +## Checkpoint 1: 🎬 Deploy Smart Contracts Deploying a smart contract in a production setting involves submitting the contract code to the blockchain's main network (Mainnet), where it becomes part of the chain's immutable ledger. When you deploy the smart contracts in this challenge, you'll instead deploy to Futurenet, a test network with more cutting-edge features that have not yet been implemented in the Mainnet. Deploying smart contracts to a sandbox environment simulates the production-level deployment process without actually affecting Mainnet. @@ -94,7 +94,7 @@ Please, save your deployed contract ID. You will need it to complete the challen {/* */} -## Checkpoint 2: 🤝 Connect the Frontend to the Backend {#checkpoint-2--connect-the-frontend-to-the-backend} +## Checkpoint 2: 🤝 Connect the Frontend to the Backend Now that you have deployed the smart contract, it's time to check out the frontend of your dapp. The frontend is the browser interface where users will connect their digital wallets to make deposits into and withdrawals from the liquidity pool. The frontend is also where users will be able to see their balances and swap tokens. @@ -116,7 +116,7 @@ Now that you have the frontend running, it's time to connect it with the backend You will need to add some Futurenet network lumens to your wallet to interact with the dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create), and follow the instructions to create and or fund an account on Futurenet. Remember, these are test lumens for use on Futurenet and cannot be used on Mainnet. -## Checkpoint 3: 🌊 Dive into the Liquidity Pool {#checkpoint-3--dive-into-the-liquidity-pool} +## Checkpoint 3: 🌊 Dive into the Liquidity Pool Embark on a tidal journey! In this step you will mint, deposit, swap, and withdraw tokens from the liquidity pool. Minting tokens, depositing liquidity, swapping between asset types, and withdrawing funds from the liquidity pool constitute the basic lifecycle of interacting with a DeFi protocol. @@ -139,7 +139,7 @@ In the context of liquidity pools, depositing and withdrawing assets involve con -#### Mint USDC and BTC {#mint-usdc-and-btc} +#### Mint USDC and BTC In order to use this liquidity pool dapp, you will need to mint test tokens which can then be used to make deposits and swaps via the frontend of the dapp. To mint USDC and BTC test tokens, open the dapp frontend and click the "MINT" button for USDC and BTC. @@ -148,7 +148,7 @@ In order to use this liquidity pool dapp, you will need to mint test tokens whic -#### Approve Transaction {#approve-transaction} +#### Approve Transaction You should see a popup from Freighter asking you to sign the transactions. Click on "Approve" and wait for the transaction to be confirmed. @@ -157,7 +157,7 @@ You should see a popup from Freighter asking you to sign the transactions. Click -#### Check Updated Balance {#check-updated-balance} +#### Check Updated Balance You should see an updated balance in the account balance component. @@ -178,7 +178,7 @@ You should see an updated balance in the account balance component. -#### Deposit into the Liquidity Pool {#deposit-into-the-liquidity-pool} +#### Deposit into the Liquidity Pool Depositing assets into the liquidity pool involves users submitting deposit transactions via the frontend to deposit tokens from their wallet into the liquidity pool. In this dapp you will make a deposit of two asset types in order to swap between those asset types. In other DeFi protocols, users may also deposit liquidity into a liquidity pool in order to earn yields on their deposits. The intial deposit of liquidity into a liquidity pool is what sets the initial price of the tokens in the pool. For example, if a user deposits 37000 USDC and 1 BTC, the price of each BTC token will be 37000 USDC. @@ -189,7 +189,7 @@ Open the frontend, enter the desired token amounts, and click the "Deposit" butt -#### Approve Transaction {#approve-transaction-1} +#### Approve Transaction Click on "Approve" and wait for the transaction to be confirmed. Once the transaction is confirmed, you should see your balances updated. @@ -197,7 +197,7 @@ Click on "Approve" and wait for the transaction to be confirmed. Once the transa -#### Check Updated Balance {#check-updated-balance-1} +#### Check Updated Balance You should see an updated balance in the amounts you have deposited in the account and reserve balance components, respectively. Following the example, you should see 50 USDC, 50 BTC, and 50 POOL. @@ -219,7 +219,7 @@ You should see an updated balance in the amounts you have deposited in the accou -#### Swap Tokens {#swap-tokens} +#### Swap Tokens Now that you have funded the liquidity pool, you can make a swap to easily exchange one token for another. Swaps in a liquidity pool usually depend on the relationship between two or more different tokens that can be exchanged with each other. Typical liquidity pools rely on a mathematical formula that determines the price of the tokens within the pool. With every deposit and withdraw transaction to or from the pool, the formula adjusts the token price of each token based on this formula. When a swap occurs, the liquidity pool uses the formula and the balances of each token with the pool to determine the swap value of each token relative to the others within the pool. @@ -237,7 +237,7 @@ To complete a swap between USDC and BTC test tokens, open the swap tab of the fr -#### Approve Transaction {#approve-transaction-2} +#### Approve Transaction Click on "Approve" and wait for the transaction to be confirmed. @@ -245,7 +245,7 @@ Click on "Approve" and wait for the transaction to be confirmed. -#### Check Updated Balance {#check-updated-balance-2} +#### Check Updated Balance Once the transaction is confirmed, you should see updated balances on the frontend. @@ -267,7 +267,7 @@ Once the transaction is confirmed, you should see updated balances on the fronte -#### Withdraw Tokens from the Liquidity Pool {#withdraw-tokens-from-the-liquidity-pool} +#### Withdraw Tokens from the Liquidity Pool Now that you have swapped tokens through the liquidity pool, you can make a withdrawal of your funds. @@ -281,7 +281,7 @@ Open the withdraw tab, select how much liquidity you want to remove with the sli -#### Approve Transaction {#approve-transaction-3} +#### Approve Transaction Click on "Approve" and wait for the transaction to be confirmed. @@ -289,7 +289,7 @@ Click on "Approve" and wait for the transaction to be confirmed. -#### Check Updated Balance {#check-updated-balance-3} +#### Check Updated Balance Once the transaction is confirmed, you should see updated balances on the frontend. @@ -305,7 +305,7 @@ Once the transaction is confirmed, you should see updated balances on the fronte {/* Transactions completed */} -## Checkpoint 4: 🚢 Ship It! 🚁 {#checkpoint-4--ship-it-} +## Checkpoint 4: 🚢 Ship It! 🚁 Now that your dapp is fully functional, its time to deploy it to a production environment. In this step, you will learn how to deploy your dapp to Vercel, a cloud platform for static sites that offers a quick and effective way to deploy the frontend of your dapp. This section requires that you have a [Vercel account] and install the Vercel CLI. @@ -421,7 +421,7 @@ You can now visit the preview link to see your deployed dapp! 🎉 Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create your Freighter account on Futurenet. -## Checkpoint 5: ✅ Complete the Challenge! {#checkpoint-5--complete-the-challenge} +## Checkpoint 5: ✅ Complete the Challenge! Now it's time to submit your work! @@ -429,7 +429,7 @@ Submit your `Production` URL from the previous step into the challenge form to p {/* */} -## Checkpoint 6: 💪 Flex! {#checkpoint-6--flex} +## Checkpoint 6: 💪 Flex! 🍴 [Fork the Soroban Dapps Challenge repo] and make your own changes to the Liquidity Pool branch. @@ -440,7 +440,7 @@ Take this opportunity to showcase your skills and make your mark on the Liquidit [stellar lab]: https://lab.stellar.org/?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;; [fork the soroban dapps challenge repo]: https://github.com/stellar/soroban-dapps-challenge/fork -## 📚 User Workflows Checklist {#-user-workflows-checklist} +## 📚 User Workflows Checklist During this exercise, you should be able to: @@ -458,6 +458,6 @@ Then, via the web UI, you should be able to: - Withdraw assets - See your transaction(s) appear on the page as the transactions are confirmed -## 🛡️🗡️ Take On More Challenges {#️️-take-on-more-challenges} +## 🛡️🗡️ Take On More Challenges View your progress and take on more challenges by visiting your [User Dashboard!](../dashboard) diff --git a/src/pages/docs/learn/interactive/dapps/challenges/challenge-3-oracle.mdx b/src/pages/docs/learn/interactive/dapps/challenges/challenge-3-oracle.mdx index a33e132b8..197100c21 100644 --- a/src/pages/docs/learn/interactive/dapps/challenges/challenge-3-oracle.mdx +++ b/src/pages/docs/learn/interactive/dapps/challenges/challenge-3-oracle.mdx @@ -32,7 +32,7 @@ This challenge will guide you through the process of building and shipping an or In this challenge, you will learn how to deploy smart contracts to Futurenet, and how to interact with them through a web frontend. In this context, the term "ship" refers to finalizing the development process of your dapp, ensuring that it functions as expected, and is accessible for user interaction and testing through a hosted frontend. However, it's crucial to clarify that despite its functionality, the dapp is not promoted nor intended for deployment in a production-level setting on Mainnet. The challenge is designed for educational purposes only, helping you understand how a dapp can be built and interacted with, with further customization and development, it has the potential to evolve into a full-fledged, ready-to-use oracle solution. -## Checkpoint 0: 📦 Install 📚 {#checkpoint-0--install-} +## Checkpoint 0: 📦 Install 📚 Start by installing the required dependencies. @@ -60,7 +60,7 @@ cargo install --locked --version 20.0.0-rc.4.1 soroban-cli Soroban CLI is the command line interface to Soroban. It allows you to build, deploy, and interact with smart contracts; configure identities; generate key pairs; manage networks; and more. -## Checkpoint 1: 📝 Setup the `initialize.sh` Script {#checkpoint-1--setup-the-initializesh-script} +## Checkpoint 1: 📝 Setup the `initialize.sh` Script The `initialize.sh` script is a shell script that will help you initialize the contracts and install dependencies. It is located in the top level directory. @@ -115,7 +115,7 @@ Here is a description of each parameter: - `` - frequency (in seconds) of price updates - `` - address of the wallet that will update the price (in the backend, in the CRON task). It is suggested to create a dedicated wallet for this ([be sure to fund with test Lumens](https://lab.stellar.org/?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;)) -## Checkpoint 2: 🎬 Deploy Smart Contracts {#checkpoint-2--deploy-smart-contracts} +## Checkpoint 2: 🎬 Deploy Smart Contracts Now that the initialization script is set up it's time to deploy the smart contracts to a Sandbox environment. Deploying a smart contract in a production setting involves submitting the contract code to the blockchain's main network ( Mainnet ), where it becomes part of the chain's immutable ledger. Deploying smart contracts to a Sandbox environment simulates that process without actually affecting Mainnet. When you deploy the smart contracts, you'll instead deploy to Futurenet, a test network with more cutting-edge features that have not yet been implemented in the Mainnet. @@ -162,7 +162,7 @@ Please, save your deployed contract ID, you will need it to complete the challen {/* */} -## Checkpoint 3: ⏯️ Create a CRON task {#checkpoint-3-️-create-a-cron-task} +## Checkpoint 3: ⏯️ Create a CRON task A CRON task is a scheduled operation performed at specified intervals, functioning as a customizable backend service. Here, you will run a CRON task to update the BTC price within the Oracle contract. Data can be fetched from an API and set to the contract using the `set_price` function, in this case, the tutorial will use the [CryptoPrice API](https://api-ninjas.com/api/cryptoprice). This is a free API that provides real-time cryptocurrency prices, and it is used in this tutorial for demonstration purposes only. You are free to use any price feed API of your choice. @@ -220,7 +220,7 @@ cron.schedule("*/5 * * * *", async () => { It's important to note that since the price feed is dependent on the CRON task, the price will not update until the CRON task has run at least once. Furthermore, the CRON task will need to keep running in order to keep the price feed updated. You can host the task on your localhost or on a server such as [Vercel](https://vercel.com/docs/cron-jobs). For this example, the CRON task is hosted on a local host. -## Checkpoint 4: 🤝 Connect the Frontend to the Backend {#checkpoint-4--connect-the-frontend-to-the-backend} +## Checkpoint 4: 🤝 Connect the Frontend to the Backend Now that you have the smart contracts deployed, and the cron job running, it's time to check out the frontend of your dapp. @@ -240,7 +240,7 @@ You will need to add some Futurenet network lumens to your wallet to interact wi > Note: These are test lumens for use with Futurenet and cannot be used on Mainnet -## Checkpoint 5: 🧿 Oracle Insights {#checkpoint-5--oracle-insights} +## Checkpoint 5: 🧿 Oracle Insights Gaze into the crystal ball of APIs and retrive the price feed from the all connected internet. Data at your fingertips, at one time an abyss but pioneers have paved the way for many to cross. Here you will reach into the realm of off-chain data and pull out the price of BTC. In this section, you will mint tokens and deposit Bitcoin (BTC) into the donation contract. The conversion to USD will utilize the oracle price feed to ensure your donation is aligned with the current BTC to USD conversion rate. @@ -260,7 +260,7 @@ Gaze into the crystal ball of APIs and retrive the price feed from the all conne -#### Connect a Wallet {#connect-a-wallet} +#### Connect a Wallet Open the dapp frontend and click the "connect" and choose the wallet you want to use. For this example, you will use Freighter. @@ -271,7 +271,7 @@ Open the dapp frontend and click the "connect" and choose the wallet you want to -#### Mint USDC and BTC {#mint-usdc-and-btc} +#### Mint USDC and BTC Open the `Mint BTC Tokens` tab, enter the desired token amount, and click the "Mint" button. @@ -280,7 +280,7 @@ Open the `Mint BTC Tokens` tab, enter the desired token amount, and click the "M -#### Approve Transaction {#approve-transaction} +#### Approve Transaction You should see a popup from Freighter asking you to sign the transactions. Click on "Approve" and wait for the transaction to be confirmed. @@ -289,7 +289,7 @@ You should see a popup from Freighter asking you to sign the transactions. Click -#### Check Updated Balance {#check-updated-balance} +#### Check Updated Balance You should see an updated balance in the account balance component. @@ -310,7 +310,7 @@ You should see an updated balance in the account balance component. -#### Deposit into the Donation Contract {#deposit-into-the-donation-contract} +#### Deposit into the Donation Contract Open the frontend, enter the amount of BTC in USD that you would like to donate, then click the "Calculate" button. You should see the amount of BTC that you need to deposit in order to donate the specified amount in USD. For example, if you enter 35923.82 USD, you should see 1 BTC. @@ -319,7 +319,7 @@ Open the frontend, enter the amount of BTC in USD that you would like to donate, -#### Approve Transaction {#approve-transaction-1} +#### Approve Transaction Click on "Approve" and wait for the transaction to be confirmed. @@ -327,7 +327,7 @@ Click on "Approve" and wait for the transaction to be confirmed. -#### Check Updated Balance {#check-updated-balance-1} +#### Check Updated Balance Once the transaction is confirmed, you should see the contract and your wallet balances update in the `Donate` and `Mint BTC Tokens` tabs, respectively. @@ -346,7 +346,7 @@ Once the transaction is confirmed, you should see the contract and your wallet b {/* Funding completed */} -## Checkpoint 6: 🚢 Ship it! 🚁 {#checkpoint-6--ship-it-} +## Checkpoint 6: 🚢 Ship it! 🚁 In this step, you will deploy your dapp to a hosting platform so that it can be accessed by anyone with an internet connection. Note that it's on futurenet, the network used for testing, not mainnet for production use. You can use any hosting platform you like, but for demonstration purposes, this section will use [Vercel](https://vercel.com/). Vercel is a cloud platform for static sites and serverless functions that offers a free tier for developers. It also has a built-in integration with GitHub, which makes it easy to deploy your dapp directly from your GitHub repository. @@ -471,7 +471,7 @@ You can now visit the preview link to see your deployed dapp! 🎉 Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit [Stellar Lab](https://lab.stellar.org/account/create?$=network$id=futurenet&label=Futurenet&horizonUrl=https:////horizon-futurenet.stellar.org&rpcUrl=https:////rpc-futurenet.stellar.org&passphrase=Test%20SDF%20Future%20Network%20/;%20October%202022;;), and follow the instructions to create your Freighter account on Futurenet. -## Checkpoint 7: 💪 Pass the Challenge! {#checkpoint-7--pass-the-challenge} +## Checkpoint 7: 💪 Pass the Challenge! Now it's time to submit your work! @@ -485,7 +485,7 @@ Join [our Community in Discord](https://discord.gg/stellardev) in case you have ::: -## Checkpoint 8: ✅ Check your work! {#checkpoint-8--check-your-work} +## Checkpoint 8: ✅ Check your work! In order to successfully complete this challenge, your work needs to be checked. Please, follow this steps: @@ -508,7 +508,7 @@ Public Key: GBSXUXZSA2VEXN5VGOWE5ODAJLC575JCMWRJ4FFRDWSTRCJ123456789 Invite a friend to try out your dapp and ask them to provide feedback! -## ⚔️ Side Quests {#️-side-quests} +## ⚔️ Side Quests 🪬 Add a new feature to your dapp (e.g. add a new price feed, add a new token, etc.) @@ -516,7 +516,7 @@ Invite a friend to try out your dapp and ask them to provide feedback! 💡 Develop a function to respond to a significant BTC price change. -## 📚 User Workflows Checklist {#-user-workflows-checklist} +## 📚 User Workflows Checklist During this exercise you should be able to: @@ -535,6 +535,6 @@ Then via the web UI, you should be able to: - Deposit an asset - See your deposit(s) appear on the page as the transactions are confirmed -## 🛡️🗡️ Take On More Challenges {#️️-take-on-more-challenges} +## 🛡️🗡️ Take On More Challenges View your progress and take on more challenges by visiting your [User Dashboard!](../dashboard) diff --git a/src/pages/index.mdx b/src/pages/index.mdx index 0e2df57a8..4260348ad 100644 --- a/src/pages/index.mdx +++ b/src/pages/index.mdx @@ -14,43 +14,43 @@ If you can’t find answers to your questions in the docs, search for your answe -## Navigating the docs {#navigating-the-docs} +## Navigating the docs -### [Build](/docs/build) {#build} +### [Build](/docs/build) Contains tutorials and how-to guides for writing smart contracts, building applications, interacting with the network, and more. -### [Learn](/docs/learn/fundamentals) {#learn} +### [Learn](/docs/learn/fundamentals) Find all informational and conceptual content here. Learn about Stellar fundamentals like how accounts and transactions function, dive deeper into the functionality of each operation, discover how fees work, and more. -### [Tokens](/docs/tokens) {#tokens} +### [Tokens](/docs/tokens) Information on how to issue assets on the Stellar network and create custom smart contract tokens. -### [Data](/docs/data) {#data} +### [Data](/docs/data) Discover various data availability options: RPC, Hubble, and Horizon. -### [Tools](/docs/tools) {#tools} +### [Tools](/docs/tools) Learn about all the available tools at your disposal for building on, interacting with, or just watching the Stellar network. Also, find information on how to use the Anchor Platform or Stellar Disbursement Platform. -### [Networks](/docs/networks) {#networks} +### [Networks](/docs/networks) Information about delpoyed networks (Mainnet, Testnet, and Futurenet), current software versions, and resource limitations and fees. -### [Validators](/docs/validators) {#validators} +### [Validators](/docs/validators) Everything you'll need to know if you want to run, operate, and maintain a core validator node on the Stellar network. -## Contribute to the docs and leave feedback {#contribute-to-the-docs-and-leave-feedback} +## Contribute to the docs and leave feedback Stellar’s Developer Documentation is open-source, and contributions to the docs are encouraged. You can file an issue or pull request to add new content, suggest revisions to existing content, submit suggestions, report bugs, and more in the [Stellar Docs GitHub Repo](https://github.com/stellar/stellar-docs). Also, feel free to leave any additional feedback by filing issues in the various other [Stellar repos](https://github.com/stellar). -## Developer resources {#developer-resources} +## Developer resources Interact with other Stellar developers, keep up with ecosystem standards and protocol upgrades, and learn about upcoming events. diff --git a/src/pages/platforms.mdx b/src/pages/platforms.mdx index 5d4dc9b5b..2fac6fdb1 100644 --- a/src/pages/platforms.mdx +++ b/src/pages/platforms.mdx @@ -2,13 +2,13 @@ SDF has open-sourced some "platforms" that make it easier to accomplish certain things on the network. -## Anchor Platform {#anchor-platform} +## Anchor Platform The Anchor Platform is a set of tools and APIs that enable developers and businesses to build their own on and off-ramp services for the Stellar network. It provides a standardized interface, including the implementation of several Stellar Ecosystem Proposals (SEPs), to make it easy for businesses to integrate with Stellar-based wallets and exchanges. [Learn more about the Anchor Platform API here!](/platforms/anchor-platform) -## Stellar Disbursement Platform {#stellar-disbursement-platform} +## Stellar Disbursement Platform The Stellar Disbursement Platform (SDP) enables organizations to disburse bulk payments to recipients using Stellar. From 8b91c0ff517c2bae488d25223470bcb2776a9c4d Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 9 Dec 2024 11:31:36 -0600 Subject: [PATCH 41/60] fix some broken links --- .../version-2.10/admin-guide/sep24/integration.mdx | 4 ++-- .../version-2.11/admin-guide/sep24/integration.mdx | 4 ++-- .../version-2.8/admin-guide/sep24/integration.mdx | 4 ++-- .../version-2.9/admin-guide/sep24/integration.mdx | 4 ++-- .../guides/testing/detecting-changes-with-test-snapshots.mdx | 4 ++-- platforms/anchor-platform/admin-guide/sep24/integration.mdx | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx index 865922840..ce7fd2d73 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep24/integration.mdx @@ -1016,6 +1016,6 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-9]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md [sep-24]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md -[event-handling]: /ap_versioned_docs/version-2.10/admin-guide/events/README.mdx -[rate-callback]: /ap_versioned_docs/version-2.10/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [json-rpc-methods]: ../../api-reference/platform/rpc/methods/README.mdx diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx index bb3a9f759..ce7fd2d73 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep24/integration.mdx @@ -1016,6 +1016,6 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-9]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md [sep-24]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md -[event-handling]: /ap_versioned_docs/version-2.11/admin-guide/events/README.mdx -[rate-callback]: /ap_versioned_docs/version-2.11/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [json-rpc-methods]: ../../api-reference/platform/rpc/methods/README.mdx diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx index 099bd817d..ce7fd2d73 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep24/integration.mdx @@ -1016,6 +1016,6 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-9]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md [sep-24]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md -[event-handling]: /ap_versioned_docs/version-2.8/admin-guide/events/README.mdx -[rate-callback]: /ap_versioned_docs/version-2.8/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [json-rpc-methods]: ../../api-reference/platform/rpc/methods/README.mdx diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx index f07b332a6..ce7fd2d73 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep24/integration.mdx @@ -1016,6 +1016,6 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-9]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md [sep-24]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md -[event-handling]: /ap_versioned_docs/version-2.9/admin-guide/events/README.mdx -[rate-callback]: /ap_versioned_docs/version-2.9/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [json-rpc-methods]: ../../api-reference/platform/rpc/methods/README.mdx diff --git a/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx b/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx index f595ae9dd..11d615741 100644 --- a/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx +++ b/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx @@ -49,5 +49,5 @@ Note that test snapshots are extremely verbose and thoroughly understanding each To give this a go, check out the [Getting Started] contract or any of the [examples], run the tests, and look for the test snapshots on disk. -[Getting Started]: ../../smart-contracts/getting-started -[examples]: ../../smart-contracts/example-contracts +[Getting Started]: ../../smart-contracts/getting-started.mdx +[examples]: ../../smart-contracts/example-contracts.mdx diff --git a/platforms/anchor-platform/admin-guide/sep24/integration.mdx b/platforms/anchor-platform/admin-guide/sep24/integration.mdx index 4fae1b17e..6caf77d25 100644 --- a/platforms/anchor-platform/admin-guide/sep24/integration.mdx +++ b/platforms/anchor-platform/admin-guide/sep24/integration.mdx @@ -1016,6 +1016,6 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-9]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md [sep-24]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md -[event-handling]: /platforms/anchor-platform/admin-guide/events/README.mdx -[rate-callback]: /platforms/anchor-platform/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [json-rpc-methods]: ../../api-reference/platform/rpc/methods/README.mdx From 9f4c675812147cb19a20d1e61aa47b33aeb17217 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 9 Dec 2024 11:32:04 -0600 Subject: [PATCH 42/60] warn instead of log broken links --- docusaurus.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 1f49cbb0e..012d7923c 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -16,8 +16,8 @@ const config: Config = { url: "https://developers.stellar.org", baseUrl: "/", trailingSlash: false, - onBrokenLinks: "log", - onBrokenMarkdownLinks: "log", + onBrokenLinks: "warn", + onBrokenMarkdownLinks: "warn", onBrokenAnchors: "warn", // onBrokenLinks: "throw", // onBrokenMarkdownLinks: "throw", From 51f91ff61103db75577d9a14cf5ab0edfc940429 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 9 Dec 2024 11:58:19 -0600 Subject: [PATCH 43/60] fix some poorly formed links in sdp docs --- .../admin-guide/configuring-sdp.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx b/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx index 7b12f2f3a..55d764c1f 100644 --- a/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx +++ b/platforms/stellar-disbursement-platform/admin-guide/configuring-sdp.mdx @@ -39,8 +39,8 @@ Operational Configuration allows controlling metrics, logging, and other operati - `SENTRY_DSN` - 🔑 The DSN (client key) of the Sentry project. If not provided, Sentry will not be used. - `ENVIRONMENT` - The environment where the application is running. Example: "development", "staging", "production". Default: "development". - `DATABASE_URL` - 🔑 The connection string for the PostgreSQL database. Format is `postgres://username:password@host:port/database?sslmode=disable`. Default: "postgres://localhost:5432/sdp?sslmode=disable". -- `BASE_URL` - The SDP backend server's base URL. Default: "http://localhost:8000". Tenant-specific URLs will be configured during the [tenant provisioning process](tenant-provisioning#creating-tenants). -- `SDP_UI_BASE_URL` - The SDP UI/dashboard Base URL used to send the invitation link when a new user is created. Tenant-specific URLs will be configured during the [tenant provisioning process](tenant-provisioning#creating-tenants). +- `BASE_URL` - The SDP backend server's base URL. Default: "http://localhost:8000". Tenant-specific URLs will be configured during the [tenant provisioning process](./tenant-provisioning.mdx#creating-tenants). +- `SDP_UI_BASE_URL` - The SDP UI/dashboard Base URL used to send the invitation link when a new user is created. Tenant-specific URLs will be configured during the [tenant provisioning process](./tenant-provisioning.mdx#creating-tenants). ### Messaging Configuration @@ -86,7 +86,7 @@ Stellar Configuration allows configuring accounts, transactions, and other Stell - `SEP10_SIGNING_PRIVATE_KEY` - 🔑 The private key of the Stellar account that signs the SEP-10 transactions. It's also used to sign URLs. - `MAX_BASE_FEE` - The max base fee for submitting a Stellar transaction. Default: 10000. -The remaining configurations related to distribution accounts are detailed in the `Stellar accounts configuration` section of [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). +The remaining configurations related to distribution accounts are detailed in the `Stellar accounts configuration` section of [1.x to 2.x Migration Guide](./single-tenant-to-multi-tenant-migration.mdx#environment-variables). ### Security Configuration @@ -124,11 +124,11 @@ Anchor Platform Configuration allows configuring the anchor platform used by the For asynchronous processing, the SDP Core Service gives user the choice to use either the Event Broker or Scheduled Jobs. -The configurations for this section are detailed in the `Event Broker and Scheduler Configurations` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). +The configurations for this section are detailed in the `Event Broker and Scheduler Configurations` of the [1.x to 2.x Migration Guide](./single-tenant-to-multi-tenant-migration.mdx#environment-variables). ### Multi-tenancy Configuration -The configurations for this section are detailed in `General Environment Variables` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). +The configurations for this section are detailed in `General Environment Variables` of the [1.x to 2.x Migration Guide](./single-tenant-to-multi-tenant-migration.mdx#environment-variables). ## Transaction Submission Service (TSS) @@ -175,7 +175,7 @@ The following configurations are required for using channel accounts to submit t #### Distribution Accounts Configuration -The following configurations are related to the distribution accounts used to send funds to recipients. This configuration should match the configuration in the SDP Core Service. For more details, refer to the `Stellar accounts configuration` section of [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). +The following configurations are related to the distribution accounts used to send funds to recipients. This configuration should match the configuration in the SDP Core Service. For more details, refer to the `Stellar accounts configuration` section of [1.x to 2.x Migration Guide](./single-tenant-to-multi-tenant-migration.mdx#environment-variables). - `DISTRIBUTION_ACCOUNT_ENCRYPTION_PASSPHRASE` - 🔑 A Stellar-compliant ed25519 private key used to encrypt/decrypt the in-memory distribution accounts' private keys. - `DISTRIBUTION_PUBLIC_KEY` - The public key of the HOST's Stellar distribution account, used to create channel accounts. @@ -183,7 +183,7 @@ The following configurations are related to the distribution accounts used to se ### Event Broker Configuration -If an Event Broker is used for asynchronous processing, the TSS will need to be configured to use it. For more details, refer to the `Event Broker and Scheduler Configurations` of the [1.x to 2.x Migration Guide](single-tenant-to-multi-tenant-migration#environment-variables). +If an Event Broker is used for asynchronous processing, the TSS will need to be configured to use it. For more details, refer to the `Event Broker and Scheduler Configurations` of the [1.x to 2.x Migration Guide](./single-tenant-to-multi-tenant-migration.mdx#environment-variables). - `EVENT_BROKER_TYPE` - The type of event broker to use. Options: "KAFKA", "NONE". Default: "KAFKA". - `BROKER_URLS` - List of Message Broker URLs comma-separated. From ad8818cd0968168c993df8b2de230676393a03e3 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 9 Dec 2024 13:18:30 -0600 Subject: [PATCH 44/60] add another crowdin fix to the script --- scripts/fix_md_comments.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/fix_md_comments.sh b/scripts/fix_md_comments.sh index fc99fd931..d8d3cc6b4 100755 --- a/scripts/fix_md_comments.sh +++ b/scripts/fix_md_comments.sh @@ -4,3 +4,4 @@ perl -i -pe's/{\/_/{\/\*/' i18n/es/docusaurus-plugin-content-pages/docs/learn/in perl -i -pe's/_\/}/\*\/}/' i18n/es/docusaurus-plugin-content-pages/docs/learn/interactive/dapps/challenges/* perl -i -pe's/<(http.*)>/[\1](\1)/' i18n/es/docusaurus-plugin-content-pages/docs/learn/interactive/dapps/challenges/* perl -i -pe's/\s\{/ \\{/g' i18n/es/docusaurus-plugin-content-docs/current/learn/fundamentals/transactions/list-of-operations.mdx +perl -i -pe's/<\s(.*\.mdx)>/\1/' i18n/es/docusaurus-plugin-content-docs-ap/**/admin-guide/component/observer/observer.mdx From 760a59acaa8277c9b8357c3e570b502849f20a59 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 10:09:51 -0600 Subject: [PATCH 45/60] upgrade crowdin cli to v4.5.0 --- package.json | 2 +- yarn.lock | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 56a3aa0db..b551ad599 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "ap:versions:new": "docusaurus docs:version:ap $VERSION && node scripts/ap_new_version.mjs $VERSION" }, "dependencies": { - "@crowdin/cli": "^4.1.1", + "@crowdin/cli": "^4.5.0", "@docusaurus/core": "3.4.0", "@docusaurus/preset-classic": "3.4.0", "@docusaurus/remark-plugin-npm2yarn": "3.4.0", diff --git a/yarn.lock b/yarn.lock index 0f24c7822..9205c9aec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1248,10 +1248,10 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@crowdin/cli@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@crowdin/cli/-/cli-4.1.1.tgz#1a2067e79a53639920121870ae488a38dd2513ff" - integrity sha512-OC5xJgaXM9eC9UgiAV17HZrCDP1gM1gs2yMdSRFjM6ydu9LddybntMKgWU3ffRHjCjK6wDTrC31jo932Czrs+A== +"@crowdin/cli@^4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@crowdin/cli/-/cli-4.5.0.tgz#c84bde006473fdb6303274ead578e0c5aad994c2" + integrity sha512-faj84fCXT8GcM0CwZ6KuXQ6ckwRHj2OKFFib048RobykRoMFJxXJnu6P/OBjWpcqFFbxWJB0QL0VkS42hqdMng== dependencies: command-exists-promise "^2.0.2" node-fetch "2.7.0" @@ -12398,7 +12398,16 @@ stream-http@^3.2.0: readable-stream "^3.6.0" xtend "^4.0.2" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12475,7 +12484,14 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -13663,7 +13679,16 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From f333879b0316c6d9abdbca937b817615bf89bf6a Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 10:14:53 -0600 Subject: [PATCH 46/60] fix markdown formatting on ap rpc methods page --- .../platform/rpc/methods/README.mdx | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/platforms/anchor-platform/api-reference/platform/rpc/methods/README.mdx b/platforms/anchor-platform/api-reference/platform/rpc/methods/README.mdx index 2e66a5c05..ee8fdac5d 100644 --- a/platforms/anchor-platform/api-reference/platform/rpc/methods/README.mdx +++ b/platforms/anchor-platform/api-reference/platform/rpc/methods/README.mdx @@ -13,27 +13,31 @@ The OpenRPC Specification for JSON-RPC API is available [here](https://playgroun Postman collection is available [here](https://documenter.getpostman.com/view/9257637/2s9Y5U1kra) - | | | | --- | --- | | | [do_stellar_payment](do_stellar_payment.mdx) | | | - [do_stellar_refund](do_stellar_refund.mdx) | | | - [get_transaction](get_transaction.mdx) | | | - [get_transactions](get_transactions.mdx) | | | - [notify_amounts_updated](notify_amounts_updated.mdx) | | | - [notify_customer_info_updated](notify_customer_info_updated.mdx) | | | - [notify_interactive_flow_completed](notify_interactive_flow_completed.mdx) | | - | [notify_offchain_funds_available](notify_offchain_funds_available.mdx) | | | - [notify_offchain_funds_pending](notify_offchain_funds_pending.mdx) | | | - [notify_offchain_funds_received](notify_offchain_funds_received.mdx) | | | - [notify_offchain_funds_sent](notify_offchain_funds_sent.mdx) | | | - [notify_onchain_funds_received](notify_onchain_funds_received.mdx) | | | - [notify_onchain_funds_sent](notify_onchain_funds_sent.mdx) | | | - [notify_refund_pending](notify_refund_pending.mdx) | | | - [notify_refund_sent](notify_refund_sent.mdx) | | | - [notify_transaction_error](notify_transaction_error.mdx) | | | - [notify_transaction_expired](notify_transaction_expired.mdx) | | | - [notify_transaction_on_hold](notify_transaction_on_hold.mdx) | | | - [notify_transaction_recovery](notify_transaction_recovery.mdx) | | | - [notify_trust_set](notify_trust_set.mdx) | | | - [request_offchain_funds](request_offchain_funds.mdx) | | | - [request_onchain_funds](request_onchain_funds.mdx) | | | - [request_trust](request_trust.mdx) | + +| | | +| --- | --- | +| | [do_stellar_payment](./do_stellar_payment.mdx) | +| | [do_stellar_refund](./do_stellar_refund.mdx) | +| | [get_transaction](./get_transaction.mdx) | +| | [get_transactions](./get_transactions.mdx) | +| | [notify_amounts_updated](./notify_amounts_updated.mdx) | +| | [notify_customer_info_updated](./notify_customer_info_updated.mdx) | +| | [notify_interactive_flow_completed](./notify_interactive_flow_completed.mdx) | +| | [notify_offchain_funds_available](./notify_offchain_funds_available.mdx) | +| | [notify_offchain_funds_pending](./notify_offchain_funds_pending.mdx) | +| | [notify_offchain_funds_received](./notify_offchain_funds_received.mdx) | +| | [notify_offchain_funds_sent](./notify_offchain_funds_sent.mdx) | +| | [notify_onchain_funds_received](./notify_onchain_funds_received.mdx) | +| | [notify_onchain_funds_sent](./notify_onchain_funds_sent.mdx) | +| | [notify_refund_pending](./notify_refund_pending.mdx) | +| | [notify_refund_sent](./notify_refund_sent.mdx) | +| | [notify_transaction_error](./notify_transaction_error.mdx) | +| | [notify_transaction_expired](./notify_transaction_expired.mdx) | +| | [notify_transaction_on_hold](./notify_transaction_on_hold.mdx) | +| | [notify_transaction_recovery](./notify_transaction_recovery.mdx) | +| | [notify_trust_set](./notify_trust_set.mdx) | +| | [request_offchain_funds](./request_offchain_funds.mdx) | +| | [request_onchain_funds](./request_onchain_funds.mdx) | +| | [request_trust](./request_trust.mdx) | + From 2246259c7bd0b59a52b039712ef6374ecd6a488f Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 11:08:29 -0600 Subject: [PATCH 47/60] fix some broken ap links --- .../version-2.10/admin-guide/events/getting-started.mdx | 4 ++-- .../version-2.11/admin-guide/events/getting-started.mdx | 2 +- .../version-2.8/admin-guide/events/getting-started.mdx | 4 ++-- .../version-2.9/admin-guide/events/getting-started.mdx | 4 ++-- .../version-3.0.0/admin-guide/events/getting-started.mdx | 2 +- .../anchor-platform/admin-guide/events/getting-started.mdx | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ap_versioned_docs/version-2.10/admin-guide/events/getting-started.mdx b/ap_versioned_docs/version-2.10/admin-guide/events/getting-started.mdx index 229bbc799..7547bbf70 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/events/getting-started.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/events/getting-started.mdx @@ -11,7 +11,7 @@ Anchor Platform provides an event service that sends HTTP webhook notifications - Quote updates - Customer KYC status changes -Event schemas for business servers are defined in the [API reference](/platforms/anchor-platform/next/api-reference/callbacks/post-event). +Event schemas for business servers are defined in the [API reference](../../api-reference/callbacks/post-event.api.mdx). **Client Applications** @@ -25,4 +25,4 @@ _Event schemas for client applications are defined in their respective SEPs:_ - [SEP-24 Transaction Events](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#single-historical-transaction) - [SEP-31 Transaction Events](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#get-transaction) -This eliminates the need for business servers and client applications to continuously poll the APIs for updates. \ No newline at end of file +This eliminates the need for business servers and client applications to continuously poll the APIs for updates. diff --git a/ap_versioned_docs/version-2.11/admin-guide/events/getting-started.mdx b/ap_versioned_docs/version-2.11/admin-guide/events/getting-started.mdx index 5001c7931..7547bbf70 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/events/getting-started.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/events/getting-started.mdx @@ -11,7 +11,7 @@ Anchor Platform provides an event service that sends HTTP webhook notifications - Quote updates - Customer KYC status changes -Event schemas for business servers are defined in the [API reference](/platforms/anchor-platform/next/api-reference/callbacks/post-event). +Event schemas for business servers are defined in the [API reference](../../api-reference/callbacks/post-event.api.mdx). **Client Applications** diff --git a/ap_versioned_docs/version-2.8/admin-guide/events/getting-started.mdx b/ap_versioned_docs/version-2.8/admin-guide/events/getting-started.mdx index bd98c3d65..7547bbf70 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/events/getting-started.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/events/getting-started.mdx @@ -11,7 +11,7 @@ Anchor Platform provides an event service that sends HTTP webhook notifications - Quote updates - Customer KYC status changes -Event schemas for business servers are defined in the [API reference](/ap_versioned_docs/version-2.8/api-reference/callbacks/post-event.api.mdx). +Event schemas for business servers are defined in the [API reference](../../api-reference/callbacks/post-event.api.mdx). **Client Applications** @@ -25,4 +25,4 @@ _Event schemas for client applications are defined in their respective SEPs:_ - [SEP-24 Transaction Events](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#single-historical-transaction) - [SEP-31 Transaction Events](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#get-transaction) -This eliminates the need for business servers and client applications to continuously poll the APIs for updates. \ No newline at end of file +This eliminates the need for business servers and client applications to continuously poll the APIs for updates. diff --git a/ap_versioned_docs/version-2.9/admin-guide/events/getting-started.mdx b/ap_versioned_docs/version-2.9/admin-guide/events/getting-started.mdx index 229bbc799..7547bbf70 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/events/getting-started.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/events/getting-started.mdx @@ -11,7 +11,7 @@ Anchor Platform provides an event service that sends HTTP webhook notifications - Quote updates - Customer KYC status changes -Event schemas for business servers are defined in the [API reference](/platforms/anchor-platform/next/api-reference/callbacks/post-event). +Event schemas for business servers are defined in the [API reference](../../api-reference/callbacks/post-event.api.mdx). **Client Applications** @@ -25,4 +25,4 @@ _Event schemas for client applications are defined in their respective SEPs:_ - [SEP-24 Transaction Events](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#single-historical-transaction) - [SEP-31 Transaction Events](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md#get-transaction) -This eliminates the need for business servers and client applications to continuously poll the APIs for updates. \ No newline at end of file +This eliminates the need for business servers and client applications to continuously poll the APIs for updates. diff --git a/ap_versioned_docs/version-3.0.0/admin-guide/events/getting-started.mdx b/ap_versioned_docs/version-3.0.0/admin-guide/events/getting-started.mdx index 5001c7931..7547bbf70 100644 --- a/ap_versioned_docs/version-3.0.0/admin-guide/events/getting-started.mdx +++ b/ap_versioned_docs/version-3.0.0/admin-guide/events/getting-started.mdx @@ -11,7 +11,7 @@ Anchor Platform provides an event service that sends HTTP webhook notifications - Quote updates - Customer KYC status changes -Event schemas for business servers are defined in the [API reference](/platforms/anchor-platform/next/api-reference/callbacks/post-event). +Event schemas for business servers are defined in the [API reference](../../api-reference/callbacks/post-event.api.mdx). **Client Applications** diff --git a/platforms/anchor-platform/admin-guide/events/getting-started.mdx b/platforms/anchor-platform/admin-guide/events/getting-started.mdx index 5001c7931..7547bbf70 100644 --- a/platforms/anchor-platform/admin-guide/events/getting-started.mdx +++ b/platforms/anchor-platform/admin-guide/events/getting-started.mdx @@ -11,7 +11,7 @@ Anchor Platform provides an event service that sends HTTP webhook notifications - Quote updates - Customer KYC status changes -Event schemas for business servers are defined in the [API reference](/platforms/anchor-platform/next/api-reference/callbacks/post-event). +Event schemas for business servers are defined in the [API reference](../../api-reference/callbacks/post-event.api.mdx). **Client Applications** From 0e754926f43ea07e66f32dcfa9a02576dbceeb84 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 11:10:00 -0600 Subject: [PATCH 48/60] fix some broken links in one of the guides --- docs/build/guides/dapps/frontend-guide.mdx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/build/guides/dapps/frontend-guide.mdx b/docs/build/guides/dapps/frontend-guide.mdx index 401364e59..743789fdb 100644 --- a/docs/build/guides/dapps/frontend-guide.mdx +++ b/docs/build/guides/dapps/frontend-guide.mdx @@ -365,7 +365,7 @@ Calculating these fees can be cumbersome but the Stellar SDK provides a way to c The ABI or spec is a json file that contains the contract's interface. It defines the functions that can be called on the contract, their parameters, and return types. The ABI is used by clients to interact with the contract and execute its functions. The ABI is generated from the contract's source code and is used to compile the contract into XDR for execution on the Stellar network. -ABI can be genrated for a contract using the [`stellar contract bindings`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-bindings-json) command and can be used to interact with the contract. +ABI can be genrated for a contract using the [`stellar contract bindings`](../../../tools/developer-tools/cli/stellar-cli.mdx#stellar-contract-bindings-json) command and can be used to interact with the contract. This ABI can also be generated as a typescript library to ease development in your DApp and we'll be looking it later in this guide @@ -725,7 +725,7 @@ Notice how we used a different operation `contract.call("increment")` to interac After calling the transaction to increment successfully, we need to poll and then call another method `server.getTransaction` to get the transaction result. The transaction result contains the new counter value which we extract and display to the user. -The value gotten from the transaction result is stored in a form called `scval` due to the limited [number of types](/docs/learn/encyclopedia/contract-development/types/built-in-types) that exist in soroban today. This value is transmitted about in the form of `xdr` which can be converted to an `scVal` using the sdk. The value is then parsed as `u32` which is a 32-bit unsigned integer. We will learn more about converting these types when [working with contract specs](/docs/build/guides/conventions) +The value gotten from the transaction result is stored in a form called `scval` due to the limited [number of types](../../../learn/encyclopedia/contract-development/types/built-in-types.mdx) that exist in soroban today. This value is transmitted about in the form of `xdr` which can be converted to an `scVal` using the sdk. The value is then parsed as `u32` which is a 32-bit unsigned integer. We will learn more about converting these types when [working with contract specs](../conventions/work-contractspec-js.mdx) :::tip @@ -743,7 +743,7 @@ This is made possible by using the `server.getEvents` method which allows you to We will be editing the `CounterPage` component to read events from the counter smart contract immediately the page loads to get the initial counter value and update instead of using "Unknown". Before we continue, please take a look at the [contract code](https://github.com/stellar/soroban-examples/blob/main/events/src/lib.rs). In the contract code, an event named `increment` is emitted whenever the `increment` function is called. It is published over 2 topics, `increment` and `COUNTER` and we need to listen to these topics to get the events. -The topics are stored in a data type called `symbol` and we will need to convert both `increment` and `COUNTER` to `symbol` before we can use them in the [`server.getEvents`](https://developers.stellar.org/docs/data/rpc/api-reference/methods/getEvents) method. At maximum, stellar RPCs keep track of events for 7 days and you can query events that happened within the last 7 days, so if you need to store events for longer, you may need to make use of an [indexer](/docs/data/data-indexers/README.mdx). +The topics are stored in a data type called `symbol` and we will need to convert both `increment` and `COUNTER` to `symbol` before we can use them in the [`server.getEvents`](https://developers.stellar.org/docs/data/rpc/api-reference/methods/getEvents) method. At maximum, stellar RPCs keep track of events for 7 days and you can query events that happened within the last 7 days, so if you need to store events for longer, you may need to make use of an [indexer](../../../data/data-indexers/README.mdx). To use events,we edit our counter page and add the following code: @@ -801,21 +801,21 @@ The library generated contains helper methods for calling each contract and also To achieve this, you need to -- Have the [Stellar CLI](/docs/tools/developer-tools/cli/install-cli) installed. +- Have the [Stellar CLI](../../../tools/developer-tools/cli/install-cli.mdx) installed. - Have either source code or deployed contract ID of the contract. - Know the network it was deployed to. #### Scenario 1: I have the Contract ID but no code -In this scenario, we need to use the command [`stellar contract fetch`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-fetch) to fetch the wasm code of the contract +In this scenario, we need to use the command [`stellar contract fetch`](../../../tools/developer-tools/cli/stellar-cli.mdx#stellar-contract-fetch) to fetch the wasm code of the contract #### Scenario 2: I have the code -The next step here is to build it to a wasm file using the [`stellar contract build`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-build) command. +The next step here is to build it to a wasm file using the [`stellar contract build`](../../../tools/developer-tools/cli/stellar-cli.mdx#stellar-contract-build) command. ### Generating the Library -After getting the wasm, we can now run [`stellar contract bindings typescript`](/docs/tools/developer-tools/cli/stellar-cli#stellar-contract-bindings-typescript) to generate the library which is ready to be published to NPM. The library generated is suited for working with complex contracts. +After getting the wasm, we can now run [`stellar contract bindings typescript`](../../../tools/developer-tools/cli/stellar-cli.mdx#stellar-contract-bindings-typescript) to generate the library which is ready to be published to NPM. The library generated is suited for working with complex contracts. ## 7. Common Pitfalls @@ -827,15 +827,15 @@ The data types in Javascript are different from the data types in soroban. When ### Fees -Calculating fees for transactions can be tricky. The Stellar SDK provides a way to calculate fees using the `server.prepareTransaction` method, which simulates the transaction and returns the appropriate fees. Fees are calculated in [stroops](/docs/learn/glossary#stroop) +Calculating fees for transactions can be tricky. The Stellar SDK provides a way to calculate fees using the `server.prepareTransaction` method, which simulates the transaction and returns the appropriate fees. Fees are calculated in [stroops](../../../learn/glossary.mdx#stroop) ### SendTransaction and GetTransaction -Results from a smart contract execution or any of the [valid transactions](/docs/learn/fundamentals/transactions/list-of-operations#extend-footprint-ttl) on soroban are not immediate. They are kept in a `PENDING` state until they are confirmed. You need to poll the `getTransaction` method to get the final result of the transaction. +Results from a smart contract execution or any of the [valid transactions](../../../learn/fundamentals/transactions/list-of-operations.mdx#extend-footprint-ttl) on soroban are not immediate. They are kept in a `PENDING` state until they are confirmed. You need to poll the `getTransaction` method to get the final result of the transaction. ### State Archival -State Archival is a characteristic of soroban contracts where some data stored on the ledger about the contract might be archived. This [guide](/docs/build/guides/archival) helps to understand how to work with state archival in DApps. +State Archival is a characteristic of soroban contracts where some data stored on the ledger about the contract might be archived. These [guides](../archival/README.mdx) helps to understand how to work with state archival in DApps. ### Data Retention From c0a0ba7736a88d6df62a15569380929938d16c67 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 11:31:59 -0600 Subject: [PATCH 49/60] translate wayfinding box titles --- src/components/WayfindingBoxes/index.js | 33 +++++++++++++++++++------ 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/components/WayfindingBoxes/index.js b/src/components/WayfindingBoxes/index.js index a581363f2..8785c7189 100644 --- a/src/components/WayfindingBoxes/index.js +++ b/src/components/WayfindingBoxes/index.js @@ -3,11 +3,14 @@ import clsx from 'clsx'; import Heading from '@theme/Heading'; import Link from '@docusaurus/Link'; import styles from './styles.module.css'; -import Translate from '@docusaurus/Translate'; +import Translate, {translate} from '@docusaurus/Translate'; const WayfindingWays = [ { - title: 'Stellar 101', + title: translate({ + message: 'Stellar 101', + id: 'components.WayfindingBoxes.Stellar101.Title' + }), image: require('@site/static/icons/stellar-101.png').default, description: ( ), - // temporarily set this to /docs/soroban until "smart contracts" section is done link: ( @@ -50,7 +55,10 @@ const WayfindingWays = [ ), }, { - title: 'Issue an Asset', + title: translate({ + message: 'Issue an Asset', + id: 'components.WayfindingBoxes.IssueAnAsset.Title' + }), image: require('@site/static/icons/issue-assets.png').default, description: ( Date: Tue, 17 Dec 2024 11:37:47 -0600 Subject: [PATCH 50/60] remove dapps-challenge translations fixes, rename script file --- package.json | 2 +- scripts/fix_md_comments.sh | 7 ------- scripts/fix_translations.sh | 4 ++++ 3 files changed, 5 insertions(+), 8 deletions(-) delete mode 100755 scripts/fix_md_comments.sh create mode 100755 scripts/fix_translations.sh diff --git a/package.json b/package.json index b551ad599..4b79e1abf 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "rpcspec:validate": "node openrpc/scripts/build.mjs && node openrpc/scripts/validate.mjs", "stellar-cli:build": "node scripts/stellar_cli.mjs", "crowdin": "crowdin", - "crowdin:fix": "node scripts/copyIgnoredFiles.mjs && ./scripts/fix_md_comments.sh", + "crowdin:fix": "node scripts/copyIgnoredFiles.mjs && ./scripts/fix_translations.sh", "crowdin:sync": "docusaurus write-translations && crowdin upload --delete-obsolete --no-progress && crowdin download --no-progress", "ap:versions:clean": "docusaurus clean-api-docs:version -p ap-apis ap_platform:all && docusaurus clean-api-docs:version -p ap-apis ap_callbacks:all && docusaurus clean-api-docs:version -p ap-apis ap_custody:all", "ap:versions:gen": "docusaurus gen-api-docs:version -p ap-apis ap_platform:all && docusaurus gen-api-docs:version -p ap-apis ap_callbacks:all && docusaurus gen-api-docs:version -p ap-apis ap_custody:all && rm ap_versioned_docs/version-*/api-reference/{callbacks,custody,platform/transactions}/*.info.mdx", diff --git a/scripts/fix_md_comments.sh b/scripts/fix_md_comments.sh deleted file mode 100755 index d8d3cc6b4..000000000 --- a/scripts/fix_md_comments.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env sh - -perl -i -pe's/{\/_/{\/\*/' i18n/es/docusaurus-plugin-content-pages/docs/learn/interactive/dapps/challenges/* -perl -i -pe's/_\/}/\*\/}/' i18n/es/docusaurus-plugin-content-pages/docs/learn/interactive/dapps/challenges/* -perl -i -pe's/<(http.*)>/[\1](\1)/' i18n/es/docusaurus-plugin-content-pages/docs/learn/interactive/dapps/challenges/* -perl -i -pe's/\s\{/ \\{/g' i18n/es/docusaurus-plugin-content-docs/current/learn/fundamentals/transactions/list-of-operations.mdx -perl -i -pe's/<\s(.*\.mdx)>/\1/' i18n/es/docusaurus-plugin-content-docs-ap/**/admin-guide/component/observer/observer.mdx diff --git a/scripts/fix_translations.sh b/scripts/fix_translations.sh new file mode 100755 index 000000000..96f2655de --- /dev/null +++ b/scripts/fix_translations.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +perl -i -pe's/\s\{/ \\{/g' i18n/es/docusaurus-plugin-content-docs/current/learn/fundamentals/transactions/list-of-operations.mdx +perl -i -pe's/<\s(.*\.mdx)>/\1/' i18n/es/docusaurus-plugin-content-docs-ap/**/admin-guide/component/observer/observer.mdx From 31e2610884dbe0d0e1453a6d8c785e25feeba251 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 12:03:31 -0600 Subject: [PATCH 51/60] fix more broken links --- .../version-2.10/admin-guide/sep6/integration.mdx | 6 +++--- .../version-2.11/admin-guide/sep6/integration.mdx | 6 +++--- .../version-2.8/admin-guide/sep6/integration.mdx | 6 +++--- .../version-2.9/admin-guide/sep6/integration.mdx | 6 +++--- platforms/anchor-platform/admin-guide/sep6/integration.mdx | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx index 87a6919b9..98a4c3916 100644 --- a/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.10/admin-guide/sep6/integration.mdx @@ -985,7 +985,7 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-6]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md -[event-handling]: /ap_versioned_docs/version-2.10/admin-guide/events/README.mdx -[customer-callback]: /ap_versioned_docs/version-2.10/api-reference/callbacks/README.mdx -[rate-callback]: /ap_versioned_docs/version-2.10/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[customer-callback]: ../../api-reference/callbacks/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [get-transactions]: ../../api-reference/platform/transactions/get-transactions.api.mdx diff --git a/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx index 5b4d53d58..98a4c3916 100644 --- a/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.11/admin-guide/sep6/integration.mdx @@ -985,7 +985,7 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-6]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md -[event-handling]: /ap_versioned_docs/version-2.11/admin-guide/events/README.mdx -[customer-callback]: /ap_versioned_docs/version-2.11/api-reference/callbacks/README.mdx -[rate-callback]: /ap_versioned_docs/version-2.11/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[customer-callback]: ../../api-reference/callbacks/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [get-transactions]: ../../api-reference/platform/transactions/get-transactions.api.mdx diff --git a/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx index 7e19260cc..5beb354bf 100644 --- a/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.8/admin-guide/sep6/integration.mdx @@ -981,7 +981,7 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-6]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md -[event-handling]: /ap_versioned_docs/version-2.8/admin-guide/events/README.mdx -[customer-callback]: /ap_versioned_docs/version-2.8/api-reference/callbacks/README.mdx -[rate-callback]: /ap_versioned_docs/version-2.8/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[customer-callback]: ../../api-reference/callbacks/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [get-transactions]: ../../api-reference/platform/transactions/get-transactions.api.mdx diff --git a/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx index c1836b071..98a4c3916 100644 --- a/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-2.9/admin-guide/sep6/integration.mdx @@ -985,7 +985,7 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-6]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md -[event-handling]: /ap_versioned_docs/version-2.9/admin-guide/events/README.mdx -[customer-callback]: /ap_versioned_docs/version-2.9/api-reference/callbacks/README.mdx -[rate-callback]: /ap_versioned_docs/version-2.9/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[customer-callback]: ../../api-reference/callbacks/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [get-transactions]: ../../api-reference/platform/transactions/get-transactions.api.mdx diff --git a/platforms/anchor-platform/admin-guide/sep6/integration.mdx b/platforms/anchor-platform/admin-guide/sep6/integration.mdx index 7627af2e8..179218144 100644 --- a/platforms/anchor-platform/admin-guide/sep6/integration.mdx +++ b/platforms/anchor-platform/admin-guide/sep6/integration.mdx @@ -985,7 +985,7 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-6]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md -[event-handling]: /platforms/anchor-platform/admin-guide/events/README.mdx -[customer-callback]: /platforms/anchor-platform/api-reference/callbacks/README.mdx -[rate-callback]: /platforms/anchor-platform/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[customer-callback]: ../../api-reference/callbacks/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [get-transactions]: ../../api-reference/platform/transactions/get-transactions.api.mdx From 807aca81ebc378b9defd03a93678a209506bff50 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 12:21:05 -0600 Subject: [PATCH 52/60] yet another batch of link fixing --- docs/build/guides/dapps/frontend-guide.mdx | 6 +++--- .../testing/detecting-changes-with-test-snapshots.mdx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/build/guides/dapps/frontend-guide.mdx b/docs/build/guides/dapps/frontend-guide.mdx index 743789fdb..8dc1601ba 100644 --- a/docs/build/guides/dapps/frontend-guide.mdx +++ b/docs/build/guides/dapps/frontend-guide.mdx @@ -345,11 +345,11 @@ This setup provides a solid foundation for building the user interface of our St Before we start integrating smart contract functionality into our Stellar dapp, let's understand the basic concepts of Soroban contracts. -Soroban is a smart contract platform built on the Stellar network. It allows developers to write and deploy smart contracts that run on the Stellar blockchain. Soroban contracts are written in Rust and compiled to [XDR (External Data Representation)](/docs/learn/encyclopedia/data-format/xdr) for execution on the Stellar network. +Soroban is a smart contract platform built on the Stellar network. It allows developers to write and deploy smart contracts that run on the Stellar blockchain. Soroban contracts are written in Rust and compiled to [XDR (External Data Representation)](../../../learn/encyclopedia/data-format/xdr.mdx) for execution on the Stellar network. ### Data Types -Stellar supports a few data types that can be used in Soroban contracts and we need to do conversions from time to time between those types and the types we have in Javascript. The full list of primitive data types are explained [here](/docs/learn/encyclopedia/contract-development/types/built-in-types). +Stellar supports a few data types that can be used in Soroban contracts and we need to do conversions from time to time between those types and the types we have in Javascript. The full list of primitive data types are explained [here](../../../learn/encyclopedia/contract-development/types/built-in-types.mdx). ### XDR @@ -725,7 +725,7 @@ Notice how we used a different operation `contract.call("increment")` to interac After calling the transaction to increment successfully, we need to poll and then call another method `server.getTransaction` to get the transaction result. The transaction result contains the new counter value which we extract and display to the user. -The value gotten from the transaction result is stored in a form called `scval` due to the limited [number of types](../../../learn/encyclopedia/contract-development/types/built-in-types.mdx) that exist in soroban today. This value is transmitted about in the form of `xdr` which can be converted to an `scVal` using the sdk. The value is then parsed as `u32` which is a 32-bit unsigned integer. We will learn more about converting these types when [working with contract specs](../conventions/work-contractspec-js.mdx) +The value gotten from the transaction result is stored in a form called `scval` due to the limited [number of types](../../../learn/encyclopedia/contract-development/types/built-in-types.mdx) that exist in soroban today. This value is transmitted about in the form of `xdr` which can be converted to an `scVal` using the sdk. The value is then parsed as `u32` which is a 32-bit unsigned integer. We will learn more about converting these types [in this collection of guides](../conversions/README.mdx). :::tip diff --git a/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx b/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx index 11d615741..f53f29332 100644 --- a/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx +++ b/docs/build/guides/testing/detecting-changes-with-test-snapshots.mdx @@ -49,5 +49,5 @@ Note that test snapshots are extremely verbose and thoroughly understanding each To give this a go, check out the [Getting Started] contract or any of the [examples], run the tests, and look for the test snapshots on disk. -[Getting Started]: ../../smart-contracts/getting-started.mdx -[examples]: ../../smart-contracts/example-contracts.mdx +[Getting Started]: ../../smart-contracts/getting-started/README.mdx +[examples]: ../../smart-contracts/example-contracts/README.mdx From 98566d8c3f12eccc7f7ef06220f5863066619ffc Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 12:48:52 -0600 Subject: [PATCH 53/60] more broken links --- .../version-3.0.0/admin-guide/sep24/integration.mdx | 4 ++-- .../version-3.0.0/admin-guide/sep6/integration.mdx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ap_versioned_docs/version-3.0.0/admin-guide/sep24/integration.mdx b/ap_versioned_docs/version-3.0.0/admin-guide/sep24/integration.mdx index 4fae1b17e..6caf77d25 100644 --- a/ap_versioned_docs/version-3.0.0/admin-guide/sep24/integration.mdx +++ b/ap_versioned_docs/version-3.0.0/admin-guide/sep24/integration.mdx @@ -1016,6 +1016,6 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-9]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md [sep-24]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md -[event-handling]: /platforms/anchor-platform/admin-guide/events/README.mdx -[rate-callback]: /platforms/anchor-platform/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [json-rpc-methods]: ../../api-reference/platform/rpc/methods/README.mdx diff --git a/ap_versioned_docs/version-3.0.0/admin-guide/sep6/integration.mdx b/ap_versioned_docs/version-3.0.0/admin-guide/sep6/integration.mdx index 7627af2e8..179218144 100644 --- a/ap_versioned_docs/version-3.0.0/admin-guide/sep6/integration.mdx +++ b/ap_versioned_docs/version-3.0.0/admin-guide/sep6/integration.mdx @@ -985,7 +985,7 @@ Works in the same manner as for the deposit flow. For more details, see [Transac [sep-6]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md -[event-handling]: /platforms/anchor-platform/admin-guide/events/README.mdx -[customer-callback]: /platforms/anchor-platform/api-reference/callbacks/README.mdx -[rate-callback]: /platforms/anchor-platform/api-reference/callbacks/README.mdx +[event-handling]: ../events/README.mdx +[customer-callback]: ../../api-reference/callbacks/README.mdx +[rate-callback]: ../../api-reference/callbacks/README.mdx [get-transactions]: ../../api-reference/platform/transactions/get-transactions.api.mdx From 1c3b9f2f4541866dd2dc9189c0f5b59fd3273b77 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 13:04:18 -0600 Subject: [PATCH 54/60] remove unused link definition --- docs/build/guides/transactions/README.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/build/guides/transactions/README.mdx b/docs/build/guides/transactions/README.mdx index 8ea06bb69..a396ea736 100644 --- a/docs/build/guides/transactions/README.mdx +++ b/docs/build/guides/transactions/README.mdx @@ -6,5 +6,3 @@ sidebar_position: 120 --- The entry point for every smart contract interaction is ultimately a transaction on the Stellar network. Read more about transactions in the [Operations and Transactions section](../../../learn/fundamentals/transactions/README.mdx). - -[transaction]: ../../../learn/fundamentals/transactions/operations-and-transactions.mdx From 3d965df3cb06db4f3febb933f5baf6a15f253394 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 13:24:56 -0600 Subject: [PATCH 55/60] build for english and spanish locales --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c2d138492..953768226 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn crowdin:sync RUN yarn crowdin:fix # TODO: It's actually this part that is more time-consuming. The best way to # speed this up is to generate the preview for only `--locale en` -RUN NODE_OPTIONS="--max-old-space-size=4096" yarn build --locale es +RUN NODE_OPTIONS="--max-old-space-size=4096" yarn build FROM nginx:1.27 From c697aec89ec44ec03f3464668a6f3dcc9273e4df Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 13:26:00 -0600 Subject: [PATCH 56/60] make build fail on broken link --- docusaurus.config.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index ab3e7b41f..76b1b968b 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -16,11 +16,9 @@ const config: Config = { url: "https://developers.stellar.org", baseUrl: "/", trailingSlash: false, - onBrokenLinks: "warn", - onBrokenMarkdownLinks: "warn", onBrokenAnchors: "warn", - // onBrokenLinks: "throw", - // onBrokenMarkdownLinks: "throw", + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "throw", favicon: "img/favicon-96x96.png", organizationName: "stellar", projectName: "stellar-docs", From a3300eb066e2b97ced5e370d4991154f1c87faf6 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 14:19:07 -0600 Subject: [PATCH 57/60] fix a couple wrong anchor links (in english) --- docs/learn/fundamentals/lumens.mdx | 2 +- docs/validators/admin-guide/configuring.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/learn/fundamentals/lumens.mdx b/docs/learn/fundamentals/lumens.mdx index 7beaa964b..900306ff0 100644 --- a/docs/learn/fundamentals/lumens.mdx +++ b/docs/learn/fundamentals/lumens.mdx @@ -3,7 +3,7 @@ title: Lumens (XLM) sidebar_position: 30 --- -Lumens (XLM) are the native currency of the Stellar network. The lumen is the only token that doesn’t require an issuer or trustline. They are used to pay all transaction [fees](#transaction-fees), fund [rent](fees-resource-limits-metering.mdx#resource-fees), and to cover [minimum balance requirements](stellar-data-structures/accounts.mdx#base-reserves-and-subentries) on the network. +Lumens (XLM) are the native currency of the Stellar network. The lumen is the only token that doesn’t require an issuer or trustline. They are used to pay all transaction [fees](#transaction-fees), fund [rent](./fees-resource-limits-metering.mdx#resource-fee), and to cover [minimum balance requirements](stellar-data-structures/accounts.mdx#base-reserves-and-subentries) on the network. To read up on the basics of lumens, head over to our Stellar Learn site: [Stellar Learn: Lumens](https://www.stellar.org/lumens) diff --git a/docs/validators/admin-guide/configuring.mdx b/docs/validators/admin-guide/configuring.mdx index af49e996e..39b6a8807 100644 --- a/docs/validators/admin-guide/configuring.mdx +++ b/docs/validators/admin-guide/configuring.mdx @@ -205,7 +205,7 @@ ADDRESS="core.rando.com" :::info Important Note -Your quorum set is automatically configured based on the information you provide in the `[[VALIDATORS]]` and/or `[[HOME_DOMAINS]]` tables. Removing a validator will result in a new quorum set being generated and may have unintended consequence for you and other network participants. Be sure to carefully consider the implications of removing a validator from your configuration and follow the guidance to [coordinate with other validators](../tier-1-orgs.mdx#coordinating-with-other-validators) before making changes. +Your quorum set is automatically configured based on the information you provide in the `[[VALIDATORS]]` and/or `[[HOME_DOMAINS]]` tables. Removing a validator will result in a new quorum set being generated and may have unintended consequence for you and other network participants. Be sure to carefully consider the implications of removing a validator from your configuration and follow the guidance to [coordinate with other validators](../tier-1-orgs.mdx#coordinate-with-other-validators) before making changes. ::: From 42518d1971d07da37d4fc2e42ea7dbea88e706dd Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 15:03:47 -0600 Subject: [PATCH 58/60] more properly display related guides in how-to guides pages --- src/theme/DocCardList/index.tsx | 4 ++-- src/theme/DocItem/Footer/index.tsx | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/theme/DocCardList/index.tsx b/src/theme/DocCardList/index.tsx index fa0a857c0..4f502eb57 100644 --- a/src/theme/DocCardList/index.tsx +++ b/src/theme/DocCardList/index.tsx @@ -10,9 +10,9 @@ type Props = WrapperProps; function DocCardListForCurrentSidebarCategory(props: Props): JSX.Element { const category = useCurrentSidebarCategory(); - return category.label === 'Example Contracts' + return (category.label === 'Example Contracts' || category.label === 'Ejemplos de contratos') ? - : category.label === 'How-To Guides' + : (category.label === 'How-To Guides' || category.label === 'Guías de Cómo-Hacer') ? : ; } diff --git a/src/theme/DocItem/Footer/index.tsx b/src/theme/DocItem/Footer/index.tsx index 5bc8efde9..83fadb994 100644 --- a/src/theme/DocItem/Footer/index.tsx +++ b/src/theme/DocItem/Footer/index.tsx @@ -6,18 +6,25 @@ import DocCardList from '@theme/DocCardList'; import type FooterType from '@theme/DocItem/Footer'; import type { WrapperProps } from '@docusaurus/types'; import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; type Props = WrapperProps; export default function FooterWrapper(props: Props): JSX.Element { const { metadata } = useDoc(); - const canDisplayDocCardsOnGuide = metadata.permalink?.startsWith('/docs/build/guides'); + const canDisplayDocCardsOnGuide = metadata.permalink?.includes('/docs/build/guides'); + const isMainGuidesPage = metadata.id === 'build/guides/README' return ( <> {canDisplayDocCardsOnGuide && -
- {metadata.permalink !== '/docs/build/guides/' &&

Guides in this category:

} +
+ {!isMainGuidesPage &&

+ Guides in this category: +

}
} From 587556637b663ba3f0d08c241fd91b0bea3e6067 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 17 Dec 2024 15:08:06 -0600 Subject: [PATCH 59/60] display platforms and data sidebars better in spanish --- src/theme/DocSidebar/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/theme/DocSidebar/index.tsx b/src/theme/DocSidebar/index.tsx index 8c18e3205..a89fb693b 100644 --- a/src/theme/DocSidebar/index.tsx +++ b/src/theme/DocSidebar/index.tsx @@ -9,7 +9,12 @@ export default function DocSidebarWrapper(props: Props): JSX.Element { let newProps; // For all `/platforms` and `/docs/data` sidebars, remove the parent category from the sidebar. - if (props.path.startsWith('/platforms') || props.path.startsWith('/docs/data')) { + if ( + props.path.startsWith('/platforms') || + props.path.startsWith('/docs/data') || + props.path.startsWith('/es/platforms') || + props.path.startsWith('/es/docs/data') + ) { newProps = { ...props, }; From c73eb820c1fb2249daf91e8d3c93139a362e3576 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 18 Dec 2024 09:44:37 -0600 Subject: [PATCH 60/60] build: only build translations in production (set via docker arg) --- Dockerfile | 17 +++++++++-------- Makefile | 4 +++- package.json | 5 +++-- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 953768226..ab31dfa0d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,18 +16,19 @@ RUN apt-get update && apt-get install --no-install-recommends -y gpg curl git ma COPY . /app/ ARG CROWDIN_PERSONAL_TOKEN +ARG BUILD_TRANSLATIONS="False" RUN yarn install RUN yarn rpcspec:build RUN yarn stellar-cli:build -# TODO: This takes a bit of time, we should probably make sure it's only done -# for production builds -# See: https://docusaurus.io/docs/3.4.0/i18n/crowdin#automate-with-ci -RUN CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn crowdin:sync -RUN yarn crowdin:fix -# TODO: It's actually this part that is more time-consuming. The best way to -# speed this up is to generate the preview for only `--locale en` -RUN NODE_OPTIONS="--max-old-space-size=4096" yarn build + +ENV NODE_OPTIONS="--max-old-space-size=4096" +RUN if [ "$BUILD_TRANSLATIONS" = "True" ]; then \ + CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} yarn build:production; \ + else \ + # In the preview build, we only want to build for English. Much quicker + yarn build; \ + fi FROM nginx:1.27 diff --git a/Makefile b/Makefile index d0f21ebab..5f6e07272 100644 --- a/Makefile +++ b/Makefile @@ -7,9 +7,11 @@ LABEL ?= $(shell git rev-parse --short HEAD)$(and $(shell git status -s),-dirty- TAG ?= stellar/stellar-docs:$(LABEL) # https://github.com/opencontainers/image-spec/blob/master/annotations.md BUILD_DATE := $(shell date -u +%FT%TZ) +# If we're not in production, don't build translations +BUILD_TRANSLATIONS ?= "False" docker-build: - $(SUDO) docker build --no-cache --pull --label org.opencontainers.image.created="$(BUILD_DATE)" -t $(TAG) . --build-arg CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} + $(SUDO) docker build --no-cache --pull --label org.opencontainers.image.created="$(BUILD_DATE)" -t $(TAG) . --build-arg CROWDIN_PERSONAL_TOKEN=${CROWDIN_PERSONAL_TOKEN} --build-arg BUILD_TRANSLATIONS=${BUILD_TRANSLATIONS} docker-push: $(SUDO) docker push $(TAG) diff --git a/package.json b/package.json index 4b79e1abf..e16ed41fe 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "scripts": { "docusaurus": "docusaurus", "start": "docusaurus start", - "build": "docusaurus build", + "build": "docusaurus build --locale en", + "build:production": "yarn crowdin:sync && yarn crowdin:fix && yarn build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", @@ -30,7 +31,7 @@ "stellar-cli:build": "node scripts/stellar_cli.mjs", "crowdin": "crowdin", "crowdin:fix": "node scripts/copyIgnoredFiles.mjs && ./scripts/fix_translations.sh", - "crowdin:sync": "docusaurus write-translations && crowdin upload --delete-obsolete --no-progress && crowdin download --no-progress", + "crowdin:sync": "docusaurus write-translations && crowdin upload --no-progress && crowdin download --no-progress", "ap:versions:clean": "docusaurus clean-api-docs:version -p ap-apis ap_platform:all && docusaurus clean-api-docs:version -p ap-apis ap_callbacks:all && docusaurus clean-api-docs:version -p ap-apis ap_custody:all", "ap:versions:gen": "docusaurus gen-api-docs:version -p ap-apis ap_platform:all && docusaurus gen-api-docs:version -p ap-apis ap_callbacks:all && docusaurus gen-api-docs:version -p ap-apis ap_custody:all && rm ap_versioned_docs/version-*/api-reference/{callbacks,custody,platform/transactions}/*.info.mdx", "ap:versions:regen": "yarn ap:versions:clean && yarn ap:versions:gen",