├── packages
├── auth-kit
│ ├── example
│ │ ├── .env.sample
│ │ ├── src
│ │ │ ├── vite-env.d.ts
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ ├── AppBar.tsx
│ │ │ └── App.tsx
│ │ ├── tsconfig.node.json
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── tsconfig.json
│ │ ├── vite.config.ts
│ │ ├── package.json
│ │ └── public
│ │ │ └── vite.svg
│ ├── src
│ │ ├── index.ts
│ │ ├── types.ts
│ │ ├── adapters
│ │ │ └── Web3AuthAdapter.ts
│ │ └── SafeAuthKit.ts
│ ├── tsconfig.json
│ ├── README.md
│ └── package.json
├── onramp-kit
│ ├── example
│ │ ├── client
│ │ │ ├── src
│ │ │ │ ├── vite-env.d.ts
│ │ │ │ ├── index.css
│ │ │ │ ├── main.tsx
│ │ │ │ ├── AppBar.tsx
│ │ │ │ └── App.tsx
│ │ │ ├── .env.sample
│ │ │ ├── tsconfig.node.json
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── index.html
│ │ │ ├── tsconfig.json
│ │ │ ├── vite.config.ts
│ │ │ ├── package.json
│ │ │ └── public
│ │ │ │ └── vite.svg
│ │ └── server
│ │ │ ├── src
│ │ │ ├── router
│ │ │ │ ├── router.ts
│ │ │ │ └── stripe-router.ts
│ │ │ ├── lib
│ │ │ │ └── logger
│ │ │ │ │ └── logger.ts
│ │ │ ├── server.ts
│ │ │ ├── controllers
│ │ │ │ └── stripe-controller.ts
│ │ │ └── services
│ │ │ │ └── stripe-service.ts
│ │ │ ├── README.md
│ │ │ ├── example.env
│ │ │ ├── index.ts
│ │ │ ├── .gitignore
│ │ │ ├── package.json
│ │ │ ├── tsconfig.json
│ │ │ └── yarn.lock
│ ├── src
│ │ ├── types
│ │ │ ├── declarations.d.ts
│ │ │ ├── index.ts
│ │ │ ├── events.ts
│ │ │ ├── onRamp.ts
│ │ │ └── stripe.ts
│ │ ├── index.ts
│ │ ├── adapters
│ │ │ └── stripe
│ │ │ │ ├── stripeApi.ts
│ │ │ │ ├── utils.ts
│ │ │ │ └── StripeAdapter.ts
│ │ └── SafeOnRampKit.ts
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
├── relay-kit
│ ├── src
│ │ ├── index.ts
│ │ ├── constants.ts
│ │ ├── types.ts
│ │ └── GelatoRelayAdapter.ts
│ ├── tsconfig.json
│ ├── README.md
│ └── package.json
└── account-abstraction-kit
│ ├── src
│ ├── utils
│ │ ├── index.ts
│ │ ├── signatures.ts
│ │ ├── deployments.ts
│ │ └── contracts.ts
│ ├── index.ts
│ ├── constants
│ │ └── index.ts
│ ├── types
│ │ └── index.ts
│ └── AccountAbstraction.ts
│ ├── tsconfig.json
│ ├── scripts
│ └── typechain.ts
│ ├── README.md
│ └── package.json
├── .github
├── PULL_REQUEST_TEMPLATE.md
├── workflows
│ ├── lint.yml
│ ├── test.yml
│ └── cla.yml
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── .prettierrc.json
├── lerna.json
├── tsconfig.json
├── .eslintrc.js
├── playground
├── config
│ └── run.ts
└── relay-kit
│ ├── sponsored-transaction.ts
│ └── paid-transaction.ts
├── .gitignore
├── LICENSE.md
├── package.json
├── tsconfig.settings.json
└── README.md
/packages/auth-kit/example/.env.sample:
--------------------------------------------------------------------------------
1 | VITE_WEB3AUTH_CLIENT_ID=
2 | VITE_INFURA_KEY=
--------------------------------------------------------------------------------
/packages/auth-kit/example/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/relay-kit/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './GelatoRelayAdapter'
2 | export * from './types'
3 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## What it solves
2 |
3 | Resolves #
4 |
5 | ## How this PR fixes it
6 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/types/declarations.d.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line
2 | declare var StripeOnramp: any
3 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/src/index.css:
--------------------------------------------------------------------------------
1 | @import url('../node_modules/@safe-global/safe-react-components/dist/fonts.css');
2 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './events'
2 | export * from './onRamp'
3 | export * from './stripe'
4 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "semi": false,
4 | "singleQuote": true,
5 | "trailingComma": "none"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/.env.sample:
--------------------------------------------------------------------------------
1 | VITE_STRIPE_PUBLIC_KEY=
2 | VITE_SAFE_STRIPE_BACKEND_BASE_URL=
3 | VITE_SESSION_ADDRESS=
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/src/index.css:
--------------------------------------------------------------------------------
1 | @import url('../node_modules/@safe-global/safe-react-components/dist/fonts.css');
2 |
--------------------------------------------------------------------------------
/packages/auth-kit/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 |
3 | import SafeAuthKit from './SafeAuthKit'
4 |
5 | export { SafeAuthKit }
6 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './contracts'
2 | export * from './deployments'
3 | export * from './signatures'
4 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 |
3 | import { SafeOnRampKit } from './SafeOnRampKit'
4 |
5 | export { SafeOnRampKit }
6 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/src/index.ts:
--------------------------------------------------------------------------------
1 | import AccountAbstraction from './AccountAbstraction'
2 |
3 | export default AccountAbstraction
4 | export * from './types'
5 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/src/router/router.ts:
--------------------------------------------------------------------------------
1 | import stripeRouter from '../router/stripe-router'
2 |
3 | const routes = [stripeRouter]
4 |
5 | export default routes
6 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | "packages/*"
4 | ],
5 | "version": "independent",
6 | "useWorkspaces": true,
7 | "command": {
8 | "run": {
9 | "npmClient": "yarn"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/auth-kit/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "composite": true,
5 | "outDir": "dist",
6 | "baseUrl": "src"
7 | },
8 | "include": ["src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/onramp-kit/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "composite": true,
5 | "outDir": "dist",
6 | "baseUrl": "src"
7 | },
8 | "include": ["src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/relay-kit/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "composite": true,
5 | "outDir": "dist",
6 | "baseUrl": "src"
7 | },
8 | "include": ["src", "src/**/*.json"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "composite": true,
5 | "outDir": "dist",
6 | "baseUrl": "src"
7 | },
8 | "include": ["src", "typechain"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "packages/account-abstraction-kit" },
5 | { "path": "packages/relay-kit" },
6 | { "path": "packages/auth-kit" },
7 | { "path": "packages/onramp-kit" }
8 | ],
9 | "include": ["contracts/abis/**/*.json"]
10 | }
11 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/README.md:
--------------------------------------------------------------------------------
1 | # How to use
2 |
3 | ### create a .env file
4 |
5 | ```
6 | FRONTEND_ORGIN=http://localhost:3000,http://127.0.0.1:5173
7 | SERVER_PORT=3001
8 | STRIPE_SERVER_SECRET_KEY=
9 | ```
10 |
11 | ### run server
12 |
13 | ```bash
14 | yarn install
15 | yarn start
16 | ```
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/example.env:
--------------------------------------------------------------------------------
1 |
2 | # Frontend origin (CORS)
3 | FRONTEND_ORGIN=http://localhost:3000,http://127.0.0.1:5173
4 |
5 | # Server port
6 | SERVER_PORT=3001
7 |
8 | # Stripe merchant Id see: https://paper.dropbox.com/doc/Public-Crypto-Onramp-Pilot-API-Testing-Guide-csKFlmSELSKNvuc1xenRd
9 | STRIPE_SERVER_SECRET_KEY=
10 |
--------------------------------------------------------------------------------
/packages/relay-kit/src/constants.ts:
--------------------------------------------------------------------------------
1 | export const GELATO_NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'
2 |
3 | export const GELATO_FEE_COLLECTOR = '0x3AC05161b76a35c1c28dC99Aa01BEd7B24cEA3bf'
4 |
5 | export const GELATO_RELAY_URL = 'https://relay.gelato.digital'
6 |
7 | export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
8 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/README.md:
--------------------------------------------------------------------------------
1 | # How to use
2 |
3 | This is an example of how to use the `@safe-global/onramp-kit` package.
4 |
5 | ```bash
6 | yarn install
7 | yarn start
8 | ```
9 |
10 | This example can be used as a playground to test the package as it is relatively imported from the root of the project.
11 |
12 | ```typescript
13 | import { SafeOnRampKit, SafeOnRampProviderType } from '../../src/index'
14 | ```
15 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/README.md:
--------------------------------------------------------------------------------
1 | # How to use
2 |
3 | This is an example of how to use the `@safe-global/auth-kit` package.
4 |
5 | ```bash
6 | yarn install
7 | yarn start
8 | ```
9 |
10 | This example can be used as a playground to test the package as it is relatively imported from the root of the project.
11 |
12 | ```typescript
13 | import { SafeAuthKit, SafeAuthProviderType, SafeAuthSignInData } from '../../src/index'
14 | ```
15 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Auth Provider demo
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | name: 'ESLint check'
2 | on: [pull_request]
3 |
4 | jobs:
5 | eslint:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - uses: actions/checkout@v3
9 |
10 | - uses: actions/setup-node@v3
11 | with:
12 | node-version: 18
13 | cache: yarn
14 |
15 | - name: Install Dependencies
16 | run: yarn install --frozen-lockfile
17 |
18 | - name: Run eslint
19 | run: yarn lint:check
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Payments Provider demo
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/src/lib/logger/logger.ts:
--------------------------------------------------------------------------------
1 | import pinoHttp from 'pino-http'
2 |
3 | const logger = pinoHttp({
4 | serializers: {
5 | req(req) {
6 | req.body = req.raw.body // log the body request
7 | return req
8 | }
9 | },
10 |
11 | // Override attribute keys for the log object
12 | customAttributeKeys: {
13 | req: 'request',
14 | res: 'response'
15 | }
16 | })
17 |
18 | export default logger
19 |
20 | export const log = logger.logger
21 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/index.ts:
--------------------------------------------------------------------------------
1 | import dotenv from 'dotenv'
2 |
3 | import Server from './src/server'
4 | import routes from './src/router/router'
5 |
6 | dotenv.config()
7 |
8 | const { SERVER_PORT, FRONTEND_ORGIN } = process.env
9 |
10 | const allowedOrigins = FRONTEND_ORGIN?.split(',')
11 |
12 | const DEFAULT_SERVER_PORT = '3001'
13 |
14 | const server = new Server()
15 |
16 | server.configureCors(allowedOrigins)
17 |
18 | server.registerRoutes(routes)
19 |
20 | server.start(SERVER_PORT || DEFAULT_SERVER_PORT)
21 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # environment variables
4 | .env
5 |
6 | # dependencies
7 | node_modules
8 | /.pnp
9 | .pnp.js
10 |
11 | # testing
12 | coverage
13 | coverage.json
14 |
15 | # production
16 | build
17 |
18 | # misc
19 | .DS_Store
20 | .env.local
21 | .env.development.local
22 | .env.test.local
23 | .env.production.local
24 |
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
29 | typechain
30 | typechain-types
31 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/adapters/stripe/stripeApi.ts:
--------------------------------------------------------------------------------
1 | export const createSession = (
2 | baseUrl: string,
3 | { walletAddress, networks }: { walletAddress: string; networks: string[] }
4 | ) => {
5 | return fetch(`${baseUrl}/api/v1/onramp/stripe/session`, {
6 | method: 'POST',
7 | headers: {
8 | 'Content-Type': 'application/json'
9 | },
10 | body: JSON.stringify({ walletAddress, networks })
11 | })
12 | }
13 |
14 | export const getSession = (baseUrl: string, sessionId: string) => {
15 | return fetch(`${baseUrl}/api/v1/onramp/stripe/session/${sessionId}`)
16 | }
17 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/src/router/stripe-router.ts:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 |
3 | import stripeController from '../controllers/stripe-controller'
4 |
5 | const STRIPE_CREATE_SESSION_PATHNAME = '/api/v1/onramp/stripe/session'
6 | const STRIPE_GET_SESSION_PATHNAME = '/api/v1/onramp/stripe/session/:sessionId'
7 |
8 | const stripeRouter = express.Router()
9 |
10 | stripeRouter.post(STRIPE_CREATE_SESSION_PATHNAME, stripeController.getStripeClientSecret)
11 | stripeRouter.get(STRIPE_GET_SESSION_PATHNAME, stripeController.getStripeSession)
12 |
13 | export default stripeRouter
14 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/src/main.tsx:
--------------------------------------------------------------------------------
1 | import ReactDOM from 'react-dom/client'
2 | import { SafeThemeProvider } from '@safe-global/safe-react-components'
3 | import { ThemeProvider, CssBaseline } from '@mui/material'
4 |
5 | import App from './App'
6 |
7 | import './index.css'
8 |
9 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
10 |
11 | {(safeTheme) => (
12 |
13 |
14 |
15 |
16 | )}
17 |
18 | )
19 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser', // Specifies the ESLint parser
3 | extends: [
4 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
5 | 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
6 | ],
7 | parserOptions: {
8 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
9 | sourceType: 'module', // Allows for the use of imports
10 | },
11 | }
--------------------------------------------------------------------------------
/playground/config/run.ts:
--------------------------------------------------------------------------------
1 | import { execSync } from 'child_process'
2 |
3 | const playInput = process.argv[2]
4 |
5 | const playgroundPaths = {
6 | 'paid-transaction': 'relay-kit/paid-transaction',
7 | 'sponsored-transaction': 'relay-kit/sponsored-transaction'
8 | }
9 |
10 | const path = playgroundPaths[playInput]
11 | if (!path) {
12 | console.log('Execute one of the existing playgrounds:')
13 | const playgrounds = Object.keys(playgroundPaths)
14 | playgrounds.forEach((playground) => {
15 | console.log(` > yarn play ${playground}`)
16 | })
17 | process.exit()
18 | }
19 |
20 | execSync(`ts-node ./playground/${path}`, { stdio: 'inherit' })
21 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/types/events.ts:
--------------------------------------------------------------------------------
1 | type eventCallback = (eventData: SafeOnRampEvent) => void
2 |
3 | export interface SafeOnRampEventHandlers {
4 | onLoaded?: () => void
5 | onPaymentSuccessful?: eventCallback
6 | onPaymentError?: eventCallback
7 | onPaymentProcessing?: eventCallback
8 | }
9 |
10 | export interface SafeOnRampEvent {
11 | txId: string
12 | walletAddress: string
13 | totalFee: string
14 | totalAmount: string
15 | destination: {
16 | asset?: string
17 | amount: string | null
18 | network?: string
19 | }
20 | source: {
21 | asset?: string
22 | amount: string | null
23 | network?: string
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": 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 | "references": [{ "path": "./tsconfig.node.json" }]
21 | }
22 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": 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 | "references": [{ "path": "./tsconfig.node.json" }]
21 | }
22 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import { SafeThemeProvider } from '@safe-global/safe-react-components'
4 | import { ThemeProvider, CssBaseline } from '@mui/material'
5 |
6 | import App from './App'
7 |
8 | import './index.css'
9 |
10 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
11 |
12 |
13 | {(safeTheme) => (
14 |
15 |
16 |
17 |
18 | )}
19 |
20 |
21 | )
22 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/types/onRamp.ts:
--------------------------------------------------------------------------------
1 | import { SafeOnRampEventHandlers } from './events'
2 | import { StripeProviderConfig } from './stripe'
3 |
4 | export interface SafeOnRampClient {
5 | init(): Promise
6 | open(options: SafeOnRampOpenOptions): Promise
7 | close(): Promise
8 | }
9 |
10 | type Network = 'ethereum' | 'polygon'
11 |
12 | export interface SafeOnRampOpenOptions {
13 | element: HTMLElement | string
14 | walletAddress: string
15 | networks: Network[]
16 | events?: SafeOnRampEventHandlers
17 | sessionId?: string
18 | }
19 |
20 | export enum SafeOnRampProviderType {
21 | Stripe
22 | }
23 |
24 | export interface SafeOnRampConfig {
25 | onRampProviderConfig: StripeProviderConfig // Add other providers here when adapters are created
26 | }
27 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/scripts/typechain.ts:
--------------------------------------------------------------------------------
1 | import { glob, runTypeChain } from 'typechain'
2 |
3 | const safeContractsRoute = '../../node_modules/@gnosis.pm/safe-contracts/build/artifacts/contracts'
4 |
5 | async function main() {
6 | const cwd = process.cwd()
7 | // find all files matching the glob
8 | const allFiles = glob(cwd, [
9 | `${safeContractsRoute}/GnosisSafe.sol/GnosisSafe.json`,
10 | `${safeContractsRoute}/proxies/GnosisSafeProxyFactory.sol/GnosisSafeProxyFactory.json`,
11 | `${safeContractsRoute}/libraries/MultiSendCallOnly.sol/MultiSendCallOnly.json`
12 | ])
13 | const result = await runTypeChain({
14 | cwd,
15 | filesToProcess: allFiles,
16 | allFiles,
17 | outDir: 'typechain',
18 | target: 'ethers-v5'
19 | })
20 | }
21 |
22 | main().catch(console.error)
23 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
4 | import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'
5 |
6 | export default defineConfig({
7 | plugins: [react()],
8 | server: {
9 | port: 3000
10 | },
11 | optimizeDeps: {
12 | disabled: false,
13 | esbuildOptions: {
14 | define: {
15 | global: 'globalThis'
16 | },
17 | plugins: [
18 | NodeGlobalsPolyfillPlugin({
19 | buffer: true,
20 | process: true
21 | }),
22 | NodeModulesPolyfillPlugin()
23 | ]
24 | }
25 | },
26 | define: {
27 | 'process.env': {},
28 | global: {}
29 | }
30 | })
31 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/src/AppBar.tsx:
--------------------------------------------------------------------------------
1 | import { AppBar as MuiAppBar, Typography, styled } from '@mui/material'
2 |
3 | const AppBar = () => {
4 | return (
5 |
6 |
7 | Payments Provider Demo
8 |
9 |
10 | )
11 | }
12 |
13 | const StyledAppBar = styled(MuiAppBar)`
14 | && {
15 | position: sticky;
16 | top: 0;
17 | background: ${({ theme }) => theme.palette.background.paper};
18 | height: 70px;
19 | align-items: center;
20 | justify-content: space-between;
21 | flex-direction: row;
22 | border-bottom: 2px solid ${({ theme }) => theme.palette.background.paper};
23 | box-shadow: none;
24 | }
25 | `
26 |
27 | export default AppBar
28 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
4 | import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'
5 |
6 | export default defineConfig({
7 | plugins: [react()],
8 | server: {
9 | port: 3000
10 | },
11 | optimizeDeps: {
12 | disabled: false,
13 | esbuildOptions: {
14 | define: {
15 | global: 'globalThis'
16 | },
17 | plugins: [
18 | NodeGlobalsPolyfillPlugin({
19 | buffer: true,
20 | process: true
21 | }),
22 | NodeModulesPolyfillPlugin()
23 | ]
24 | }
25 | },
26 | define: {
27 | 'process.env': {},
28 | global: {}
29 | }
30 | })
31 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/adapters/stripe/utils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Utility function to load a script and inject it into the DOM
3 | * @param url The url of the script to load
4 | * @param async If the script should be loaded asynchronously
5 | * @param type The type of the script
6 | */
7 | export const loadScript = (
8 | url: string,
9 | async = 'true',
10 | type = 'text/javascript'
11 | ): Promise => {
12 | return new Promise((resolve, reject) => {
13 | const scriptElement = document.createElement('script')
14 |
15 | scriptElement.setAttribute('src', url)
16 | scriptElement.setAttribute('type', type)
17 | scriptElement.setAttribute('async', async)
18 |
19 | document.body.appendChild(scriptElement)
20 |
21 | scriptElement.addEventListener('load', () => {
22 | resolve()
23 | })
24 |
25 | scriptElement.addEventListener('error', () => {
26 | reject()
27 | })
28 | })
29 | }
30 |
--------------------------------------------------------------------------------
/packages/auth-kit/src/types.ts:
--------------------------------------------------------------------------------
1 | import { ExternalProvider } from '@ethersproject/providers'
2 |
3 | export interface SafeAuthSignInData {
4 | chainId: string
5 | eoa: string
6 | safes?: string[]
7 | }
8 |
9 | export interface SafeAuthClient {
10 | provider: ExternalProvider | null
11 | init(): Promise
12 | signIn(): Promise
13 | signOut(): Promise
14 | }
15 |
16 | export enum SafeAuthProviderType {
17 | Web3Auth
18 | }
19 |
20 | export interface Web3AuthProviderConfig {
21 | rpcTarget: string
22 | clientId: string
23 | network: 'mainnet' | 'aqua' | 'celeste' | 'cyan' | 'testnet'
24 | theme: 'light' | 'dark' | 'auto'
25 | appLogo?: string
26 | }
27 |
28 | export interface SafeAuthConfig {
29 | chainId: string
30 | txServiceUrl?: string
31 | authProviderConfig: Web3AuthProviderConfig
32 | }
33 |
34 | export const SafeAuthEvents = {
35 | SIGNED_IN: 'SIGNED_IN',
36 | SIGNED_OUT: 'SIGNED_OUT'
37 | }
38 |
--------------------------------------------------------------------------------
/packages/relay-kit/src/types.ts:
--------------------------------------------------------------------------------
1 | import { RelayResponse, TransactionStatusResponse } from '@gelatonetwork/relay-sdk'
2 | import { BigNumber } from 'ethers'
3 |
4 | // TO-DO: Duplicated. Remove local type and import from "types" package
5 | // {
6 |
7 | export interface MetaTransactionOptions {
8 | gasLimit: BigNumber
9 | gasToken?: string
10 | isSponsored?: boolean
11 | }
12 |
13 | export interface RelayAdapter {
14 | getFeeCollector(): string
15 | getEstimateFee(chainId: number, gasLimit: BigNumber, gasToken?: string): Promise
16 | getTaskStatus(taskId: string): Promise
17 | relayTransaction(transaction: RelayTransaction): Promise
18 | }
19 |
20 | export interface RelayTransaction {
21 | target: string
22 | encodedTransaction: string
23 | chainId: number
24 | options: MetaTransactionOptions
25 | }
26 |
27 | // }
28 | // TO-DO: Duplicated. Remove local type and import from "types" package
29 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@safe-global/auth-kit-example",
3 | "private": true,
4 | "version": "0.1.0",
5 | "type": "module",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "@emotion/react": "^11.10.5",
13 | "@emotion/styled": "^11.10.5",
14 | "@mui/material": "^5.11.7",
15 | "@safe-global/safe-react-components": "^2.0.1",
16 | "ethers": "^6.0.3",
17 | "react": "^18.2.0",
18 | "react-dom": "^18.2.0"
19 | },
20 | "devDependencies": {
21 | "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
22 | "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
23 | "@rollup/plugin-commonjs": "^24.0.1",
24 | "@types/react": "^18.0.27",
25 | "@types/react-dom": "^18.0.10",
26 | "@vitejs/plugin-react": "^3.1.0",
27 | "rollup-plugin-polyfill-node": "^0.12.0",
28 | "typescript": "^4.9.3",
29 | "vite": "^4.1.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/relay-kit/README.md:
--------------------------------------------------------------------------------
1 | # Relay Kit
2 |
3 | [](https://badge.fury.io/js/%40safe-global%2Frelay-kit)
4 | [](https://github.com/safe-global/account-abstraction-sdk/releases)
5 | [](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md)
6 |
7 | The Relay Kit allows to abstract users from the transaction fees payment (gas fees) allowing the use of native token or ERC-20 tokens. This will enable you to pay transaction fees directly from funding available in a Safe.
8 |
9 | ## Reference
10 |
11 | - [Relay Kit docs](https://docs.safe.global/learn/safe-core-account-abstraction-sdk/relay-kit)
12 |
13 |
14 | ## License
15 |
16 | This library is [released under MIT](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md).
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@safe-global/onramp-kit-example-client",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "@emotion/react": "^11.10.5",
13 | "@emotion/styled": "^11.10.5",
14 | "@mui/material": "^5.11.7",
15 | "@safe-global/safe-react-components": "^2.0.1",
16 | "ethers": "^6.0.3",
17 | "react": "^18.2.0",
18 | "react-dom": "^18.2.0"
19 | },
20 | "devDependencies": {
21 | "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
22 | "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
23 | "@rollup/plugin-commonjs": "^24.0.1",
24 | "@types/react": "^18.0.27",
25 | "@types/react-dom": "^18.0.10",
26 | "@vitejs/plugin-react": "^3.1.0",
27 | "rollup-plugin-polyfill-node": "^0.12.0",
28 | "typescript": "^4.9.3",
29 | "vite": "^4.1.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | yarn-debug.log*
5 | yarn-error.log*
6 |
7 | # Diagnostic reports (https://nodejs.org/api/report.html)
8 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
9 |
10 | # Coverage directory used by tools like istanbul
11 | coverage
12 | *.lcov
13 |
14 | # nyc test coverage
15 | .nyc_output
16 |
17 | # Compiled binary addons
18 | build/
19 | dist/
20 |
21 | # Dependency directories
22 | node_modules/
23 |
24 | # Optional npm cache directory
25 | .npm
26 |
27 | # Optional eslint cache
28 | .eslintcache
29 |
30 | # Yarn Integrity file
31 | .yarn-integrity
32 |
33 | # dotenv environment variables file
34 | .env
35 | .env.test
36 | .env.local
37 |
38 | # Stores VSCode versions used for testing VSCode extensions
39 | .vscode
40 | .vscode-test
41 |
42 | # yarn v2
43 | .yarn/cache
44 | .yarn/unplugged
45 | .yarn/build-state.yml
46 | .yarn/install-state.gz
47 | .pnp.*
48 |
49 | # macOS
50 | .DS_Store
51 |
52 | # Hardhat files
53 | cache
54 | artifacts
55 | deployments
56 |
57 | # Typechain
58 | typechain
59 |
60 | openapi/
61 |
62 | .idea
63 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea or feature request for the Safe Account Abstraction SDK
4 | ---
5 |
6 | ## Prerequisites
7 |
8 | - First, many thanks for taking part in the community and helping us improve. We appreciate that a lot.
9 | - Support questions are better asked in our Discord chat: https://chat.safe.global/
10 | - Please ensure the issue isn't already reported.
11 |
12 | _Please delete the above section and the instructions in the sections below before submitting_
13 |
14 | ## Context / issue
15 |
16 | Why is this feature needed?
17 |
18 | In case your feature request related to a problem, please add clear and concise description of what the issue is.
19 |
20 | ## Proposed solution
21 |
22 | Please add a clear and concise description of what you want to happen.
23 |
24 | ## Alternatives
25 |
26 | Please add a clear and concise description of any alternative solutions or features you have considered.
27 |
28 | ## Additional context
29 |
30 | Add any other context about the feature request here.
31 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@safe-global/onramp-kit-example-client",
3 | "version": "0.1.0",
4 | "description": "Account abstraction basic Stripe service",
5 | "main": "index.ts",
6 | "license": "MIT",
7 | "author": "Daniel Somoza",
8 | "private": true,
9 | "scripts": {
10 | "build": "tsc",
11 | "prestart:prod": "yarn build",
12 | "start:prod": "node build/index.js | pino-pretty",
13 | "start": "nodemon --exec ts-node index.ts | pino-pretty",
14 | "test": "echo 'add tests'",
15 | "test:coverage": "echo 'add tests'"
16 | },
17 | "dependencies": {
18 | "axios": "^1.3.3",
19 | "cors": "^2.8.5",
20 | "dotenv": "^16.0.3",
21 | "express": "^4.18.2",
22 | "pine": "^1.1.1",
23 | "pino-http": "^8.3.3",
24 | "pino-pretty": "^9.2.0"
25 | },
26 | "devDependencies": {
27 | "@types/cors": "^2.8.13",
28 | "@types/express": "^4.17.17",
29 | "@types/node": "^18.13.0",
30 | "nodemon": "^2.0.20",
31 | "ts-node": "^10.9.1",
32 | "typescript": "^4.9.5"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Monorepo Test
2 | on:
3 | pull_request:
4 | push:
5 | branches:
6 | - main
7 | - development
8 | env:
9 | INFURA_KEY: ${{ secrets.INFURA_KEY }}
10 | jobs:
11 | test:
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | node-version: [16.x]
16 | steps:
17 | - uses: actions/checkout@v3
18 | - name: Use Node.js ${{ matrix.node-version }}
19 | uses: actions/setup-node@v3
20 | with:
21 | node-version: ${{ matrix.node-version }}
22 |
23 | - name: Yarn cache
24 | uses: actions/cache@v2
25 | with:
26 | path: '**/node_modules'
27 | key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
28 |
29 | - name: Yarn install
30 | run: |
31 | mkdir .yarncache
32 | yarn install --cache-folder ./.yarncache --frozen-lockfile
33 | rm -rf .yarncache
34 | yarn cache clean
35 |
36 | - name: Build
37 | run: yarn build
38 |
39 | - name: Test
40 | run: yarn test
41 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/src/constants/index.ts:
--------------------------------------------------------------------------------
1 | export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
2 |
3 | // keccak256(toUtf8Bytes('Safe Account Abstraction'))
4 | export const PREDETERMINED_SALT_NONCE =
5 | '0xb1073742015cbcf5a3a4d9d1ae33ecf619439710b89475f92e2abd2117e90f90'
6 |
7 | export const SIGNED_TYPE_DATA_METHOD = 'eth_signTypedData_v4'
8 |
9 | export const EIP712_SAFE_TX_TYPES = {
10 | EIP712Domain: [
11 | {
12 | type: 'uint256',
13 | name: 'chainId'
14 | },
15 | {
16 | type: 'address',
17 | name: 'verifyingContract'
18 | }
19 | ],
20 | SafeTx: [
21 | { type: 'address', name: 'to' },
22 | { type: 'uint256', name: 'value' },
23 | { type: 'bytes', name: 'data' },
24 | { type: 'uint8', name: 'operation' },
25 | { type: 'uint256', name: 'safeTxGas' },
26 | { type: 'uint256', name: 'baseGas' },
27 | { type: 'uint256', name: 'gasPrice' },
28 | { type: 'address', name: 'gasToken' },
29 | { type: 'address', name: 'refundReceiver' },
30 | { type: 'uint256', name: 'nonce' }
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Bug report about the Safe Account Abstraction SDK
4 | ---
5 |
6 | ## Prerequisites
7 |
8 | - First, many thanks for taking part in the community and helping us improve. We appreciate that a lot.
9 | - Support questions are better asked in our Discord chat: https://chat.safe.global/
10 | - Please ensure the issue isn't already reported.
11 |
12 | _Please delete the above section and the instructions in the sections below before submitting_
13 |
14 | ## Description
15 |
16 | Please describe concisely the bug you have found.
17 |
18 | ## Environment
19 |
20 | - Safe Account Abstraction SDK version:
21 | - Safe contract version:
22 | - Environment:
23 | - browser
24 | - non-browser
25 |
26 | ## Steps to reproduce
27 |
28 | If applicable, please provide a screenshot or small video reproducing the bug.
29 | Provide as much information as necessary to reproduce the bug.
30 |
31 | ## Expected result
32 |
33 | Please describe concisely what you expect instead.
34 |
35 | ## Additional context
36 |
37 | Add any other context about the problem here.
38 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/src/server.ts:
--------------------------------------------------------------------------------
1 | import express, { Application, Router, Request, Response } from 'express'
2 | import cors from 'cors'
3 |
4 | import logger, { log } from './lib/logger/logger'
5 |
6 | export type RequestType = Request
7 | export type ResponseType = Response
8 |
9 | class Server {
10 | app: Application
11 |
12 | constructor() {
13 | this.app = express()
14 | this.app.use(express.json())
15 | this.app.use(logger)
16 | }
17 |
18 | start(serverPort: string) {
19 | this.app.listen(serverPort, () => {
20 | log.info(`Server running on port: ${serverPort}`)
21 | })
22 | }
23 |
24 | registerRoutes(routes: Router[]) {
25 | routes.forEach((route) => {
26 | this.app.use(route)
27 | })
28 | }
29 |
30 | configureCors(origins?: string[]) {
31 | this.app.options('*', cors())
32 | this.app.post(
33 | '*',
34 | cors({
35 | origin: origins
36 | })
37 | )
38 | this.app.get(
39 | '*',
40 | cors({
41 | origin: origins
42 | })
43 | )
44 | }
45 | }
46 |
47 | export default Server
48 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Safe Ecosystem Foundation
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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "account-abstraction-sdk",
3 | "private": true,
4 | "scripts": {
5 | "clean": "lerna clean && rm -rf ./node_modules",
6 | "format:check": "lerna run format:check",
7 | "format": "prettier --write */**/*.{js,json,md,ts}",
8 | "unbuild": "lerna run unbuild",
9 | "build": "lerna run build --stream",
10 | "test": "FORCE_COLOR=1 lerna run test --stream",
11 | "play": "ts-node ./playground/config/run.ts",
12 | "lint:check": "eslint './packages/**/*.{js,jsx,ts,tsx}'"
13 | },
14 | "workspaces": {
15 | "packages": [
16 | "packages/*"
17 | ]
18 | },
19 | "author": "Safe (https://safe.global)",
20 | "license": "MIT",
21 | "devDependencies": {
22 | "@types/node": "^18.11.18",
23 | "@typescript-eslint/eslint-plugin": "^5.49.0",
24 | "@typescript-eslint/parser": "^5.49.0",
25 | "eslint": "^8.32.0",
26 | "eslint-config-prettier": "^8.6.0",
27 | "eslint-plugin-prettier": "^4.2.1",
28 | "lerna": "^6.4.1",
29 | "prettier": "^2.8.3",
30 | "ts-node": "^10.9.1",
31 | "typescript": "^4.9.4"
32 | },
33 | "resolutions": {
34 | "@ethereumjs/tx": "4.0.2"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/auth-kit/README.md:
--------------------------------------------------------------------------------
1 | # Auth Kit
2 |
3 | [](https://badge.fury.io/js/%40safe-global%2Fauth-kit)
4 | [](https://github.com/safe-global/account-abstraction-sdk/releases)
5 | [](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md)
6 |
7 | The Auth Kit provides a way to authenticate blockchain accounts using email addresses, social accounts or traditional web3 wallets (ex. Metamask). When using web2 methods as your email or social account, a derived Ethereum address will be generated.
8 |
9 | ## Reference
10 |
11 | - [Auth Kit docs](https://docs.safe.global/learn/safe-core-account-abstraction-sdk/auth-kit)
12 |
13 | ## Example
14 |
15 | [Check a functional demo](https://github.com/safe-global/account-abstraction-sdk/tree/dev/packages/auth-kit/example) using the `auth-kit`
16 |
17 | ## License
18 |
19 | This library is [released under MIT](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md).
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/src/controllers/stripe-controller.ts:
--------------------------------------------------------------------------------
1 | import { RequestType, ResponseType } from 'src/server'
2 | import stripeService from '../services/stripe-service'
3 |
4 | const HTTP_ERROR_STATUS = 400
5 |
6 | async function getStripeClientSecret(request: RequestType, response: ResponseType) {
7 | const { walletAddress, networks } = request.body
8 |
9 | try {
10 | const stripeResponse = await stripeService.getStripeClientSecret(walletAddress, networks)
11 |
12 | return response.send(stripeResponse)
13 | } catch (error: any) {
14 | response.status(HTTP_ERROR_STATUS)
15 |
16 | return response.send(error.response.data)
17 | }
18 | }
19 |
20 | async function getStripeSession(request: RequestType, response: ResponseType) {
21 | const { sessionId } = request.params
22 |
23 | try {
24 | const stripeResponse = await stripeService.getStripeSession(sessionId)
25 |
26 | return response.send(stripeResponse)
27 | } catch (error: any) {
28 | response.status(HTTP_ERROR_STATUS)
29 |
30 | return response.send(error.response.data)
31 | }
32 | }
33 |
34 | const stripeController = {
35 | getStripeClientSecret,
36 | getStripeSession
37 | }
38 |
39 | export default stripeController
40 |
--------------------------------------------------------------------------------
/packages/relay-kit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@safe-global/relay-kit",
3 | "version": "0.1.0-alpha.2",
4 | "description": "Relay library to abstract transaction gas fees",
5 | "main": "dist/src/index.js",
6 | "typings": "dist/src/index.d.ts",
7 | "scripts": {
8 | "format:check": "prettier --check \"*/**/*.{js,json,md,ts}\"",
9 | "format": "prettier --write */**/*.{js,json,md,ts}",
10 | "unbuild": "rm -rf dist",
11 | "build": "rm -rf dist && yarn tsc",
12 | "test": "echo \"Error: no test specified\""
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/safe-global/account-abstraction-sdk.git"
17 | },
18 | "keywords": [
19 | "Safe",
20 | "Ethereum",
21 | "Account Abstraction",
22 | "SDK",
23 | "Relay"
24 | ],
25 | "author": "Safe (https://safe.global)",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/safe-global/account-abstraction-sdk/issues"
29 | },
30 | "files": [
31 | "dist"
32 | ],
33 | "homepage": "https://github.com/safe-global/account-abstraction-sdk#readme",
34 | "publishConfig": {
35 | "access": "public"
36 | },
37 | "dependencies": {
38 | "@gelatonetwork/relay-sdk": "^3.1.0",
39 | "ethers": "^5.7.2"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/packages/onramp-kit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@safe-global/onramp-kit",
3 | "version": "0.1.0-alpha.2",
4 | "description": "Onramp library",
5 | "main": "dist/src/index.js",
6 | "types": "dist/src/index.d.ts",
7 | "scripts": {
8 | "format:check": "prettier --check \"*/**/*.{js,json,md,ts}\"",
9 | "format": "prettier --write */**/*.{js,json,md,ts}",
10 | "unbuild": "rm -rf dist",
11 | "build": "rm -rf dist && yarn tsc",
12 | "test": "echo \"Error: no test specified\""
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/safe-global/account-abstraction-sdk.git"
17 | },
18 | "keywords": [
19 | "Safe",
20 | "Ethereum",
21 | "Account Abstraction",
22 | "SDK",
23 | "Onramp"
24 | ],
25 | "author": "Safe (https://safe.global)",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/safe-global/account-abstraction-sdk/issues"
29 | },
30 | "files": [
31 | "dist"
32 | ],
33 | "homepage": "https://github.com/safe-global/account-abstraction-sdk#readme",
34 | "publishConfig": {
35 | "access": "public"
36 | },
37 | "devDependencies": {
38 | "@testing-library/jest-dom": "^5.16.5"
39 | },
40 | "dependencies": {
41 | "@ethersproject/address": "^5.7.0"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/src/AppBar.tsx:
--------------------------------------------------------------------------------
1 | import { AppBar as MuiAppBar, Typography, styled, Box, Button } from '@mui/material'
2 |
3 | type AppBarProps = {
4 | isLoggedIn: boolean
5 | onLogin: () => void
6 | onLogout: () => void
7 | }
8 |
9 | const AppBar = ({ isLoggedIn, onLogin, onLogout }: AppBarProps) => {
10 | return (
11 |
12 |
13 | Auth Provider Demo
14 |
15 |
16 |
17 | {isLoggedIn ? (
18 |
21 | ) : (
22 |
25 | )}
26 |
27 |
28 | )
29 | }
30 |
31 | const StyledAppBar = styled(MuiAppBar)`
32 | && {
33 | position: sticky;
34 | top: 0;
35 | background: ${({ theme }) => theme.palette.background.paper};
36 | height: 70px;
37 | align-items: center;
38 | justify-content: space-between;
39 | flex-direction: row;
40 | border-bottom: 2px solid ${({ theme }) => theme.palette.background.paper};
41 | box-shadow: none;
42 | }
43 | `
44 |
45 | export default AppBar
46 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/README.md:
--------------------------------------------------------------------------------
1 | # Safe Account Abstraction SDK
2 |
3 | [](https://badge.fury.io/js/%40safe-global%2Faccount-abstraction-kit-poc)
4 | [](https://github.com/safe-global/account-abstraction-sdk/releases)
5 | [](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md)
6 |
7 | Description TBD
8 |
9 | ## Table of contents
10 |
11 | - [Installation](#installation)
12 | - [Build](#build)
13 | - [Initialization](#initialization)
14 | - [License](#license)
15 |
16 | ## Installation
17 |
18 | Install the package with yarn or npm:
19 |
20 | ```bash
21 | yarn install
22 | npm install
23 | ```
24 |
25 | ## Build
26 |
27 | Build the package with yarn or npm:
28 |
29 | ```bash
30 | yarn build
31 | npm build
32 | ```
33 |
34 | ## Initialization
35 |
36 | Initialization TBD
37 |
38 | ```js
39 |
40 | ```
41 |
42 | ## License
43 |
44 | This library is [released under MIT](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md).
45 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/src/services/stripe-service.ts:
--------------------------------------------------------------------------------
1 | import axios, { AxiosInstance } from 'axios'
2 | import dotenv from 'dotenv'
3 |
4 | type stripeSuccessType = Promise<{
5 | clientSecret: string
6 | }>
7 |
8 | type stripeErrorType = any
9 |
10 | dotenv.config()
11 |
12 | const { STRIPE_SERVER_SECRET_KEY } = process.env
13 |
14 | const STRIPE_BASE_URL = 'https://api.stripe.com'
15 | const GET_STRIPE_CLIENT_SECRET_PATH = 'v1/crypto/onramp_sessions'
16 |
17 | const axiosStripeAPI: AxiosInstance = axios.create({
18 | baseURL: STRIPE_BASE_URL,
19 | headers: {
20 | Authorization: `Bearer ${STRIPE_SERVER_SECRET_KEY}`,
21 | 'content-type': 'application/x-www-form-urlencoded'
22 | }
23 | })
24 |
25 | async function getStripeClientSecret(
26 | walletAddress: string,
27 | supportedNetworks: string[]
28 | ): Promise {
29 | const { data } = await axiosStripeAPI.post(GET_STRIPE_CLIENT_SECRET_PATH, {
30 | transaction_details: {
31 | wallet_address: walletAddress,
32 | lock_wallet_address: true,
33 | supported_destination_networks: supportedNetworks
34 | }
35 | })
36 |
37 | return data
38 | }
39 |
40 | async function getStripeSession(sessionId: string) {
41 | const { data } = await axiosStripeAPI.get(
42 | `${GET_STRIPE_CLIENT_SECRET_PATH}/${sessionId}`
43 | )
44 |
45 | return data
46 | }
47 |
48 | const stripeService = {
49 | getStripeClientSecret,
50 | getStripeSession
51 | }
52 |
53 | export default stripeService
54 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@safe-global/account-abstraction-kit-poc",
3 | "version": "0.1.0-alpha.1",
4 | "description": "Safe Account Abstraction",
5 | "main": "dist/src/index.js",
6 | "typings": "dist/src/index.d.ts",
7 | "scripts": {
8 | "format:check": "prettier --check \"*/**/*.{js,json,md,ts}\"",
9 | "format": "prettier --write */**/*.{js,json,md,ts}",
10 | "unbuild": "rm -rf dist typechain",
11 | "build": "rm -rf dist && ts-node ./scripts/typechain && yarn tsc",
12 | "test": "echo \"Error: no test specified\""
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/safe-global/account-abstraction-sdk.git"
17 | },
18 | "keywords": [
19 | "Safe",
20 | "Ethereum",
21 | "Account Abstraction",
22 | "SDK"
23 | ],
24 | "author": "Safe (https://safe.global)",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/safe-global/account-abstraction-sdk/issues"
28 | },
29 | "files": [
30 | "dist"
31 | ],
32 | "homepage": "https://github.com/safe-global/account-abstraction-sdk#readme",
33 | "publishConfig": {
34 | "access": "public"
35 | },
36 | "devDependencies": {
37 | "@typechain/ethers-v5": "^10.2.0",
38 | "typechain": "^8.1.1"
39 | },
40 | "dependencies": {
41 | "@gnosis.pm/safe-contracts": "^1.3.0",
42 | "@safe-global/relay-kit": "^0.1.0-alpha.2",
43 | "@safe-global/safe-deployments": "^1.20.2",
44 | "ethereumjs-util": "^7.1.5",
45 | "ethers": "^5.7.2"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/packages/auth-kit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@safe-global/auth-kit",
3 | "version": "0.1.0-alpha.2",
4 | "description": "Authentication library for web2 logins",
5 | "main": "dist/src/index.js",
6 | "types": "dist/src/index.d.ts",
7 | "scripts": {
8 | "format:check": "prettier --check \"*/**/*.{js,json,md,ts}\"",
9 | "format": "prettier --write */**/*.{js,json,md,ts}",
10 | "unbuild": "rm -rf dist",
11 | "build": "rm -rf dist && yarn tsc",
12 | "test": "echo \"Error: no test specified\""
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/safe-global/account-abstraction-sdk.git"
17 | },
18 | "keywords": [
19 | "Safe",
20 | "Ethereum",
21 | "Account Abstraction",
22 | "SDK",
23 | "Authentication"
24 | ],
25 | "author": "Safe (https://safe.global)",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/safe-global/account-abstraction-sdk/issues"
29 | },
30 | "files": [
31 | "dist"
32 | ],
33 | "homepage": "https://github.com/safe-global/account-abstraction-sdk#readme",
34 | "publishConfig": {
35 | "access": "public"
36 | },
37 | "devDependencies": {
38 | "@testing-library/jest-dom": "^5.16.5",
39 | "@web3auth/base": "^4.3.0",
40 | "@web3auth/modal": "^4.3.1",
41 | "@web3auth/openlogin-adapter": "^4.3.0"
42 | },
43 | "dependencies": {
44 | "@safe-global/safe-ethers-lib": "^1.9.1",
45 | "@safe-global/safe-service-client": "^1.5.1",
46 | "@walletconnect/client": "^1.8.0",
47 | "ethers": "^5.7.2",
48 | "events": "^3.3.0"
49 | },
50 | "peerDependencies": {
51 | "@web3auth/base": "^4.3.0",
52 | "@web3auth/modal": "^4.3.1",
53 | "@web3auth/openlogin-adapter": "^4.3.0"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/src/utils/signatures.ts:
--------------------------------------------------------------------------------
1 | import { TypedDataSigner } from '@ethersproject/abstract-signer'
2 | import { Signer } from 'ethers'
3 | import { EIP712_SAFE_TX_TYPES } from '../constants'
4 | import { SafeTransactionData, SafeTxTypedData } from '../types'
5 |
6 | export function isTypedDataSigner(signer: any): signer is TypedDataSigner {
7 | return (signer as unknown as TypedDataSigner)._signTypedData !== undefined
8 | }
9 |
10 | export function getSignTypedData(
11 | safeAddress: string,
12 | transaction: SafeTransactionData,
13 | chainId: number
14 | ): SafeTxTypedData {
15 | return {
16 | types: EIP712_SAFE_TX_TYPES,
17 | domain: {
18 | chainId,
19 | verifyingContract: safeAddress
20 | },
21 | primaryType: 'SafeTx',
22 | message: {
23 | to: transaction.to,
24 | value: transaction.value.toString(),
25 | data: transaction.data,
26 | operation: transaction.operation,
27 | safeTxGas: transaction.safeTxGas.toString(),
28 | baseGas: transaction.baseGas.toString(),
29 | gasPrice: transaction.gasPrice.toString(),
30 | gasToken: transaction.gasToken,
31 | refundReceiver: transaction.refundReceiver,
32 | nonce: transaction.nonce.toString()
33 | }
34 | }
35 | }
36 |
37 | export async function getSignature(
38 | signer: Signer,
39 | safeAddress: string,
40 | transaction: SafeTransactionData,
41 | chainId: number
42 | ): Promise {
43 | const typedData = getSignTypedData(safeAddress, transaction, chainId)
44 | let signature = ''
45 | if (isTypedDataSigner(signer)) {
46 | signature = await signer._signTypedData(
47 | typedData.domain,
48 | { SafeTx: typedData.types.SafeTx },
49 | typedData.message
50 | )
51 | }
52 | return signature
53 | }
54 |
--------------------------------------------------------------------------------
/packages/onramp-kit/README.md:
--------------------------------------------------------------------------------
1 | # ⚠️ Warning ⚠️
2 |
3 | This package is provided for testing purposes only. It's not ready for production use. We are working with Stripe and participating in the pilot test for their new [crypto on-ramp](https://stripe.com/es/blog/crypto-onramp). Considering this, we provide a public key and a testing server already configured during the [Safe Account Abstraction hackathon](https://gnosis-safe.notion.site/Safe-d6c6ed61389041e28f5c7c925f653701)
4 |
5 | Once the hackathon and Stripe pilot are over, the server will be removed and you should use your own keys and server in case you opt-in for the [StripeAdapter](https://github.com/safe-global/account-abstraction-sdk/blob/195588a4388b15f06b05d2027ffd43185781be34/packages/onramp-kit/src/adapters/StripeAdapter.ts).
6 |
7 | # OnRamp Kit
8 |
9 | [](https://badge.fury.io/js/%40safe-global%2Fonramp-kit)
10 | [](https://github.com/safe-global/account-abstraction-sdk/releases)
11 | [](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md)
12 |
13 | The Onramp Kit allows users to buy cryptocurrencies using a credit card and other payment options.
14 |
15 | ## Reference
16 |
17 | - [OnRamp Kit docs](https://docs.safe.global/learn/safe-core-account-abstraction-sdk/onramp-kit)
18 |
19 | ## Example
20 |
21 | [Check a functional demo](https://github.com/safe-global/account-abstraction-sdk/tree/195588a4388b15f06b05d2027ffd43185781be34/packages/onramp-kit/example) using the `onramp-kit`
22 |
23 | ## License
24 |
25 | This library is [released under MIT](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md).
--------------------------------------------------------------------------------
/packages/onramp-kit/src/SafeOnRampKit.ts:
--------------------------------------------------------------------------------
1 | import StripeAdapter from './adapters/stripe/StripeAdapter'
2 | import type { SafeOnRampConfig, SafeOnRampClient, SafeOnRampOpenOptions } from './types'
3 |
4 | import { SafeOnRampProviderType } from './types/onRamp'
5 |
6 | /**
7 | * This class allows to initialize the Safe OnRamp Kit for convert fiat to crypto
8 | * @class SafeOnRampKit
9 | */
10 | export class SafeOnRampKit {
11 | #client: SafeOnRampClient
12 |
13 | /**
14 | * Initialize the SafeOnRampKit
15 | * @constructor
16 | * @param client - The client implementing the SafeOnRampClient interface
17 | */
18 | constructor(client: SafeOnRampClient) {
19 | this.#client = client
20 | }
21 |
22 | /**
23 | *
24 | * @param providerType The provider service to use. Currently only Stripe is supported
25 | * @param config The configuration object including the specific provider options
26 | * @returns A SafeOnRampKit instance
27 | * @throws Error if the provider type is not supported
28 | */
29 | static async init(providerType: SafeOnRampProviderType, config: SafeOnRampConfig) {
30 | let client
31 |
32 | switch (providerType) {
33 | case SafeOnRampProviderType.Stripe:
34 | client = new StripeAdapter(config.onRampProviderConfig)
35 | break
36 | default:
37 | throw new Error('Provider type not supported')
38 | }
39 |
40 | await client.init()
41 |
42 | return new SafeOnRampKit(client)
43 | }
44 |
45 | /**
46 | * This method opens the onramp widget using the provided options
47 | * @param options The options to open the onramp widget
48 | */
49 | async open(options: SafeOnRampOpenOptions): Promise {
50 | return await this.#client.open(options)
51 | }
52 |
53 | /**
54 | * This method destroys the onramp widget
55 | */
56 | async close() {
57 | await this.#client.close()
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/types/stripe.ts:
--------------------------------------------------------------------------------
1 | interface QuoteCurrency {
2 | id: string
3 | asset_code: string
4 | asset_display_name: string
5 | currency_minor_units: number
6 | currency_network: string
7 | currency_symbol: string
8 | currency_symbol_location: string
9 | }
10 |
11 | interface Fees {
12 | network_fee: string
13 | network_fee_monetary: string
14 | total_fee: string
15 | transaction_fee: string
16 | transaction_fee_monetary: string
17 | }
18 |
19 | interface Quote {
20 | blockchain_tx_id: string
21 | destination_amount: string | null
22 | destination_crypto_amount: string | null
23 | destination_currency: QuoteCurrency | null
24 | expiration: number
25 | fees: Fees
26 | fixed_currency_side: string
27 | source_amount: string | null
28 | source_currency: QuoteCurrency | null
29 | source_monetary_amount: string | null
30 | time_to_expiration: number
31 | total_amount: string
32 | }
33 |
34 | interface FixedTransactionDetails {
35 | destination_amount: string | null
36 | destination_crypto_amount: string | null
37 | destination_currency: string | null
38 | destination_network: string | null
39 | lock_wallet_address: boolean
40 | source_amount: string | null
41 | source_currency: string | null
42 | source_monetary_amount: string | null
43 | supported_destination_currencies: string[]
44 | supported_destination_networks: string[]
45 | wallet_address: string
46 | wallet_addresses: any
47 | }
48 |
49 | export interface Session {
50 | id: string
51 | object: string
52 | livemode: boolean
53 | client_secret: string
54 | quote: Quote
55 | wallet_address: string
56 | fixed_transaction_details: FixedTransactionDetails
57 | status: string
58 | }
59 |
60 | interface Payload {
61 | session: Session
62 | }
63 |
64 | export interface OnrampSessionUpdatedEvent {
65 | type: string
66 | payload: Payload
67 | }
68 |
69 | export interface StripeProviderConfig {
70 | stripePublicKey: string
71 | onRampBackendUrl: string
72 | }
73 |
74 | export interface StripeSession {
75 | mount: (element: string) => void
76 | addEventListener: (event: string, callback: (e: any) => void) => void
77 | removeEventListener: (event: string, callback: (e: any) => void) => void
78 | }
79 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/src/types/index.ts:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@ethersproject/bignumber'
2 |
3 | export enum OperationType {
4 | Call,
5 | DelegateCall
6 | }
7 |
8 | export interface AccountAbstractionConfig {
9 | relayAdapter: RelayAdapter
10 | }
11 |
12 | export interface MetaTransactionData {
13 | to: string
14 | value: BigNumber
15 | data: string
16 | operation?: OperationType
17 | }
18 |
19 | export interface SafeTransactionData extends MetaTransactionData {
20 | operation: OperationType
21 | safeTxGas: BigNumber
22 | baseGas: BigNumber
23 | gasPrice: BigNumber
24 | gasToken: string
25 | refundReceiver: string
26 | nonce: number
27 | }
28 |
29 | // TO-DO: Duplicated. Remove local type and import from "types" package
30 | // {
31 |
32 | export interface MetaTransactionOptions {
33 | gasLimit: BigNumber
34 | gasToken?: string
35 | isSponsored?: boolean
36 | }
37 |
38 | export interface RelayTransaction {
39 | target: string
40 | encodedTransaction: string
41 | chainId: number
42 | options: MetaTransactionOptions
43 | }
44 |
45 | // import { RelayResponse } from '@gelatonetwork/relay-sdk'
46 | export interface RelayResponse {
47 | taskId: string
48 | }
49 |
50 | export interface RelayAdapter {
51 | getFeeCollector(): string
52 | getEstimateFee(chainId: number, gasLimit: BigNumber, gasToken?: string): Promise
53 | relayTransaction(transaction: RelayTransaction): Promise
54 | }
55 |
56 | // }
57 | // TO-DO: Duplicated. Remove local type and import from "types" package
58 |
59 | export interface SafeSetupConfig {
60 | owners: string[]
61 | threshold: number
62 | fallbackHandlerAddress: string
63 | }
64 |
65 | interface Eip712MessageTypes {
66 | EIP712Domain: {
67 | type: string
68 | name: string
69 | }[]
70 | SafeTx: {
71 | type: string
72 | name: string
73 | }[]
74 | }
75 |
76 | export interface SafeTxTypedData {
77 | types: Eip712MessageTypes
78 | domain: {
79 | chainId?: number
80 | verifyingContract: string
81 | }
82 | primaryType: 'SafeTx'
83 | message: {
84 | to: string
85 | value: string
86 | data: string
87 | operation: OperationType
88 | safeTxGas: string
89 | baseGas: string
90 | gasPrice: string
91 | gasToken: string
92 | refundReceiver: string
93 | nonce: string
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/tsconfig.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
4 | "module": "CommonJS", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
5 | "allowJs": false, /* Allow javascript files to be compiled. */
6 | "declaration": true, /* Generates corresponding '.d.ts' file. */
7 | "sourceMap": true, /* Generates corresponding '.map' file. */
8 | "strict": true, /* Enable all strict type-checking options. */
9 | "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
10 | "strictNullChecks": true, /* Enable strict null checks. */
11 | "strictFunctionTypes": true, /* Enable strict checking of function types. */
12 | "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
13 | "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
14 | "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
15 | "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
16 | "noUnusedParameters": true, /* Report errors on unused parameters. */
17 | "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
18 | "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
19 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
20 | "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
21 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
22 | "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
23 | "skipLibCheck": true, /* Skip type checking of declaration files. */
24 | "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
25 | "resolveJsonModule": true
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [DEPRECATED] Safe Account Abstraction SDK
2 |
3 | ATTENTION: please find the current version of this code in [Safe Core SDK](https://github.com/safe-global/safe-core-sdk) repository
4 |
5 | [](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md)
6 |
7 | DESCRIPTION TBD
8 |
9 | ## Packages
10 |
11 | | Package | Release | Description |
12 | | ------- | :-----: | ----------- |
13 | | [account-abstraction](https://github.com/safe-global/account-abstraction-sdk/tree/main/packages/account-abstraction-kit) | [](https://badge.fury.io/js/%40safe-global%2Faccount-abstraction-kit-poc) | TBD |
14 | | [auth-kit](https://github.com/safe-global/account-abstraction-sdk/tree/main/packages/auth-kit) | [](https://badge.fury.io/js/%40safe-global%2Fauth-kit) | Enable web2 logins for blockchain accounts |
15 | | [onramp-kit](https://github.com/safe-global/account-abstraction-sdk/tree/main/packages/onramp-kit) | [](https://badge.fury.io/js/%40safe-global%2Fonramp-kit) | Enable transition from fiat to crypto |
16 | | [relay-kit](https://github.com/safe-global/account-abstraction-sdk/tree/main/packages/relay-kit) | [](https://badge.fury.io/js/%40safe-global%2Frelay-kit) | Abstract Safe signers from transaction gas |
17 |
18 |
19 | ## Installation
20 |
21 | Install the package with yarn or npm:
22 |
23 | ```bash
24 | yarn install
25 | npm install
26 | ```
27 |
28 | ## Build
29 |
30 | Build the package with yarn or npm:
31 |
32 | ```bash
33 | yarn build
34 | npm build
35 | ```
36 |
37 | ## Playground
38 |
39 | This project includes a [playground](https://github.com/safe-global/account-abstraction-sdk/tree/main/playground) with a few scripts that can be used as a starting point to use the Safe Account Abstraction SDK.
40 |
41 | #### Check all the scripts in the playground
42 |
43 | ```bash
44 | yarn play
45 | ```
46 |
47 | #### 1. Execute meta-transaction via Gelato Relay paid with balance in the Safe
48 |
49 | ```bash
50 | yarn play paid-transaction
51 | ```
52 |
53 | #### 2. Execute meta-transaction via Gelato Relay paid by 1Balance deposit
54 |
55 | ```bash
56 | yarn play sponsored-transaction
57 | ```
58 |
--------------------------------------------------------------------------------
/.github/workflows/cla.yml:
--------------------------------------------------------------------------------
1 | name: 'CLA Assistant'
2 | on:
3 | issue_comment:
4 | types: [created]
5 | pull_request_target:
6 | types: [opened, closed, synchronize]
7 |
8 | jobs:
9 | CLAssistant:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: 'CLA Assistant'
13 | if: (github.event.comment.body == 'recheckcla' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
14 | # Beta Release
15 | uses: contributor-assistant/github-action@v2.2.0
16 | env:
17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 | # the below token should have repo scope and must be manually added by you in the repository's secret
19 | PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_ACCESS_TOKEN }}
20 | with:
21 | path-to-signatures: 'signatures/version1/cla.json'
22 | path-to-document: 'https://safe.global/cla/' # e.g. a CLA or a DCO document
23 | # branch should not be protected
24 | branch: 'main'
25 | # user names of users allowed to contribute without CLA
26 | allowlist: germartinez,rmeissner,Uxio0,dasanra,luarx,DaniSomoza,yagopv,JagoFigueroa,bot*
27 |
28 | # the followings are the optional inputs - If the optional inputs are not given, then default values will be taken
29 | # enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
30 | remote-organization-name: 'safe-global'
31 | # enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository)
32 | remote-repository-name: 'cla-signatures'
33 | #create-file-commit-message: 'For example: Creating file for storing CLA Signatures'
34 | #signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo'
35 | #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
36 | #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
37 | #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'
38 | #lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true)
39 | #use-dco-flag: true - If you are using DCO instead of CLA
40 |
--------------------------------------------------------------------------------
/packages/auth-kit/src/adapters/Web3AuthAdapter.ts:
--------------------------------------------------------------------------------
1 | import { CHAIN_NAMESPACES } from '@web3auth/base'
2 | import { Web3Auth } from '@web3auth/modal'
3 | import { OpenloginAdapter } from '@web3auth/openlogin-adapter'
4 | import { ExternalProvider } from '@ethersproject/providers'
5 |
6 | import type { SafeAuthClient, Web3AuthProviderConfig } from '../types'
7 |
8 | /**
9 | * Web3AuthAdapter implements the SafeAuthClient interface for adapting the Web3Auth service provider
10 | * @class
11 | */
12 | export default class Web3AuthAdapter implements SafeAuthClient {
13 | provider: ExternalProvider | null
14 | private chainId: string
15 | private web3authInstance?: Web3Auth
16 | private config: Web3AuthProviderConfig
17 |
18 | /**
19 | *
20 | * @param chainId Chain Id
21 | * @param config Web3Auth configuration
22 | */
23 | constructor(chainId: string, config: Web3AuthProviderConfig) {
24 | this.config = config
25 | this.chainId = chainId
26 | this.provider = null
27 | }
28 |
29 | /**
30 | * Initialize the Web3Auth service provider {@link https://web3auth.io/docs/sdk/web/modal/initialize}
31 | * @throws Error if there was an error initializing Web3Auth
32 | */
33 | async init() {
34 | try {
35 | const web3auth = new Web3Auth({
36 | clientId: this.config.clientId,
37 | web3AuthNetwork: this.config.network,
38 | chainConfig: {
39 | chainNamespace: CHAIN_NAMESPACES.EIP155,
40 | chainId: this.chainId,
41 | rpcTarget: this.config.rpcTarget
42 | },
43 | uiConfig: {
44 | theme: this.config.theme,
45 | loginMethodsOrder: ['google', 'facebook']
46 | }
47 | })
48 |
49 | const openloginAdapter = new OpenloginAdapter({
50 | loginSettings: {
51 | mfaLevel: 'none'
52 | },
53 | adapterSettings: {
54 | uxMode: 'popup',
55 | whiteLabel: {
56 | name: 'Safe'
57 | }
58 | }
59 | })
60 |
61 | web3auth.configureAdapter(openloginAdapter)
62 |
63 | await web3auth.initModal()
64 |
65 | this.provider = web3auth.provider
66 | this.web3authInstance = web3auth
67 | } catch {
68 | throw new Error('There was an error initializing Web3Auth')
69 | }
70 | }
71 |
72 | /**
73 | * Connect to the Web3Auth service provider
74 | * @returns
75 | */
76 | async signIn(): Promise {
77 | if (!this.web3authInstance) return
78 |
79 | this.provider = await this.web3authInstance.connect()
80 | }
81 |
82 | /**
83 | * Disconnect from the Web3Auth service provider
84 | */
85 | async signOut(): Promise {
86 | if (!this.web3authInstance) return
87 |
88 | return await this.web3authInstance?.logout()
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/packages/relay-kit/src/GelatoRelayAdapter.ts:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@ethersproject/bignumber'
2 | import {
3 | CallWithSyncFeeRequest,
4 | GelatoRelay as GelatoNetworkRelay,
5 | RelayRequestOptions,
6 | RelayResponse,
7 | SponsoredCallRequest,
8 | TransactionStatusResponse
9 | } from '@gelatonetwork/relay-sdk'
10 | import { GELATO_FEE_COLLECTOR, GELATO_NATIVE_TOKEN_ADDRESS, ZERO_ADDRESS } from './constants'
11 | import { MetaTransactionOptions, RelayAdapter, RelayTransaction } from './types'
12 |
13 | export class GelatoRelayAdapter implements RelayAdapter {
14 | #gelatoRelay: GelatoNetworkRelay
15 | #apiKey?: string
16 |
17 | constructor(apiKey?: string) {
18 | this.#gelatoRelay = new GelatoNetworkRelay()
19 | this.#apiKey = apiKey
20 | }
21 |
22 | private _getFeeToken(gasToken?: string): string {
23 | return !gasToken || gasToken === ZERO_ADDRESS ? GELATO_NATIVE_TOKEN_ADDRESS : gasToken
24 | }
25 |
26 | getFeeCollector(): string {
27 | return GELATO_FEE_COLLECTOR
28 | }
29 |
30 | async getEstimateFee(
31 | chainId: number,
32 | gasLimit: BigNumber,
33 | gasToken?: string
34 | ): Promise {
35 | const feeToken = this._getFeeToken(gasToken)
36 | const estimation = await this.#gelatoRelay.getEstimatedFee(chainId, feeToken, gasLimit, true)
37 | return estimation
38 | }
39 |
40 | async getTaskStatus(taskId: string): Promise {
41 | return await this.#gelatoRelay.getTaskStatus(taskId)
42 | }
43 |
44 | async sponsorTransaction(
45 | target: string,
46 | encodedTransaction: string,
47 | chainId: number
48 | ): Promise {
49 | if (!this.#apiKey) {
50 | throw new Error('API key not defined')
51 | }
52 | const request: SponsoredCallRequest = {
53 | chainId,
54 | target,
55 | data: encodedTransaction
56 | }
57 | const response = await this.#gelatoRelay.sponsoredCall(request, this.#apiKey)
58 | return response
59 | }
60 |
61 | async payTransaction(
62 | target: string,
63 | encodedTransaction: string,
64 | chainId: number,
65 | options: MetaTransactionOptions
66 | ): Promise {
67 | const { gasLimit, gasToken } = options
68 | const feeToken = this._getFeeToken(gasToken)
69 | const request: CallWithSyncFeeRequest = {
70 | chainId,
71 | target,
72 | data: encodedTransaction,
73 | feeToken,
74 | isRelayContext: false
75 | }
76 | const relayRequestOptions: RelayRequestOptions = {
77 | gasLimit: gasLimit && gasLimit.toString()
78 | }
79 | const response = await this.#gelatoRelay.callWithSyncFee(request, relayRequestOptions)
80 | return response
81 | }
82 |
83 | async relayTransaction({
84 | target,
85 | encodedTransaction,
86 | chainId,
87 | options
88 | }: RelayTransaction): Promise {
89 | const response = options.isSponsored
90 | ? this.sponsorTransaction(target, encodedTransaction, chainId)
91 | : this.payTransaction(target, encodedTransaction, chainId, options)
92 | return response
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/client/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState, useRef } from 'react'
2 | import { isAddress } from '@ethersproject/address'
3 | import { SafeOnRampKit, SafeOnRampEvent, SafeOnRampProviderType } from '../../../src'
4 | import { Grid, TextField, Button } from '@mui/material'
5 |
6 | import AppBar from './AppBar'
7 |
8 | const isSessionValid = (sessionId: string) => sessionId.length === 28
9 |
10 | function App() {
11 | const [walletAddress, setWalletAddress] = useState('')
12 | const [sessionId, setSessionId] = useState('')
13 | const [onRampClient, setOnRampClient] = useState()
14 | const stripeRootRef = useRef(null)
15 |
16 | const handleCreateSession = async () => {
17 | if (!isSessionValid(sessionId) && !isAddress(walletAddress)) return
18 |
19 | if (stripeRootRef.current) {
20 | stripeRootRef.current.innerHTML = ''
21 | }
22 |
23 | const sessionData = (await onRampClient?.open({
24 | sessionId: sessionId,
25 | walletAddress,
26 | networks: ['ethereum', 'polygon'],
27 | element: '#stripe-root',
28 | events: {
29 | onLoaded: () => console.log('onLoaded()'),
30 | onPaymentSuccessful: (eventData: SafeOnRampEvent) =>
31 | console.log('onPaymentSuccessful(): ', eventData),
32 | onPaymentProcessing: (eventData: SafeOnRampEvent) =>
33 | console.log('onPaymentProcessing(): ', eventData),
34 | onPaymentError: (eventData: SafeOnRampEvent) => console.log('onPaymentError(): ', eventData)
35 | }
36 | })) as any
37 |
38 | setWalletAddress(sessionData.transaction_details.wallet_address)
39 | }
40 |
41 | useEffect(() => {
42 | ;(async () => {
43 | const onRampClient = await SafeOnRampKit.init(SafeOnRampProviderType.Stripe, {
44 | onRampProviderConfig: {
45 | stripePublicKey: import.meta.env.VITE_STRIPE_PUBLIC_KEY,
46 | onRampBackendUrl: import.meta.env.VITE_SAFE_STRIPE_BACKEND_BASE_URL
47 | }
48 | })
49 |
50 | setOnRampClient(onRampClient)
51 | })()
52 | }, [])
53 |
54 | return (
55 | <>
56 |
57 |
58 |
59 | setWalletAddress(event.target.value)}
66 | sx={{ width: '100%' }}
67 | />
68 | setSessionId(event.target.value)}
75 | sx={{ width: '100%', mt: 2 }}
76 | />
77 |
78 |
81 |
82 |
83 |
84 |
85 |
86 | >
87 | )
88 | }
89 |
90 | export default App
91 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/src/utils/deployments.ts:
--------------------------------------------------------------------------------
1 | import {
2 | DeploymentFilter,
3 | getCompatibilityFallbackHandlerDeployment,
4 | getMultiSendCallOnlyDeployment,
5 | getProxyFactoryDeployment,
6 | getSafeL2SingletonDeployment,
7 | getSafeSingletonDeployment
8 | } from '@safe-global/safe-deployments'
9 | import { ethers } from 'ethers'
10 | import { GnosisSafe__factory } from '../../typechain/factories'
11 | import { MultiSendCallOnly__factory } from '../../typechain/factories/libraries'
12 | import { GnosisSafeProxyFactory__factory } from '../../typechain/factories/proxies'
13 | import { GnosisSafe } from '../../typechain/GnosisSafe'
14 | import { MultiSendCallOnly } from './../../typechain/libraries/MultiSendCallOnly'
15 | import { GnosisSafeProxyFactory } from './../../typechain/proxies/GnosisSafeProxyFactory'
16 |
17 | export const safeDeploymentsL1ChainIds: number[] = [
18 | 1 // Ethereum Mainnet
19 | ]
20 |
21 | export function getSafeContract(
22 | chainId: number,
23 | signer: ethers.Signer,
24 | isL1SafeMasterCopy = false
25 | ): GnosisSafe {
26 | const filters: DeploymentFilter = {
27 | version: '1.3.0', // Only Safe v1.3.0 supported so far
28 | network: chainId.toString(),
29 | released: true
30 | }
31 | const contractDeployment =
32 | safeDeploymentsL1ChainIds.includes(chainId) || isL1SafeMasterCopy
33 | ? getSafeSingletonDeployment(filters)
34 | : getSafeL2SingletonDeployment(filters)
35 | const contractAddress = contractDeployment?.networkAddresses[chainId]
36 | if (!contractAddress) {
37 | throw new Error('Invalid SafeProxy contract address')
38 | }
39 | const contract = GnosisSafe__factory.connect(contractAddress, signer)
40 | return contract
41 | }
42 |
43 | export function getSafeProxyFactoryContract(
44 | chainId: number,
45 | signer: ethers.Signer
46 | ): GnosisSafeProxyFactory {
47 | const contractDeployment = getProxyFactoryDeployment({
48 | version: '1.3.0', // Only Safe v1.3.0 supported so far
49 | network: chainId.toString(),
50 | released: true
51 | })
52 | const contractAddress = contractDeployment?.networkAddresses[chainId]
53 | if (!contractAddress) {
54 | throw new Error('Invalid SafeProxyFactory contract address')
55 | }
56 | const contract = GnosisSafeProxyFactory__factory.connect(contractAddress, signer)
57 | return contract
58 | }
59 |
60 | export function getMultiSendCallOnlyContract(
61 | chainId: number,
62 | signer: ethers.Signer
63 | ): MultiSendCallOnly {
64 | const contractDeployment = getMultiSendCallOnlyDeployment({
65 | version: '1.3.0', // Only Safe v1.3.0 supported so far
66 | network: chainId.toString(),
67 | released: true
68 | })
69 | const contractAddress = contractDeployment?.networkAddresses[chainId]
70 | if (!contractAddress) {
71 | throw new Error('Invalid MultiSendCallOnly contract address')
72 | }
73 | const contract = MultiSendCallOnly__factory.connect(contractAddress, signer)
74 | return contract
75 | }
76 |
77 | export function getCompatibilityFallbackHandlerAddress(chainId: number): string {
78 | const contractDeployment = getCompatibilityFallbackHandlerDeployment({
79 | version: '1.3.0', // Only Safe v1.3.0 supported so far
80 | network: chainId.toString(),
81 | released: true
82 | })
83 | const contractAddress = contractDeployment?.networkAddresses[chainId]
84 | if (!contractAddress) {
85 | throw new Error('Invalid CompatibilityFallbackHandler contract address')
86 | }
87 | return contractAddress
88 | }
89 |
--------------------------------------------------------------------------------
/playground/relay-kit/sponsored-transaction.ts:
--------------------------------------------------------------------------------
1 | import AccountAbstraction, {
2 | MetaTransactionData,
3 | MetaTransactionOptions,
4 | OperationType
5 | } from '@safe-global/account-abstraction-kit-poc'
6 | import { GelatoRelayAdapter } from '@safe-global/relay-kit'
7 | import { BigNumber, ethers } from 'ethers'
8 | import { AccountAbstractionConfig } from './../../packages/account-abstraction-kit/src/types/index'
9 |
10 | // Fund the 1Balance account that will sponsor the transaction and get the API key:
11 | // https://relay.gelato.network/
12 |
13 | // Check the status of a transaction after it is relayed:
14 | // https://relay.gelato.digital/tasks/status/
15 |
16 | // Check the status of a transaction after it is executed:
17 | // https://goerli.etherscan.io/tx/
18 |
19 | const config = {
20 | SAFE_SIGNER_PRIVATE_KEY: '',
21 | RPC_URL: 'https://goerli.infura.io/v3/',
22 | RELAY_API_KEY: ''
23 | }
24 |
25 | const mockOnRampConfig = {
26 | ADDRESS: '0x4D39a545144D8e2F19E8009aB5F123FA1043cc98',
27 | PRIVATE_KEY: '0x32ecaa3b2feb4051470c98b6d2f2da8861ae83b11ccc7123aee1c9efc4ef1933'
28 | }
29 |
30 | const txConfig = {
31 | TO: '',
32 | DATA: '',
33 | VALUE: BigNumber.from(''),
34 | // Options:
35 | GAS_LIMIT: BigNumber.from('')
36 | }
37 |
38 | async function main() {
39 | console.log('Execute meta-transaction via Gelato Relay paid by 1Balance')
40 |
41 | // SDK Initialization
42 |
43 | const provider = new ethers.providers.JsonRpcProvider(config.RPC_URL)
44 | const signer = new ethers.Wallet(config.SAFE_SIGNER_PRIVATE_KEY, provider)
45 |
46 | const relayAdapter = new GelatoRelayAdapter(config.RELAY_API_KEY)
47 |
48 | const safeAccountAbstraction = new AccountAbstraction(signer)
49 | const sdkConfig: AccountAbstractionConfig = {
50 | relayAdapter
51 | }
52 | await safeAccountAbstraction.init(sdkConfig)
53 |
54 | // Calculate Safe address
55 |
56 | const predictedSafeAddress = safeAccountAbstraction.getSafeAddress()
57 | console.log({ predictedSafeAddress })
58 |
59 | const isSafeDeployed = await safeAccountAbstraction.isSafeDeployed()
60 | console.log({ isSafeDeployed })
61 |
62 | // Fake on-ramp to fund the Safe
63 |
64 | const safeBalance = await provider.getBalance(predictedSafeAddress)
65 | console.log({ safeBalance: ethers.utils.formatEther(safeBalance.toString()) })
66 | if (safeBalance.lt(txConfig.VALUE)) {
67 | const fakeOnRampSigner = new ethers.Wallet(mockOnRampConfig.PRIVATE_KEY, provider)
68 | const onRampResponse = await fakeOnRampSigner.sendTransaction({
69 | to: predictedSafeAddress,
70 | value: txConfig.VALUE
71 | })
72 | console.log(
73 | `Funding the Safe with ${ethers.utils.formatEther(txConfig.VALUE.toString())} ETH`
74 | )
75 | await onRampResponse.wait()
76 |
77 | const safeBalanceAfter = await provider.getBalance(predictedSafeAddress)
78 | console.log({ safeBalance: ethers.utils.formatEther(safeBalanceAfter.toString()) })
79 | }
80 |
81 | // Relay the transaction
82 |
83 | const safeTransaction: MetaTransactionData = {
84 | to: txConfig.TO,
85 | data: txConfig.DATA,
86 | value: txConfig.VALUE,
87 | operation: OperationType.Call
88 | }
89 | const options: MetaTransactionOptions = {
90 | gasLimit: txConfig.GAS_LIMIT,
91 | isSponsored: true
92 | }
93 |
94 | const response = await safeAccountAbstraction.relayTransaction(safeTransaction, options)
95 | console.log({ GelatoTaskId: response })
96 | }
97 |
98 | main()
99 |
--------------------------------------------------------------------------------
/packages/auth-kit/example/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 | import { SafeEventEmitterProvider } from '@web3auth/base'
3 | import { Box, Divider, Grid, Typography } from '@mui/material'
4 | import { EthHashInfo } from '@safe-global/safe-react-components'
5 | import { SafeAuthKit, SafeAuthProviderType, SafeAuthSignInData } from '../../src/index'
6 |
7 | import AppBar from './AppBar'
8 |
9 | function App() {
10 | const [safeAuthSignInResponse, setSafeAuthSignInResponse] = useState(
11 | null
12 | )
13 | const [safeAuth, setSafeAuth] = useState()
14 | const [provider, setProvider] = useState(null)
15 |
16 | useEffect(() => {
17 | ;(async () => {
18 | setSafeAuth(
19 | await SafeAuthKit.init(SafeAuthProviderType.Web3Auth, {
20 | chainId: '0x5',
21 | txServiceUrl: 'https://safe-transaction-goerli.safe.global', // Optional. Only if want to retrieve related safes
22 | authProviderConfig: {
23 | rpcTarget: `https://goerli.infura.io/v3/${import.meta.env.VITE_INFURA_KEY}`,
24 | clientId: import.meta.env.VITE_WEB3AUTH_CLIENT_ID || '',
25 | network: 'testnet',
26 | theme: 'dark'
27 | }
28 | })
29 | )
30 | })()
31 | }, [])
32 |
33 | const login = async () => {
34 | if (!safeAuth) return
35 |
36 | const response = await safeAuth.signIn()
37 | console.log('SIGN IN RESPONSE: ', response)
38 |
39 | setSafeAuthSignInResponse(response)
40 | setProvider(safeAuth.getProvider() as SafeEventEmitterProvider)
41 | }
42 |
43 | const logout = async () => {
44 | if (!safeAuth) return
45 |
46 | await safeAuth.signOut()
47 |
48 | setProvider(null)
49 | setSafeAuthSignInResponse(null)
50 | }
51 |
52 | return (
53 | <>
54 |
55 | {safeAuthSignInResponse?.eoa && (
56 |
57 |
58 |
59 | Owner account
60 |
61 |
62 |
68 |
69 |
70 | <>
71 |
72 | Available Safes
73 |
74 |
75 | {safeAuthSignInResponse?.safes?.length ? (
76 | safeAuthSignInResponse?.safes?.map((safe, index) => (
77 |
78 |
79 |
80 | ))
81 | ) : (
82 |
83 | No Available Safes
84 |
85 | )}
86 | >
87 |
88 |
89 | )}
90 | >
91 | )
92 | }
93 |
94 | const getPrefix = (chainId: string) => {
95 | switch (chainId) {
96 | case '0x1':
97 | return 'eth'
98 | case '0x5':
99 | return 'gor'
100 | case '0x100':
101 | return 'gno'
102 | case '0x137':
103 | return 'matic'
104 | default:
105 | return 'eth'
106 | }
107 | }
108 |
109 | export default App
110 |
--------------------------------------------------------------------------------
/playground/relay-kit/paid-transaction.ts:
--------------------------------------------------------------------------------
1 | import AccountAbstraction, {
2 | AccountAbstractionConfig,
3 | MetaTransactionData,
4 | MetaTransactionOptions,
5 | OperationType
6 | } from '@safe-global/account-abstraction-kit-poc'
7 | import { GelatoRelayAdapter } from '@safe-global/relay-kit'
8 | import { BigNumber, ethers } from 'ethers'
9 |
10 | // Check the status of a transaction after it is relayed:
11 | // https://relay.gelato.digital/tasks/status/
12 |
13 | // Check the status of a transaction after it is executed:
14 | // https://goerli.etherscan.io/tx/
15 |
16 | const config = {
17 | SAFE_SIGNER_PRIVATE_KEY: '',
18 | RPC_URL: 'https://goerli.infura.io/v3/'
19 | }
20 |
21 | const mockOnRampConfig = {
22 | ADDRESS: '',
23 | PRIVATE_KEY: ''
24 | }
25 |
26 | const txConfig = {
27 | TO: '',
28 | DATA: '',
29 | VALUE: BigNumber.from(''),
30 | // Options:
31 | GAS_LIMIT: BigNumber.from(''),
32 | GAS_TOKEN: ethers.constants.AddressZero
33 | }
34 |
35 | async function main() {
36 | console.log('Execute meta-transaction via Gelato Relay paid with balance in the Safe')
37 |
38 | // SDK Initialization
39 |
40 | const provider = new ethers.providers.JsonRpcProvider(config.RPC_URL)
41 | const signer = new ethers.Wallet(config.SAFE_SIGNER_PRIVATE_KEY, provider)
42 |
43 | const relayAdapter = new GelatoRelayAdapter()
44 |
45 | const safeAccountAbstraction = new AccountAbstraction(signer)
46 | const sdkConfig: AccountAbstractionConfig = {
47 | relayAdapter
48 | }
49 | await safeAccountAbstraction.init(sdkConfig)
50 |
51 | // Calculate Safe address
52 |
53 | const predictedSafeAddress = safeAccountAbstraction.getSafeAddress()
54 | console.log({ predictedSafeAddress })
55 |
56 | const isSafeDeployed = await safeAccountAbstraction.isSafeDeployed()
57 | console.log({ isSafeDeployed })
58 |
59 | // Fake on-ramp to transfer enough funds to the Safe address
60 |
61 | const chainId = (await signer.provider.getNetwork()).chainId
62 | const relayFee = await relayAdapter.getEstimateFee(
63 | chainId,
64 | txConfig.GAS_LIMIT,
65 | txConfig.GAS_TOKEN
66 | )
67 | const safeBalance = await provider.getBalance(predictedSafeAddress)
68 | console.log({ minSafeBalance: ethers.utils.formatEther(relayFee.toString()) })
69 | console.log({ safeBalance: ethers.utils.formatEther(safeBalance.toString()) })
70 |
71 | if (safeBalance.lt(relayFee)) {
72 | const fakeOnRampSigner = new ethers.Wallet(mockOnRampConfig.PRIVATE_KEY, provider)
73 | const fundingAmount = safeBalance.lt(relayFee)
74 | ? relayFee.sub(safeBalance)
75 | : safeBalance.sub(relayFee)
76 | const onRampResponse = await fakeOnRampSigner.sendTransaction({
77 | to: predictedSafeAddress,
78 | value: fundingAmount
79 | })
80 | console.log(
81 | `Funding the Safe with ${ethers.utils.formatEther(fundingAmount.toString())} ETH`
82 | )
83 | await onRampResponse.wait()
84 |
85 | const safeBalanceAfter = await provider.getBalance(predictedSafeAddress)
86 | console.log({ safeBalance: ethers.utils.formatEther(safeBalanceAfter.toString()) })
87 | }
88 |
89 | // Relay the transaction
90 |
91 | const safeTransaction: MetaTransactionData = {
92 | to: txConfig.TO,
93 | data: txConfig.DATA,
94 | value: txConfig.VALUE,
95 | operation: OperationType.Call
96 | }
97 | const options: MetaTransactionOptions = {
98 | gasLimit: txConfig.GAS_LIMIT,
99 | gasToken: txConfig.GAS_TOKEN
100 | }
101 |
102 | const response = await safeAccountAbstraction.relayTransaction(safeTransaction, options)
103 | console.log({ GelatoTaskId: response })
104 | }
105 |
106 | main()
107 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/src/utils/contracts.ts:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@ethersproject/bignumber'
2 | import { arrayify, BytesLike } from '@ethersproject/bytes'
3 | import { pack as solidityPack } from '@ethersproject/solidity'
4 | import { BigNumberish, ethers, Signer } from 'ethers'
5 | import { GnosisSafe } from '../../typechain/GnosisSafe'
6 | import { GnosisSafeProxyFactory } from '../../typechain/proxies/GnosisSafeProxyFactory'
7 | import { PREDETERMINED_SALT_NONCE, ZERO_ADDRESS } from '../constants'
8 | import { MetaTransactionData, SafeTransactionData } from '../types'
9 | import {
10 | getCompatibilityFallbackHandlerAddress,
11 | getSafeContract,
12 | getSafeProxyFactoryContract
13 | } from './deployments'
14 |
15 | export function encodeCreateProxyWithNonce(
16 | safeProxyFactoryContract: GnosisSafeProxyFactory,
17 | safeSingletonAddress: string,
18 | initializer: string
19 | ) {
20 | return safeProxyFactoryContract.interface.encodeFunctionData('createProxyWithNonce', [
21 | safeSingletonAddress,
22 | initializer,
23 | PREDETERMINED_SALT_NONCE
24 | ])
25 | }
26 |
27 | export function encodeSetupCallData(
28 | safeContract: GnosisSafe,
29 | owners: string[],
30 | chainId: number
31 | ): string {
32 | return safeContract.interface.encodeFunctionData('setup', [
33 | owners,
34 | BigNumber.from(1) as BigNumberish,
35 | ZERO_ADDRESS,
36 | '0x' as BytesLike,
37 | getCompatibilityFallbackHandlerAddress(chainId),
38 | ZERO_ADDRESS,
39 | BigNumber.from(0) as BigNumberish,
40 | ZERO_ADDRESS
41 | ])
42 | }
43 |
44 | export function encodeExecTransaction(
45 | safeContract: GnosisSafe,
46 | transaction: SafeTransactionData,
47 | signature: string
48 | ): string {
49 | return safeContract.interface.encodeFunctionData('execTransaction', [
50 | transaction.to,
51 | transaction.value,
52 | transaction.data,
53 | transaction.operation,
54 | transaction.safeTxGas,
55 | transaction.baseGas,
56 | transaction.gasPrice,
57 | transaction.gasToken,
58 | transaction.refundReceiver,
59 | signature
60 | ])
61 | }
62 |
63 | function encodeMetaTransaction(tx: MetaTransactionData): string {
64 | const data = arrayify(tx.data)
65 | const encoded = solidityPack(
66 | ['uint8', 'address', 'uint256', 'uint256', 'bytes'],
67 | [tx.operation, tx.to, tx.value, data.length, data]
68 | )
69 | return encoded.slice(2)
70 | }
71 |
72 | export function encodeMultiSendData(txs: MetaTransactionData[]): string {
73 | return '0x' + txs.map((tx) => encodeMetaTransaction(tx)).join('')
74 | }
75 |
76 | export async function getSafeInitializer(
77 | safeContract: GnosisSafe,
78 | signerAddress: string,
79 | chainId: number
80 | ): Promise {
81 | const initializer = await encodeSetupCallData(safeContract, [signerAddress], chainId)
82 | return initializer
83 | }
84 |
85 | export async function calculateChainSpecificProxyAddress(
86 | safeProxyFactoryContract: GnosisSafeProxyFactory,
87 | signer: Signer,
88 | chainId: number
89 | ): Promise {
90 | const safeSingletonContract = getSafeContract(chainId, signer)
91 | const deployer = safeProxyFactoryContract.address
92 | const signerAddress = await signer.getAddress()
93 |
94 | const deploymentCode = ethers.utils.solidityPack(
95 | ['bytes', 'uint256'],
96 | [
97 | await getSafeProxyFactoryContract(chainId, signer).proxyCreationCode(),
98 | safeSingletonContract.address
99 | ]
100 | )
101 | const salt = ethers.utils.solidityKeccak256(
102 | ['bytes32', 'uint256'],
103 | [
104 | ethers.utils.solidityKeccak256(
105 | ['bytes'],
106 | [await getSafeInitializer(safeSingletonContract, signerAddress, chainId)]
107 | ),
108 | PREDETERMINED_SALT_NONCE
109 | ]
110 | )
111 | const derivedAddress = ethers.utils.getCreate2Address(
112 | deployer,
113 | salt,
114 | ethers.utils.keccak256(deploymentCode)
115 | )
116 | return derivedAddress
117 | }
118 |
--------------------------------------------------------------------------------
/packages/onramp-kit/src/adapters/stripe/StripeAdapter.ts:
--------------------------------------------------------------------------------
1 | import {
2 | SafeOnRampClient,
3 | StripeSession,
4 | SafeOnRampOpenOptions,
5 | StripeProviderConfig,
6 | SafeOnRampEventHandlers,
7 | SafeOnRampEvent,
8 | OnrampSessionUpdatedEvent
9 | } from '../../types'
10 |
11 | import * as stripeApi from './stripeApi'
12 |
13 | import { loadScript } from './utils'
14 |
15 | const STRIPE_JS_URL = 'https://js.stripe.com/v3/'
16 | const STRIPE_CRYPTO_JS_URL = 'https://crypto-js.stripe.com/crypto-onramp-outer.js'
17 |
18 | /**
19 | * This class implements the SafeOnRampClient interface for the Stripe provider
20 | * @class StripeAdapter
21 | */
22 | export default class StripeAdapter implements SafeOnRampClient {
23 | #stripeOnRamp: any
24 | #onRampSession?: StripeSession
25 | #config: StripeProviderConfig
26 | #currentSessionOptions?: SafeOnRampOpenOptions
27 |
28 | /**
29 | * Initialize the StripeAdapter
30 | * @constructor
31 | * @param config The configuration object for the Stripe provider
32 | */
33 | constructor(config: StripeProviderConfig) {
34 | this.#config = config
35 | }
36 |
37 | /**
38 | * This method loads the Stripe JS files and initializes the StripeOnRamp object
39 | */
40 | async init() {
41 | try {
42 | await loadScript(STRIPE_JS_URL)
43 | await loadScript(STRIPE_CRYPTO_JS_URL)
44 |
45 | this.#stripeOnRamp = StripeOnramp(this.#config.stripePublicKey)
46 | } catch {
47 | throw new Error("Couldn't load Stripe's JS files")
48 | }
49 | }
50 |
51 | /**
52 | * This method open the onramp widget with the provided options
53 | * @param options The options to open the onramp widget
54 | */
55 | async open(options: SafeOnRampOpenOptions) {
56 | try {
57 | let response
58 |
59 | if (options.sessionId) {
60 | response = await stripeApi.getSession(this.#config.onRampBackendUrl, options.sessionId)
61 | } else {
62 | response = await stripeApi.createSession(this.#config.onRampBackendUrl, {
63 | walletAddress: options.walletAddress,
64 | networks: options.networks
65 | })
66 | }
67 |
68 | const data = await response.json()
69 |
70 | if (!response.ok) throw new Error()
71 |
72 | const onRampSession = await this.#stripeOnRamp.createSession({
73 | clientSecret: data.client_secret
74 | })
75 |
76 | this.#onRampSession = onRampSession
77 | this.#currentSessionOptions = options
78 |
79 | if (options.events) this.#bindEvents(options.events)
80 |
81 | onRampSession.mount(options.element)
82 |
83 | return data
84 | } catch {
85 | throw new Error('Error trying to create a new Stripe session')
86 | }
87 | }
88 |
89 | /**
90 | * This method close the onramp widget
91 | */
92 | async close() {
93 | throw new Error('Method not implemented.')
94 | }
95 |
96 | /**
97 | * This method binds the event handlers to the onramp widget
98 | * @param events The event handlers to bind to the onramp widget
99 | */
100 | #bindEvents(events: SafeOnRampEventHandlers) {
101 | this.#onRampSession?.addEventListener('onramp_ui_loaded', () => {
102 | events?.onLoaded?.()
103 | })
104 |
105 | this.#onRampSession?.addEventListener(
106 | 'onramp_session_updated',
107 | (e: OnrampSessionUpdatedEvent) => {
108 | const safeEvent = this.stripeEventToSafeEvent(e)
109 |
110 | // TODO: Remove this check when not required
111 | // This is only in order to preserve testnets liquidity pools during the hackaton
112 | if (Number(e.payload.session.quote.source_monetary_amount?.replace(',', '.')) > 10) {
113 | document.querySelector(this.#currentSessionOptions?.element as string)?.remove()
114 | throw new Error(
115 | "The amount you are trying to use to complete your purchase can't be greater than 10 in order to preserve testnets liquidity pools"
116 | )
117 | }
118 |
119 | if (e.payload.session.status === 'fulfillment_complete') {
120 | events?.onPaymentSuccessful?.(safeEvent)
121 | }
122 |
123 | if (e.payload.session.status === 'fulfillment_processing') {
124 | events?.onPaymentProcessing?.(safeEvent)
125 | }
126 |
127 | if (e.payload.session.status === 'rejected') {
128 | events?.onPaymentError?.(safeEvent)
129 | }
130 | }
131 | )
132 | }
133 |
134 | private stripeEventToSafeEvent(stripeEvent: OnrampSessionUpdatedEvent): SafeOnRampEvent {
135 | const { session } = stripeEvent.payload
136 | const { quote } = session
137 |
138 | return {
139 | txId: quote.blockchain_tx_id,
140 | walletAddress: session.wallet_address,
141 | totalFee: quote.fees?.total_fee,
142 | totalAmount: quote.total_amount,
143 | destination: {
144 | asset: quote.destination_currency?.asset_code,
145 | amount: quote.destination_amount,
146 | network: quote.destination_currency?.currency_network
147 | },
148 | source: {
149 | asset: quote.source_currency?.asset_code,
150 | amount: quote.source_amount,
151 | network: quote.source_currency?.currency_network
152 | }
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/packages/auth-kit/src/SafeAuthKit.ts:
--------------------------------------------------------------------------------
1 | import { ethers } from 'ethers'
2 | import EventEmitter from 'events'
3 | import EthersAdapter from '@safe-global/safe-ethers-lib'
4 | import SafeServiceClient from '@safe-global/safe-service-client'
5 | import Web3AuthAdapter from './adapters/Web3AuthAdapter'
6 |
7 | import {
8 | SafeAuthClient,
9 | SafeAuthConfig,
10 | SafeAuthProviderType,
11 | SafeAuthSignInData,
12 | SafeAuthEvents
13 | } from './types'
14 |
15 | /**
16 | * SafeAuthKit provides a simple interface for web2 logins
17 | */
18 | export default class SafeAuthKit extends EventEmitter {
19 | safeAuthData?: SafeAuthSignInData
20 | #client: SafeAuthClient
21 | #config: SafeAuthConfig
22 |
23 | /**
24 | * Initialize the SafeAuthKit
25 | * @constructor
26 | * @param client The client implementing the SafeAuthClient interface
27 | * @param config The configuration options
28 | */
29 | constructor(client: SafeAuthClient, config: SafeAuthConfig) {
30 | super()
31 |
32 | this.#client = client
33 | this.#config = config
34 | }
35 |
36 | /**
37 | * The static method allows to initialize the SafeAuthKit asynchronously
38 | * @param providerType Choose the provider service to use
39 | * @param config The configuration including the one for the specific provider
40 | * @returns A SafeAuthKit instance
41 | * @throws Error if the provider type is not supported
42 | */
43 | static async init(
44 | providerType: SafeAuthProviderType,
45 | config: SafeAuthConfig
46 | ): Promise {
47 | let client
48 |
49 | switch (providerType) {
50 | case SafeAuthProviderType.Web3Auth:
51 | client = new Web3AuthAdapter(config.chainId, config.authProviderConfig)
52 | break
53 | default:
54 | throw new Error('Provider type not supported')
55 | }
56 |
57 | await client.init()
58 |
59 | return new SafeAuthKit(client, config)
60 | }
61 |
62 | /**
63 | * Authenticate the user
64 | * @returns the derived external owned account and the safes associated with the user if the txServiceUrl is provided
65 | * @throws Error if the provider was not created
66 | * @throws Error if there was an error while trying to get the safes for the current user using the provided txServiceUrl
67 | */
68 | async signIn(): Promise {
69 | await this.#client.signIn()
70 |
71 | if (!this.#client.provider) {
72 | throw new Error('Provider is not defined')
73 | }
74 |
75 | const ethersProvider = new ethers.providers.Web3Provider(this.#client.provider)
76 | const signer = ethersProvider.getSigner()
77 | const address = await signer.getAddress()
78 |
79 | let safes: string[] | undefined
80 |
81 | // Retrieve safes if txServiceUrl is provided
82 | if (this.#config.txServiceUrl) {
83 | try {
84 | const safesByOwner = await this.#getSafeCoreClient().getSafesByOwner(address)
85 | safes = safesByOwner.safes
86 | } catch (e) {
87 | throw new Error('There was an error while trying to get the safes for the current user')
88 | }
89 | }
90 |
91 | this.emit(SafeAuthEvents.SIGNED_IN)
92 |
93 | this.safeAuthData = {
94 | chainId: this.#config.chainId,
95 | eoa: address,
96 | safes
97 | }
98 |
99 | return this.safeAuthData
100 | }
101 |
102 | /**
103 | * Sign out the user
104 | */
105 | async signOut(): Promise {
106 | await this.#client?.signOut()
107 |
108 | this.safeAuthData = undefined
109 | this.emit(SafeAuthEvents.SIGNED_OUT)
110 | }
111 |
112 | /**
113 | *
114 | * @returns The Ethereum provider
115 | */
116 | getProvider() {
117 | if (!this.#client) return null
118 |
119 | return this.#client?.provider
120 | }
121 |
122 | /**
123 | * Subscribe to an event
124 | * @param eventName The event name to subscribe to. Choose from SafeAuthEvents type
125 | * @param listener The callback function to be called when the event is emitted
126 | */
127 | subscribe(eventName: typeof SafeAuthEvents, listener: (...args: any[]) => void) {
128 | this.on(eventName.toString(), listener)
129 | }
130 |
131 | /**
132 | * Unsubscribe from an event
133 | * @param eventName The event name to unsubscribe from. Choose from SafeAuthEvents type
134 | * @param listener The callback function to unsubscribe
135 | */
136 | unsubscribe(eventName: typeof SafeAuthEvents, listener: (...args: any[]) => void) {
137 | this.off(eventName.toString(), listener)
138 | }
139 |
140 | /**
141 | * Get the SafeServiceClient instance
142 | * @returns A SafeServiceClient instance
143 | */
144 | #getSafeCoreClient(): SafeServiceClient {
145 | if (!this.#client?.provider) {
146 | throw new Error('Provider is not defined')
147 | }
148 |
149 | if (!this.#config.txServiceUrl) {
150 | throw new Error('txServiceUrl is not defined')
151 | }
152 |
153 | const provider = new ethers.providers.Web3Provider(this.#client?.provider)
154 | const safeOwner = provider.getSigner(0)
155 |
156 | const adapter = new EthersAdapter({
157 | ethers,
158 | signerOrProvider: safeOwner
159 | })
160 |
161 | return new SafeServiceClient({
162 | txServiceUrl: this.#config.txServiceUrl,
163 | ethAdapter: adapter
164 | })
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/packages/account-abstraction-kit/src/AccountAbstraction.ts:
--------------------------------------------------------------------------------
1 | import { BigNumber, ethers } from 'ethers'
2 | import { GnosisSafe__factory } from '../typechain/factories'
3 | import { GnosisSafe } from '../typechain/GnosisSafe'
4 | import { MultiSendCallOnly } from '../typechain/libraries'
5 | import { GnosisSafeProxyFactory } from '../typechain/proxies'
6 | import { ZERO_ADDRESS } from './constants'
7 | import {
8 | AccountAbstractionConfig,
9 | MetaTransactionData,
10 | MetaTransactionOptions,
11 | OperationType,
12 | RelayAdapter,
13 | RelayTransaction,
14 | SafeTransactionData
15 | } from './types'
16 | import { getMultiSendCallOnlyContract, getSafeContract, getSafeProxyFactoryContract } from './utils'
17 | import {
18 | calculateChainSpecificProxyAddress,
19 | encodeCreateProxyWithNonce,
20 | encodeExecTransaction,
21 | encodeMultiSendData,
22 | getSafeInitializer
23 | } from './utils/contracts'
24 | import { getSignature } from './utils/signatures'
25 |
26 | class AccountAbstraction {
27 | #signer: ethers.Signer
28 | #chainId?: number
29 | #safeContract?: GnosisSafe
30 | #safeProxyFactoryContract?: GnosisSafeProxyFactory
31 | #multiSendCallOnlyContract?: MultiSendCallOnly
32 | #relayAdapter?: RelayAdapter
33 |
34 | constructor(signer: ethers.Signer) {
35 | this.#signer = signer
36 | }
37 |
38 | async init(options: AccountAbstractionConfig) {
39 | if (!this.#signer.provider) {
40 | throw new Error('Signer must be connected to a provider')
41 | }
42 | const { relayAdapter } = options
43 | this.setRelayAdapter(relayAdapter)
44 |
45 | this.#chainId = (await this.#signer.provider.getNetwork()).chainId
46 | this.#safeProxyFactoryContract = getSafeProxyFactoryContract(this.#chainId, this.#signer)
47 | this.#multiSendCallOnlyContract = getMultiSendCallOnlyContract(this.#chainId, this.#signer)
48 | const safeAddress = await calculateChainSpecificProxyAddress(
49 | this.#safeProxyFactoryContract,
50 | this.#signer,
51 | this.#chainId
52 | )
53 | this.#safeContract = GnosisSafe__factory.connect(safeAddress, this.#signer)
54 | }
55 |
56 | setRelayAdapter(relayAdapter: RelayAdapter) {
57 | this.#relayAdapter = relayAdapter
58 | }
59 |
60 | async getSignerAddress(): Promise {
61 | const signerAddress = await this.#signer.getAddress()
62 | return signerAddress
63 | }
64 |
65 | async getNonce(): Promise {
66 | if (!this.#safeContract) {
67 | throw new Error('SDK not initialized')
68 | }
69 | return (await this.isSafeDeployed()) ? (await this.#safeContract.nonce()).toNumber() : 0
70 | }
71 |
72 | getSafeAddress(): string {
73 | if (!this.#safeContract) {
74 | throw new Error('SDK not initialized')
75 | }
76 | return this.#safeContract.address
77 | }
78 |
79 | async isSafeDeployed(): Promise {
80 | if (!this.#signer.provider) {
81 | throw new Error('SDK not initialized')
82 | }
83 | const address = this.getSafeAddress()
84 | const codeAtAddress = await this.#signer.provider.getCode(address)
85 | const isDeployed = codeAtAddress !== '0x'
86 | return isDeployed
87 | }
88 |
89 | private async _standardizeSafeTransactionData(
90 | transaction: MetaTransactionData,
91 | options: MetaTransactionOptions
92 | ): Promise {
93 | if (!this.#relayAdapter || !this.#chainId) {
94 | throw new Error('SDK not initialized')
95 | }
96 | const { gasLimit, gasToken, isSponsored } = options
97 | const estimation = await this.#relayAdapter.getEstimateFee(this.#chainId, gasLimit, gasToken)
98 |
99 | const standardizedSafeTx: SafeTransactionData = {
100 | to: transaction.to,
101 | value: transaction.value,
102 | data: transaction.data,
103 | operation: transaction.operation ?? OperationType.Call,
104 | safeTxGas: BigNumber.from(0), // Only Safe v1.3.0 supported so far
105 | baseGas: !isSponsored ? estimation : BigNumber.from(0),
106 | gasPrice: !isSponsored ? BigNumber.from(1) : BigNumber.from(0),
107 | gasToken: gasToken ?? ZERO_ADDRESS,
108 | refundReceiver: !isSponsored ? this.#relayAdapter.getFeeCollector() : ZERO_ADDRESS,
109 | nonce: await this.getNonce()
110 | }
111 | return standardizedSafeTx
112 | }
113 |
114 | async relayTransaction(
115 | transaction: MetaTransactionData,
116 | options: MetaTransactionOptions
117 | ): Promise {
118 | if (
119 | !this.#relayAdapter ||
120 | !this.#chainId ||
121 | !this.#safeContract ||
122 | !this.#multiSendCallOnlyContract ||
123 | !this.#safeProxyFactoryContract
124 | ) {
125 | throw new Error('SDK not initialized')
126 | }
127 |
128 | const standardizedSafeTx = await this._standardizeSafeTransactionData(transaction, options)
129 | const signature = await getSignature(
130 | this.#signer,
131 | this.getSafeAddress(),
132 | standardizedSafeTx,
133 | this.#chainId
134 | )
135 | const transactionData = await encodeExecTransaction(
136 | this.#safeContract,
137 | standardizedSafeTx,
138 | signature
139 | )
140 |
141 | let relayTransactionTarget = ''
142 | let encodedTransaction = ''
143 | const isSafeDeployed = await this.isSafeDeployed()
144 | if (isSafeDeployed) {
145 | relayTransactionTarget = this.#safeContract.address
146 | encodedTransaction = transactionData
147 | } else {
148 | relayTransactionTarget = this.#multiSendCallOnlyContract.address
149 | const safeSingletonContract = getSafeContract(this.#chainId, this.#signer)
150 | const initializer = await getSafeInitializer(
151 | this.#safeContract,
152 | await this.getSignerAddress(),
153 | this.#chainId
154 | )
155 |
156 | const safeDeploymentTransaction: MetaTransactionData = {
157 | to: this.#safeProxyFactoryContract.address,
158 | value: BigNumber.from(0),
159 | data: encodeCreateProxyWithNonce(
160 | this.#safeProxyFactoryContract,
161 | safeSingletonContract.address,
162 | initializer
163 | ),
164 | operation: OperationType.Call
165 | }
166 | const safeTransaction: MetaTransactionData = {
167 | to: this.#safeContract.address,
168 | value: BigNumber.from(0),
169 | data: transactionData,
170 | operation: OperationType.Call
171 | }
172 |
173 | const multiSendData = encodeMultiSendData([safeDeploymentTransaction, safeTransaction])
174 | encodedTransaction = this.#multiSendCallOnlyContract.interface.encodeFunctionData(
175 | 'multiSend',
176 | [multiSendData]
177 | )
178 | }
179 |
180 | const relayTransaction: RelayTransaction = {
181 | target: relayTransactionTarget,
182 | encodedTransaction: encodedTransaction,
183 | chainId: this.#chainId,
184 | options
185 | }
186 | const response = await this.#relayAdapter.relayTransaction(relayTransaction)
187 | return response.taskId
188 | }
189 | }
190 |
191 | export default AccountAbstraction
192 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/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": "es2020", /* 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": "node16", /* 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": "./build", /* Specify an output folder for all emitted files. */
53 | // "removeComments": true, /* Disable emitting comments. */
54 | "noEmit": false, /* 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 |
--------------------------------------------------------------------------------
/packages/onramp-kit/example/server/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@cspotcode/source-map-support@^0.8.0":
6 | version "0.8.1"
7 | resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
8 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
9 | dependencies:
10 | "@jridgewell/trace-mapping" "0.3.9"
11 |
12 | "@jridgewell/resolve-uri@^3.0.3":
13 | version "3.1.0"
14 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
15 | integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
16 |
17 | "@jridgewell/sourcemap-codec@^1.4.10":
18 | version "1.4.14"
19 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
20 | integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
21 |
22 | "@jridgewell/trace-mapping@0.3.9":
23 | version "0.3.9"
24 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
25 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
26 | dependencies:
27 | "@jridgewell/resolve-uri" "^3.0.3"
28 | "@jridgewell/sourcemap-codec" "^1.4.10"
29 |
30 | "@tsconfig/node10@^1.0.7":
31 | version "1.0.9"
32 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
33 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
34 |
35 | "@tsconfig/node12@^1.0.7":
36 | version "1.0.11"
37 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
38 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
39 |
40 | "@tsconfig/node14@^1.0.0":
41 | version "1.0.3"
42 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
43 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
44 |
45 | "@tsconfig/node16@^1.0.2":
46 | version "1.0.3"
47 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
48 | integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
49 |
50 | "@types/body-parser@*":
51 | version "1.19.2"
52 | resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
53 | integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==
54 | dependencies:
55 | "@types/connect" "*"
56 | "@types/node" "*"
57 |
58 | "@types/connect@*":
59 | version "3.4.35"
60 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
61 | integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==
62 | dependencies:
63 | "@types/node" "*"
64 |
65 | "@types/cors@^2.8.13":
66 | version "2.8.13"
67 | resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94"
68 | integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==
69 | dependencies:
70 | "@types/node" "*"
71 |
72 | "@types/express-serve-static-core@^4.17.33":
73 | version "4.17.33"
74 | resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz#de35d30a9d637dc1450ad18dd583d75d5733d543"
75 | integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==
76 | dependencies:
77 | "@types/node" "*"
78 | "@types/qs" "*"
79 | "@types/range-parser" "*"
80 |
81 | "@types/express@^4.17.17":
82 | version "4.17.17"
83 | resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4"
84 | integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==
85 | dependencies:
86 | "@types/body-parser" "*"
87 | "@types/express-serve-static-core" "^4.17.33"
88 | "@types/qs" "*"
89 | "@types/serve-static" "*"
90 |
91 | "@types/mime@*":
92 | version "3.0.1"
93 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
94 | integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
95 |
96 | "@types/node@*", "@types/node@^18.13.0":
97 | version "18.13.0"
98 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.13.0.tgz#0400d1e6ce87e9d3032c19eb6c58205b0d3f7850"
99 | integrity sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==
100 |
101 | "@types/qs@*":
102 | version "6.9.7"
103 | resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
104 | integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
105 |
106 | "@types/range-parser@*":
107 | version "1.2.4"
108 | resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
109 | integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
110 |
111 | "@types/serve-static@*":
112 | version "1.15.0"
113 | resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155"
114 | integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==
115 | dependencies:
116 | "@types/mime" "*"
117 | "@types/node" "*"
118 |
119 | abbrev@1:
120 | version "1.1.1"
121 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
122 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
123 |
124 | abort-controller@^3.0.0:
125 | version "3.0.0"
126 | resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
127 | integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
128 | dependencies:
129 | event-target-shim "^5.0.0"
130 |
131 | accepts@~1.3.8:
132 | version "1.3.8"
133 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
134 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
135 | dependencies:
136 | mime-types "~2.1.34"
137 | negotiator "0.6.3"
138 |
139 | acorn-walk@^8.1.1:
140 | version "8.2.0"
141 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
142 | integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
143 |
144 | acorn@^8.4.1:
145 | version "8.8.2"
146 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
147 | integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
148 |
149 | anymatch@~3.1.2:
150 | version "3.1.3"
151 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
152 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
153 | dependencies:
154 | normalize-path "^3.0.0"
155 | picomatch "^2.0.4"
156 |
157 | arg@^4.1.0:
158 | version "4.1.3"
159 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
160 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
161 |
162 | array-flatten@1.1.1:
163 | version "1.1.1"
164 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
165 | integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
166 |
167 | async@^2.6.4:
168 | version "2.6.4"
169 | resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
170 | integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
171 | dependencies:
172 | lodash "^4.17.14"
173 |
174 | asynckit@^0.4.0:
175 | version "0.4.0"
176 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
177 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
178 |
179 | atomic-sleep@^1.0.0:
180 | version "1.0.0"
181 | resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b"
182 | integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==
183 |
184 | axios@^1.3.3:
185 | version "1.3.3"
186 | resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.3.tgz#e7011384ba839b885007c9c9fae1ff23dceb295b"
187 | integrity sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==
188 | dependencies:
189 | follow-redirects "^1.15.0"
190 | form-data "^4.0.0"
191 | proxy-from-env "^1.1.0"
192 |
193 | balanced-match@^1.0.0:
194 | version "1.0.2"
195 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
196 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
197 |
198 | base64-js@^1.3.1:
199 | version "1.5.1"
200 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
201 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
202 |
203 | binary-extensions@^2.0.0:
204 | version "2.2.0"
205 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
206 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
207 |
208 | body-parser@1.20.1:
209 | version "1.20.1"
210 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
211 | integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
212 | dependencies:
213 | bytes "3.1.2"
214 | content-type "~1.0.4"
215 | debug "2.6.9"
216 | depd "2.0.0"
217 | destroy "1.2.0"
218 | http-errors "2.0.0"
219 | iconv-lite "0.4.24"
220 | on-finished "2.4.1"
221 | qs "6.11.0"
222 | raw-body "2.5.1"
223 | type-is "~1.6.18"
224 | unpipe "1.0.0"
225 |
226 | brace-expansion@^1.1.7:
227 | version "1.1.11"
228 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
229 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
230 | dependencies:
231 | balanced-match "^1.0.0"
232 | concat-map "0.0.1"
233 |
234 | brace-expansion@^2.0.1:
235 | version "2.0.1"
236 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
237 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
238 | dependencies:
239 | balanced-match "^1.0.0"
240 |
241 | braces@~3.0.2:
242 | version "3.0.2"
243 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
244 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
245 | dependencies:
246 | fill-range "^7.0.1"
247 |
248 | buffer@^6.0.3:
249 | version "6.0.3"
250 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
251 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
252 | dependencies:
253 | base64-js "^1.3.1"
254 | ieee754 "^1.2.1"
255 |
256 | bytes@3.1.2:
257 | version "3.1.2"
258 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
259 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
260 |
261 | call-bind@^1.0.0:
262 | version "1.0.2"
263 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
264 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
265 | dependencies:
266 | function-bind "^1.1.1"
267 | get-intrinsic "^1.0.2"
268 |
269 | caller@^1.0.0:
270 | version "1.1.0"
271 | resolved "https://registry.yarnpkg.com/caller/-/caller-1.1.0.tgz#46228555cfecb57d82bcd173b493f87cee9680fe"
272 | integrity sha512-n+21IZC3j06YpCWaxmUy5AnVqhmCIM2bQtqQyy00HJlmStRt6kwDX5F9Z97pqwAB+G/tgSz6q/kUBbNyQzIubw==
273 |
274 | chokidar@^3.5.2:
275 | version "3.5.3"
276 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
277 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
278 | dependencies:
279 | anymatch "~3.1.2"
280 | braces "~3.0.2"
281 | glob-parent "~5.1.2"
282 | is-binary-path "~2.1.0"
283 | is-glob "~4.0.1"
284 | normalize-path "~3.0.0"
285 | readdirp "~3.6.0"
286 | optionalDependencies:
287 | fsevents "~2.3.2"
288 |
289 | colorette@^2.0.7:
290 | version "2.0.19"
291 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
292 | integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
293 |
294 | colors@1.0.x:
295 | version "1.0.3"
296 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
297 | integrity sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==
298 |
299 | combined-stream@^1.0.8:
300 | version "1.0.8"
301 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
302 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
303 | dependencies:
304 | delayed-stream "~1.0.0"
305 |
306 | concat-map@0.0.1:
307 | version "0.0.1"
308 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
309 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
310 |
311 | content-disposition@0.5.4:
312 | version "0.5.4"
313 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
314 | integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
315 | dependencies:
316 | safe-buffer "5.2.1"
317 |
318 | content-type@~1.0.4:
319 | version "1.0.5"
320 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
321 | integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
322 |
323 | cookie-signature@1.0.6:
324 | version "1.0.6"
325 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
326 | integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
327 |
328 | cookie@0.5.0:
329 | version "0.5.0"
330 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
331 | integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
332 |
333 | cors@^2.8.5:
334 | version "2.8.5"
335 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
336 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
337 | dependencies:
338 | object-assign "^4"
339 | vary "^1"
340 |
341 | create-require@^1.1.0:
342 | version "1.1.1"
343 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
344 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
345 |
346 | cycle@1.0.x:
347 | version "1.0.3"
348 | resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
349 | integrity sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==
350 |
351 | dateformat@^4.6.3:
352 | version "4.6.3"
353 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5"
354 | integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==
355 |
356 | debug@2.6.9:
357 | version "2.6.9"
358 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
359 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
360 | dependencies:
361 | ms "2.0.0"
362 |
363 | debug@^3.2.7:
364 | version "3.2.7"
365 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
366 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
367 | dependencies:
368 | ms "^2.1.1"
369 |
370 | delayed-stream@~1.0.0:
371 | version "1.0.0"
372 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
373 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
374 |
375 | depd@2.0.0:
376 | version "2.0.0"
377 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
378 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
379 |
380 | destroy@1.2.0:
381 | version "1.2.0"
382 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
383 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
384 |
385 | diff@^4.0.1:
386 | version "4.0.2"
387 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
388 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
389 |
390 | dotenv@^16.0.3:
391 | version "16.0.3"
392 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07"
393 | integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==
394 |
395 | ee-first@1.1.1:
396 | version "1.1.1"
397 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
398 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
399 |
400 | encodeurl@~1.0.2:
401 | version "1.0.2"
402 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
403 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
404 |
405 | end-of-stream@^1.1.0:
406 | version "1.4.4"
407 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
408 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
409 | dependencies:
410 | once "^1.4.0"
411 |
412 | escape-html@~1.0.3:
413 | version "1.0.3"
414 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
415 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
416 |
417 | etag@~1.8.1:
418 | version "1.8.1"
419 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
420 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
421 |
422 | event-target-shim@^5.0.0:
423 | version "5.0.1"
424 | resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
425 | integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
426 |
427 | events@^3.3.0:
428 | version "3.3.0"
429 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
430 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
431 |
432 | express@^4.18.2:
433 | version "4.18.2"
434 | resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
435 | integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
436 | dependencies:
437 | accepts "~1.3.8"
438 | array-flatten "1.1.1"
439 | body-parser "1.20.1"
440 | content-disposition "0.5.4"
441 | content-type "~1.0.4"
442 | cookie "0.5.0"
443 | cookie-signature "1.0.6"
444 | debug "2.6.9"
445 | depd "2.0.0"
446 | encodeurl "~1.0.2"
447 | escape-html "~1.0.3"
448 | etag "~1.8.1"
449 | finalhandler "1.2.0"
450 | fresh "0.5.2"
451 | http-errors "2.0.0"
452 | merge-descriptors "1.0.1"
453 | methods "~1.1.2"
454 | on-finished "2.4.1"
455 | parseurl "~1.3.3"
456 | path-to-regexp "0.1.7"
457 | proxy-addr "~2.0.7"
458 | qs "6.11.0"
459 | range-parser "~1.2.1"
460 | safe-buffer "5.2.1"
461 | send "0.18.0"
462 | serve-static "1.15.0"
463 | setprototypeof "1.2.0"
464 | statuses "2.0.1"
465 | type-is "~1.6.18"
466 | utils-merge "1.0.1"
467 | vary "~1.1.2"
468 |
469 | eyes@0.1.x:
470 | version "0.1.8"
471 | resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
472 | integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==
473 |
474 | fast-copy@^3.0.0:
475 | version "3.0.0"
476 | resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-3.0.0.tgz#875ebf33b13948ae012b6e51d33da5e6e7571ab8"
477 | integrity sha512-4HzS+9pQ5Yxtv13Lhs1Z1unMXamBdn5nA4bEi1abYpDNSpSp7ODYQ1KPMF6nTatfEzgH6/zPvXKU1zvHiUjWlA==
478 |
479 | fast-redact@^3.1.1:
480 | version "3.1.2"
481 | resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.1.2.tgz#d58e69e9084ce9fa4c1a6fa98a3e1ecf5d7839aa"
482 | integrity sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==
483 |
484 | fast-safe-stringify@^2.1.1:
485 | version "2.1.1"
486 | resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
487 | integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
488 |
489 | fill-range@^7.0.1:
490 | version "7.0.1"
491 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
492 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
493 | dependencies:
494 | to-regex-range "^5.0.1"
495 |
496 | finalhandler@1.2.0:
497 | version "1.2.0"
498 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
499 | integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
500 | dependencies:
501 | debug "2.6.9"
502 | encodeurl "~1.0.2"
503 | escape-html "~1.0.3"
504 | on-finished "2.4.1"
505 | parseurl "~1.3.3"
506 | statuses "2.0.1"
507 | unpipe "~1.0.0"
508 |
509 | follow-redirects@^1.15.0:
510 | version "1.15.2"
511 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
512 | integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
513 |
514 | form-data@^4.0.0:
515 | version "4.0.0"
516 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
517 | integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
518 | dependencies:
519 | asynckit "^0.4.0"
520 | combined-stream "^1.0.8"
521 | mime-types "^2.1.12"
522 |
523 | forwarded@0.2.0:
524 | version "0.2.0"
525 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
526 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
527 |
528 | fresh@0.5.2:
529 | version "0.5.2"
530 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
531 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
532 |
533 | fs.realpath@^1.0.0:
534 | version "1.0.0"
535 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
536 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
537 |
538 | fsevents@~2.3.2:
539 | version "2.3.2"
540 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
541 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
542 |
543 | function-bind@^1.1.1:
544 | version "1.1.1"
545 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
546 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
547 |
548 | get-caller-file@^2.0.5:
549 | version "2.0.5"
550 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
551 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
552 |
553 | get-intrinsic@^1.0.2:
554 | version "1.2.0"
555 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f"
556 | integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==
557 | dependencies:
558 | function-bind "^1.1.1"
559 | has "^1.0.3"
560 | has-symbols "^1.0.3"
561 |
562 | glob-parent@~5.1.2:
563 | version "5.1.2"
564 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
565 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
566 | dependencies:
567 | is-glob "^4.0.1"
568 |
569 | glob@^8.0.0:
570 | version "8.1.0"
571 | resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
572 | integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
573 | dependencies:
574 | fs.realpath "^1.0.0"
575 | inflight "^1.0.4"
576 | inherits "2"
577 | minimatch "^5.0.1"
578 | once "^1.3.0"
579 |
580 | has-flag@^3.0.0:
581 | version "3.0.0"
582 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
583 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
584 |
585 | has-symbols@^1.0.3:
586 | version "1.0.3"
587 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
588 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
589 |
590 | has@^1.0.3:
591 | version "1.0.3"
592 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
593 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
594 | dependencies:
595 | function-bind "^1.1.1"
596 |
597 | help-me@^4.0.1:
598 | version "4.2.0"
599 | resolved "https://registry.yarnpkg.com/help-me/-/help-me-4.2.0.tgz#50712bfd799ff1854ae1d312c36eafcea85b0563"
600 | integrity sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==
601 | dependencies:
602 | glob "^8.0.0"
603 | readable-stream "^3.6.0"
604 |
605 | http-errors@2.0.0:
606 | version "2.0.0"
607 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
608 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
609 | dependencies:
610 | depd "2.0.0"
611 | inherits "2.0.4"
612 | setprototypeof "1.2.0"
613 | statuses "2.0.1"
614 | toidentifier "1.0.1"
615 |
616 | iconv-lite@0.4.24:
617 | version "0.4.24"
618 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
619 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
620 | dependencies:
621 | safer-buffer ">= 2.1.2 < 3"
622 |
623 | ieee754@^1.2.1:
624 | version "1.2.1"
625 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
626 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
627 |
628 | ignore-by-default@^1.0.1:
629 | version "1.0.1"
630 | resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
631 | integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==
632 |
633 | inflight@^1.0.4:
634 | version "1.0.6"
635 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
636 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
637 | dependencies:
638 | once "^1.3.0"
639 | wrappy "1"
640 |
641 | inherits@2, inherits@2.0.4, inherits@^2.0.3:
642 | version "2.0.4"
643 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
644 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
645 |
646 | ipaddr.js@1.9.1:
647 | version "1.9.1"
648 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
649 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
650 |
651 | is-binary-path@~2.1.0:
652 | version "2.1.0"
653 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
654 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
655 | dependencies:
656 | binary-extensions "^2.0.0"
657 |
658 | is-extglob@^2.1.1:
659 | version "2.1.1"
660 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
661 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
662 |
663 | is-glob@^4.0.1, is-glob@~4.0.1:
664 | version "4.0.3"
665 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
666 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
667 | dependencies:
668 | is-extglob "^2.1.1"
669 |
670 | is-number@^7.0.0:
671 | version "7.0.0"
672 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
673 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
674 |
675 | isstream@0.1.x:
676 | version "0.1.2"
677 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
678 | integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
679 |
680 | joycon@^3.1.1:
681 | version "3.1.1"
682 | resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03"
683 | integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==
684 |
685 | lodash-node@^2.4.1:
686 | version "2.4.1"
687 | resolved "https://registry.yarnpkg.com/lodash-node/-/lodash-node-2.4.1.tgz#ea82f7b100c733d1a42af76801e506105e2a80ec"
688 | integrity sha512-egEt8eNQp2kZWRmngahiqMoDCDCENv3uM188S7Ed5t4k3v6RrLELXC+FqLNMUnhCo7gvQX3G1V8opK/Lcslahg==
689 |
690 | lodash@^4.17.14:
691 | version "4.17.21"
692 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
693 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
694 |
695 | make-error@^1.1.1:
696 | version "1.3.6"
697 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
698 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
699 |
700 | media-typer@0.3.0:
701 | version "0.3.0"
702 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
703 | integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
704 |
705 | merge-descriptors@1.0.1:
706 | version "1.0.1"
707 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
708 | integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
709 |
710 | methods@~1.1.2:
711 | version "1.1.2"
712 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
713 | integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
714 |
715 | mime-db@1.52.0:
716 | version "1.52.0"
717 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
718 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
719 |
720 | mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34:
721 | version "2.1.35"
722 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
723 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
724 | dependencies:
725 | mime-db "1.52.0"
726 |
727 | mime@1.6.0:
728 | version "1.6.0"
729 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
730 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
731 |
732 | minimatch@^3.1.2:
733 | version "3.1.2"
734 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
735 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
736 | dependencies:
737 | brace-expansion "^1.1.7"
738 |
739 | minimatch@^5.0.1:
740 | version "5.1.6"
741 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
742 | integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
743 | dependencies:
744 | brace-expansion "^2.0.1"
745 |
746 | minimist@^1.2.6:
747 | version "1.2.8"
748 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
749 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
750 |
751 | ms@2.0.0:
752 | version "2.0.0"
753 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
754 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
755 |
756 | ms@2.1.3, ms@^2.1.1:
757 | version "2.1.3"
758 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
759 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
760 |
761 | negotiator@0.6.3:
762 | version "0.6.3"
763 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
764 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
765 |
766 | nodemon@^2.0.20:
767 | version "2.0.20"
768 | resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.20.tgz#e3537de768a492e8d74da5c5813cb0c7486fc701"
769 | integrity sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==
770 | dependencies:
771 | chokidar "^3.5.2"
772 | debug "^3.2.7"
773 | ignore-by-default "^1.0.1"
774 | minimatch "^3.1.2"
775 | pstree.remy "^1.1.8"
776 | semver "^5.7.1"
777 | simple-update-notifier "^1.0.7"
778 | supports-color "^5.5.0"
779 | touch "^3.1.0"
780 | undefsafe "^2.0.5"
781 |
782 | nopt@~1.0.10:
783 | version "1.0.10"
784 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
785 | integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==
786 | dependencies:
787 | abbrev "1"
788 |
789 | normalize-path@^3.0.0, normalize-path@~3.0.0:
790 | version "3.0.0"
791 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
792 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
793 |
794 | object-assign@^4:
795 | version "4.1.1"
796 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
797 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
798 |
799 | object-inspect@^1.9.0:
800 | version "1.12.3"
801 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9"
802 | integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==
803 |
804 | on-exit-leak-free@^2.1.0:
805 | version "2.1.0"
806 | resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz#5c703c968f7e7f851885f6459bf8a8a57edc9cc4"
807 | integrity sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==
808 |
809 | on-finished@2.4.1:
810 | version "2.4.1"
811 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
812 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
813 | dependencies:
814 | ee-first "1.1.1"
815 |
816 | once@^1.3.0, once@^1.3.1, once@^1.4.0:
817 | version "1.4.0"
818 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
819 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
820 | dependencies:
821 | wrappy "1"
822 |
823 | parseurl@~1.3.3:
824 | version "1.3.3"
825 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
826 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
827 |
828 | path-to-regexp@0.1.7:
829 | version "0.1.7"
830 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
831 | integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
832 |
833 | picomatch@^2.0.4, picomatch@^2.2.1:
834 | version "2.3.1"
835 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
836 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
837 |
838 | pine@^1.1.1:
839 | version "1.1.1"
840 | resolved "https://registry.yarnpkg.com/pine/-/pine-1.1.1.tgz#4a74df92601096a8608742bc4b792c9d680eb865"
841 | integrity sha512-Xk+dW+1oCpPVjNgzg0PPrHamc7aCj9LM37Qwp8pxraWIW1JFlYExr3CBXEl0ghBG2L2cCcFp8JHPDC55Dv+7iw==
842 | dependencies:
843 | caller "^1.0.0"
844 | lodash-node "^2.4.1"
845 | winston "^2.2.0"
846 |
847 | pino-abstract-transport@^1.0.0, pino-abstract-transport@v1.0.0:
848 | version "1.0.0"
849 | resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz#cc0d6955fffcadb91b7b49ef220a6cc111d48bb3"
850 | integrity sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==
851 | dependencies:
852 | readable-stream "^4.0.0"
853 | split2 "^4.0.0"
854 |
855 | pino-http@^8.3.3:
856 | version "8.3.3"
857 | resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-8.3.3.tgz#2b140e734bfc6babe0df272a43bb8f36f2b525c0"
858 | integrity sha512-p4umsNIXXVu95HD2C8wie/vXH7db5iGRpc+yj1/ZQ3sRtTQLXNjoS6Be5+eI+rQbqCRxen/7k/KSN+qiZubGDw==
859 | dependencies:
860 | get-caller-file "^2.0.5"
861 | pino "^8.0.0"
862 | pino-std-serializers "^6.0.0"
863 | process-warning "^2.0.0"
864 |
865 | pino-pretty@^9.2.0:
866 | version "9.2.0"
867 | resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-9.2.0.tgz#4a6bcc677533f4053acd841bd9ccc9be9122c8af"
868 | integrity sha512-7CeszmFqrUD08+JvtYcFXowNE7duFlE1XScmR41qTMbwQOhn7gijYYrRb5udH+z8xq4+A8vN8rQNYVPCTfzmGw==
869 | dependencies:
870 | colorette "^2.0.7"
871 | dateformat "^4.6.3"
872 | fast-copy "^3.0.0"
873 | fast-safe-stringify "^2.1.1"
874 | help-me "^4.0.1"
875 | joycon "^3.1.1"
876 | minimist "^1.2.6"
877 | on-exit-leak-free "^2.1.0"
878 | pino-abstract-transport "^1.0.0"
879 | pump "^3.0.0"
880 | readable-stream "^4.0.0"
881 | secure-json-parse "^2.4.0"
882 | sonic-boom "^3.0.0"
883 | strip-json-comments "^3.1.1"
884 |
885 | pino-std-serializers@^6.0.0:
886 | version "6.1.0"
887 | resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-6.1.0.tgz#307490fd426eefc95e06067e85d8558603e8e844"
888 | integrity sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g==
889 |
890 | pino@^8.0.0:
891 | version "8.10.0"
892 | resolved "https://registry.yarnpkg.com/pino/-/pino-8.10.0.tgz#fe35a3fe90554630b0254d3f810f6fae27c38990"
893 | integrity sha512-ODfIe+giJtQGsvNAEj5/sHHpL3TFBg161JBH4W62Hc0l0PJjsDFD1R7meLI4PZ2aoHDJznxFNShkJcaG/qJToQ==
894 | dependencies:
895 | atomic-sleep "^1.0.0"
896 | fast-redact "^3.1.1"
897 | on-exit-leak-free "^2.1.0"
898 | pino-abstract-transport v1.0.0
899 | pino-std-serializers "^6.0.0"
900 | process-warning "^2.0.0"
901 | quick-format-unescaped "^4.0.3"
902 | real-require "^0.2.0"
903 | safe-stable-stringify "^2.3.1"
904 | sonic-boom "^3.1.0"
905 | thread-stream "^2.0.0"
906 |
907 | process-warning@^2.0.0:
908 | version "2.1.0"
909 | resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-2.1.0.tgz#1e60e3bfe8183033bbc1e702c2da74f099422d1a"
910 | integrity sha512-9C20RLxrZU/rFnxWncDkuF6O999NdIf3E1ws4B0ZeY3sRVPzWBMsYDE2lxjxhiXxg464cQTgKUGm8/i6y2YGXg==
911 |
912 | process@^0.11.10:
913 | version "0.11.10"
914 | resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
915 | integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
916 |
917 | proxy-addr@~2.0.7:
918 | version "2.0.7"
919 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
920 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
921 | dependencies:
922 | forwarded "0.2.0"
923 | ipaddr.js "1.9.1"
924 |
925 | proxy-from-env@^1.1.0:
926 | version "1.1.0"
927 | resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
928 | integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
929 |
930 | pstree.remy@^1.1.8:
931 | version "1.1.8"
932 | resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
933 | integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
934 |
935 | pump@^3.0.0:
936 | version "3.0.0"
937 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
938 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
939 | dependencies:
940 | end-of-stream "^1.1.0"
941 | once "^1.3.1"
942 |
943 | qs@6.11.0:
944 | version "6.11.0"
945 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
946 | integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
947 | dependencies:
948 | side-channel "^1.0.4"
949 |
950 | quick-format-unescaped@^4.0.3:
951 | version "4.0.4"
952 | resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7"
953 | integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==
954 |
955 | range-parser@~1.2.1:
956 | version "1.2.1"
957 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
958 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
959 |
960 | raw-body@2.5.1:
961 | version "2.5.1"
962 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
963 | integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
964 | dependencies:
965 | bytes "3.1.2"
966 | http-errors "2.0.0"
967 | iconv-lite "0.4.24"
968 | unpipe "1.0.0"
969 |
970 | readable-stream@^3.6.0:
971 | version "3.6.0"
972 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
973 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
974 | dependencies:
975 | inherits "^2.0.3"
976 | string_decoder "^1.1.1"
977 | util-deprecate "^1.0.1"
978 |
979 | readable-stream@^4.0.0:
980 | version "4.3.0"
981 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.3.0.tgz#0914d0c72db03b316c9733bb3461d64a3cc50cba"
982 | integrity sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==
983 | dependencies:
984 | abort-controller "^3.0.0"
985 | buffer "^6.0.3"
986 | events "^3.3.0"
987 | process "^0.11.10"
988 |
989 | readdirp@~3.6.0:
990 | version "3.6.0"
991 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
992 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
993 | dependencies:
994 | picomatch "^2.2.1"
995 |
996 | real-require@^0.2.0:
997 | version "0.2.0"
998 | resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78"
999 | integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==
1000 |
1001 | safe-buffer@5.2.1, safe-buffer@~5.2.0:
1002 | version "5.2.1"
1003 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
1004 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
1005 |
1006 | safe-stable-stringify@^2.3.1:
1007 | version "2.4.2"
1008 | resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz#ec7b037768098bf65310d1d64370de0dc02353aa"
1009 | integrity sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==
1010 |
1011 | "safer-buffer@>= 2.1.2 < 3":
1012 | version "2.1.2"
1013 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
1014 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
1015 |
1016 | secure-json-parse@^2.4.0:
1017 | version "2.7.0"
1018 | resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862"
1019 | integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==
1020 |
1021 | semver@^5.7.1:
1022 | version "5.7.1"
1023 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
1024 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
1025 |
1026 | semver@~7.0.0:
1027 | version "7.0.0"
1028 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
1029 | integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
1030 |
1031 | send@0.18.0:
1032 | version "0.18.0"
1033 | resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
1034 | integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
1035 | dependencies:
1036 | debug "2.6.9"
1037 | depd "2.0.0"
1038 | destroy "1.2.0"
1039 | encodeurl "~1.0.2"
1040 | escape-html "~1.0.3"
1041 | etag "~1.8.1"
1042 | fresh "0.5.2"
1043 | http-errors "2.0.0"
1044 | mime "1.6.0"
1045 | ms "2.1.3"
1046 | on-finished "2.4.1"
1047 | range-parser "~1.2.1"
1048 | statuses "2.0.1"
1049 |
1050 | serve-static@1.15.0:
1051 | version "1.15.0"
1052 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
1053 | integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
1054 | dependencies:
1055 | encodeurl "~1.0.2"
1056 | escape-html "~1.0.3"
1057 | parseurl "~1.3.3"
1058 | send "0.18.0"
1059 |
1060 | setprototypeof@1.2.0:
1061 | version "1.2.0"
1062 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
1063 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
1064 |
1065 | side-channel@^1.0.4:
1066 | version "1.0.4"
1067 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
1068 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
1069 | dependencies:
1070 | call-bind "^1.0.0"
1071 | get-intrinsic "^1.0.2"
1072 | object-inspect "^1.9.0"
1073 |
1074 | simple-update-notifier@^1.0.7:
1075 | version "1.1.0"
1076 | resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82"
1077 | integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==
1078 | dependencies:
1079 | semver "~7.0.0"
1080 |
1081 | sonic-boom@^3.0.0, sonic-boom@^3.1.0:
1082 | version "3.2.1"
1083 | resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.2.1.tgz#972ceab831b5840a08a002fa95a672008bda1c38"
1084 | integrity sha512-iITeTHxy3B9FGu8aVdiDXUVAcHMF9Ss0cCsAOo2HfCrmVGT3/DT5oYaeu0M/YKZDlKTvChEyPq0zI9Hf33EX6A==
1085 | dependencies:
1086 | atomic-sleep "^1.0.0"
1087 |
1088 | split2@^4.0.0:
1089 | version "4.1.0"
1090 | resolved "https://registry.yarnpkg.com/split2/-/split2-4.1.0.tgz#101907a24370f85bb782f08adaabe4e281ecf809"
1091 | integrity sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==
1092 |
1093 | stack-trace@0.0.x:
1094 | version "0.0.10"
1095 | resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
1096 | integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==
1097 |
1098 | statuses@2.0.1:
1099 | version "2.0.1"
1100 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
1101 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
1102 |
1103 | string_decoder@^1.1.1:
1104 | version "1.3.0"
1105 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
1106 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
1107 | dependencies:
1108 | safe-buffer "~5.2.0"
1109 |
1110 | strip-json-comments@^3.1.1:
1111 | version "3.1.1"
1112 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
1113 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
1114 |
1115 | supports-color@^5.5.0:
1116 | version "5.5.0"
1117 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
1118 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
1119 | dependencies:
1120 | has-flag "^3.0.0"
1121 |
1122 | thread-stream@^2.0.0:
1123 | version "2.3.0"
1124 | resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-2.3.0.tgz#4fc07fb39eff32ae7bad803cb7dd9598349fed33"
1125 | integrity sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==
1126 | dependencies:
1127 | real-require "^0.2.0"
1128 |
1129 | to-regex-range@^5.0.1:
1130 | version "5.0.1"
1131 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
1132 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
1133 | dependencies:
1134 | is-number "^7.0.0"
1135 |
1136 | toidentifier@1.0.1:
1137 | version "1.0.1"
1138 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
1139 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
1140 |
1141 | touch@^3.1.0:
1142 | version "3.1.0"
1143 | resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b"
1144 | integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==
1145 | dependencies:
1146 | nopt "~1.0.10"
1147 |
1148 | ts-node@^10.9.1:
1149 | version "10.9.1"
1150 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
1151 | integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
1152 | dependencies:
1153 | "@cspotcode/source-map-support" "^0.8.0"
1154 | "@tsconfig/node10" "^1.0.7"
1155 | "@tsconfig/node12" "^1.0.7"
1156 | "@tsconfig/node14" "^1.0.0"
1157 | "@tsconfig/node16" "^1.0.2"
1158 | acorn "^8.4.1"
1159 | acorn-walk "^8.1.1"
1160 | arg "^4.1.0"
1161 | create-require "^1.1.0"
1162 | diff "^4.0.1"
1163 | make-error "^1.1.1"
1164 | v8-compile-cache-lib "^3.0.1"
1165 | yn "3.1.1"
1166 |
1167 | type-is@~1.6.18:
1168 | version "1.6.18"
1169 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
1170 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
1171 | dependencies:
1172 | media-typer "0.3.0"
1173 | mime-types "~2.1.24"
1174 |
1175 | typescript@^4.9.5:
1176 | version "4.9.5"
1177 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
1178 | integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
1179 |
1180 | undefsafe@^2.0.5:
1181 | version "2.0.5"
1182 | resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
1183 | integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
1184 |
1185 | unpipe@1.0.0, unpipe@~1.0.0:
1186 | version "1.0.0"
1187 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
1188 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
1189 |
1190 | util-deprecate@^1.0.1:
1191 | version "1.0.2"
1192 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
1193 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
1194 |
1195 | utils-merge@1.0.1:
1196 | version "1.0.1"
1197 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
1198 | integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
1199 |
1200 | v8-compile-cache-lib@^3.0.1:
1201 | version "3.0.1"
1202 | resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
1203 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
1204 |
1205 | vary@^1, vary@~1.1.2:
1206 | version "1.1.2"
1207 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
1208 | integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
1209 |
1210 | winston@^2.2.0:
1211 | version "2.4.7"
1212 | resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.7.tgz#5791fe08ea7e90db090f1cb31ef98f32531062f1"
1213 | integrity sha512-vLB4BqzCKDnnZH9PHGoS2ycawueX4HLqENXQitvFHczhgW2vFpSOn31LZtVr1KU8YTw7DS4tM+cqyovxo8taVg==
1214 | dependencies:
1215 | async "^2.6.4"
1216 | colors "1.0.x"
1217 | cycle "1.0.x"
1218 | eyes "0.1.x"
1219 | isstream "0.1.x"
1220 | stack-trace "0.0.x"
1221 |
1222 | wrappy@1:
1223 | version "1.0.2"
1224 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1225 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
1226 |
1227 | yn@3.1.1:
1228 | version "3.1.1"
1229 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
1230 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
1231 |
--------------------------------------------------------------------------------