├── nodejs └── express │ ├── simple-meta-transactions-webhook │ ├── .gitignore │ ├── .env.dist │ ├── package.json │ ├── README.md │ ├── src │ │ └── index.js │ └── package-lock.json │ ├── mint-nft-by-role-meta-transactions │ ├── .gitignore │ ├── .env.dist │ ├── package.json │ ├── README.md │ └── src │ │ └── index.js │ └── mint-one-of-one-nfts-meta-transactions │ ├── .gitignore │ ├── .env.dist │ ├── package.json │ ├── README.md │ └── src │ └── index.js ├── react ├── .DS_Store ├── custom-nft-minting-sales │ ├── src │ │ ├── react-app-env.d.ts │ │ ├── index.css │ │ ├── setupTests.ts │ │ ├── reportWebVitals.ts │ │ ├── index.tsx │ │ └── App.tsx │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── index.html │ ├── .env │ ├── postcss.config.js │ ├── collection-public-minting.png │ ├── config-overrides.js │ ├── .gitignore │ ├── tailwind.config.js │ ├── tsconfig.json │ ├── app.json │ ├── package.json │ └── README.md ├── community-airdrop-reward-stream │ ├── src │ │ ├── react-app-env.d.ts │ │ ├── index.css │ │ ├── setupTests.ts │ │ ├── reportWebVitals.ts │ │ ├── index.tsx │ │ └── App.tsx │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── index.html │ ├── postcss.config.js │ ├── preset-selection.png │ ├── staking-screenshot.png │ ├── config-overrides.js │ ├── .gitignore │ ├── tailwind.config.js │ ├── tsconfig.json │ ├── package.json │ └── README.md └── simple-wallet-integration │ └── README.md ├── typescript └── express │ └── mint-one-of-one-nfts-meta-transactions │ ├── .gitignore │ ├── .env.dist │ ├── package.json │ ├── README.md │ ├── src │ └── index.ts │ └── tsconfig.json ├── README.md └── LICENSE /nodejs/express/simple-meta-transactions-webhook/.gitignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /nodejs/express/mint-nft-by-role-meta-transactions/.gitignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /nodejs/express/mint-one-of-one-nfts-meta-transactions/.gitignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /react/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/.DS_Store -------------------------------------------------------------------------------- /typescript/express/mint-one-of-one-nfts-meta-transactions/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | dist -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Moved to [@flair-sdk/examples](https://github.com/flair-sdk/examples) 2 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; -------------------------------------------------------------------------------- /nodejs/express/simple-meta-transactions-webhook/.env.dist: -------------------------------------------------------------------------------- 1 | WEBHOOK_SECRET=my-secret-to-ensure-only-flair-is-sending-hook-requests -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/.env: -------------------------------------------------------------------------------- 1 | REACT_APP_COLLECTION_CHAIN_ID=137 2 | REACT_APP_COLLECTION_CONTRACT_ADDRESS=0xecb1788fa81221cd69b2ad2757981ddbb8786043 -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/custom-nft-minting-sales/public/favicon.ico -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/custom-nft-minting-sales/public/logo192.png -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/custom-nft-minting-sales/public/logo512.png -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/preset-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/community-airdrop-reward-stream/preset-selection.png -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/community-airdrop-reward-stream/public/favicon.ico -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/community-airdrop-reward-stream/public/logo192.png -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/community-airdrop-reward-stream/public/logo512.png -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/staking-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/community-airdrop-reward-stream/staking-screenshot.png -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/collection-public-minting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xflair/examples/HEAD/react/custom-nft-minting-sales/collection-public-minting.png -------------------------------------------------------------------------------- /nodejs/express/mint-nft-by-role-meta-transactions/.env.dist: -------------------------------------------------------------------------------- 1 | FLAIR_CLIENT_ID=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 2 | CONTRACT_CHAIN_ID=137 3 | MINTER_PRIVATE_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 4 | NFT_COLLECTION_ADDRESS=0xecb1788fa81221cd69b2ad2757981ddbb8786043 -------------------------------------------------------------------------------- /nodejs/express/mint-one-of-one-nfts-meta-transactions/.env.dist: -------------------------------------------------------------------------------- 1 | FLAIR_CLIENT_ID=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 2 | CONTRACT_CHAIN_ID=137 3 | MINTER_PRIVATE_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 4 | NFT_COLLECTION_ADDRESS=0xecb1788fa81221cd69b2ad2757981ddbb8786043 -------------------------------------------------------------------------------- /typescript/express/mint-one-of-one-nfts-meta-transactions/.env.dist: -------------------------------------------------------------------------------- 1 | FLAIR_CLIENT_ID=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 2 | CONTRACT_CHAIN_ID=137 3 | MINTER_PRIVATE_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 4 | NFT_COLLECTION_ADDRESS=0xecb1788fa81221cd69b2ad2757981ddbb8786043 -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/config-overrides.js: -------------------------------------------------------------------------------- 1 | const webpack = require("webpack"); 2 | 3 | module.exports = function override(config) { 4 | config.plugins = (config.plugins || []).concat([ 5 | new webpack.ProvidePlugin({ 6 | Buffer: ["buffer", "Buffer"], 7 | }), 8 | ]); 9 | 10 | return config; 11 | }; 12 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/config-overrides.js: -------------------------------------------------------------------------------- 1 | const webpack = require("webpack"); 2 | 3 | module.exports = function override(config) { 4 | config.plugins = (config.plugins || []).concat([ 5 | new webpack.ProvidePlugin({ 6 | Buffer: ["buffer", "Buffer"], 7 | }), 8 | ]); 9 | 10 | return config; 11 | }; 12 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: [ 3 | './public/**/*.html', 4 | './src/**/*.{js,jsx,ts,tsx,vue}', 5 | './node_modules/@0xflair/**/*.{js,jsx,ts,tsx,vue}', 6 | ], 7 | content: [ 8 | './public/**/*.html', 9 | './src/**/*.{js,jsx,ts,tsx,vue}', 10 | './node_modules/@0xflair/**/*.{js,jsx,ts,tsx,vue}', 11 | ], 12 | theme: { 13 | extend: {}, 14 | }, 15 | plugins: [ 16 | require('@tailwindcss/forms'), 17 | require('@tailwindcss/aspect-ratio'), 18 | ], 19 | safelist: [], 20 | }; 21 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: [ 3 | './public/**/*.html', 4 | './src/**/*.{js,jsx,ts,tsx,vue}', 5 | './node_modules/@0xflair/**/*.{js,jsx,ts,tsx,vue}', 6 | ], 7 | content: [ 8 | './public/**/*.html', 9 | './src/**/*.{js,jsx,ts,tsx,vue}', 10 | './node_modules/@0xflair/**/*.{js,jsx,ts,tsx,vue}', 11 | ], 12 | theme: { 13 | extend: {}, 14 | }, 15 | plugins: [ 16 | require('@tailwindcss/forms'), 17 | require('@tailwindcss/aspect-ratio'), 18 | ], 19 | safelist: [], 20 | }; 21 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"] 20 | } 21 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"] 20 | } 21 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import { FlairProvider } from 'flair-sdk'; 4 | 5 | import './index.css'; 6 | import App from './App'; 7 | import reportWebVitals from './reportWebVitals'; 8 | 9 | const root = ReactDOM.createRoot( 10 | document.getElementById('root') as HTMLElement 11 | ); 12 | root.render( 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | 20 | // If you want to start measuring performance in your app, pass a function 21 | // to log results (for example: reportWebVitals(console.log)) 22 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 23 | reportWebVitals(); 24 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import { FlairProvider } from 'flair-sdk'; 4 | 5 | import './index.css'; 6 | import App from './App'; 7 | import reportWebVitals from './reportWebVitals'; 8 | 9 | const root = ReactDOM.createRoot( 10 | document.getElementById('root') as HTMLElement 11 | ); 12 | root.render( 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | 20 | // If you want to start measuring performance in your app, pass a function 21 | // to log results (for example: reportWebVitals(console.log)) 22 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 23 | reportWebVitals(); 24 | -------------------------------------------------------------------------------- /typescript/express/mint-one-of-one-nfts-meta-transactions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mint-one-of-one-nfts-meta-transactions", 3 | "version": "1.0.0", 4 | "description": "This example uses Flair SDK to mint new NFTs from your backend using meta transactions. In this approach you will configure a private key that has the \"minter\" role on your NFT collection.", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "npx tsc", 8 | "start": "node dist/index.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "dependencies": { 14 | "@0xflair/ipfs": "^0.120.3", 15 | "@0xflair/meta-transactions": "^0.120.3", 16 | "dotenv": "^16.0.1", 17 | "ethers": "^5.7.0", 18 | "express": "^4.18.1", 19 | "express-async-handler": "^1.2.0" 20 | }, 21 | "devDependencies": { 22 | "@types/express": "^4.17.13", 23 | "@types/node": "^18.7.14", 24 | "typescript": "^4.8.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /nodejs/express/simple-meta-transactions-webhook/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-meta-transactions-webhook", 3 | "version": "1.0.0", 4 | "description": "Node.js and Express example to mint NFTs via meta transactions using Flair SDK", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "start": "node src/index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/0xflair/examples.git" 13 | }, 14 | "keywords": [ 15 | "ethereum", 16 | "nft", 17 | "mint", 18 | "flair", 19 | "sdk", 20 | "nodejs", 21 | "express" 22 | ], 23 | "author": "Flair Foundation", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/0xflair/examples/issues" 27 | }, 28 | "homepage": "https://github.com/0xflair/examples#readme", 29 | "dependencies": { 30 | "dotenv": "^16.0.1", 31 | "express": "^4.18.1", 32 | "express-async-handler": "^1.2.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /nodejs/express/mint-nft-by-role-meta-transactions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mint-nft-by-role-meta-transactions", 3 | "version": "1.0.0", 4 | "description": "Node.js and Express example to mint NFTs via meta transactions using Flair SDK", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "start": "node src/index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/0xflair/examples.git" 13 | }, 14 | "keywords": [ 15 | "ethereum", 16 | "nft", 17 | "mint", 18 | "flair", 19 | "sdk", 20 | "nodejs", 21 | "express" 22 | ], 23 | "author": "Flair Foundation", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/0xflair/examples/issues" 27 | }, 28 | "homepage": "https://github.com/0xflair/examples#readme", 29 | "dependencies": { 30 | "@0xflair/meta-transactions": "^0.120.3", 31 | "dotenv": "^16.0.1", 32 | "express": "^4.18.1", 33 | "express-async-handler": "^1.2.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /nodejs/express/mint-one-of-one-nfts-meta-transactions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mint-one-of-one-nfts-meta-transactions", 3 | "version": "1.0.0", 4 | "description": "Node.js and Express example to mint NFTs via meta transactions using Flair SDK", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "start": "node src/index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/0xflair/examples.git" 13 | }, 14 | "keywords": [ 15 | "ethereum", 16 | "nft", 17 | "mint", 18 | "flair", 19 | "sdk", 20 | "nodejs", 21 | "express" 22 | ], 23 | "author": "Flair Foundation", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/0xflair/examples/issues" 27 | }, 28 | "homepage": "https://github.com/0xflair/examples#readme", 29 | "dependencies": { 30 | "@0xflair/ipfs": "^0.120.3", 31 | "@0xflair/meta-transactions": "^0.120.3", 32 | "dotenv": "^16.0.1", 33 | "express": "^4.18.1", 34 | "express-async-handler": "^1.2.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Flair 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-nft-minting-sales", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@headlessui/react": "^1.6.4", 7 | "@heroicons/react": "^1.0.6", 8 | "@tailwindcss/aspect-ratio": "^0.4.0", 9 | "@testing-library/jest-dom": "^5.16.4", 10 | "@testing-library/react": "^13.3.0", 11 | "@testing-library/user-event": "^13.5.0", 12 | "@types/jest": "^27.5.2", 13 | "@types/node": "^16.11.38", 14 | "@types/react": "^18.0.10", 15 | "@types/react-dom": "^18.0.5", 16 | "flair-sdk": "^0.59.4", 17 | "react": "^18.1.0", 18 | "react-dom": "^18.1.0", 19 | "react-scripts": "5.0.1", 20 | "tailwindcss": "^3.0.24", 21 | "typescript": "^4.7.2", 22 | "web-vitals": "^2.1.4" 23 | }, 24 | "scripts": { 25 | "start": "react-app-rewired start", 26 | "build": "react-app-rewired build", 27 | "test": "react-app-rewired test", 28 | "eject": "react-scripts eject" 29 | }, 30 | "eslintConfig": { 31 | "extends": [ 32 | "react-app", 33 | "react-app/jest" 34 | ] 35 | }, 36 | "browserslist": { 37 | "production": [ 38 | ">0.2%", 39 | "not dead", 40 | "not op_mini all" 41 | ], 42 | "development": [ 43 | "last 1 chrome version", 44 | "last 1 firefox version", 45 | "last 1 safari version" 46 | ] 47 | }, 48 | "devDependencies": { 49 | "buffer": "^6.0.3", 50 | "react-app-rewired": "^2.2.1" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "community-airdrop-reward-stream", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@headlessui/react": "^1.6.4", 7 | "@heroicons/react": "^1.0.6", 8 | "@tailwindcss/aspect-ratio": "^0.4.0", 9 | "@tailwindcss/forms": "^0.5.2", 10 | "@testing-library/jest-dom": "^5.16.4", 11 | "@testing-library/react": "^13.3.0", 12 | "@testing-library/user-event": "^13.5.0", 13 | "@types/jest": "^27.5.2", 14 | "@types/node": "^16.11.38", 15 | "@types/react": "^18.0.10", 16 | "@types/react-dom": "^18.0.5", 17 | "flair-sdk": "^0.123.1", 18 | "react": "^18.1.0", 19 | "react-dom": "^18.1.0", 20 | "react-scripts": "5.0.1", 21 | "tailwindcss": "^3.0.24", 22 | "typescript": "^4.7.2", 23 | "web-vitals": "^2.1.4" 24 | }, 25 | "scripts": { 26 | "start": "react-app-rewired start", 27 | "build": "react-app-rewired build", 28 | "test": "react-app-rewired test", 29 | "eject": "react-scripts eject" 30 | }, 31 | "eslintConfig": { 32 | "extends": [ 33 | "react-app", 34 | "react-app/jest" 35 | ] 36 | }, 37 | "browserslist": { 38 | "production": [ 39 | ">0.2%", 40 | "not dead", 41 | "not op_mini all" 42 | ], 43 | "development": [ 44 | "last 1 chrome version", 45 | "last 1 firefox version", 46 | "last 1 safari version" 47 | ] 48 | }, 49 | "devDependencies": { 50 | "buffer": "^6.0.3", 51 | "react-app-rewired": "^2.2.1" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-nft-minting-sales", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@gnosis.pm/safe-apps-provider": "^0.13.1", 7 | "@gnosis.pm/safe-apps-sdk": "^7.8.0", 8 | "@headlessui/react": "^1.6.4", 9 | "@heroicons/react": "^1.0.6", 10 | "@tailwindcss/aspect-ratio": "^0.4.0", 11 | "@tailwindcss/forms": "^0.5.2", 12 | "@testing-library/jest-dom": "^5.16.4", 13 | "@testing-library/react": "^13.3.0", 14 | "@testing-library/user-event": "^13.5.0", 15 | "@types/jest": "^27.5.2", 16 | "@types/node": "^16.11.38", 17 | "@types/react": "^18.0.10", 18 | "@types/react-blockies": "^1.4.1", 19 | "@types/react-dom": "^18.0.5", 20 | "@types/react-modal": "^3.13.1", 21 | "flair-sdk": "^0.121.0", 22 | "react": "^18.1.0", 23 | "react-blockies": "^1.4.1", 24 | "react-dom": "^18.1.0", 25 | "react-modal": "^3.15.1", 26 | "react-scripts": "5.0.1", 27 | "tailwindcss": "^3.0.24", 28 | "typescript": "^4.7.2", 29 | "web-vitals": "^2.1.4" 30 | }, 31 | "scripts": { 32 | "start": "react-app-rewired start", 33 | "build": "react-app-rewired build", 34 | "test": "react-app-rewired test", 35 | "eject": "react-scripts eject" 36 | }, 37 | "eslintConfig": { 38 | "extends": [ 39 | "react-app", 40 | "react-app/jest" 41 | ] 42 | }, 43 | "browserslist": { 44 | "production": [ 45 | ">0.2%", 46 | "not dead", 47 | "not op_mini all" 48 | ], 49 | "development": [ 50 | "last 1 chrome version", 51 | "last 1 firefox version", 52 | "last 1 safari version" 53 | ] 54 | }, 55 | "devDependencies": { 56 | "buffer": "^6.0.3", 57 | "react-app-rewired": "^2.2.1" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /nodejs/express/simple-meta-transactions-webhook/README.md: -------------------------------------------------------------------------------- 1 | # Example: Simple webhook for Meta Transactions 2 | 3 | This example uses Flair Webhooks to listen to results of a [meta transaction](../mint-nft-by-role-meta-transactions/) which is helpful to capture final transaction hash and nonce where your meta transactions are included. 4 | 5 | ##### Dependencies 6 | 7 | * Node.js 8 | * Express 9 | * A backend that sends meta transactions like [this example](../mint-nft-by-role-meta-transactions/) 10 | 11 | ## :fire: Quick Start 12 | 13 | 1. Create a test collection and run an example server which sends meta transactions, like [this example](../mint-nft-by-role-meta-transactions/). 14 | 15 | 2. Clone this repo and navigate to the example directory: 16 | 17 | ```bash 18 | git clone https://github.com/0xflair/examples 19 | 20 | cd examples/nodejs/express/simple-meta-transactions-webhook 21 | 22 | npm install 23 | ``` 24 | 25 | 3. Copy `.env.dist` and create a new `.env` file: 26 | 27 | ```bash 28 | cp .env.dist .env 29 | ``` 30 | 31 | 4. Put the correct values in `.env` file: 32 | * *FLAIR_CLIENT_ID*: copy from step 1 above where you created your [Flair API Client](https://app.flair.finance/clients). 33 | 34 | 5. Start the test server: 35 | 36 | ```bash 37 | npm start 38 | ``` 39 | 40 | 6. Use [ngrok](https://ngrok.com/) to expose the test server publicly: 41 | 42 | ```bash 43 | ngrok http 8090 44 | ``` 45 | 46 | 7. Create a webhook in your Flair Client page, and set the URL based on ngrok domain: 47 | 48 | ```bash 49 | # for example: 50 | https://0da8-24-57-101-201.ngrok.io/meta-transactions/webhook 51 | ``` 52 | 53 | ## Need help? 54 | 55 | Our developers are happy to help you debug issues and problems, join our [Discord](https://discord.gg/flair) and drop a message. 56 | -------------------------------------------------------------------------------- /nodejs/express/simple-meta-transactions-webhook/src/index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | 3 | const express = require("express"); 4 | const asyncHandler = require("express-async-handler"); 5 | 6 | const app = express(); 7 | 8 | app.use(express.json()); 9 | 10 | app.post( 11 | "/meta-transactions/webhook", 12 | asyncHandler(async (req, res) => { 13 | if (req.header('X-Webhook-Secret') !== process.env.WEBHOOK_SECRET) { 14 | res.status(401).send(`Wrong webhook secret: ${req.header('X-Webhook-Secret')}`); 15 | return; 16 | } 17 | 18 | console.log('# Webhook received: '); 19 | console.log('\t- Transaction ID: ' + req.body.payload.id); 20 | console.log('\t- Transaction hash: ' + req.body.payload.txHash); 21 | console.log('\t- Transaction nonce: ' + req.body.payload.txNonce); 22 | console.log('\t- Transaction chainId: ' + req.body.payload.chainId); 23 | console.log('\t- Transaction forwarder: ' + req.body.payload.forwarder); 24 | console.log('\t- Transaction signature: ' + req.body.payload.signature); 25 | console.log('\t- Meta transaction from: ' + req.body.payload.from); 26 | console.log('\t- Meta transaction to: ' + req.body.payload.to); 27 | console.log('\t- Meta transaction value: ' + req.body.payload.value); 28 | console.log('\t- Meta transaction nonce: ' + req.body.payload.nonce); 29 | 30 | res.send({ 31 | webhookCategory: req.body.category, 32 | webhookEvent: req.body.event, 33 | webhookPayload: req.body.payload 34 | }); 35 | }) 36 | ); 37 | 38 | const port = 8090; 39 | 40 | app.listen(port, () => { 41 | console.log(`Flair SDK Example - Simple Meta Transactions Webhook!`); 42 | console.log(`- Listening on port ${port}`); 43 | console.log(``); 44 | console.log(`Now you will receive webhooks on: http://localhost:${port}/meta-transactions/webhook`); 45 | }); 46 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Flair - Custom NFT Minting Sales 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Flair - Community Airdrop Reward Stream 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /react/simple-wallet-integration/README.md: -------------------------------------------------------------------------------- 1 | # Example: Simple Wallet Integration using React 2 | 3 | This example React app renders a connect button and when wallet is connected it shows a dropdown menu with wallet's address, balance and disconnect button. 4 | 5 | ##### Dependencies 6 | 7 | - `flair-sdk`: latest 8 | - `react`: v17.x or v18.x 9 | 10 | 30 | 31 | ## 🔮 Tutorial 32 | 33 | To use this example within your app: 34 | 35 | 1. Install `flair-sdk` in your React app: 36 | 37 | ```sh 38 | npm install flair-sdk 39 | ``` 40 | 41 | 2. Configure FlairProvider around your root App: 42 | 43 | ```ts 44 | import { FlairProvider } from "flair-sdk"; 45 | 46 | // ... 47 | 48 | 49 | ; 50 | // ... 51 | ``` 52 | 53 | 3. _(optional)_ If you're using Webpack 5 (e.g. React v17+) you might to manually configure Buffer for Coinbase wallet to work: 54 | 55 | 1. Install `npm install react-app-rewired buffer` 56 | 2. Then create a [config-overrides.js](config-overrides.js) to inject the Buffer. 57 | 58 | 4. Add ``, `` and/or `` components in your dApp. 59 | 60 | ```ts 61 | import { 62 | ConnectButton, 63 | DisconnectButton, 64 | IfConnected, 65 | WalletProfile, 66 | WalletDropdown 67 | } from "flair-sdk"; 68 | 69 | const App = () => { 70 | return ( 71 |
72 | {/* Render a simple connect button */} 73 | Hi! You can connect here: 74 | 75 | {/* If user is connected render a dropdown */} 76 | 77 | 78 | 79 | 80 | {/* Render a wallet profile right after connect button */} 81 | 82 | 83 | 84 | 85 | {/* Render a dropdown with wallet profile and menu right after connect button */} 86 | 87 | 88 | 89 | 90 | {/* Render a disconnect button after user has connected */} 91 | 92 | 93 | 94 |
95 | ); 96 | }; 97 | ``` 98 | 99 | 5. Profit :rocket: 100 | -------------------------------------------------------------------------------- /nodejs/express/mint-one-of-one-nfts-meta-transactions/README.md: -------------------------------------------------------------------------------- 1 | # Example: Mint 1-of-1 NFTs from your backend (Node.js) 2 | 3 | This example uses Flair SDK to mint new NFTs from your backend using meta transactions. In this approach you will configure a private key that has the "minter" role on your NFT collection (or is contract owner -- which is less secure). 4 | 5 | We're going to use "Digital Asset Collection" collection, which is using [OneOfOneExtension](https://docs.flair.finance/sdk/nft-collections/minting/of-1-mint), and will mint NFTs with dedicated dynamic metadata and image URI. This means each NFT will have it's own metadata and image IPFS URI. 6 | 7 | ##### Dependencies 8 | 9 | * Node.js 10 | * Express 11 | * `flair-sdk`: latest 12 | * An Ethereum-compatible wallet private key (either [via Javascript](https://www.quicknode.com/guides/web3-sdks/how-to-generate-a-new-ethereum-address-in-javascript) using [MetaMask](https://metamask.io/)) 13 | 14 | ## :fire: Quick Start 15 | 16 | 1. Create and deploy a **Digital Asset Collection** under 2 minutes via [Flair's Collections](https://app.flair.finance/collections/create/ERC721OneOfOne). 17 | 18 | 2. Create your first API Key if not already done via [Flair's API Keys](https://app.flair.finance/clients). 19 | 20 | 3. Clone this repo and navigate to the example directory: 21 | 22 | ```bash 23 | git clone https://github.com/0xflair/examples 24 | 25 | cd examples/nodejs/express/mint-one-of-one-nft-meta-transactions 26 | 27 | npm install 28 | ``` 29 | 30 | 4. Copy `.env.dist` and create a new `.env` file: 31 | 32 | ```bash 33 | cp .env.dist .env 34 | ``` 35 | 36 | 5. Put the correct values in `.env` file: 37 | * *FLAIR_CLIENT_ID*: copy from step2 above. 38 | * *CONTRACT_CHAIN_ID*: based on the chain you used to deploy the contract. `1` for Eth mainnet, `4` for Rinkeby testnet, `137` for Polygon mainnet, etc. 39 | * *MINTER_PRIVATE_KEY*: the private key of your wallet, or a new wallet you created just for minting. 40 | 41 | 6. If you're using a minter wallet other than your contract owner, give that minter address "MINTER_ROLE", so it can mint NFTs: 42 | 1. Go to your collection dashboard 43 | 2. Go to "Roles" admin section 44 | 3. Paste your minter address, and click on "Grant role". 45 | 46 | 7. Allow Flair's trusted forwarder to send meta-transactions to your collection: 47 | 1. Go to your collection dashboard 48 | 2. Go to "Minting" admin section, scroll down to "Backend minting" card. 49 | 3. Configure your trusted forwarder address with the value of Flair's latest trusted forwarder shown at the bottom of the same card. 50 | 51 | 8. Start the test server: 52 | 53 | ```bash 54 | npm start 55 | ``` 56 | 57 | 9. Open the test endpoint in your browser to mint the first NFT: 58 | 59 | * [http://localhost:8080/mint](http://localhost:8080/mint) 60 | 61 | ## Need help? 62 | 63 | Our developers are happy to help you debug issues and problems, join our [Discord](https://discord.gg/flair) and drop a message. 64 | -------------------------------------------------------------------------------- /nodejs/express/mint-nft-by-role-meta-transactions/README.md: -------------------------------------------------------------------------------- 1 | # Example: Mint NFTs by role from your backend 2 | 3 | This example uses Flair SDK to mint new NFTs from your backend using meta transactions. In this approach you will configure a private key that has the "minter" role on your NFT collection (or is contract owner -- which is less secure). 4 | 5 | We're going to rely on [ERC721RoleBasedMintExtension](https://github.com/0xflair/evm-contracts/blob/main/contracts/collections/ERC721/extensions/ERC721RoleBasedMintExtension.sol) to mint NFTs. This means you'll grant MINTER_ROLE to a specific admin wallet on your backend, which is able to mint NFTs based on your own logic in your backend. 6 | 7 | ##### Dependencies 8 | 9 | * Node.js 10 | * Express 11 | * `flair-sdk`: latest 12 | * An Ethereum-compatible wallet private key (either [via Javascript](https://www.quicknode.com/guides/web3-sdks/how-to-generate-a-new-ethereum-address-in-javascript) using [MetaMask](https://metamask.io/)) 13 | 14 | ## :fire: Quick Start 15 | 16 | 1. Create and deploy a **Simple or Tiered Sales Collection** under 2 minutes via [Flair's Collections](https://app.flair.finance/collections/create). 17 | 18 | 2. Create your first API Key if not already done via [Flair's API Keys](https://app.flair.finance/clients). 19 | 20 | 3. Clone this repo and navigate to the example directory: 21 | 22 | ```bash 23 | git clone https://github.com/0xflair/examples 24 | 25 | cd examples/nodejs/express/mint-nft-by-role-meta-transactions 26 | 27 | npm install 28 | ``` 29 | 30 | 4. Copy `.env.dist` and create a new `.env` file: 31 | 32 | ```bash 33 | cp .env.dist .env 34 | ``` 35 | 36 | 5. Put the correct values in `.env` file: 37 | * *FLAIR_CLIENT_ID*: copy from step2 above. 38 | * *CONTRACT_CHAIN_ID*: based on the chain you used to deploy the contract. `1` for Eth mainnet, `4` for Rinkeby testnet, `137` for Polygon mainnet, etc. 39 | * *MINTER_PRIVATE_KEY*: the private key of your wallet, or a new wallet you created just for minting. 40 | 41 | 6. If you're using a minter wallet other than your contract owner, give that minter address "MINTER_ROLE", so it can mint NFTs: 42 | 1. Go to your collection dashboard 43 | 2. Go to "Roles" admin section 44 | 3. Paste your minter address, and click on "Grant role". 45 | 46 | 7. Allow Flair's trusted forwarder to send meta-transactions to your collection: 47 | 1. Go to your collection dashboard 48 | 2. Go to "Minting" admin section, scroll down to "Backend minting" card. 49 | 3. Configure your trusted forwarder address with the value of Flair's latest trusted forwarder shown at the bottom of the same card. 50 | 51 | 8. Start the test server: 52 | 53 | ```bash 54 | npm start 55 | ``` 56 | 57 | 9. Open the test endpoint in your browser to mint the first NFT: 58 | 59 | * [http://localhost:8080/mint](http://localhost:8080/mint) 60 | 61 | ## Need help? 62 | 63 | Our developers are happy to help you debug issues and problems, join our [Discord](https://discord.gg/flair) and drop a message. 64 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/README.md: -------------------------------------------------------------------------------- 1 | # Example: Custom NFT Minting Sales Page using React 2 | 3 | This example React app renders a minting pre-sale/public-sale widget for an NFT collection. 4 | 5 | ##### Dependencies 6 | 7 | * `flair-sdk`: latest 8 | * `react`: v17.x or v18.x 9 | 10 | ## :fire: Quick Start 11 | 12 | 1. Create a new NFT collection using [Flair's dashboard](https://app.flair.finance/collections). Note that you will be the full owner of smart contract. 13 | 2. Clone the examples repo, install dependencies in the `custom-nft-minting-sales` directory: 14 | 15 | ```sh 16 | git clone https://github.com/0xflair/examples 17 | 18 | cd examples/react/custom-nft-minting-sales 19 | 20 | npm install 21 | ``` 22 | 23 | 3. Grab your contract address and chain ID, and update [.env](./.env): 24 | * Set `REACT_APP_COLLECTION_CONTRACT_ADDRESS` to your deployed contract address you get from Flair's dashboard > Collections > your-collection > Deploy tab. 25 | * Set `REACT_APP_COLLECTION_CHAIN_ID` depending on the contract chain. Use `1` for Eth mainnet, `4` for Rinkeby testnet, `137` for Polygon mainnet, etc. 26 | 4. Run the react app in the `custom-nft-minting-sales` directory: 27 | 28 | ```sh 29 | npm start 30 | ``` 31 | 32 | 5. Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 33 | 34 | ![Screenshot](./collection-public-minting.png) 35 | 36 | ## 🔮 Tutorial 37 | 38 | To use this example within your app: 39 | 40 | 1. Install `flair-sdk` in your React app: 41 | 42 | ```sh 43 | npm install flair-sdk 44 | ``` 45 | 46 | 2. Configure FlairProvider around your root App: 47 | 48 | ```ts 49 | import { FlairProvider } from 'flair-sdk'; 50 | 51 | // ... 52 | 53 | 54 | 55 | // ... 56 | ``` 57 | 58 | 3. Implement the minting widget depending on your preferred customizability: 59 | * Easiest approach with minimum customizability you can copy the code within [App.tsx](./src/App.tsx). 60 | * To have your own layout you can use individual components as in [CollectionSalesMintingSection.tsx](https://github.com/0xflair/typescript-sdk/blob/main/packages/react-nft-collections/src/extensions/sales/sections/CollectionSalesMintingSection.tsx#L28-L135) 61 | 62 | 4. *(optional)* To get the default styling you can install and configure [tailwindcss](https://tailwindcss.com/docs/installation/using-postcss): 63 | 1. Install `npm install tailwindcss @headlessui/react @heroicons/react` 64 | 2. Configure [tailwind.config.js](./tailwind.config.js) 65 | 3. Configure [postcss.config.js](./postcss.config.js) 66 | 4. Import tailwind in your [index.css](./src/index.css). Make sure your app imports the CSS `import './index.css';`. 67 | 68 | 5. *(optional)* If you're using Webpack 5 (e.g. React v17+) you need to manually configure Buffer for Coinbase wallet to work: 69 | 1. Install `npm install react-app-rewired buffer` 70 | 2. Then create a [config-overrides.js](config-overrides.js) to inject the Buffer. 71 | 72 | 6. Profit :rocket: 73 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/README.md: -------------------------------------------------------------------------------- 1 | # Example: Airdrop rewards to your NFT community 2 | 3 | This example React app uses Flair token streams to render a claiming widget for holders of your NFT collection to claim some ERC20 rewards over a specific period of time. 4 | 5 | ##### Dependencies 6 | 7 | * `flair-sdk`: latest 8 | * `react`: v17.x or v18.x 9 | 10 | ## :fire: Quick Start 11 | 12 | 1. Create a new stream in [Flair's dashboard](https://app.flair.finance/streams). Note that you will be the full owner of staking contract. 13 | 2. Make sure to create "Reward for holding NFTs" 14 | 15 | ![Screenshot](./preset-selection.png) 16 | 17 | 3. Grab your contract address and chain ID, and update [App.tsx](./src/App.tsx): 18 | * Set `STREAM_CONTRACT_ADDRESS` to your deployed contract address you get from Flair's dashboard > Streams > your-stream > Deploy tab. 19 | * Set `STREAM_CHAIN_ID` depending on the contract chain. Use `1` for Eth mainnet, `4` for Rinkeby testnet, `137` for Polygon mainnet. 20 | 4. Clone the repo, install dependencies and run the react app in the `community-airdrop-reward-stream` directory: 21 | 22 | ```sh 23 | git clone https://github.com/0xflair/examples 24 | 25 | cd examples/react/community-airdrop-reward-stream 26 | 27 | npm install 28 | 29 | npm start 30 | ``` 31 | 32 | 5. Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 33 | 34 | ![Screenshot](./staking-screenshot.png) 35 | 36 | ## 🔮 Tutorial 37 | 38 | To use this example within your own React app: 39 | 40 | 1. Install `flair-sdk`: 41 | 42 | ```sh 43 | npm install flair-sdk 44 | ``` 45 | 46 | 2. Configure FlairProvider around your root App: 47 | 48 | ```ts 49 | import { FlairProvider } from 'flair-sdk'; 50 | 51 | // ... 52 | 53 | 54 | 55 | // ... 56 | ``` 57 | 58 | 3. Implement the claiming widget depending on your preferred customizability: 59 | * Easiest approach with minimum customizability you can copy the code within [App.tsx](./src/App.tsx). 60 | * To have your own layout you can use individual components as in [StreamClaimingSection.tsx](https://github.com/0xflair/typescript-sdk/blob/main/packages/react-token-streams/src/sections/StreamClaimingSection.tsx#L61) 61 | 62 | 4. *(optional)* To get the default styling you can install and configure [tailwindcss](https://tailwindcss.com/docs/installation/using-postcss): 63 | 1. Install `npm install tailwindcss @headlessui/react @heroicons/react` 64 | 2. Configure [tailwind.config.js](./tailwind.config.js) 65 | 3. Configure [postcss.config.js](./postcss.config.js) 66 | 4. Import tailwind in your [index.css](./src/index.css). Make sure your app imports the CSS `import './index.css';`. 67 | 68 | 5. *(optional)* If you're using Webpack 5 (e.g. React v17+) you need to manually configure Buffer for Coinbase wallet to work: 69 | 1. Install `npm install react-app-rewired buffer` 70 | 2. Then create a [config-overrides.js](config-overrides.js) to inject the Buffer. 71 | 72 | 6. Profit :rocket: 73 | -------------------------------------------------------------------------------- /typescript/express/mint-one-of-one-nfts-meta-transactions/README.md: -------------------------------------------------------------------------------- 1 | # Example: Mint 1-of-1 NFTs from your backend (Typescript) 2 | 3 | This example uses Flair SDK to mint new NFTs from your backend using meta transactions. In this approach you will configure a private key that has the "minter" role on your NFT collection (or is contract owner -- which is less secure). 4 | 5 | We're going to use "Digital Asset Collection" collection, which is using [OneOfOneExtension](https://docs.flair.finance/sdk/nft-collections/minting/of-1-mint), and will mint NFTs with dedicated dynamic metadata and image URI. This means each NFT will have it's own metadata and image IPFS URI. 6 | 7 | ##### Dependencies 8 | 9 | * Node.js 10 | * Typescript 11 | * Express 12 | * `flair-sdk`: latest 13 | * An Ethereum-compatible wallet private key (either [via Javascript](https://www.quicknode.com/guides/web3-sdks/how-to-generate-a-new-ethereum-address-in-javascript) using [MetaMask](https://metamask.io/)) 14 | 15 | ## :fire: Quick Start 16 | 17 | 1. Create and deploy a **Digital Asset Collection** under 2 minutes via [Flair's Collections](https://app.flair.finance/collections/create/ERC721OneOfOne). 18 | 19 | 2. Create your first API Key if not already done via [Flair's API Keys](https://app.flair.finance/clients). 20 | 21 | 3. Clone this repo and navigate to the example directory: 22 | 23 | ```bash 24 | git clone https://github.com/0xflair/examples 25 | 26 | cd examples/nodejs/express/mint-one-of-one-nft-meta-transactions 27 | 28 | npm install 29 | ``` 30 | 31 | 4. Copy `.env.dist` and create a new `.env` file: 32 | 33 | ```bash 34 | cp .env.dist .env 35 | ``` 36 | 37 | 5. Put the correct values in `.env` file: 38 | * *FLAIR_CLIENT_ID*: copy from step2 above. 39 | * *CONTRACT_CHAIN_ID*: based on the chain you used to deploy the contract. `1` for Eth mainnet, `4` for Rinkeby testnet, `137` for Polygon mainnet, etc. 40 | * *MINTER_PRIVATE_KEY*: the private key of your wallet, or a new wallet you created just for minting. 41 | 42 | 6. If you're using a minter wallet other than your contract owner, give that minter address "MINTER_ROLE", so it can mint NFTs: 43 | 1. Go to your collection dashboard 44 | 2. Go to "Roles" admin section 45 | 3. Paste your minter address, and click on "Grant role". 46 | 47 | 7. Allow Flair's trusted forwarder to send meta-transactions to your collection: 48 | 1. Go to your collection dashboard 49 | 2. Go to "Minting" admin section, scroll down to "Backend minting" card. 50 | 3. Configure your trusted forwarder address with the value of Flair's latest trusted forwarder shown at the bottom of the same card. 51 | 52 | 8. Build the project to get javascript files based on typescript code: 53 | 54 | ```bash 55 | npm run build 56 | ``` 57 | 58 | 9. Start the test server: 59 | 60 | ```bash 61 | npm start 62 | ``` 63 | 64 | 10. Open the test endpoint in your browser to mint the first NFT: 65 | 66 | * [http://localhost:8080/mint](http://localhost:8080/mint) 67 | 68 | ## Need help? 69 | 70 | Our developers are happy to help you debug issues and problems, join our [Discord](https://discord.gg/flair) and drop a message. 71 | -------------------------------------------------------------------------------- /nodejs/express/mint-nft-by-role-meta-transactions/src/index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | 3 | const express = require("express"); 4 | const asyncHandler = require("express-async-handler"); 5 | 6 | /** 7 | * 1) Import required libraries: 8 | * 9 | * - "ethers" helps us create a Wallet object based on a private key, which helps us sign transactions. 10 | * - "flair-sdk" provides a contract object with ability to submit meta transactions. 11 | */ 12 | const { Wallet } = require("ethers"); 13 | const { createFlairContractWithMetaTransactions } = require("@0xflair/meta-transactions"); 14 | 15 | /** 16 | * 2) Load configurations from environment variables (or any config management you use): 17 | * 18 | * - "chainId" is the numeric ID of the chain where your NFT contract is deployed (1 for Ethereum, 4 for Rinkeby Testnet, 137 for Polygon). 19 | * - "flairClientId" unique client ID of your Flair account, used for billing purposes. 20 | * - "signer" is created based on private key of the minter wallet, used to sign NFT minting meta transactions. 21 | * - "nftCollectionAddress" contract address for your deployed NFT collection on the blockchain. 22 | */ 23 | const chainId = Number(process.env.CONTRACT_CHAIN_ID); 24 | const flairClientId = process.env.FLAIR_CLIENT_ID; 25 | const signer = new Wallet(process.env.MINTER_PRIVATE_KEY); 26 | const nftCollectionAddress = process.env.NFT_COLLECTION_ADDRESS; 27 | 28 | /** 29 | * 3) Create client instance for the ethers.js-compatible contract augmented with meta transactions. 30 | * 31 | * In this example we use one of ready-made presets (ERC721SimpleSalesCollection). 32 | * To use a custom built contract you can manually create the meta transactions client instance (new ). 33 | */ 34 | const nftContract = createFlairContractWithMetaTransactions({ 35 | chainId: chainId, 36 | flairClientId: flairClientId, 37 | contractFqn: "collections/ERC721/extensions/ERC721RoleBasedMintExtension", 38 | addressOrName: nftCollectionAddress, 39 | signer: signer, 40 | }); 41 | 42 | /** 43 | * 4) Example endpoints: 44 | * 45 | * - "GET /mint" endpoint simply uploads a new metadata to IPFS and mints a new 1-of-1 NFT based on that metadata. 46 | */ 47 | const app = express(); 48 | 49 | app.get( 50 | "/mint", 51 | asyncHandler(async (req, res) => { 52 | // 53 | // A) "to" is the wallet address that receives the new NFT 54 | // 55 | const to = "0x8016f96b5cCC4663324E8D117c337BB7aA68d909"; 56 | 57 | // 58 | // B) "count" is the number of NFTs to send to this wallet 59 | // 60 | const count = 1; 61 | 62 | console.log(``); 63 | console.log(`Minting ${count} NFTs to ${to}:`); 64 | 65 | // 66 | // C) Sign a meta transaction and submit it to the Flair backend relayer for processing 67 | // 68 | const data = await nftContract.metaTransaction.mintByRole( 69 | to, 70 | count 71 | ); 72 | 73 | console.log(` - Signature: ${data.signature}`); 74 | console.log(` - Transaction is being processed and mined check your contract on EtherScan to see the status...`); 75 | console.log(``); 76 | 77 | // The response is a successfully submitted (but not yet mined) meta transaction. 78 | // Note that depending on traffic on the blockchain it might take a few minutes to be mined and processed. 79 | res.send({ 80 | response: data 81 | }); 82 | }) 83 | ); 84 | 85 | const port = 8080; 86 | 87 | app.listen(port, () => { 88 | console.log(`Flair SDK Example - Mint NFTs by role via Meta Transactions!`); 89 | console.log(`- Listening on port ${port}`); 90 | console.log(``); 91 | console.log(`Now you can mint NFTs by opening: http://localhost:${port}/mint`); 92 | }); 93 | -------------------------------------------------------------------------------- /nodejs/express/mint-one-of-one-nfts-meta-transactions/src/index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | 3 | const express = require("express"); 4 | const asyncHandler = require("express-async-handler"); 5 | 6 | /** 7 | * 1) Import required libraries: 8 | * 9 | * - "ethers" helps us create a Wallet object based on a private key, which helps us sign transactions. 10 | * - "flair-sdk" provides a contract object with ability to submit meta transactions. 11 | */ 12 | const { Wallet } = require("ethers"); 13 | const { IpfsClient } = require("@0xflair/ipfs"); 14 | const { createFlairContractWithMetaTransactions } = require("@0xflair/meta-transactions"); 15 | 16 | /** 17 | * 2) Load configurations from environment variables (or any config management you use): 18 | * 19 | * - "chainId" is the numeric ID of the chain where your NFT contract is deployed (1 for Ethereum, 4 for Rinkeby Testnet, 137 for Polygon). 20 | * - "flairClientId" unique client ID of your Flair account, used for billing purposes. 21 | * - "signer" is created based on private key of the minter wallet, used to sign NFT minting meta transactions. 22 | * - "nftCollectionAddress" contract address for your deployed NFT collection on the blockchain. 23 | */ 24 | const chainId = Number(process.env.CONTRACT_CHAIN_ID); 25 | const flairClientId = process.env.FLAIR_CLIENT_ID; 26 | const signer = new Wallet(process.env.MINTER_PRIVATE_KEY); 27 | const nftCollectionAddress = process.env.NFT_COLLECTION_ADDRESS; 28 | 29 | /** 30 | * 3) Create client instance for the ethers.js-compatible contract augmented with meta transactions. 31 | * 32 | * In this example we use one of ready-made presets (ERC721OneOfOneCollection). 33 | * To use a custom built contract you can manually create the meta transactions client instance (new ). 34 | */ 35 | const nftContract = createFlairContractWithMetaTransactions({ 36 | chainId: chainId, 37 | flairClientId: flairClientId, 38 | contractFqn: "collections/ERC721/extensions/ERC721OneOfOneMintExtension", 39 | addressOrName: nftCollectionAddress, 40 | signer: signer, 41 | forwarder: "0xb1780c61a8b0714bF08E8c403f6cd5c1374F6AA9", 42 | }); 43 | 44 | const ipfsClient = new IpfsClient({ 45 | flairClientId: flairClientId, 46 | }); 47 | 48 | /** 49 | * 4) Example endpoints: 50 | * 51 | * - "GET /mint" endpoint simply uploads a new metadata to IPFS and mints a new 1-of-1 NFT based on that metadata. 52 | */ 53 | const app = express(); 54 | 55 | app.get( 56 | "/mint", 57 | asyncHandler(async (req, res) => { 58 | // 59 | // A) "to" is the wallet address that receives the new NFT 60 | // 61 | const to = "0x8016f96b5cCC4663324E8D117c337BB7aA68d909"; 62 | 63 | // 64 | // B) "count" is the number of NFTs to send to this wallet 65 | // 66 | const count = 1; 67 | 68 | // 69 | // C) Uploading a new metadata to IPFS 70 | // 71 | const someRandomId = Math.floor(Math.random() * 10000000000); 72 | /** @type {import("flair-sdk").NftCollectionMetadata} */ 73 | const nftMetadata = { 74 | name: `Angel #${someRandomId}`, 75 | image: `https://my-awesome-site.com/nft/${someRandomId}.png`, 76 | description: "This is the first NFT in the collection", 77 | external_url: `https://my-awesome-site.com/nft/${someRandomId}`, 78 | }; 79 | const tokenOneIpfsHash = await ipfsClient.uploadJson(nftMetadata); 80 | 81 | // 82 | // D) "tokenURIs" an array with exact size of "count" of metadata URLs for the newly minted NFTs 83 | // 84 | const tokenURIs = [`ipfs://${tokenOneIpfsHash}`]; 85 | 86 | console.log(``); 87 | console.log(`Minting ${count} NFTs to ${to}:`); 88 | console.log(` - TokenURI: ${tokenURIs[0]}`); 89 | 90 | // 91 | // E) Sign a meta transaction and submit it to the Flair backend relayer for processing 92 | // 93 | const data = await nftContract.metaTransaction.mintWithTokenURIsByRole( 94 | to, 95 | count, 96 | tokenURIs 97 | ); 98 | 99 | console.log(` - Signature: ${data.signature}`); 100 | console.log(` - Transaction is being processed and mined check your contract on EtherScan to see the status...`); 101 | console.log(``); 102 | 103 | // The response is a successfully submitted (but not yet mined) meta transaction. 104 | // Note that depending on traffic on the blockchain it might take a few minutes to be mined and processed. 105 | res.send({ 106 | tokenURIs: tokenURIs, 107 | nftMetadata: nftMetadata, 108 | response: data 109 | }); 110 | }) 111 | ); 112 | 113 | const port = 8080; 114 | 115 | app.listen(port, () => { 116 | console.log(`Flair SDK Example - Mint 1-of-1 NFTs via Meta Transactions!`); 117 | console.log(`- Listening on port ${port}`); 118 | console.log(``); 119 | console.log(`Now you can mint NFTs by opening: http://localhost:${port}/mint`); 120 | }); 121 | -------------------------------------------------------------------------------- /typescript/express/mint-one-of-one-nfts-meta-transactions/src/index.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import express, { Express, Request, Response } from 'express'; 3 | import asyncHandler from 'express-async-handler'; 4 | 5 | dotenv.config(); 6 | 7 | /** 8 | * 1) Import required libraries: 9 | * 10 | * - "ethers" helps us create a Wallet object based on a private key, which helps us sign transactions. 11 | * - "flair-sdk" provides a contract object with ability to submit meta transactions. 12 | */ 13 | import { Wallet } from "ethers"; 14 | import { V1_22_ERC721OneOfOneCollection } from "@0xflair/contracts-registry"; 15 | import { IpfsClient } from "@0xflair/ipfs"; 16 | import { createFlairContractWithMetaTransactions } from "@0xflair/meta-transactions"; 17 | 18 | /** 19 | * 2) Load configurations from environment variables (or any config management you use): 20 | * 21 | * - "chainId" is the numeric ID of the chain where your NFT contract is deployed (1 for Ethereum, 4 for Rinkeby Testnet, 137 for Polygon). 22 | * - "flairClientId" unique client ID of your Flair account, used for billing purposes. 23 | * - "signer" is created based on private key of the minter wallet, used to sign NFT minting meta transactions. 24 | * - "nftCollectionAddress" contract address for your deployed NFT collection on the blockchain. 25 | */ 26 | const chainId = Number(process.env.CONTRACT_CHAIN_ID); 27 | const flairClientId = process.env.FLAIR_CLIENT_ID as string; 28 | const signer = new Wallet(process.env.MINTER_PRIVATE_KEY as string); 29 | const nftCollectionAddress = process.env.NFT_COLLECTION_ADDRESS; 30 | 31 | /** 32 | * 3) Create client instance for the ethers.js-compatible contract augmented with meta transactions. 33 | * 34 | * In this example we use one of ready-made presets (ERC721OneOfOneCollection). 35 | * To use a custom built contract you can manually create the meta transactions client instance (new ). 36 | */ 37 | const nftContract = createFlairContractWithMetaTransactions({ 38 | chainId: chainId, 39 | flairClientId: flairClientId, 40 | contractFqn: "collections/ERC721/extensions/ERC721OneOfOneMintExtension", 41 | addressOrName: nftCollectionAddress, 42 | signer: signer, 43 | }); 44 | 45 | const ipfsClient = new IpfsClient({ 46 | flairClientId: flairClientId, 47 | }); 48 | 49 | /** 50 | * 4) Example endpoints: 51 | * 52 | * - "GET /mint" endpoint simply uploads a new metadata to IPFS and mints a new 1-of-1 NFT based on that metadata. 53 | */ 54 | const app: Express = express(); 55 | 56 | app.get( 57 | "/mint", 58 | asyncHandler(async (req: Request, res: Response) => { 59 | // 60 | // A) "to" is the wallet address that receives the new NFT 61 | // 62 | const to = "0x8016f96b5cCC4663324E8D117c337BB7aA68d909"; 63 | 64 | // 65 | // B) "count" is the number of NFTs to send to this wallet 66 | // 67 | const count = 1; 68 | 69 | // 70 | // C) Uploading a new metadata to IPFS 71 | // 72 | const someRandomId = Math.floor(Math.random() * 10000000000); 73 | /** @type {import("flair-sdk").NftCollectionMetadata} */ 74 | const nftMetadata = { 75 | name: `Angel #${someRandomId}`, 76 | image: `https://my-awesome-site.com/nft/${someRandomId}.png`, 77 | description: "This is the first NFT in the collection", 78 | external_link: `https://my-awesome-site.com/nft/${someRandomId}`, 79 | }; 80 | const tokenOneIpfsHash = await ipfsClient.uploadJson(nftMetadata); 81 | 82 | // 83 | // D) "tokenURIs" an array with exact size of "count" of metadata URLs for the newly minted NFTs 84 | // 85 | const tokenURIs = [`ipfs://${tokenOneIpfsHash}`]; 86 | 87 | console.log(``); 88 | console.log(`Minting ${count} NFTs to ${to}:`); 89 | console.log(` - TokenURI: ${tokenURIs[0]}`); 90 | 91 | // 92 | // E) Sign a meta transaction and submit it to the Flair backend relayer for processing 93 | // 94 | const data = await nftContract.metaTransaction.mintWithTokenURIsByRole( 95 | to, 96 | count, 97 | tokenURIs 98 | ); 99 | 100 | console.log(` - Signature: ${data.signature}`); 101 | console.log(` - Transaction is being processed and mined check your contract on EtherScan to see the status...`); 102 | console.log(``); 103 | 104 | // The response is a successfully submitted (but not yet mined) meta transaction. 105 | // Note that depending on traffic on the blockchain it might take a few minutes to be mined and processed. 106 | res.send({ 107 | tokenURIs: tokenURIs, 108 | nftMetadata: nftMetadata, 109 | response: data 110 | }); 111 | }) 112 | ); 113 | 114 | const port = 8080; 115 | 116 | app.listen(port, () => { 117 | console.log(`Flair SDK Example - Mint 1-of-1 NFTs via Meta Transactions!`); 118 | console.log(`- Listening on port ${port}`); 119 | console.log(``); 120 | console.log(`Now you can mint NFTs by opening: http://localhost:${port}/mint`); 121 | }); 122 | -------------------------------------------------------------------------------- /react/community-airdrop-reward-stream/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ConnectButton, 3 | StreamClaimableAmount, 4 | StreamClaimButton, 5 | StreamClaimingProvider, 6 | StreamRateByTokens, 7 | StreamEmissionTimeUnit, 8 | StreamTotalClaimed, 9 | SwitchChainButton, 10 | WalletDropdown, 11 | StreamClaimingStatusBar, 12 | IfWalletConnected, 13 | StreamProvider, 14 | IfWalletNotConnected, 15 | } from "flair-sdk"; 16 | 17 | const STREAM_CHAIN_ID = "137"; 18 | const STREAM_CONTRACT_ADDRESS = "0xbb1cb56e057022fba8d55c8dde1d17adbd3be649"; 19 | 20 | function App() { 21 | const chainId = Number(STREAM_CHAIN_ID); 22 | const contractAddress = STREAM_CONTRACT_ADDRESS; 23 | 24 | const buttonClass = 25 | "mt-4 w-full bg-indigo-600 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"; 26 | 27 | return ( 28 | 32 | {({ data: { stream } }) => ( 33 | <> 34 | 35 |
36 |

37 | {stream?.publicTitle || stream?.contractAddress?.substring(0, 8)} 38 |

39 | 40 |
41 | 42 | 43 | 44 |
45 | 46 | 47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | Your total claimed 56 | 57 | Sum of all previous claims 58 | 59 |
60 |
61 | 62 |
63 |
64 |
65 |
66 | Reward rate 67 | 68 | How many tokens you receive{' '} 69 | 70 | 71 |
72 |
73 | 74 |
75 |
76 |
77 |
78 | Claim window 79 | 80 | How often can you claim 81 | 82 |
83 |
84 | 85 |
86 |
87 |
88 |
89 | Claimable now for you 90 |
91 |
92 | 93 |
94 |
95 |
96 | 97 |
98 | 102 | 106 | 107 | 108 | 109 |
110 | 111 | 112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | 120 | )} 121 |
122 | ); 123 | } 124 | 125 | export default App; 126 | -------------------------------------------------------------------------------- /react/custom-nft-minting-sales/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | CollectionImage, 3 | CollectionProvider, 4 | CollectionSalesActiveStatus, 5 | CollectionSalesAllowlistStatus, 6 | CollectionSalesMintingProvider, 7 | CollectionSalesMintStatusBar, 8 | CollectionSalesPrice, 9 | CollectionSupplyCounter, 10 | CollectionSalesMintInput, 11 | CollectionSalesMintButton, 12 | CollectionTitle, 13 | ConnectButton, 14 | SwitchChainButton, 15 | WalletDropdown, 16 | IfWalletConnected, 17 | } from "flair-sdk"; 18 | 19 | import { useState } from "react"; 20 | import { useAccount } from "wagmi"; 21 | import { BigNumberish } from "ethers"; 22 | 23 | const chainId = Number(process.env.REACT_APP_COLLECTION_CHAIN_ID); 24 | const contractAddress = process.env.REACT_APP_COLLECTION_CONTRACT_ADDRESS as string; 25 | 26 | function App() { 27 | const { data: account } = useAccount(); 28 | 29 | const [mintCount, setMintCount] = useState("1"); 30 | 31 | const mintButtonClass = 32 | "w-full bg-indigo-600 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"; 33 | 34 | return ( 35 |
36 | 40 | {({ data: { collection, collectionMetadata } }) => ( 41 | <> 42 |
43 |
44 |
45 | {/* Sales Info */} 46 |
47 | 48 | 49 | 50 | 51 |
52 |
53 | 54 | {/* Image */} 55 |
56 |
57 | 58 |
59 |
60 | 61 |
62 | 63 |
64 |
65 | {/* Sale Information */} 66 |
67 |
68 | 69 | 70 | 71 | 72 | {account && } 73 |
74 | 75 | 76 |
77 |
78 | 79 |
80 |
81 | {/* Mint count */} 82 |
83 |
84 |

85 | How many to mint? 86 |

87 |
88 | 89 |
90 | 91 | Choose number of mints 92 | 93 |
94 | 99 |
100 |
101 |
102 | 103 | {/* Mint button */} 104 | 105 |
106 | 110 | 114 | 115 |
116 |
117 |
118 | 119 | 120 |
121 |
122 |
123 | 124 | {/* Description */} 125 | {collectionMetadata?.description || 126 | collection?.config?.collectionDescription ? ( 127 |
128 |

129 | Description 130 |

131 | 132 |
133 | {collectionMetadata?.description || 134 | collection?.config?.collectionDescription} 135 |
136 |
137 | ) : null} 138 |
139 |
140 |
141 | 142 | )} 143 |
144 | 145 | {/* OR, import the whole prebuilt minting component: 146 | 147 | 148 | 149 | 150 | 151 | */} 152 |
153 | ); 154 | } 155 | 156 | export default App; 157 | -------------------------------------------------------------------------------- /typescript/express/mint-one-of-one-nfts-meta-transactions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs" /* Specify what module code is generated. */, 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "resolveJsonModule": true, /* Enable importing .json files. */ 39 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 40 | 41 | /* JavaScript Support */ 42 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 45 | 46 | /* Emit */ 47 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 48 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 49 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 50 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 51 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 52 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 53 | // "removeComments": true, /* Disable emitting comments. */ 54 | // "noEmit": true, /* Disable emitting files from a compilation. */ 55 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 56 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 57 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 58 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 61 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 62 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 63 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 64 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 65 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 66 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 67 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 68 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 69 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 70 | 71 | /* Interop Constraints */ 72 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 73 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 74 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 75 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 76 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 77 | 78 | /* Type Checking */ 79 | "strict": true /* Enable all strict type-checking options. */, 80 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 81 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 82 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 83 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 84 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 85 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 86 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 87 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 88 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 89 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 90 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 91 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 92 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 93 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 94 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 95 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 96 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 97 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 98 | 99 | /* Completeness */ 100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 101 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /nodejs/express/simple-meta-transactions-webhook/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-meta-transactions-webhook", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "simple-meta-transactions-webhook", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "dotenv": "^16.0.1", 13 | "express": "^4.18.1", 14 | "express-async-handler": "^1.2.0" 15 | } 16 | }, 17 | "node_modules/accepts": { 18 | "version": "1.3.8", 19 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 20 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 21 | "dependencies": { 22 | "mime-types": "~2.1.34", 23 | "negotiator": "0.6.3" 24 | }, 25 | "engines": { 26 | "node": ">= 0.6" 27 | } 28 | }, 29 | "node_modules/array-flatten": { 30 | "version": "1.1.1", 31 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 32 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 33 | }, 34 | "node_modules/body-parser": { 35 | "version": "1.20.0", 36 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", 37 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", 38 | "dependencies": { 39 | "bytes": "3.1.2", 40 | "content-type": "~1.0.4", 41 | "debug": "2.6.9", 42 | "depd": "2.0.0", 43 | "destroy": "1.2.0", 44 | "http-errors": "2.0.0", 45 | "iconv-lite": "0.4.24", 46 | "on-finished": "2.4.1", 47 | "qs": "6.10.3", 48 | "raw-body": "2.5.1", 49 | "type-is": "~1.6.18", 50 | "unpipe": "1.0.0" 51 | }, 52 | "engines": { 53 | "node": ">= 0.8", 54 | "npm": "1.2.8000 || >= 1.4.16" 55 | } 56 | }, 57 | "node_modules/bytes": { 58 | "version": "3.1.2", 59 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 60 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 61 | "engines": { 62 | "node": ">= 0.8" 63 | } 64 | }, 65 | "node_modules/call-bind": { 66 | "version": "1.0.2", 67 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 68 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 69 | "dependencies": { 70 | "function-bind": "^1.1.1", 71 | "get-intrinsic": "^1.0.2" 72 | }, 73 | "funding": { 74 | "url": "https://github.com/sponsors/ljharb" 75 | } 76 | }, 77 | "node_modules/content-disposition": { 78 | "version": "0.5.4", 79 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 80 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 81 | "dependencies": { 82 | "safe-buffer": "5.2.1" 83 | }, 84 | "engines": { 85 | "node": ">= 0.6" 86 | } 87 | }, 88 | "node_modules/content-type": { 89 | "version": "1.0.4", 90 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 91 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 92 | "engines": { 93 | "node": ">= 0.6" 94 | } 95 | }, 96 | "node_modules/cookie": { 97 | "version": "0.5.0", 98 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 99 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 100 | "engines": { 101 | "node": ">= 0.6" 102 | } 103 | }, 104 | "node_modules/cookie-signature": { 105 | "version": "1.0.6", 106 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 107 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 108 | }, 109 | "node_modules/debug": { 110 | "version": "2.6.9", 111 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 112 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 113 | "dependencies": { 114 | "ms": "2.0.0" 115 | } 116 | }, 117 | "node_modules/depd": { 118 | "version": "2.0.0", 119 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 120 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 121 | "engines": { 122 | "node": ">= 0.8" 123 | } 124 | }, 125 | "node_modules/destroy": { 126 | "version": "1.2.0", 127 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 128 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 129 | "engines": { 130 | "node": ">= 0.8", 131 | "npm": "1.2.8000 || >= 1.4.16" 132 | } 133 | }, 134 | "node_modules/dotenv": { 135 | "version": "16.0.3", 136 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", 137 | "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", 138 | "engines": { 139 | "node": ">=12" 140 | } 141 | }, 142 | "node_modules/ee-first": { 143 | "version": "1.1.1", 144 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 145 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 146 | }, 147 | "node_modules/encodeurl": { 148 | "version": "1.0.2", 149 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 150 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 151 | "engines": { 152 | "node": ">= 0.8" 153 | } 154 | }, 155 | "node_modules/escape-html": { 156 | "version": "1.0.3", 157 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 158 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 159 | }, 160 | "node_modules/etag": { 161 | "version": "1.8.1", 162 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 163 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 164 | "engines": { 165 | "node": ">= 0.6" 166 | } 167 | }, 168 | "node_modules/express": { 169 | "version": "4.18.1", 170 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", 171 | "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", 172 | "dependencies": { 173 | "accepts": "~1.3.8", 174 | "array-flatten": "1.1.1", 175 | "body-parser": "1.20.0", 176 | "content-disposition": "0.5.4", 177 | "content-type": "~1.0.4", 178 | "cookie": "0.5.0", 179 | "cookie-signature": "1.0.6", 180 | "debug": "2.6.9", 181 | "depd": "2.0.0", 182 | "encodeurl": "~1.0.2", 183 | "escape-html": "~1.0.3", 184 | "etag": "~1.8.1", 185 | "finalhandler": "1.2.0", 186 | "fresh": "0.5.2", 187 | "http-errors": "2.0.0", 188 | "merge-descriptors": "1.0.1", 189 | "methods": "~1.1.2", 190 | "on-finished": "2.4.1", 191 | "parseurl": "~1.3.3", 192 | "path-to-regexp": "0.1.7", 193 | "proxy-addr": "~2.0.7", 194 | "qs": "6.10.3", 195 | "range-parser": "~1.2.1", 196 | "safe-buffer": "5.2.1", 197 | "send": "0.18.0", 198 | "serve-static": "1.15.0", 199 | "setprototypeof": "1.2.0", 200 | "statuses": "2.0.1", 201 | "type-is": "~1.6.18", 202 | "utils-merge": "1.0.1", 203 | "vary": "~1.1.2" 204 | }, 205 | "engines": { 206 | "node": ">= 0.10.0" 207 | } 208 | }, 209 | "node_modules/express-async-handler": { 210 | "version": "1.2.0", 211 | "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", 212 | "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" 213 | }, 214 | "node_modules/finalhandler": { 215 | "version": "1.2.0", 216 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 217 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 218 | "dependencies": { 219 | "debug": "2.6.9", 220 | "encodeurl": "~1.0.2", 221 | "escape-html": "~1.0.3", 222 | "on-finished": "2.4.1", 223 | "parseurl": "~1.3.3", 224 | "statuses": "2.0.1", 225 | "unpipe": "~1.0.0" 226 | }, 227 | "engines": { 228 | "node": ">= 0.8" 229 | } 230 | }, 231 | "node_modules/forwarded": { 232 | "version": "0.2.0", 233 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 234 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 235 | "engines": { 236 | "node": ">= 0.6" 237 | } 238 | }, 239 | "node_modules/fresh": { 240 | "version": "0.5.2", 241 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 242 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 243 | "engines": { 244 | "node": ">= 0.6" 245 | } 246 | }, 247 | "node_modules/function-bind": { 248 | "version": "1.1.1", 249 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 250 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 251 | }, 252 | "node_modules/get-intrinsic": { 253 | "version": "1.1.3", 254 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", 255 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", 256 | "dependencies": { 257 | "function-bind": "^1.1.1", 258 | "has": "^1.0.3", 259 | "has-symbols": "^1.0.3" 260 | }, 261 | "funding": { 262 | "url": "https://github.com/sponsors/ljharb" 263 | } 264 | }, 265 | "node_modules/has": { 266 | "version": "1.0.3", 267 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 268 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 269 | "dependencies": { 270 | "function-bind": "^1.1.1" 271 | }, 272 | "engines": { 273 | "node": ">= 0.4.0" 274 | } 275 | }, 276 | "node_modules/has-symbols": { 277 | "version": "1.0.3", 278 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 279 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 280 | "engines": { 281 | "node": ">= 0.4" 282 | }, 283 | "funding": { 284 | "url": "https://github.com/sponsors/ljharb" 285 | } 286 | }, 287 | "node_modules/http-errors": { 288 | "version": "2.0.0", 289 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 290 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 291 | "dependencies": { 292 | "depd": "2.0.0", 293 | "inherits": "2.0.4", 294 | "setprototypeof": "1.2.0", 295 | "statuses": "2.0.1", 296 | "toidentifier": "1.0.1" 297 | }, 298 | "engines": { 299 | "node": ">= 0.8" 300 | } 301 | }, 302 | "node_modules/iconv-lite": { 303 | "version": "0.4.24", 304 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 305 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 306 | "dependencies": { 307 | "safer-buffer": ">= 2.1.2 < 3" 308 | }, 309 | "engines": { 310 | "node": ">=0.10.0" 311 | } 312 | }, 313 | "node_modules/inherits": { 314 | "version": "2.0.4", 315 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 316 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 317 | }, 318 | "node_modules/ipaddr.js": { 319 | "version": "1.9.1", 320 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 321 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 322 | "engines": { 323 | "node": ">= 0.10" 324 | } 325 | }, 326 | "node_modules/media-typer": { 327 | "version": "0.3.0", 328 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 329 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 330 | "engines": { 331 | "node": ">= 0.6" 332 | } 333 | }, 334 | "node_modules/merge-descriptors": { 335 | "version": "1.0.1", 336 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 337 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 338 | }, 339 | "node_modules/methods": { 340 | "version": "1.1.2", 341 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 342 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 343 | "engines": { 344 | "node": ">= 0.6" 345 | } 346 | }, 347 | "node_modules/mime": { 348 | "version": "1.6.0", 349 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 350 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 351 | "bin": { 352 | "mime": "cli.js" 353 | }, 354 | "engines": { 355 | "node": ">=4" 356 | } 357 | }, 358 | "node_modules/mime-db": { 359 | "version": "1.52.0", 360 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 361 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 362 | "engines": { 363 | "node": ">= 0.6" 364 | } 365 | }, 366 | "node_modules/mime-types": { 367 | "version": "2.1.35", 368 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 369 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 370 | "dependencies": { 371 | "mime-db": "1.52.0" 372 | }, 373 | "engines": { 374 | "node": ">= 0.6" 375 | } 376 | }, 377 | "node_modules/ms": { 378 | "version": "2.0.0", 379 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 380 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 381 | }, 382 | "node_modules/negotiator": { 383 | "version": "0.6.3", 384 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 385 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 386 | "engines": { 387 | "node": ">= 0.6" 388 | } 389 | }, 390 | "node_modules/object-inspect": { 391 | "version": "1.12.2", 392 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 393 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", 394 | "funding": { 395 | "url": "https://github.com/sponsors/ljharb" 396 | } 397 | }, 398 | "node_modules/on-finished": { 399 | "version": "2.4.1", 400 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 401 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 402 | "dependencies": { 403 | "ee-first": "1.1.1" 404 | }, 405 | "engines": { 406 | "node": ">= 0.8" 407 | } 408 | }, 409 | "node_modules/parseurl": { 410 | "version": "1.3.3", 411 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 412 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 413 | "engines": { 414 | "node": ">= 0.8" 415 | } 416 | }, 417 | "node_modules/path-to-regexp": { 418 | "version": "0.1.7", 419 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 420 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 421 | }, 422 | "node_modules/proxy-addr": { 423 | "version": "2.0.7", 424 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 425 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 426 | "dependencies": { 427 | "forwarded": "0.2.0", 428 | "ipaddr.js": "1.9.1" 429 | }, 430 | "engines": { 431 | "node": ">= 0.10" 432 | } 433 | }, 434 | "node_modules/qs": { 435 | "version": "6.10.3", 436 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", 437 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", 438 | "dependencies": { 439 | "side-channel": "^1.0.4" 440 | }, 441 | "engines": { 442 | "node": ">=0.6" 443 | }, 444 | "funding": { 445 | "url": "https://github.com/sponsors/ljharb" 446 | } 447 | }, 448 | "node_modules/range-parser": { 449 | "version": "1.2.1", 450 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 451 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 452 | "engines": { 453 | "node": ">= 0.6" 454 | } 455 | }, 456 | "node_modules/raw-body": { 457 | "version": "2.5.1", 458 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 459 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 460 | "dependencies": { 461 | "bytes": "3.1.2", 462 | "http-errors": "2.0.0", 463 | "iconv-lite": "0.4.24", 464 | "unpipe": "1.0.0" 465 | }, 466 | "engines": { 467 | "node": ">= 0.8" 468 | } 469 | }, 470 | "node_modules/safe-buffer": { 471 | "version": "5.2.1", 472 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 473 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 474 | "funding": [ 475 | { 476 | "type": "github", 477 | "url": "https://github.com/sponsors/feross" 478 | }, 479 | { 480 | "type": "patreon", 481 | "url": "https://www.patreon.com/feross" 482 | }, 483 | { 484 | "type": "consulting", 485 | "url": "https://feross.org/support" 486 | } 487 | ] 488 | }, 489 | "node_modules/safer-buffer": { 490 | "version": "2.1.2", 491 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 492 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 493 | }, 494 | "node_modules/send": { 495 | "version": "0.18.0", 496 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 497 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 498 | "dependencies": { 499 | "debug": "2.6.9", 500 | "depd": "2.0.0", 501 | "destroy": "1.2.0", 502 | "encodeurl": "~1.0.2", 503 | "escape-html": "~1.0.3", 504 | "etag": "~1.8.1", 505 | "fresh": "0.5.2", 506 | "http-errors": "2.0.0", 507 | "mime": "1.6.0", 508 | "ms": "2.1.3", 509 | "on-finished": "2.4.1", 510 | "range-parser": "~1.2.1", 511 | "statuses": "2.0.1" 512 | }, 513 | "engines": { 514 | "node": ">= 0.8.0" 515 | } 516 | }, 517 | "node_modules/send/node_modules/ms": { 518 | "version": "2.1.3", 519 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 520 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 521 | }, 522 | "node_modules/serve-static": { 523 | "version": "1.15.0", 524 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 525 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 526 | "dependencies": { 527 | "encodeurl": "~1.0.2", 528 | "escape-html": "~1.0.3", 529 | "parseurl": "~1.3.3", 530 | "send": "0.18.0" 531 | }, 532 | "engines": { 533 | "node": ">= 0.8.0" 534 | } 535 | }, 536 | "node_modules/setprototypeof": { 537 | "version": "1.2.0", 538 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 539 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 540 | }, 541 | "node_modules/side-channel": { 542 | "version": "1.0.4", 543 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 544 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 545 | "dependencies": { 546 | "call-bind": "^1.0.0", 547 | "get-intrinsic": "^1.0.2", 548 | "object-inspect": "^1.9.0" 549 | }, 550 | "funding": { 551 | "url": "https://github.com/sponsors/ljharb" 552 | } 553 | }, 554 | "node_modules/statuses": { 555 | "version": "2.0.1", 556 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 557 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 558 | "engines": { 559 | "node": ">= 0.8" 560 | } 561 | }, 562 | "node_modules/toidentifier": { 563 | "version": "1.0.1", 564 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 565 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 566 | "engines": { 567 | "node": ">=0.6" 568 | } 569 | }, 570 | "node_modules/type-is": { 571 | "version": "1.6.18", 572 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 573 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 574 | "dependencies": { 575 | "media-typer": "0.3.0", 576 | "mime-types": "~2.1.24" 577 | }, 578 | "engines": { 579 | "node": ">= 0.6" 580 | } 581 | }, 582 | "node_modules/unpipe": { 583 | "version": "1.0.0", 584 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 585 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 586 | "engines": { 587 | "node": ">= 0.8" 588 | } 589 | }, 590 | "node_modules/utils-merge": { 591 | "version": "1.0.1", 592 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 593 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 594 | "engines": { 595 | "node": ">= 0.4.0" 596 | } 597 | }, 598 | "node_modules/vary": { 599 | "version": "1.1.2", 600 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 601 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 602 | "engines": { 603 | "node": ">= 0.8" 604 | } 605 | } 606 | }, 607 | "dependencies": { 608 | "accepts": { 609 | "version": "1.3.8", 610 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 611 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 612 | "requires": { 613 | "mime-types": "~2.1.34", 614 | "negotiator": "0.6.3" 615 | } 616 | }, 617 | "array-flatten": { 618 | "version": "1.1.1", 619 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 620 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 621 | }, 622 | "body-parser": { 623 | "version": "1.20.0", 624 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", 625 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", 626 | "requires": { 627 | "bytes": "3.1.2", 628 | "content-type": "~1.0.4", 629 | "debug": "2.6.9", 630 | "depd": "2.0.0", 631 | "destroy": "1.2.0", 632 | "http-errors": "2.0.0", 633 | "iconv-lite": "0.4.24", 634 | "on-finished": "2.4.1", 635 | "qs": "6.10.3", 636 | "raw-body": "2.5.1", 637 | "type-is": "~1.6.18", 638 | "unpipe": "1.0.0" 639 | } 640 | }, 641 | "bytes": { 642 | "version": "3.1.2", 643 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 644 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 645 | }, 646 | "call-bind": { 647 | "version": "1.0.2", 648 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 649 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 650 | "requires": { 651 | "function-bind": "^1.1.1", 652 | "get-intrinsic": "^1.0.2" 653 | } 654 | }, 655 | "content-disposition": { 656 | "version": "0.5.4", 657 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 658 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 659 | "requires": { 660 | "safe-buffer": "5.2.1" 661 | } 662 | }, 663 | "content-type": { 664 | "version": "1.0.4", 665 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 666 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 667 | }, 668 | "cookie": { 669 | "version": "0.5.0", 670 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 671 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 672 | }, 673 | "cookie-signature": { 674 | "version": "1.0.6", 675 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 676 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 677 | }, 678 | "debug": { 679 | "version": "2.6.9", 680 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 681 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 682 | "requires": { 683 | "ms": "2.0.0" 684 | } 685 | }, 686 | "depd": { 687 | "version": "2.0.0", 688 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 689 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 690 | }, 691 | "destroy": { 692 | "version": "1.2.0", 693 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 694 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 695 | }, 696 | "dotenv": { 697 | "version": "16.0.3", 698 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", 699 | "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" 700 | }, 701 | "ee-first": { 702 | "version": "1.1.1", 703 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 704 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 705 | }, 706 | "encodeurl": { 707 | "version": "1.0.2", 708 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 709 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 710 | }, 711 | "escape-html": { 712 | "version": "1.0.3", 713 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 714 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 715 | }, 716 | "etag": { 717 | "version": "1.8.1", 718 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 719 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 720 | }, 721 | "express": { 722 | "version": "4.18.1", 723 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", 724 | "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", 725 | "requires": { 726 | "accepts": "~1.3.8", 727 | "array-flatten": "1.1.1", 728 | "body-parser": "1.20.0", 729 | "content-disposition": "0.5.4", 730 | "content-type": "~1.0.4", 731 | "cookie": "0.5.0", 732 | "cookie-signature": "1.0.6", 733 | "debug": "2.6.9", 734 | "depd": "2.0.0", 735 | "encodeurl": "~1.0.2", 736 | "escape-html": "~1.0.3", 737 | "etag": "~1.8.1", 738 | "finalhandler": "1.2.0", 739 | "fresh": "0.5.2", 740 | "http-errors": "2.0.0", 741 | "merge-descriptors": "1.0.1", 742 | "methods": "~1.1.2", 743 | "on-finished": "2.4.1", 744 | "parseurl": "~1.3.3", 745 | "path-to-regexp": "0.1.7", 746 | "proxy-addr": "~2.0.7", 747 | "qs": "6.10.3", 748 | "range-parser": "~1.2.1", 749 | "safe-buffer": "5.2.1", 750 | "send": "0.18.0", 751 | "serve-static": "1.15.0", 752 | "setprototypeof": "1.2.0", 753 | "statuses": "2.0.1", 754 | "type-is": "~1.6.18", 755 | "utils-merge": "1.0.1", 756 | "vary": "~1.1.2" 757 | } 758 | }, 759 | "express-async-handler": { 760 | "version": "1.2.0", 761 | "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", 762 | "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" 763 | }, 764 | "finalhandler": { 765 | "version": "1.2.0", 766 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 767 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 768 | "requires": { 769 | "debug": "2.6.9", 770 | "encodeurl": "~1.0.2", 771 | "escape-html": "~1.0.3", 772 | "on-finished": "2.4.1", 773 | "parseurl": "~1.3.3", 774 | "statuses": "2.0.1", 775 | "unpipe": "~1.0.0" 776 | } 777 | }, 778 | "forwarded": { 779 | "version": "0.2.0", 780 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 781 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 782 | }, 783 | "fresh": { 784 | "version": "0.5.2", 785 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 786 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 787 | }, 788 | "function-bind": { 789 | "version": "1.1.1", 790 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 791 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 792 | }, 793 | "get-intrinsic": { 794 | "version": "1.1.3", 795 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", 796 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", 797 | "requires": { 798 | "function-bind": "^1.1.1", 799 | "has": "^1.0.3", 800 | "has-symbols": "^1.0.3" 801 | } 802 | }, 803 | "has": { 804 | "version": "1.0.3", 805 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 806 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 807 | "requires": { 808 | "function-bind": "^1.1.1" 809 | } 810 | }, 811 | "has-symbols": { 812 | "version": "1.0.3", 813 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 814 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 815 | }, 816 | "http-errors": { 817 | "version": "2.0.0", 818 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 819 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 820 | "requires": { 821 | "depd": "2.0.0", 822 | "inherits": "2.0.4", 823 | "setprototypeof": "1.2.0", 824 | "statuses": "2.0.1", 825 | "toidentifier": "1.0.1" 826 | } 827 | }, 828 | "iconv-lite": { 829 | "version": "0.4.24", 830 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 831 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 832 | "requires": { 833 | "safer-buffer": ">= 2.1.2 < 3" 834 | } 835 | }, 836 | "inherits": { 837 | "version": "2.0.4", 838 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 839 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 840 | }, 841 | "ipaddr.js": { 842 | "version": "1.9.1", 843 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 844 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 845 | }, 846 | "media-typer": { 847 | "version": "0.3.0", 848 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 849 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 850 | }, 851 | "merge-descriptors": { 852 | "version": "1.0.1", 853 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 854 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 855 | }, 856 | "methods": { 857 | "version": "1.1.2", 858 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 859 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 860 | }, 861 | "mime": { 862 | "version": "1.6.0", 863 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 864 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 865 | }, 866 | "mime-db": { 867 | "version": "1.52.0", 868 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 869 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 870 | }, 871 | "mime-types": { 872 | "version": "2.1.35", 873 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 874 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 875 | "requires": { 876 | "mime-db": "1.52.0" 877 | } 878 | }, 879 | "ms": { 880 | "version": "2.0.0", 881 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 882 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 883 | }, 884 | "negotiator": { 885 | "version": "0.6.3", 886 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 887 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 888 | }, 889 | "object-inspect": { 890 | "version": "1.12.2", 891 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 892 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" 893 | }, 894 | "on-finished": { 895 | "version": "2.4.1", 896 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 897 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 898 | "requires": { 899 | "ee-first": "1.1.1" 900 | } 901 | }, 902 | "parseurl": { 903 | "version": "1.3.3", 904 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 905 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 906 | }, 907 | "path-to-regexp": { 908 | "version": "0.1.7", 909 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 910 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 911 | }, 912 | "proxy-addr": { 913 | "version": "2.0.7", 914 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 915 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 916 | "requires": { 917 | "forwarded": "0.2.0", 918 | "ipaddr.js": "1.9.1" 919 | } 920 | }, 921 | "qs": { 922 | "version": "6.10.3", 923 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", 924 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", 925 | "requires": { 926 | "side-channel": "^1.0.4" 927 | } 928 | }, 929 | "range-parser": { 930 | "version": "1.2.1", 931 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 932 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 933 | }, 934 | "raw-body": { 935 | "version": "2.5.1", 936 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 937 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 938 | "requires": { 939 | "bytes": "3.1.2", 940 | "http-errors": "2.0.0", 941 | "iconv-lite": "0.4.24", 942 | "unpipe": "1.0.0" 943 | } 944 | }, 945 | "safe-buffer": { 946 | "version": "5.2.1", 947 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 948 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 949 | }, 950 | "safer-buffer": { 951 | "version": "2.1.2", 952 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 953 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 954 | }, 955 | "send": { 956 | "version": "0.18.0", 957 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 958 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 959 | "requires": { 960 | "debug": "2.6.9", 961 | "depd": "2.0.0", 962 | "destroy": "1.2.0", 963 | "encodeurl": "~1.0.2", 964 | "escape-html": "~1.0.3", 965 | "etag": "~1.8.1", 966 | "fresh": "0.5.2", 967 | "http-errors": "2.0.0", 968 | "mime": "1.6.0", 969 | "ms": "2.1.3", 970 | "on-finished": "2.4.1", 971 | "range-parser": "~1.2.1", 972 | "statuses": "2.0.1" 973 | }, 974 | "dependencies": { 975 | "ms": { 976 | "version": "2.1.3", 977 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 978 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 979 | } 980 | } 981 | }, 982 | "serve-static": { 983 | "version": "1.15.0", 984 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 985 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 986 | "requires": { 987 | "encodeurl": "~1.0.2", 988 | "escape-html": "~1.0.3", 989 | "parseurl": "~1.3.3", 990 | "send": "0.18.0" 991 | } 992 | }, 993 | "setprototypeof": { 994 | "version": "1.2.0", 995 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 996 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 997 | }, 998 | "side-channel": { 999 | "version": "1.0.4", 1000 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1001 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1002 | "requires": { 1003 | "call-bind": "^1.0.0", 1004 | "get-intrinsic": "^1.0.2", 1005 | "object-inspect": "^1.9.0" 1006 | } 1007 | }, 1008 | "statuses": { 1009 | "version": "2.0.1", 1010 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1011 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 1012 | }, 1013 | "toidentifier": { 1014 | "version": "1.0.1", 1015 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1016 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 1017 | }, 1018 | "type-is": { 1019 | "version": "1.6.18", 1020 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1021 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1022 | "requires": { 1023 | "media-typer": "0.3.0", 1024 | "mime-types": "~2.1.24" 1025 | } 1026 | }, 1027 | "unpipe": { 1028 | "version": "1.0.0", 1029 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1030 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 1031 | }, 1032 | "utils-merge": { 1033 | "version": "1.0.1", 1034 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1035 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 1036 | }, 1037 | "vary": { 1038 | "version": "1.1.2", 1039 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1040 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" 1041 | } 1042 | } 1043 | } 1044 | --------------------------------------------------------------------------------