├── .gitignore ├── .npmignore ├── .prettierrc.json ├── README.md ├── src ├── index.ts ├── types.ts ├── utils │ ├── pda.ts │ ├── constants.ts │ ├── tick.ts │ ├── pool.ts │ ├── tickQuery.ts │ └── math.ts ├── amm.ts └── raydiumCLMM.ts ├── tsconfig.json ├── tsup.config.ts ├── .eslintrc.js ├── package.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /src 3 | tsconfig.json 4 | .cache 5 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "singleQuote": true, 4 | "semi": true 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # raydium-clmm-sdk 2 | 3 | A modified version of Raydium's CLMM sdk 4 | 5 | TODO: 6 | 7 | - Use IDL rather than @solana/buffer-layout (wen IDL?) 8 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './amm'; 2 | export * from './utils/pda'; 3 | export * from './utils/tick'; 4 | export * from './types'; 5 | export * from './idl/amm_v3'; 6 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { BN, IdlAccounts, IdlTypes } from '@project-serum/anchor'; 2 | import { AmmV3 } from './idl/amm_v3'; 3 | 4 | export type AmmConfig = IdlAccounts['ammConfig']; 5 | export type PoolState = IdlAccounts['poolState']; 6 | 7 | export type TickArrayState = IdlAccounts['tickArrayState']; 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "esModuleInterop": true, 6 | "declaration": true, 7 | "outDir": "./lib", 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true 10 | }, 11 | "include": ["src"], 12 | "exclude": ["node_modules", "src/raydiumCLMM.ts"] 13 | } -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig((options) => ({ 4 | entry: ['src/index.ts'], 5 | format: ['esm', 'cjs'], 6 | splitting: true, 7 | sourcemap: false, 8 | minify: true, 9 | clean: true, 10 | skipNodeModulesBundle: true, 11 | dts: true, 12 | outDir: 'lib', 13 | external: ['node_modules', 'src/raydiumCLMM.ts'], 14 | })); 15 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | }, 6 | extends: [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/recommended", 9 | "prettier", 10 | ], 11 | plugins: [ 12 | "@typescript-eslint" 13 | ], 14 | parser: "@typescript-eslint/parser", 15 | parserOptions: { 16 | "sourceType": "module", 17 | "project": "./tsconfig.json" 18 | }, 19 | root: true, 20 | rules: { 21 | "@typescript-eslint/ban-ts-comment": "off", 22 | "@typescript-eslint/no-explicit-any": 0, 23 | "@typescript-eslint/no-non-null-assertion": 0, 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@jup-ag/raydium-clmm-sdk", 3 | "version": "1.0.6", 4 | "description": "", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "module": "lib/index.mjs", 8 | "files": [ 9 | "lib" 10 | ], 11 | "scripts": { 12 | "build": "tsup" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "MIT", 17 | "devDependencies": { 18 | "tsup": "^6.4.0", 19 | "typescript": "^4.4.4" 20 | }, 21 | "dependencies": { 22 | "@project-serum/anchor": "0.24.2", 23 | "@project-serum/borsh": "^0.2.5", 24 | "@solana/spl-token": "0.1.8", 25 | "@solana/web3.js": "^1.66.2", 26 | "decimal.js": "^10.3.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/pda.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from '@solana/web3.js'; 2 | 3 | function i32ToBytes(num: number) { 4 | const arr = new ArrayBuffer(4); 5 | const view = new DataView(arr); 6 | view.setInt32(0, num, false); 7 | return new Uint8Array(arr); 8 | } 9 | 10 | const TICK_ARRAY_SEED = Buffer.from("tick_array", "utf8"); 11 | 12 | function findProgramAddress( 13 | seeds: Array, 14 | programId: PublicKey 15 | ) { 16 | const [publicKey, nonce] = PublicKey.findProgramAddressSync( 17 | seeds, 18 | programId 19 | ) 20 | return { publicKey, nonce } 21 | } 22 | 23 | export function getPdaTickArrayAddress( 24 | programId: PublicKey, 25 | poolId: PublicKey, 26 | startIndex: number 27 | ) { 28 | const { publicKey, nonce } = findProgramAddress( 29 | [TICK_ARRAY_SEED, poolId.toBuffer(), i32ToBytes(startIndex)], 30 | programId 31 | ); 32 | return { publicKey, nonce }; 33 | } 34 | -------------------------------------------------------------------------------- /src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from '@solana/web3.js'; 2 | import BN from 'bn.js'; 3 | 4 | export const ZERO = new BN(0); 5 | export const ONE = new BN(1); 6 | export const NEGATIVE_ONE = new BN(-1); 7 | 8 | export const Q64 = new BN(1).shln(64); 9 | export const Q128 = new BN(1).shln(128); 10 | 11 | export const MaxU64 = Q64.sub(ONE); 12 | 13 | export const U64Resolution = 64; 14 | 15 | export const MaxUint128 = Q128.subn(1); 16 | 17 | export const MIN_TICK = -307200; 18 | export const MAX_TICK = -MIN_TICK; 19 | 20 | export const MIN_SQRT_PRICE_X64: BN = new BN('3939943522091'); 21 | export const MAX_SQRT_PRICE_X64: BN = new BN('86367321006760116002434269'); 22 | 23 | export const MIN_TICK_ARRAY_START_INDEX = -307200; 24 | export const MAX_TICK_ARRAY_START_INDEX = 306600; 25 | 26 | export const BIT_PRECISION = 14; 27 | export const LOG_B_2_X32 = '59543866431248'; 28 | export const LOG_B_P_ERR_MARGIN_LOWER_X64 = '184467440737095516'; 29 | export const LOG_B_P_ERR_MARGIN_UPPER_X64 = '15793534762490258745'; 30 | 31 | export const FEE_RATE_DENOMINATOR = new BN(10).pow(new BN(6)); 32 | 33 | export enum Fee { 34 | rate_500 = 500, // 500 / 10e6 = 0.0005 35 | rate_3000 = 3000, // 3000/ 10e6 = 0.003 36 | rate_10000 = 10000, // 10000 /10e6 = 0.01 37 | } 38 | export const TICK_SPACINGS: { [amount in Fee]: number } = { 39 | [Fee.rate_500]: 10, 40 | [Fee.rate_3000]: 60, 41 | [Fee.rate_10000]: 200, 42 | }; 43 | 44 | export const TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'); 45 | -------------------------------------------------------------------------------- /src/utils/tick.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from '@solana/web3.js'; 2 | import BN from 'bn.js'; 3 | import { TickArrayState } from '../types'; 4 | 5 | export const TICK_ARRAY_SIZE = 60; 6 | export const TICK_ARRAY_BITMAP_SIZE = 1024; 7 | 8 | export type Tick = { 9 | tick: number; 10 | liquidityNet: BN; 11 | liquidityGross: BN; 12 | feeGrowthOutsideX64A: BN; 13 | feeGrowthOutsideX64B: BN; 14 | rewardGrowthsOutsideX64: BN[]; 15 | }; 16 | 17 | export type TickArray = TickArrayState & { address: PublicKey }; 18 | 19 | export class TickUtils { 20 | public static getTickArrayStartIndexByTick(tickIndex: number, tickSpacing: number) { 21 | let startIndex: number = tickIndex / (TICK_ARRAY_SIZE * tickSpacing); 22 | if (tickIndex < 0 && tickIndex % (TICK_ARRAY_SIZE * tickSpacing) != 0) { 23 | startIndex = Math.ceil(startIndex) - 1; 24 | } else { 25 | startIndex = Math.floor(startIndex); 26 | } 27 | return startIndex * (tickSpacing * TICK_ARRAY_SIZE); 28 | } 29 | 30 | public static getTickArrayOffsetInBitmapByTick(tick: number, tickSpacing: number) { 31 | const multiplier = tickSpacing * TICK_ARRAY_SIZE; 32 | const compressed = Math.floor(tick / multiplier) + 512; 33 | return Math.abs(compressed); 34 | } 35 | 36 | public static checkTickArrayIsInitialized(bitmap: BN, tick: number, tickSpacing: number) { 37 | const multiplier = tickSpacing * TICK_ARRAY_SIZE; 38 | const compressed = Math.floor(tick / multiplier) + 512; 39 | const bit_pos = Math.abs(compressed); 40 | return { 41 | isInitialized: bitmap.testn(bit_pos), 42 | startIndex: (bit_pos - 512) * multiplier, 43 | }; 44 | } 45 | 46 | public static getNextTickArrayStartIndex(lastTickArrayStartIndex: number, tickSpacing: number, zeroForOne: boolean) { 47 | return zeroForOne 48 | ? lastTickArrayStartIndex - tickSpacing * TICK_ARRAY_SIZE 49 | : lastTickArrayStartIndex + tickSpacing * TICK_ARRAY_SIZE; 50 | } 51 | 52 | public static mergeTickArrayBitmap(bns: BN[]) { 53 | return bns[0] 54 | .add(bns[1].shln(64)) 55 | .add(bns[2].shln(128)) 56 | .add(bns[3].shln(192)) 57 | .add(bns[4].shln(256)) 58 | .add(bns[5].shln(320)) 59 | .add(bns[6].shln(384)) 60 | .add(bns[7].shln(448)) 61 | .add(bns[8].shln(512)) 62 | .add(bns[9].shln(576)) 63 | .add(bns[10].shln(640)) 64 | .add(bns[11].shln(704)) 65 | .add(bns[12].shln(768)) 66 | .add(bns[13].shln(832)) 67 | .add(bns[14].shln(896)) 68 | .add(bns[15].shln(960)); 69 | } 70 | 71 | public static getInitializedTickArrayInRange( 72 | tickArrayBitmap: BN, 73 | tickSpacing: number, 74 | tickArrayStartIndex: number, 75 | expectedCount: number 76 | ) { 77 | if (tickArrayStartIndex % (tickSpacing * TICK_ARRAY_SIZE) != 0) { 78 | throw new Error('Invild tickArrayStartIndex'); 79 | } 80 | const tickArrayOffset = Math.floor(tickArrayStartIndex / (tickSpacing * TICK_ARRAY_SIZE)) + 512; 81 | return [ 82 | // find right of currenct offset 83 | ...TickUtils.searchLowBitFromStart(tickArrayBitmap, tickArrayOffset - 1, 0, expectedCount, tickSpacing), 84 | 85 | // find left of current offset 86 | ...TickUtils.searchHightBitFromStart( 87 | tickArrayBitmap, 88 | tickArrayOffset, 89 | TICK_ARRAY_BITMAP_SIZE, 90 | expectedCount, 91 | tickSpacing 92 | ), 93 | ]; 94 | } 95 | 96 | public static searchLowBitFromStart( 97 | tickArrayBitmap: BN, 98 | start: number, 99 | end: number, 100 | expectedCount: number, 101 | tickSpacing: number 102 | ) { 103 | let fetchNum = 0; 104 | const result: number[] = []; 105 | for (let i = start; i >= end; i--) { 106 | if (tickArrayBitmap.shrn(i).and(new BN(1)).eqn(1)) { 107 | const nextStartIndex = (i - 512) * (tickSpacing * TICK_ARRAY_SIZE); 108 | result.push(nextStartIndex); 109 | fetchNum++; 110 | } 111 | if (fetchNum >= expectedCount) { 112 | break; 113 | } 114 | } 115 | return result; 116 | } 117 | 118 | public static searchHightBitFromStart( 119 | tickArrayBitmap: BN, 120 | start: number, 121 | end: number, 122 | expectedCount: number, 123 | tickSpacing: number 124 | ) { 125 | let fetchNum = 0; 126 | const result: number[] = []; 127 | for (let i = start; i < end; i++) { 128 | if (tickArrayBitmap.shrn(i).and(new BN(1)).eqn(1)) { 129 | const nextStartIndex = (i - 512) * (tickSpacing * TICK_ARRAY_SIZE); 130 | result.push(nextStartIndex); 131 | fetchNum++; 132 | } 133 | if (fetchNum >= expectedCount) { 134 | break; 135 | } 136 | } 137 | return result; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/utils/pool.ts: -------------------------------------------------------------------------------- 1 | import BN from 'bn.js'; 2 | 3 | import { PublicKey } from '@solana/web3.js'; 4 | 5 | import { AmmV3PoolInfo } from '../amm'; 6 | import { NEGATIVE_ONE } from './constants'; 7 | import { SwapMath } from './math'; 8 | import { getPdaTickArrayAddress } from './pda'; 9 | import { 10 | TickArray, 11 | TickUtils, 12 | } from './tick'; 13 | 14 | export class PoolUtils { 15 | public static getOutputAmountAndRemainAccounts( 16 | poolInfo: AmmV3PoolInfo, 17 | tickArrayCache: { [key: string]: TickArray }, 18 | inputTokenMint: PublicKey, 19 | inputAmount: BN, 20 | sqrtPriceLimitX64?: BN 21 | ) { 22 | const zeroForOne = inputTokenMint.equals(poolInfo.mintA.mint); 23 | 24 | const allNeededAccounts: PublicKey[] = []; 25 | const { 26 | isExist, 27 | startIndex: firstTickArrayStartIndex, 28 | nextAccountMeta, 29 | } = this.getFirstInitializedTickArray(poolInfo, zeroForOne); 30 | if (!isExist || firstTickArrayStartIndex === undefined || !nextAccountMeta) { 31 | throw new Error('Invalid tick array'); 32 | } 33 | 34 | try { 35 | const preTick = this.preInitializedTickArrayStartIndex(poolInfo, !zeroForOne) 36 | if (preTick.isExist) { 37 | const { publicKey: address } = getPdaTickArrayAddress( 38 | poolInfo.programId, 39 | poolInfo.id, 40 | preTick.nextStartIndex 41 | ); 42 | allNeededAccounts.push(address) 43 | } 44 | } catch (e) { } 45 | 46 | allNeededAccounts.push(nextAccountMeta); 47 | const { 48 | amountCalculated: outputAmount, 49 | accounts: reaminAccounts, 50 | sqrtPriceX64: executionPrice, 51 | feeAmount, 52 | } = SwapMath.swapCompute( 53 | poolInfo.programId, 54 | poolInfo.id, 55 | tickArrayCache, 56 | zeroForOne, 57 | poolInfo.ammConfig.tradeFeeRate, 58 | poolInfo.liquidity, 59 | poolInfo.tickCurrent, 60 | poolInfo.tickSpacing, 61 | poolInfo.sqrtPriceX64, 62 | inputAmount, 63 | firstTickArrayStartIndex, 64 | sqrtPriceLimitX64 65 | ); 66 | allNeededAccounts.push(...reaminAccounts); 67 | return { 68 | expectedAmountOut: outputAmount.mul(NEGATIVE_ONE), 69 | remainingAccounts: allNeededAccounts, 70 | executionPrice, 71 | feeAmount, 72 | }; 73 | } 74 | 75 | public static getInputAmountAndRemainAccounts( 76 | poolInfo: AmmV3PoolInfo, 77 | tickArrayCache: { [key: string]: TickArray }, 78 | outputTokenMint: PublicKey, 79 | outputAmount: BN, 80 | sqrtPriceLimitX64?: BN, 81 | ) { 82 | const zeroForOne = outputTokenMint.equals(poolInfo.mintB.mint); 83 | 84 | const allNeededAccounts: PublicKey[] = []; 85 | const { isExist, startIndex: firstTickArrayStartIndex, nextAccountMeta } = this.getFirstInitializedTickArray(poolInfo, zeroForOne); 86 | if (!isExist || firstTickArrayStartIndex === undefined || !nextAccountMeta) throw new Error("Invalid tick array"); 87 | 88 | try { 89 | const preTick = this.preInitializedTickArrayStartIndex(poolInfo, !zeroForOne) 90 | if (preTick.isExist) { 91 | const { publicKey: address } = getPdaTickArrayAddress( 92 | poolInfo.programId, 93 | poolInfo.id, 94 | preTick.nextStartIndex 95 | ); 96 | allNeededAccounts.push(address) 97 | } 98 | } catch (e) { } 99 | 100 | allNeededAccounts.push(nextAccountMeta); 101 | const { 102 | amountCalculated: inputAmount, 103 | accounts: reaminAccounts, 104 | sqrtPriceX64: executionPrice, 105 | feeAmount 106 | } = SwapMath.swapCompute( 107 | poolInfo.programId, 108 | poolInfo.id, 109 | tickArrayCache, 110 | zeroForOne, 111 | poolInfo.ammConfig.tradeFeeRate, 112 | poolInfo.liquidity, 113 | poolInfo.tickCurrent, 114 | poolInfo.tickSpacing, 115 | poolInfo.sqrtPriceX64, 116 | outputAmount.mul(NEGATIVE_ONE), 117 | firstTickArrayStartIndex, 118 | sqrtPriceLimitX64 119 | ); 120 | allNeededAccounts.push(...reaminAccounts); 121 | return { expectedAmountIn: inputAmount, remainingAccounts: allNeededAccounts, executionPrice, feeAmount }; 122 | } 123 | 124 | public static getFirstInitializedTickArray( 125 | poolInfo: AmmV3PoolInfo, 126 | zeroForOne: boolean 127 | ): 128 | | { isExist: true; startIndex: number; nextAccountMeta: PublicKey } 129 | | { isExist: false; startIndex: undefined; nextAccountMeta: undefined } { 130 | const tickArrayBitmap = TickUtils.mergeTickArrayBitmap(poolInfo.tickArrayBitmap); 131 | const { isInitialized, startIndex } = TickUtils.checkTickArrayIsInitialized( 132 | tickArrayBitmap, 133 | poolInfo.tickCurrent, 134 | poolInfo.tickSpacing 135 | ); 136 | if (isInitialized) { 137 | const { publicKey: address } = getPdaTickArrayAddress(poolInfo.programId, poolInfo.id, startIndex); 138 | return { 139 | isExist: true, 140 | startIndex, 141 | nextAccountMeta: address, 142 | }; 143 | } 144 | const { isExist, nextStartIndex } = this.nextInitializedTickArrayStartIndex(poolInfo, zeroForOne); 145 | if (isExist) { 146 | const { publicKey: address } = getPdaTickArrayAddress(poolInfo.programId, poolInfo.id, nextStartIndex); 147 | return { 148 | isExist: true, 149 | startIndex: nextStartIndex, 150 | nextAccountMeta: address, 151 | }; 152 | } 153 | return { isExist: false, nextAccountMeta: undefined, startIndex: undefined }; 154 | } 155 | 156 | public static nextInitializedTickArrayStartIndex(poolInfo: AmmV3PoolInfo, zeroForOne: boolean) { 157 | const tickArrayBitmap = TickUtils.mergeTickArrayBitmap(poolInfo.tickArrayBitmap); 158 | const currentOffset = TickUtils.getTickArrayOffsetInBitmapByTick(poolInfo.tickCurrent, poolInfo.tickSpacing); 159 | const result: number[] = zeroForOne 160 | ? TickUtils.searchLowBitFromStart(tickArrayBitmap, currentOffset - 1, 0, 1, poolInfo.tickSpacing) 161 | : TickUtils.searchHightBitFromStart(tickArrayBitmap, currentOffset, 1024, 1, poolInfo.tickSpacing); 162 | 163 | return result.length > 0 ? { isExist: true, nextStartIndex: result[0] } : { isExist: false, nextStartIndex: 0 }; 164 | } 165 | 166 | public static preInitializedTickArrayStartIndex( 167 | poolInfo: AmmV3PoolInfo, 168 | zeroForOne: boolean) { 169 | const tickArrayBitmap = TickUtils.mergeTickArrayBitmap( 170 | poolInfo.tickArrayBitmap 171 | ); 172 | const currentOffset = TickUtils.getTickArrayOffsetInBitmapByTick( 173 | poolInfo.tickCurrent, 174 | poolInfo.tickSpacing 175 | ); 176 | const result: number[] = zeroForOne ? TickUtils.searchLowBitFromStart( 177 | tickArrayBitmap, 178 | currentOffset - 1, 179 | 0, 180 | 1, 181 | poolInfo.tickSpacing 182 | ) : TickUtils.searchHightBitFromStart( 183 | tickArrayBitmap, 184 | currentOffset + 1, 185 | 1024, 186 | 1, 187 | poolInfo.tickSpacing 188 | ); 189 | 190 | return result.length > 0 ? { isExist: true, nextStartIndex: result[0] } : { isExist: false, nextStartIndex: 0 } 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/utils/tickQuery.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from '@solana/web3.js'; 2 | 3 | import { 4 | MAX_TICK_ARRAY_START_INDEX, 5 | MIN_TICK_ARRAY_START_INDEX, 6 | } from './constants'; 7 | import { getPdaTickArrayAddress } from './pda'; 8 | import { 9 | Tick, 10 | TICK_ARRAY_SIZE, 11 | TickArray, 12 | TickUtils, 13 | } from './tick'; 14 | 15 | export const FETCH_TICKARRAY_COUNT = 15 16 | 17 | export declare type PoolVars = { 18 | key: PublicKey 19 | tokenA: PublicKey 20 | tokenB: PublicKey 21 | fee: number 22 | } 23 | 24 | export class TickQuery { 25 | public static nextInitializedTick( 26 | programId: PublicKey, 27 | poolId: PublicKey, 28 | tickArrayCache: { [key: string]: TickArray }, 29 | tickIndex: number, 30 | tickSpacing: number, 31 | zeroForOne: boolean 32 | ) { 33 | let { 34 | initializedTick: nextTick, 35 | tickArrayAddress, 36 | tickArrayStartTickIndex, 37 | } = this.nextInitializedTickInOneArray( 38 | programId, 39 | poolId, 40 | tickArrayCache, 41 | tickIndex, 42 | tickSpacing, 43 | zeroForOne 44 | ) 45 | while (nextTick == undefined || nextTick.liquidityGross.lten(0)) { 46 | tickArrayStartTickIndex = TickUtils.getNextTickArrayStartIndex( 47 | tickArrayStartTickIndex, 48 | tickSpacing, 49 | zeroForOne 50 | ) 51 | if ( 52 | tickArrayStartTickIndex < MIN_TICK_ARRAY_START_INDEX || 53 | tickArrayStartTickIndex > MAX_TICK_ARRAY_START_INDEX 54 | ) { 55 | throw new Error('No enough initialized tickArray') 56 | } 57 | const cachedTickArray = tickArrayCache[tickArrayStartTickIndex] 58 | 59 | if (cachedTickArray === undefined) continue 60 | 61 | const { 62 | nextTick: _nextTick, 63 | tickArrayAddress: _tickArrayAddress, 64 | tickArrayStartTickIndex: _tickArrayStartTickIndex, 65 | } = this.firstInitializedTickInOneArray( 66 | programId, 67 | poolId, 68 | cachedTickArray, 69 | zeroForOne 70 | ) 71 | ;[nextTick, tickArrayAddress, tickArrayStartTickIndex] = [ 72 | _nextTick, 73 | _tickArrayAddress, 74 | _tickArrayStartTickIndex, 75 | ] 76 | } 77 | if (nextTick == undefined) { 78 | throw new Error('No invaild tickArray cache') 79 | } 80 | return { nextTick, tickArrayAddress, tickArrayStartTickIndex } 81 | } 82 | 83 | public static nextInitializedTickArray( 84 | programId: PublicKey, 85 | poolId: PublicKey, 86 | tickArrayCache: { [key: string]: TickArray }, 87 | tickIndex: number, 88 | tickSpacing: number, 89 | zeroForOne: boolean 90 | ) { 91 | let { 92 | initializedTick: nextTick, 93 | tickArrayAddress, 94 | tickArrayStartTickIndex, 95 | } = this.nextInitializedTickInOneArray( 96 | programId, 97 | poolId, 98 | tickArrayCache, 99 | tickIndex, 100 | tickSpacing, 101 | zeroForOne 102 | ); 103 | do { 104 | tickArrayStartTickIndex = TickUtils.getNextTickArrayStartIndex( 105 | tickArrayStartTickIndex, 106 | tickSpacing, 107 | zeroForOne 108 | ); 109 | if ( 110 | tickArrayStartTickIndex < MIN_TICK_ARRAY_START_INDEX || 111 | tickArrayStartTickIndex > MAX_TICK_ARRAY_START_INDEX 112 | ) { 113 | throw new Error("No enough initialized tickArray"); 114 | } 115 | const cachedTickArray = tickArrayCache[tickArrayStartTickIndex]; 116 | 117 | if (cachedTickArray === undefined) return undefined 118 | 119 | const { nextTick: _nextTick, tickArrayAddress: _tickArrayAddress, tickArrayStartTickIndex: _tickArrayStartTickIndex } = this.firstInitializedTickInOneArray( 120 | programId, 121 | poolId, 122 | cachedTickArray, 123 | zeroForOne 124 | ); 125 | [nextTick, tickArrayAddress, tickArrayStartTickIndex] = [_nextTick, _tickArrayAddress, _tickArrayStartTickIndex] 126 | } while (nextTick == undefined || nextTick.liquidityGross.lten(0)) 127 | 128 | if (nextTick == undefined) { 129 | throw new Error("No invaild tickArray cache"); 130 | } 131 | return { nextTick, tickArrayAddress, tickArrayStartTickIndex }; 132 | } 133 | 134 | public static firstInitializedTickInOneArray( 135 | programId: PublicKey, 136 | poolId: PublicKey, 137 | tickArray: TickArray, 138 | zeroForOne: boolean 139 | ) { 140 | let nextInitializedTick: Tick | undefined = undefined 141 | if (zeroForOne) { 142 | let i = TICK_ARRAY_SIZE - 1 143 | while (i >= 0) { 144 | const tickInArray = tickArray.ticks[i] 145 | if (tickInArray.liquidityGross.gtn(0)) { 146 | nextInitializedTick = tickInArray 147 | break 148 | } 149 | i = i - 1 150 | } 151 | } else { 152 | let i = 0 153 | while (i < TICK_ARRAY_SIZE) { 154 | const tickInArray = tickArray.ticks[i] 155 | if (tickInArray.liquidityGross.gtn(0)) { 156 | nextInitializedTick = tickInArray 157 | break 158 | } 159 | i = i + 1 160 | } 161 | } 162 | const { publicKey: tickArrayAddress } = getPdaTickArrayAddress( 163 | programId, 164 | poolId, 165 | tickArray.startTickIndex 166 | ) 167 | return { 168 | nextTick: nextInitializedTick, 169 | tickArrayAddress, 170 | tickArrayStartTickIndex: tickArray.startTickIndex, 171 | } 172 | } 173 | 174 | public static nextInitializedTickInOneArray( 175 | programId: PublicKey, 176 | poolId: PublicKey, 177 | tickArrayCache: { [key: string]: TickArray }, 178 | tickIndex: number, 179 | tickSpacing: number, 180 | zeroForOne: boolean 181 | ): { 182 | initializedTick: Tick | undefined 183 | tickArrayAddress: PublicKey | undefined 184 | tickArrayStartTickIndex: number 185 | } { 186 | const startIndex = TickUtils.getTickArrayStartIndexByTick( 187 | tickIndex, 188 | tickSpacing 189 | ) 190 | let tickPositionInArray = Math.floor((tickIndex - startIndex) / tickSpacing) 191 | const cachedTickArray = tickArrayCache[startIndex] 192 | if (cachedTickArray == undefined) { 193 | return { 194 | initializedTick: undefined, 195 | tickArrayAddress: undefined, 196 | tickArrayStartTickIndex: startIndex, 197 | } 198 | } 199 | let nextInitializedTick: Tick | undefined = undefined 200 | if (zeroForOne) { 201 | while (tickPositionInArray >= 0) { 202 | const tickInArray = cachedTickArray.ticks[tickPositionInArray] 203 | if (tickInArray.liquidityGross.gtn(0)) { 204 | nextInitializedTick = tickInArray 205 | break 206 | } 207 | tickPositionInArray = tickPositionInArray - 1 208 | } 209 | } else { 210 | tickPositionInArray = tickPositionInArray + 1 211 | while (tickPositionInArray < TICK_ARRAY_SIZE) { 212 | const tickInArray = cachedTickArray.ticks[tickPositionInArray] 213 | if (tickInArray.liquidityGross.gtn(0)) { 214 | nextInitializedTick = tickInArray 215 | break 216 | } 217 | tickPositionInArray = tickPositionInArray + 1 218 | } 219 | } 220 | const { publicKey: tickArrayAddress } = getPdaTickArrayAddress( 221 | programId, 222 | poolId, 223 | startIndex 224 | ) 225 | return { 226 | initializedTick: nextInitializedTick, 227 | tickArrayAddress, 228 | tickArrayStartTickIndex: cachedTickArray.startTickIndex, 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/amm.ts: -------------------------------------------------------------------------------- 1 | import BN from 'bn.js'; 2 | import Decimal from 'decimal.js'; 3 | 4 | import { PublicKey } from '@solana/web3.js'; 5 | 6 | import { 7 | AmmConfig, 8 | PoolState, 9 | TickArrayState, 10 | } from './types'; 11 | import { 12 | MAX_SQRT_PRICE_X64, 13 | MIN_SQRT_PRICE_X64, 14 | ONE, 15 | } from './utils/constants'; 16 | import { SqrtPriceMath } from './utils/math'; 17 | import { getPdaTickArrayAddress } from './utils/pda'; 18 | import { PoolUtils } from './utils/pool'; 19 | import { TickUtils } from './utils/tick'; 20 | import { FETCH_TICKARRAY_COUNT } from './utils/tickQuery'; 21 | 22 | interface ReturnTypeComputeAmountOut { 23 | amountOut: BN; 24 | minAmountOut: BN; 25 | currentPrice: Decimal; 26 | executionPrice: Decimal; 27 | priceImpact: number; 28 | fee: BN; 29 | remainingAccounts: PublicKey[]; 30 | } 31 | interface ReturnTypeComputeAmountOutBaseOut { 32 | amountIn: BN, 33 | maxAmountIn: BN, 34 | currentPrice: Decimal, 35 | executionPrice: Decimal, 36 | priceImpact: number, 37 | fee: BN, 38 | remainingAccounts: PublicKey[] 39 | } 40 | 41 | export interface AmmV3ConfigInfo { 42 | id: PublicKey; 43 | index: number; 44 | protocolFeeRate: number; 45 | tradeFeeRate: number; 46 | tickSpacing: number; 47 | } 48 | 49 | export interface AmmV3PoolRewardInfo { 50 | rewardState: number; 51 | openTime: BN; 52 | endTime: BN; 53 | lastUpdateTime: BN; 54 | emissionsPerSecondX64: BN; 55 | rewardTotalEmissioned: BN; 56 | rewardClaimed: BN; 57 | tokenMint: PublicKey; 58 | tokenVault: PublicKey; 59 | authority: PublicKey; 60 | rewardGrowthGlobalX64: BN; 61 | } 62 | export interface AmmV3PoolInfo { 63 | id: PublicKey; 64 | mintA: { 65 | mint: PublicKey; 66 | vault: PublicKey; 67 | decimals: number; 68 | }; 69 | mintB: { 70 | mint: PublicKey; 71 | vault: PublicKey; 72 | decimals: number; 73 | }; 74 | 75 | ammConfig: AmmV3ConfigInfo; 76 | observationId: PublicKey; 77 | 78 | programId: PublicKey; 79 | 80 | tickSpacing: number; 81 | liquidity: BN; 82 | sqrtPriceX64: BN; 83 | currentPrice: Decimal; 84 | tickCurrent: number; 85 | observationIndex: number; 86 | observationUpdateDuration: number; 87 | tickArrayBitmap: BN[]; 88 | } 89 | 90 | export class Amm { 91 | static computeAmountOut({ 92 | poolInfo, 93 | tickArrayCache, 94 | baseMint, 95 | amountIn, 96 | slippage, 97 | priceLimit = new Decimal(0), 98 | }: { 99 | poolInfo: AmmV3PoolInfo; 100 | tickArrayCache: { [key: string]: TickArrayState & { address: PublicKey } }; 101 | baseMint: PublicKey; 102 | 103 | amountIn: BN; 104 | slippage: number; 105 | priceLimit?: Decimal; 106 | }): ReturnTypeComputeAmountOut { 107 | let sqrtPriceLimitX64: BN; 108 | if (priceLimit.equals(new Decimal(0))) { 109 | sqrtPriceLimitX64 = baseMint.equals(poolInfo.mintA.mint) 110 | ? MIN_SQRT_PRICE_X64.add(ONE) 111 | : MAX_SQRT_PRICE_X64.sub(ONE); 112 | } else { 113 | sqrtPriceLimitX64 = SqrtPriceMath.priceToSqrtPriceX64( 114 | priceLimit, 115 | poolInfo.mintA.decimals, 116 | poolInfo.mintB.decimals 117 | ); 118 | } 119 | 120 | const { 121 | expectedAmountOut, 122 | remainingAccounts, 123 | executionPrice: _executionPriceX64, 124 | feeAmount, 125 | } = PoolUtils.getOutputAmountAndRemainAccounts(poolInfo, tickArrayCache, baseMint, amountIn, sqrtPriceLimitX64); 126 | 127 | const _executionPrice = SqrtPriceMath.sqrtPriceX64ToPrice( 128 | _executionPriceX64, 129 | poolInfo.mintA.decimals, 130 | poolInfo.mintB.decimals 131 | ); 132 | const executionPrice = baseMint.equals(poolInfo.mintA.mint) ? _executionPrice : new Decimal(1).div(_executionPrice); 133 | 134 | const minAmountOut = expectedAmountOut 135 | .mul(new BN(Math.floor((1 - slippage) * 10000000000))) 136 | .div(new BN(10000000000)); 137 | 138 | const poolPrice = poolInfo.mintA.mint.equals(baseMint) 139 | ? poolInfo.currentPrice 140 | : new Decimal(1).div(poolInfo.currentPrice); 141 | const priceImpact = 142 | Math.abs(parseFloat(executionPrice.toFixed()) - parseFloat(poolPrice.toFixed())) / 143 | parseFloat(poolPrice.toFixed()); 144 | 145 | return { 146 | amountOut: expectedAmountOut, 147 | minAmountOut, 148 | currentPrice: poolInfo.currentPrice, 149 | executionPrice, 150 | priceImpact, 151 | fee: feeAmount, 152 | 153 | remainingAccounts, 154 | }; 155 | } 156 | 157 | static computeAmountIn( 158 | { poolInfo, tickArrayCache, baseMint, amountOut, slippage, priceLimit = new Decimal(0) }: { 159 | poolInfo: AmmV3PoolInfo, 160 | tickArrayCache: { [key: string]: TickArrayState & { address: PublicKey } }, 161 | baseMint: PublicKey, 162 | 163 | amountOut: BN, 164 | slippage: number, 165 | priceLimit?: Decimal 166 | } 167 | ): ReturnTypeComputeAmountOutBaseOut { 168 | let sqrtPriceLimitX64: BN; 169 | if (priceLimit.equals(new Decimal(0))) { 170 | sqrtPriceLimitX64 = baseMint.equals(poolInfo.mintB.mint) 171 | ? MIN_SQRT_PRICE_X64.add(ONE) 172 | : MAX_SQRT_PRICE_X64.sub(ONE); 173 | } else { 174 | sqrtPriceLimitX64 = SqrtPriceMath.priceToSqrtPriceX64( 175 | priceLimit, 176 | poolInfo.mintA.decimals, 177 | poolInfo.mintB.decimals 178 | ); 179 | } 180 | 181 | const { expectedAmountIn, remainingAccounts, executionPrice: _executionPriceX64, feeAmount } = PoolUtils.getInputAmountAndRemainAccounts( 182 | poolInfo, 183 | tickArrayCache, 184 | baseMint, 185 | amountOut, 186 | sqrtPriceLimitX64 187 | ); 188 | 189 | const _executionPrice = SqrtPriceMath.sqrtPriceX64ToPrice(_executionPriceX64, poolInfo.mintA.decimals, poolInfo.mintB.decimals) 190 | const executionPrice = baseMint.equals(poolInfo.mintA.mint) ? _executionPrice : new Decimal(1).div(_executionPrice) 191 | 192 | const maxAmountIn = expectedAmountIn.mul(new BN(Math.floor((1 + slippage) * 10000000000))).div(new BN(10000000000)); 193 | 194 | const poolPrice = poolInfo.mintA.mint.equals(baseMint) ? poolInfo.currentPrice : new Decimal(1).div(poolInfo.currentPrice) 195 | const priceImpact = Math.abs(parseFloat(executionPrice.toFixed()) - parseFloat(poolPrice.toFixed())) / 196 | parseFloat(poolPrice.toFixed()); 197 | 198 | return { 199 | amountIn: expectedAmountIn, 200 | maxAmountIn, 201 | currentPrice: poolInfo.currentPrice, 202 | executionPrice, 203 | priceImpact, 204 | fee: feeAmount, 205 | 206 | remainingAccounts 207 | } 208 | } 209 | 210 | static getTickArrayPks(address: PublicKey, poolState: PoolState, programId: PublicKey): PublicKey[] { 211 | const tickArrayBitmap = TickUtils.mergeTickArrayBitmap(poolState.tickArrayBitmap); 212 | const currentTickArrayStartIndex = TickUtils.getTickArrayStartIndexByTick( 213 | poolState.tickCurrent, 214 | poolState.tickSpacing 215 | ); 216 | 217 | const tickArrayPks: PublicKey[] = []; 218 | const startIndexArray = TickUtils.getInitializedTickArrayInRange( 219 | tickArrayBitmap, 220 | poolState.tickSpacing, 221 | currentTickArrayStartIndex, 222 | Math.floor(FETCH_TICKARRAY_COUNT / 2) 223 | ); 224 | for (const itemIndex of startIndexArray) { 225 | const { publicKey: tickArrayAddress } = getPdaTickArrayAddress(programId, address, itemIndex); 226 | tickArrayPks.push(tickArrayAddress); 227 | } 228 | return tickArrayPks; 229 | } 230 | 231 | static formatPoolInfo({ 232 | address, 233 | poolState, 234 | ammConfig, 235 | programId, 236 | }: { 237 | address: PublicKey; 238 | poolState: PoolState; 239 | ammConfig: AmmConfig; 240 | programId: PublicKey; 241 | }): AmmV3PoolInfo { 242 | return { 243 | id: address, 244 | mintA: { 245 | mint: poolState.tokenMint0, 246 | vault: poolState.tokenVault0, 247 | decimals: poolState.mintDecimals0, 248 | }, 249 | mintB: { 250 | mint: poolState.tokenMint1, 251 | vault: poolState.tokenVault1, 252 | decimals: poolState.mintDecimals1, 253 | }, 254 | observationId: poolState.observationKey, 255 | ammConfig: { 256 | ...ammConfig, 257 | id: poolState.ammConfig, 258 | }, 259 | 260 | programId, 261 | 262 | tickSpacing: poolState.tickSpacing, 263 | liquidity: poolState.liquidity, 264 | sqrtPriceX64: poolState.sqrtPriceX64, 265 | currentPrice: SqrtPriceMath.sqrtPriceX64ToPrice( 266 | poolState.sqrtPriceX64, 267 | poolState.mintDecimals0, 268 | poolState.mintDecimals1 269 | ), 270 | tickCurrent: poolState.tickCurrent, 271 | observationIndex: poolState.observationIndex, 272 | observationUpdateDuration: poolState.observationUpdateDuration, 273 | tickArrayBitmap: poolState.tickArrayBitmap, 274 | }; 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /src/raydiumCLMM.ts: -------------------------------------------------------------------------------- 1 | import JSBI from 'jsbi'; 2 | 3 | import { 4 | BN, 5 | BorshAccountsCoder, 6 | } from '@project-serum/anchor'; 7 | import { 8 | AccountInfo, 9 | AccountMeta, 10 | PublicKey, 11 | } from '@solana/web3.js'; 12 | 13 | import { 14 | Amm as RaydiumSdkAmm, 15 | AmmV3PoolInfo, 16 | } from './amm'; 17 | import { 18 | AmmV3 as AmmV3Idl, 19 | IDL, 20 | } from './idl/amm_v3'; 21 | import { PoolState } from './types'; 22 | import { TickArray } from './utils/tick'; 23 | 24 | type TickArrayCache = { [key: string]: TickArray }; 25 | 26 | export class RaydiumSwapV3 implements Amm { 27 | label = 'Raydium' as const; 28 | id: string; 29 | reserveTokenMints: PublicKey[]; 30 | hasDynamicAccounts = true; 31 | shouldPrefetch = false; 32 | exactOutputSupported = false; 33 | 34 | private programId: PublicKey; 35 | private poolState: PoolState; 36 | private coder: BorshAccountsCoder; 37 | 38 | tickArrayPks: PublicKey[]; 39 | tickArrayCache: TickArrayCache = {}; 40 | ammV3PoolInfo: AmmV3PoolInfo | undefined; 41 | 42 | constructor(private address: PublicKey, accountInfo: AccountInfo) { 43 | this.id = address.toBase58(); 44 | this.address = address; 45 | 46 | this.coder = new BorshAccountsCoder(IDL as AmmV3Idl); 47 | 48 | this.poolState = this.coder.decode('poolState', accountInfo.data); 49 | this.reserveTokenMints = [this.poolState.tokenMint0, this.poolState.tokenMint1]; 50 | this.programId = accountInfo.owner; 51 | this.tickArrayPks = RaydiumSdkAmm.getTickArrayPks(this.address, this.poolState, this.programId); 52 | } 53 | 54 | getAccountsForUpdate() { 55 | return [this.address, this.poolState.ammConfig, ...this.tickArrayPks]; 56 | } 57 | 58 | update(accountInfoMap: Map>) { 59 | const poolStateAccountInfo = accountInfoMap.get(this.id); 60 | if (!poolStateAccountInfo) throw new Error('Missing poolStateAccountInfo'); 61 | const ammConfigAccountInfo = accountInfoMap.get(this.poolState.ammConfig.toBase58()); 62 | if (!ammConfigAccountInfo) throw new Error('Missing ammConfigAccoutnInfo'); 63 | 64 | this.poolState = this.coder.decode('poolState', poolStateAccountInfo.data); 65 | const ammConfig = this.coder.decode('ammConfig', ammConfigAccountInfo.data); 66 | 67 | this.tickArrayPks = RaydiumSdkAmm.getTickArrayPks(this.address, this.poolState, this.programId); 68 | const tickArrayCache: TickArrayCache = {}; 69 | for (const tickArrayPk of this.tickArrayPks) { 70 | const tickArrayAccountInfo = accountInfoMap.get(tickArrayPk.toBase58()); 71 | if (!tickArrayAccountInfo) continue; 72 | const tickArray = this.coder.decode('tickArrayState', tickArrayAccountInfo.data); 73 | tickArrayCache[tickArray.startTickIndex] = { 74 | ...tickArray, 75 | address: tickArrayPk, 76 | }; 77 | } 78 | 79 | this.tickArrayCache = tickArrayCache; 80 | this.ammV3PoolInfo = RaydiumSdkAmm.formatPoolInfo({ 81 | address: this.address, 82 | poolState: this.poolState, 83 | ammConfig, 84 | programId: this.programId, 85 | }); 86 | } 87 | 88 | getQuote(quoteParams: QuoteParams) { 89 | if (!this.ammV3PoolInfo) throw new Error('Missing ammV3PoolInfo'); 90 | 91 | if (quoteParams.swapMode === 'ExactIn') { 92 | try { 93 | const { amountOut, fee, priceImpact } = RaydiumSdkAmm.computeAmountOut({ 94 | poolInfo: this.ammV3PoolInfo, 95 | tickArrayCache: this.tickArrayCache, 96 | baseMint: quoteParams.sourceMint, 97 | amountIn: new BN(quoteParams.amount.toString()), 98 | slippage: 0, 99 | }); 100 | return { 101 | notEnoughLiquidity: false, 102 | inAmount: quoteParams.amount, 103 | outAmount: JSBI.BigInt(amountOut.toString()), 104 | feeAmount: JSBI.BigInt(fee.toString()), 105 | feeMint: quoteParams.sourceMint.toString(), 106 | feePct: this.ammV3PoolInfo.ammConfig.tradeFeeRate / 10 ** 6, 107 | priceImpactPct: priceImpact, 108 | }; 109 | } catch(e) { 110 | if (e.message === 'liquidity limit') { 111 | return { 112 | notEnoughLiquidity: true, 113 | inAmount: quoteParams.amount, 114 | outAmount: JSBI.BigInt(0), 115 | feeAmount: JSBI.BigInt(0), 116 | feeMint: quoteParams.sourceMint.toString(), 117 | feePct: this.ammV3PoolInfo.ammConfig.tradeFeeRate / 10 ** 6, 118 | priceImpactPct: 0, 119 | }; 120 | } 121 | throw e 122 | } 123 | } else { 124 | try { 125 | const { amountIn, fee, priceImpact } = RaydiumSdkAmm.computeAmountIn({ 126 | poolInfo: this.ammV3PoolInfo, 127 | tickArrayCache: this.tickArrayCache, 128 | baseMint: quoteParams.destinationMint, 129 | amountOut: new BN(quoteParams.amount.toString()), 130 | slippage: 0, 131 | }); 132 | return { 133 | notEnoughLiquidity: false, 134 | inAmount: JSBI.BigInt(amountIn.toString()), 135 | outAmount: quoteParams.amount, 136 | feeAmount: JSBI.BigInt(fee.toString()), 137 | feeMint: quoteParams.sourceMint.toString(), 138 | feePct: this.ammV3PoolInfo.ammConfig.tradeFeeRate / 10 ** 6, 139 | priceImpactPct: priceImpact, 140 | }; 141 | } catch(e) { 142 | if (e.message === 'liquidity limit') { 143 | return { 144 | notEnoughLiquidity: true, 145 | inAmount: quoteParams.amount, 146 | outAmount: JSBI.BigInt(0), 147 | feeAmount: JSBI.BigInt(0), 148 | feeMint: quoteParams.sourceMint.toString(), 149 | feePct: this.ammV3PoolInfo.ammConfig.tradeFeeRate / 10 ** 6, 150 | priceImpactPct: 0, 151 | }; 152 | } 153 | throw e 154 | } 155 | } 156 | } 157 | 158 | getSwapLegAndAccounts(swapParams: SwapParams): [{}, AccountMeta[]] { 159 | if (!this.ammV3PoolInfo) throw new Error('Missing ammV3PoolInfo'); 160 | 161 | // Note, the real call should prepend with swap accounts 162 | const { remainingAccounts } = RaydiumSdkAmm.computeAmountOut({ 163 | poolInfo: this.ammV3PoolInfo, 164 | tickArrayCache: this.tickArrayCache, 165 | baseMint: swapParams.sourceMint, 166 | amountIn: new BN(swapParams.amount.toString()), 167 | slippage: 0, 168 | }); 169 | return [ 170 | {}, 171 | remainingAccounts.map((pubkey) => ({ 172 | pubkey, 173 | isSigner: false, 174 | isWritable: true, 175 | })), 176 | ]; 177 | } 178 | } 179 | 180 | interface Amm { 181 | /* Label for UI usage */ 182 | label: string; 183 | /* Unique id to recognize the AMM */ 184 | id: string; 185 | /* Reserve token mints for the purpose of routing */ 186 | reserveTokenMints: PublicKey[]; 187 | hasDynamicAccounts: boolean; 188 | /* State if we need to prefetch the accounts 1 time */ 189 | shouldPrefetch: boolean; 190 | /* Exact output swap mode is supported */ 191 | exactOutputSupported: boolean; 192 | getAccountsForUpdate(): PublicKey[]; 193 | update(accountInfoMap: Map>): void; 194 | getQuote(quoteParams: QuoteParams): Quote; 195 | getSwapLegAndAccounts(swapParams: SwapParams): SwapLegAndAccounts; 196 | } 197 | 198 | enum SwapMode { 199 | ExactIn = 'ExactIn', 200 | ExactOut = 'ExactOut', 201 | } 202 | 203 | interface QuoteParams { 204 | sourceMint: PublicKey; 205 | destinationMint: PublicKey; 206 | amount: JSBI; 207 | swapMode: SwapMode; 208 | } 209 | 210 | interface Quote { 211 | notEnoughLiquidity: boolean; 212 | minInAmount?: JSBI; 213 | minOutAmount?: JSBI; 214 | inAmount: JSBI; 215 | outAmount: JSBI; 216 | feeAmount: JSBI; 217 | feeMint: string; 218 | feePct: number; 219 | priceImpactPct: number; 220 | } 221 | 222 | interface SwapParams { 223 | sourceMint: PublicKey; 224 | destinationMint: PublicKey; 225 | userSourceTokenAccount: PublicKey; 226 | userDestinationTokenAccount: PublicKey; 227 | userTransferAuthority: PublicKey; 228 | amount: JSBI; 229 | swapMode: SwapMode; 230 | } 231 | 232 | type SwapLegAndAccounts = [{}, AccountMeta[]]; 233 | 234 | // ; (async () => { 235 | // const poolId = new PublicKey('61R1ndXxvsWXXkWSyNkCxnzwd3zUNB8Q2ibmkiLPC8ht') 236 | // const conn = new Connection(rpcUrl) 237 | // const poolInfo = await conn.getAccountInfo(poolId) 238 | // if (poolInfo === null) { 239 | // console.log('no info') 240 | // return 241 | // } 242 | 243 | // const jup = new RaydiumSwapV3(poolId, poolInfo) 244 | // const needUpdateAccounts = jup.getAccountsForUpdate() 245 | // console.log('needUpdateAccounts', needUpdateAccounts) 246 | // const mulitAccount = await conn.getMultipleAccountsInfo(needUpdateAccounts) 247 | // const accountMap: Map | null> = new Map() 248 | // for (let i = 0; i < mulitAccount.length; i++) { 249 | // accountMap.set(needUpdateAccounts[i].toString(), mulitAccount[i] as AccountInfo || null) 250 | // } 251 | // jup.update(accountMap) 252 | 253 | // console.log(jup.getQuote({ 254 | // sourceMint: new PublicKey('4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R'), 255 | // destinationMint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'), 256 | // amount: JSBI.BigInt('123123'), 257 | // // @ts-ignore 258 | // swapMode: 'ExactIn' as const 259 | // })) 260 | 261 | // })() 262 | -------------------------------------------------------------------------------- /src/utils/math.ts: -------------------------------------------------------------------------------- 1 | import BN from 'bn.js'; 2 | import Decimal from 'decimal.js'; 3 | 4 | import { PublicKey } from '@solana/web3.js'; 5 | 6 | import { 7 | BIT_PRECISION, 8 | Fee, 9 | FEE_RATE_DENOMINATOR, 10 | LOG_B_2_X32, 11 | LOG_B_P_ERR_MARGIN_LOWER_X64, 12 | LOG_B_P_ERR_MARGIN_UPPER_X64, 13 | MAX_SQRT_PRICE_X64, 14 | MAX_TICK, 15 | MaxU64, 16 | MaxUint128, 17 | MIN_SQRT_PRICE_X64, 18 | MIN_TICK, 19 | NEGATIVE_ONE, 20 | ONE, 21 | Q128, 22 | Q64, 23 | U64Resolution, 24 | ZERO, 25 | } from './constants'; 26 | import { TickArray } from './tick'; 27 | import { TickQuery } from './tickQuery'; 28 | 29 | export class MathUtil { 30 | public static mulDivRoundingUp(a: BN, b: BN, denominator: BN): BN { 31 | const numerator = a.mul(b); 32 | let result = numerator.div(denominator); 33 | if (!numerator.mod(denominator).eq(ZERO)) { 34 | result = result.add(ONE); 35 | } 36 | return result; 37 | } 38 | 39 | public static mulDivFloor(a: BN, b: BN, denominator: BN): BN { 40 | if (denominator.eq(ZERO)) { 41 | throw new Error("division by 0"); 42 | } 43 | return a.mul(b).div(denominator); 44 | } 45 | 46 | public static mulDivCeil(a: BN, b: BN, denominator: BN): BN { 47 | if (denominator.eq(ZERO)) { 48 | throw new Error("division by 0"); 49 | } 50 | const numerator = a.mul(b).add(denominator.sub(ONE)); 51 | return numerator.div(denominator); 52 | } 53 | 54 | public static x64ToDecimal(num: BN, decimalPlaces?: number): Decimal { 55 | return new Decimal(num.toString()) 56 | .div(Decimal.pow(2, 64)) 57 | .toDecimalPlaces(decimalPlaces); 58 | } 59 | 60 | public static decimalToX64(num: Decimal): BN { 61 | return new BN(num.mul(Decimal.pow(2, 64)).floor().toFixed()); 62 | } 63 | 64 | public static wrappingSubU128(n0: BN, n1: BN): BN { 65 | return n0.add(Q128).sub(n1).mod(Q128); 66 | } 67 | } 68 | 69 | // sqrt price math 70 | function mulRightShift(val: BN, mulBy: BN): BN { 71 | return signedRightShift(val.mul(mulBy), 64, 256); 72 | } 73 | 74 | function signedLeftShift(n0: BN, shiftBy: number, bitWidth: number) { 75 | const twosN0 = n0.toTwos(bitWidth).shln(shiftBy); 76 | twosN0.imaskn(bitWidth + 1); 77 | return twosN0.fromTwos(bitWidth); 78 | } 79 | 80 | function signedRightShift(n0: BN, shiftBy: number, bitWidth: number) { 81 | const twoN0 = n0.toTwos(bitWidth).shrn(shiftBy); 82 | twoN0.imaskn(bitWidth - shiftBy + 1); 83 | return twoN0.fromTwos(bitWidth - shiftBy); 84 | } 85 | 86 | export class SqrtPriceMath { 87 | public static sqrtPriceX64ToPrice( 88 | sqrtPriceX64: BN, 89 | decimalsA: number, 90 | decimalsB: number 91 | ): Decimal { 92 | return MathUtil.x64ToDecimal(sqrtPriceX64) 93 | .pow(2) 94 | .mul(Decimal.pow(10, decimalsA - decimalsB)); 95 | } 96 | 97 | public static priceToSqrtPriceX64( 98 | price: Decimal, 99 | decimalsA: number, 100 | decimalsB: number 101 | ): BN { 102 | return MathUtil.decimalToX64( 103 | price.mul(Decimal.pow(10, decimalsB - decimalsA)).sqrt() 104 | ); 105 | } 106 | 107 | public static getNextSqrtPriceX64FromInput( 108 | sqrtPriceX64: BN, 109 | liquidity: BN, 110 | amountIn: BN, 111 | zeroForOne: boolean 112 | ): BN { 113 | if (!sqrtPriceX64.gt(ZERO)) { 114 | throw new Error("sqrtPriceX64 must greater than 0"); 115 | } 116 | if (!liquidity.gt(ZERO)) { 117 | throw new Error("liquidity must greater than 0"); 118 | } 119 | 120 | return zeroForOne 121 | ? this.getNextSqrtPriceFromTokenAmountARoundingUp( 122 | sqrtPriceX64, 123 | liquidity, 124 | amountIn, 125 | true 126 | ) 127 | : this.getNextSqrtPriceFromTokenAmountBRoundingDown( 128 | sqrtPriceX64, 129 | liquidity, 130 | amountIn, 131 | true 132 | ); 133 | } 134 | 135 | public static getNextSqrtPriceX64FromOutput( 136 | sqrtPriceX64: BN, 137 | liquidity: BN, 138 | amountOut: BN, 139 | zeroForOne: boolean 140 | ): BN { 141 | if (!sqrtPriceX64.gt(ZERO)) { 142 | throw new Error("sqrtPriceX64 must greater than 0"); 143 | } 144 | if (!liquidity.gt(ZERO)) { 145 | throw new Error("liquidity must greater than 0"); 146 | } 147 | 148 | return zeroForOne 149 | ? this.getNextSqrtPriceFromTokenAmountBRoundingDown( 150 | sqrtPriceX64, 151 | liquidity, 152 | amountOut, 153 | false 154 | ) 155 | : this.getNextSqrtPriceFromTokenAmountARoundingUp( 156 | sqrtPriceX64, 157 | liquidity, 158 | amountOut, 159 | false 160 | ); 161 | } 162 | 163 | private static getNextSqrtPriceFromTokenAmountARoundingUp( 164 | sqrtPriceX64: BN, 165 | liquidity: BN, 166 | amount: BN, 167 | add: boolean 168 | ): BN { 169 | if (amount.eq(ZERO)) return sqrtPriceX64; 170 | const liquidityLeftShift = liquidity.shln(U64Resolution); 171 | 172 | if (add) { 173 | const numerator1 = liquidityLeftShift; 174 | const denominator = liquidityLeftShift.add(amount.mul(sqrtPriceX64)); 175 | if (denominator.gte(numerator1)) { 176 | return MathUtil.mulDivCeil(numerator1, sqrtPriceX64, denominator); 177 | } 178 | return MathUtil.mulDivRoundingUp( 179 | numerator1, 180 | ONE, 181 | numerator1.div(sqrtPriceX64).add(amount) 182 | ); 183 | } else { 184 | const amountMulSqrtPrice = amount.mul(sqrtPriceX64); 185 | if (!liquidityLeftShift.gt(amountMulSqrtPrice)) { 186 | throw new Error( 187 | "getNextSqrtPriceFromTokenAmountARoundingUp,liquidityLeftShift must gt amountMulSqrtPrice" 188 | ); 189 | } 190 | const denominator = liquidityLeftShift.sub(amountMulSqrtPrice); 191 | return MathUtil.mulDivCeil(liquidityLeftShift, sqrtPriceX64, denominator); 192 | } 193 | } 194 | 195 | private static getNextSqrtPriceFromTokenAmountBRoundingDown( 196 | sqrtPriceX64: BN, 197 | liquidity: BN, 198 | amount: BN, 199 | add: boolean 200 | ): BN { 201 | const deltaY = amount.shln(U64Resolution); 202 | if (add) { 203 | return sqrtPriceX64.add(deltaY.div(liquidity)); 204 | } else { 205 | const amountDivLiquidity = MathUtil.mulDivRoundingUp( 206 | deltaY, 207 | ONE, 208 | liquidity 209 | ); 210 | if (!sqrtPriceX64.gt(amountDivLiquidity)) { 211 | throw new Error( 212 | "getNextSqrtPriceFromTokenAmountBRoundingDown sqrtPriceX64 must gt amountDivLiquidity" 213 | ); 214 | } 215 | return sqrtPriceX64.sub(amountDivLiquidity); 216 | } 217 | } 218 | 219 | public static getSqrtPriceX64FromTick(tick: number): BN { 220 | if (!Number.isInteger(tick)) { 221 | throw new Error("tick must be integer"); 222 | } 223 | if (tick < MIN_TICK || tick > MAX_TICK) { 224 | throw new Error("tick must be in MIN_TICK and MAX_TICK"); 225 | } 226 | const tickAbs: number = tick < 0 ? tick * -1 : tick; 227 | 228 | let ratio: BN = 229 | (tickAbs & 0x1) != 0 230 | ? new BN("18445821805675395072") 231 | : new BN("18446744073709551616"); 232 | if ((tickAbs & 0x2) != 0) 233 | ratio = mulRightShift(ratio, new BN("18444899583751176192")); 234 | if ((tickAbs & 0x4) != 0) 235 | ratio = mulRightShift(ratio, new BN("18443055278223355904")); 236 | if ((tickAbs & 0x8) != 0) 237 | ratio = mulRightShift(ratio, new BN("18439367220385607680")); 238 | if ((tickAbs & 0x10) != 0) 239 | ratio = mulRightShift(ratio, new BN("18431993317065453568")); 240 | if ((tickAbs & 0x20) != 0) 241 | ratio = mulRightShift(ratio, new BN("18417254355718170624")); 242 | if ((tickAbs & 0x40) != 0) 243 | ratio = mulRightShift(ratio, new BN("18387811781193609216")); 244 | if ((tickAbs & 0x80) != 0) 245 | ratio = mulRightShift(ratio, new BN("18329067761203558400")); 246 | if ((tickAbs & 0x100) != 0) 247 | ratio = mulRightShift(ratio, new BN("18212142134806163456")); 248 | if ((tickAbs & 0x200) != 0) 249 | ratio = mulRightShift(ratio, new BN("17980523815641700352")); 250 | if ((tickAbs & 0x400) != 0) 251 | ratio = mulRightShift(ratio, new BN("17526086738831433728")); 252 | if ((tickAbs & 0x800) != 0) 253 | ratio = mulRightShift(ratio, new BN("16651378430235570176")); 254 | if ((tickAbs & 0x1000) != 0) 255 | ratio = mulRightShift(ratio, new BN("15030750278694412288")); 256 | if ((tickAbs & 0x2000) != 0) 257 | ratio = mulRightShift(ratio, new BN("12247334978884435968")); 258 | if ((tickAbs & 0x4000) != 0) 259 | ratio = mulRightShift(ratio, new BN("8131365268886854656")); 260 | if ((tickAbs & 0x8000) != 0) 261 | ratio = mulRightShift(ratio, new BN("3584323654725218816")); 262 | if ((tickAbs & 0x10000) != 0) 263 | ratio = mulRightShift(ratio, new BN("696457651848324352")); 264 | if ((tickAbs & 0x20000) != 0) 265 | ratio = mulRightShift(ratio, new BN("26294789957507116")); 266 | if ((tickAbs & 0x40000) != 0) 267 | ratio = mulRightShift(ratio, new BN("37481735321082")); 268 | 269 | if (tick > 0) ratio = MaxUint128.div(ratio); 270 | return ratio; 271 | } 272 | 273 | public static getTickFromPrice( 274 | price: Decimal, 275 | decimalsA: number, 276 | decimalsB: number 277 | ): number { 278 | return SqrtPriceMath.getTickFromSqrtPriceX64( 279 | SqrtPriceMath.priceToSqrtPriceX64(price, decimalsA, decimalsB) 280 | ); 281 | } 282 | 283 | public static getTickFromSqrtPriceX64(sqrtPriceX64: BN): number { 284 | if ( 285 | sqrtPriceX64.gt(MAX_SQRT_PRICE_X64) || 286 | sqrtPriceX64.lt(MIN_SQRT_PRICE_X64) 287 | ) { 288 | throw new Error( 289 | "Provided sqrtPrice is not within the supported sqrtPrice range." 290 | ); 291 | } 292 | 293 | const msb = sqrtPriceX64.bitLength() - 1; 294 | const adjustedMsb = new BN(msb - 64); 295 | const log2pIntegerX32 = signedLeftShift(adjustedMsb, 32, 128); 296 | 297 | let bit = new BN("8000000000000000", "hex"); 298 | let precision = 0; 299 | let log2pFractionX64 = new BN(0); 300 | 301 | let r = 302 | msb >= 64 ? sqrtPriceX64.shrn(msb - 63) : sqrtPriceX64.shln(63 - msb); 303 | 304 | while (bit.gt(new BN(0)) && precision < BIT_PRECISION) { 305 | r = r.mul(r); 306 | const rMoreThanTwo = r.shrn(127); 307 | r = r.shrn(63 + rMoreThanTwo.toNumber()); 308 | log2pFractionX64 = log2pFractionX64.add(bit.mul(rMoreThanTwo)); 309 | bit = bit.shrn(1); 310 | precision += 1; 311 | } 312 | 313 | const log2pFractionX32 = log2pFractionX64.shrn(32); 314 | 315 | const log2pX32 = log2pIntegerX32.add(log2pFractionX32); 316 | const logbpX64 = log2pX32.mul(new BN(LOG_B_2_X32)); 317 | 318 | const tickLow = signedRightShift( 319 | logbpX64.sub(new BN(LOG_B_P_ERR_MARGIN_LOWER_X64)), 320 | 64, 321 | 128 322 | ).toNumber(); 323 | const tickHigh = signedRightShift( 324 | logbpX64.add(new BN(LOG_B_P_ERR_MARGIN_UPPER_X64)), 325 | 64, 326 | 128 327 | ).toNumber(); 328 | 329 | if (tickLow == tickHigh) { 330 | return tickLow; 331 | } else { 332 | const derivedTickHighSqrtPriceX64 = SqrtPriceMath.getSqrtPriceX64FromTick(tickHigh) 333 | return derivedTickHighSqrtPriceX64.lte(sqrtPriceX64) ? tickHigh : tickLow 334 | } 335 | } 336 | } 337 | 338 | // tick math 339 | export class TickMath { 340 | public static getTickWithPriceAndTickspacing( 341 | price: Decimal, 342 | tickSpacing: number, 343 | mintDecimalsA: number, 344 | mintDecimalsB: number 345 | ) { 346 | const tick = SqrtPriceMath.getTickFromSqrtPriceX64( 347 | SqrtPriceMath.priceToSqrtPriceX64( 348 | price, 349 | mintDecimalsA, 350 | mintDecimalsB 351 | ) 352 | ); 353 | let result = tick / tickSpacing; 354 | if (result < 0) { 355 | result = Math.floor(result); 356 | } else { 357 | result = Math.ceil(result); 358 | } 359 | return result * tickSpacing; 360 | } 361 | 362 | public static roundPriceWithTickspacing( 363 | price: Decimal, 364 | tickSpacing: number, 365 | mintDecimalsA: number, 366 | mintDecimalsB: number 367 | ) { 368 | const tick = TickMath.getTickWithPriceAndTickspacing( 369 | price, 370 | tickSpacing, 371 | mintDecimalsA, 372 | mintDecimalsB 373 | ); 374 | const sqrtPriceX64 = SqrtPriceMath.getSqrtPriceX64FromTick(tick); 375 | return SqrtPriceMath.sqrtPriceX64ToPrice( 376 | sqrtPriceX64, 377 | mintDecimalsA, 378 | mintDecimalsB 379 | ); 380 | } 381 | } 382 | 383 | export class LiquidityMath { 384 | public static addDelta(x: BN, y: BN): BN { 385 | return x.add(y); 386 | } 387 | 388 | public static getTokenAmountAFromLiquidity( 389 | sqrtPriceX64A: BN, 390 | sqrtPriceX64B: BN, 391 | liquidity: BN, 392 | roundUp: boolean 393 | ): BN { 394 | if (sqrtPriceX64A.gt(sqrtPriceX64B)) { 395 | [sqrtPriceX64A, sqrtPriceX64B] = [sqrtPriceX64B, sqrtPriceX64A]; 396 | } 397 | 398 | if (!sqrtPriceX64A.gt(ZERO)) { 399 | throw new Error("sqrtPriceX64A must greater than 0"); 400 | } 401 | 402 | const numerator1 = liquidity.ushln(U64Resolution); 403 | const numerator2 = sqrtPriceX64B.sub(sqrtPriceX64A); 404 | 405 | return roundUp 406 | ? MathUtil.mulDivRoundingUp( 407 | MathUtil.mulDivCeil(numerator1, numerator2, sqrtPriceX64B), 408 | ONE, 409 | sqrtPriceX64A 410 | ) 411 | : MathUtil.mulDivFloor(numerator1, numerator2, sqrtPriceX64B).div( 412 | sqrtPriceX64A 413 | ); 414 | } 415 | 416 | public static getTokenAmountBFromLiquidity( 417 | sqrtPriceX64A: BN, 418 | sqrtPriceX64B: BN, 419 | liquidity: BN, 420 | roundUp: boolean 421 | ): BN { 422 | if (sqrtPriceX64A.gt(sqrtPriceX64B)) { 423 | [sqrtPriceX64A, sqrtPriceX64B] = [sqrtPriceX64B, sqrtPriceX64A]; 424 | } 425 | if (!sqrtPriceX64A.gt(ZERO)) { 426 | throw new Error("sqrtPriceX64A must greater than 0"); 427 | } 428 | 429 | return roundUp 430 | ? MathUtil.mulDivCeil(liquidity, sqrtPriceX64B.sub(sqrtPriceX64A), Q64) 431 | : MathUtil.mulDivFloor(liquidity, sqrtPriceX64B.sub(sqrtPriceX64A), Q64); 432 | } 433 | 434 | public static getLiquidityFromTokenAmountA( 435 | sqrtPriceX64A: BN, 436 | sqrtPriceX64B: BN, 437 | amountA: BN, 438 | roundUp: boolean 439 | ): BN { 440 | if (sqrtPriceX64A.gt(sqrtPriceX64B)) { 441 | [sqrtPriceX64A, sqrtPriceX64B] = [sqrtPriceX64B, sqrtPriceX64A]; 442 | } 443 | 444 | const numerator = amountA.mul(sqrtPriceX64A).mul(sqrtPriceX64B); 445 | const denominator = sqrtPriceX64B.sub(sqrtPriceX64A); 446 | const result = numerator.div(denominator); 447 | 448 | if (roundUp) { 449 | return MathUtil.mulDivRoundingUp(result, ONE, MaxU64); 450 | } else { 451 | return result.shrn(U64Resolution); 452 | } 453 | } 454 | 455 | public static getLiquidityFromTokenAmountB( 456 | sqrtPriceX64A: BN, 457 | sqrtPriceX64B: BN, 458 | amountB: BN 459 | ): BN { 460 | if (sqrtPriceX64A.gt(sqrtPriceX64B)) { 461 | [sqrtPriceX64A, sqrtPriceX64B] = [sqrtPriceX64B, sqrtPriceX64A]; 462 | } 463 | return MathUtil.mulDivFloor( 464 | amountB, 465 | MaxU64, 466 | sqrtPriceX64B.sub(sqrtPriceX64A) 467 | ); 468 | } 469 | 470 | public static getLiquidityFromTokenAmounts( 471 | sqrtPriceCurrentX64: BN, 472 | sqrtPriceX64A: BN, 473 | sqrtPriceX64B: BN, 474 | amountA: BN, 475 | amountB: BN 476 | ): BN { 477 | if (sqrtPriceX64A.gt(sqrtPriceX64B)) { 478 | [sqrtPriceX64A, sqrtPriceX64B] = [sqrtPriceX64B, sqrtPriceX64A]; 479 | } 480 | 481 | if (sqrtPriceCurrentX64.lte(sqrtPriceX64A)) { 482 | return LiquidityMath.getLiquidityFromTokenAmountA( 483 | sqrtPriceX64A, 484 | sqrtPriceX64B, 485 | amountA, 486 | false 487 | ); 488 | } else if (sqrtPriceCurrentX64.lt(sqrtPriceX64B)) { 489 | const liquidity0 = LiquidityMath.getLiquidityFromTokenAmountA( 490 | sqrtPriceCurrentX64, 491 | sqrtPriceX64B, 492 | amountA, 493 | false 494 | ); 495 | const liquidity1 = LiquidityMath.getLiquidityFromTokenAmountB( 496 | sqrtPriceX64A, 497 | sqrtPriceCurrentX64, 498 | amountB 499 | ); 500 | return liquidity0.lt(liquidity1) ? liquidity0 : liquidity1; 501 | } else { 502 | return LiquidityMath.getLiquidityFromTokenAmountB( 503 | sqrtPriceX64A, 504 | sqrtPriceX64B, 505 | amountB 506 | ); 507 | } 508 | } 509 | 510 | public static getAmountsFromLiquidity( 511 | sqrtPriceCurrentX64: BN, 512 | sqrtPriceX64A: BN, 513 | sqrtPriceX64B: BN, 514 | liquidity: BN, 515 | roundUp: boolean 516 | ): { amountA: BN, amountB: BN } { 517 | if (sqrtPriceX64A.gt(sqrtPriceX64B)) { 518 | [sqrtPriceX64A, sqrtPriceX64B] = [sqrtPriceX64B, sqrtPriceX64A]; 519 | } 520 | 521 | if (sqrtPriceCurrentX64.lte(sqrtPriceX64A)) { 522 | return { 523 | amountA: LiquidityMath.getTokenAmountAFromLiquidity( 524 | sqrtPriceX64A, 525 | sqrtPriceX64B, 526 | liquidity, 527 | roundUp 528 | ), 529 | amountB: new BN(0) 530 | }; 531 | } else if (sqrtPriceCurrentX64.lt(sqrtPriceX64B)) { 532 | const amountA = LiquidityMath.getTokenAmountAFromLiquidity( 533 | sqrtPriceCurrentX64, 534 | sqrtPriceX64B, 535 | liquidity, 536 | roundUp 537 | ); 538 | const amountB = LiquidityMath.getTokenAmountBFromLiquidity( 539 | sqrtPriceX64A, 540 | sqrtPriceCurrentX64, 541 | liquidity, 542 | roundUp 543 | ); 544 | return { amountA, amountB }; 545 | } else { 546 | return { 547 | amountA: new BN(0), 548 | amountB: LiquidityMath.getTokenAmountBFromLiquidity( 549 | sqrtPriceX64A, 550 | sqrtPriceX64B, 551 | liquidity, 552 | roundUp 553 | ), 554 | }; 555 | } 556 | } 557 | 558 | public static getAmountsFromLiquidityWithSlippage( 559 | sqrtPriceCurrentX64: BN, 560 | sqrtPriceX64A: BN, 561 | sqrtPriceX64B: BN, 562 | liquidity: BN, 563 | amountMax: boolean, 564 | roundUp: boolean, 565 | amountSlippage: number 566 | ) { 567 | const { amountA, amountB } = LiquidityMath.getAmountsFromLiquidity( 568 | sqrtPriceCurrentX64, 569 | sqrtPriceX64A, 570 | sqrtPriceX64B, 571 | liquidity, 572 | roundUp 573 | ); 574 | const coefficient = amountMax ? 1 + amountSlippage : 1 - amountSlippage; 575 | 576 | const amount0Slippage = amountA.muln(coefficient) 577 | const amount1Slippage = amountB.muln(coefficient) 578 | return { 579 | amountSlippageA: amount0Slippage, 580 | amountSlippageB: amount1Slippage, 581 | }; 582 | } 583 | } 584 | 585 | // swap math 586 | 587 | type SwapStep = { 588 | sqrtPriceX64Next: BN; 589 | amountIn: BN; 590 | amountOut: BN; 591 | feeAmount: BN; 592 | }; 593 | 594 | export interface StepComputations { 595 | sqrtPriceStartX64: BN; 596 | tickNext: number; 597 | initialized: boolean; 598 | sqrtPriceNextX64: BN; 599 | amountIn: BN; 600 | amountOut: BN; 601 | feeAmount: BN; 602 | } 603 | 604 | export abstract class SwapMath { 605 | public static swapCompute( 606 | programId: PublicKey, 607 | poolId: PublicKey, 608 | tickArrayCache: { [key: string]: TickArray }, 609 | zeroForOne: boolean, 610 | fee: number, 611 | liquidity: BN, 612 | currentTick: number, 613 | tickSpacing: number, 614 | currentSqrtPriceX64: BN, 615 | amountSpecified: BN, 616 | lastSavedTickArrayStartIndex: number, 617 | sqrtPriceLimitX64?: BN 618 | ) { 619 | if (amountSpecified.eq(ZERO)) { 620 | throw new Error("amountSpecified must not be 0"); 621 | } 622 | if (!sqrtPriceLimitX64) 623 | sqrtPriceLimitX64 = zeroForOne 624 | ? MIN_SQRT_PRICE_X64.add(ONE) 625 | : MAX_SQRT_PRICE_X64.sub(ONE); 626 | 627 | if (zeroForOne) { 628 | if (sqrtPriceLimitX64.lt(MIN_SQRT_PRICE_X64)) { 629 | throw new Error("sqrtPriceX64 must greater than MIN_SQRT_PRICE_X64"); 630 | } 631 | 632 | if (sqrtPriceLimitX64.gte(currentSqrtPriceX64)) { 633 | throw new Error("sqrtPriceX64 must smaller than current"); 634 | } 635 | } else { 636 | if (sqrtPriceLimitX64.gt(MAX_SQRT_PRICE_X64)) { 637 | throw new Error("sqrtPriceX64 must smaller than MAX_SQRT_PRICE_X64"); 638 | } 639 | 640 | if (sqrtPriceLimitX64.lte(currentSqrtPriceX64)) { 641 | throw new Error("sqrtPriceX64 must greater than current"); 642 | } 643 | } 644 | const baseInput = amountSpecified.gt(ZERO); 645 | 646 | const state = { 647 | amountSpecifiedRemaining: amountSpecified, 648 | amountCalculated: ZERO, 649 | sqrtPriceX64: currentSqrtPriceX64, 650 | tick: currentTick, 651 | accounts: [] as PublicKey[], 652 | liquidity, 653 | feeAmount: new BN(0), 654 | }; 655 | let loopCount = 0; 656 | while ( 657 | !state.amountSpecifiedRemaining.eq(ZERO) && 658 | state.sqrtPriceX64 != sqrtPriceLimitX64 && 659 | state.tick < MAX_TICK && 660 | state.tick > MIN_TICK 661 | ) { 662 | if (loopCount > 10) { 663 | throw Error("liquidity limit"); 664 | } 665 | const step: Partial = {}; 666 | step.sqrtPriceStartX64 = state.sqrtPriceX64; 667 | const { nextTick: nextInitTick, tickArrayAddress, tickArrayStartTickIndex: tickAarrayStartIndex } = TickQuery.nextInitializedTick( 668 | programId, 669 | poolId, 670 | tickArrayCache, 671 | state.tick, 672 | tickSpacing, 673 | zeroForOne 674 | ); 675 | step.tickNext = nextInitTick.tick; 676 | step.initialized = nextInitTick.liquidityGross.gtn(0); 677 | if ( 678 | lastSavedTickArrayStartIndex !== tickAarrayStartIndex && 679 | tickArrayAddress 680 | ) { 681 | state.accounts.push(tickArrayAddress); 682 | lastSavedTickArrayStartIndex = tickAarrayStartIndex; 683 | } 684 | if (step.tickNext < MIN_TICK) { 685 | step.tickNext = MIN_TICK; 686 | } else if (step.tickNext > MAX_TICK) { 687 | step.tickNext = MAX_TICK; 688 | } 689 | 690 | step.sqrtPriceNextX64 = SqrtPriceMath.getSqrtPriceX64FromTick( 691 | step.tickNext 692 | ); 693 | let targetPrice: BN; 694 | if ( 695 | (zeroForOne && step.sqrtPriceNextX64.lt(sqrtPriceLimitX64)) || 696 | (!zeroForOne && step.sqrtPriceNextX64.gt(sqrtPriceLimitX64)) 697 | ) { 698 | targetPrice = sqrtPriceLimitX64; 699 | } else { 700 | targetPrice = step.sqrtPriceNextX64; 701 | } 702 | [state.sqrtPriceX64, step.amountIn, step.amountOut, step.feeAmount] = 703 | SwapMath.swapStepCompute( 704 | state.sqrtPriceX64, 705 | targetPrice, 706 | state.liquidity, 707 | state.amountSpecifiedRemaining, 708 | fee 709 | ); 710 | 711 | state.feeAmount = state.feeAmount.add(step.feeAmount) 712 | 713 | if (baseInput) { 714 | state.amountSpecifiedRemaining = state.amountSpecifiedRemaining.sub( 715 | step.amountIn.add(step.feeAmount) 716 | ); 717 | state.amountCalculated = state.amountCalculated.sub(step.amountOut); 718 | } else { 719 | state.amountSpecifiedRemaining = state.amountSpecifiedRemaining.add( 720 | step.amountOut 721 | ); 722 | state.amountCalculated = state.amountCalculated.add( 723 | step.amountIn.add(step.feeAmount) 724 | ); 725 | } 726 | if (state.sqrtPriceX64.eq(step.sqrtPriceNextX64)) { 727 | if (step.initialized) { 728 | let liquidityNet = nextInitTick.liquidityNet; 729 | if (zeroForOne) liquidityNet = liquidityNet.mul(NEGATIVE_ONE); 730 | state.liquidity = LiquidityMath.addDelta( 731 | state.liquidity, 732 | liquidityNet 733 | ); 734 | } 735 | state.tick = zeroForOne ? step.tickNext - 1 : step.tickNext; 736 | } else if (state.sqrtPriceX64 != step.sqrtPriceStartX64) { 737 | state.tick = SqrtPriceMath.getTickFromSqrtPriceX64(state.sqrtPriceX64); 738 | } 739 | ++loopCount; 740 | } 741 | 742 | try { 743 | const { tickArrayAddress, tickArrayStartTickIndex: tickAarrayStartIndex } = TickQuery.nextInitializedTickArray( 744 | programId, 745 | poolId, 746 | tickArrayCache, 747 | state.tick, 748 | tickSpacing, 749 | zeroForOne 750 | ); 751 | if ( 752 | lastSavedTickArrayStartIndex !== tickAarrayStartIndex && 753 | tickArrayAddress 754 | ) { 755 | state.accounts.push(tickArrayAddress); 756 | lastSavedTickArrayStartIndex = tickAarrayStartIndex; 757 | } 758 | } catch(e) { } 759 | 760 | return { 761 | amountCalculated: state.amountCalculated, 762 | feeAmount: state.feeAmount, 763 | sqrtPriceX64: state.sqrtPriceX64, 764 | liquidity: state.liquidity, 765 | tickCurrent: state.tick, 766 | accounts: state.accounts, 767 | }; 768 | } 769 | 770 | private static swapStepCompute( 771 | sqrtPriceX64Current: BN, 772 | sqrtPriceX64Target: BN, 773 | liquidity: BN, 774 | amountRemaining: BN, 775 | feeRate: Fee 776 | ): [BN, BN, BN, BN] { 777 | const swapStep: SwapStep = { 778 | sqrtPriceX64Next: new BN(0), 779 | amountIn: new BN(0), 780 | amountOut: new BN(0), 781 | feeAmount: new BN(0), 782 | }; 783 | 784 | const zeroForOne = sqrtPriceX64Current.gte(sqrtPriceX64Target); 785 | const baseInput = amountRemaining.gte(ZERO); 786 | 787 | if (baseInput) { 788 | const amountRemainingSubtractFee = MathUtil.mulDivFloor( 789 | amountRemaining, 790 | FEE_RATE_DENOMINATOR.sub(new BN(feeRate.toString())), 791 | FEE_RATE_DENOMINATOR 792 | ); 793 | swapStep.amountIn = zeroForOne 794 | ? LiquidityMath.getTokenAmountAFromLiquidity( 795 | sqrtPriceX64Target, 796 | sqrtPriceX64Current, 797 | liquidity, 798 | true 799 | ) 800 | : LiquidityMath.getTokenAmountBFromLiquidity( 801 | sqrtPriceX64Current, 802 | sqrtPriceX64Target, 803 | liquidity, 804 | true 805 | ); 806 | if (amountRemainingSubtractFee.gte(swapStep.amountIn)) { 807 | swapStep.sqrtPriceX64Next = sqrtPriceX64Target; 808 | } else { 809 | swapStep.sqrtPriceX64Next = SqrtPriceMath.getNextSqrtPriceX64FromInput( 810 | sqrtPriceX64Current, 811 | liquidity, 812 | amountRemainingSubtractFee, 813 | zeroForOne 814 | ); 815 | } 816 | } else { 817 | swapStep.amountOut = zeroForOne 818 | ? LiquidityMath.getTokenAmountBFromLiquidity( 819 | sqrtPriceX64Target, 820 | sqrtPriceX64Current, 821 | liquidity, 822 | false 823 | ) 824 | : LiquidityMath.getTokenAmountAFromLiquidity( 825 | sqrtPriceX64Current, 826 | sqrtPriceX64Target, 827 | liquidity, 828 | false 829 | ); 830 | if (amountRemaining.mul(NEGATIVE_ONE).gte(swapStep.amountOut)) { 831 | swapStep.sqrtPriceX64Next = sqrtPriceX64Target; 832 | } else { 833 | swapStep.sqrtPriceX64Next = SqrtPriceMath.getNextSqrtPriceX64FromOutput( 834 | sqrtPriceX64Current, 835 | liquidity, 836 | amountRemaining.mul(NEGATIVE_ONE), 837 | zeroForOne 838 | ); 839 | } 840 | } 841 | 842 | const reachTargetPrice = sqrtPriceX64Target.eq(swapStep.sqrtPriceX64Next); 843 | 844 | if (zeroForOne) { 845 | if (!(reachTargetPrice && baseInput)) { 846 | swapStep.amountIn = LiquidityMath.getTokenAmountAFromLiquidity( 847 | swapStep.sqrtPriceX64Next, 848 | sqrtPriceX64Current, 849 | liquidity, 850 | true 851 | ); 852 | } 853 | 854 | if (!(reachTargetPrice && !baseInput)) { 855 | swapStep.amountOut = LiquidityMath.getTokenAmountBFromLiquidity( 856 | swapStep.sqrtPriceX64Next, 857 | sqrtPriceX64Current, 858 | liquidity, 859 | false 860 | ); 861 | } 862 | } else { 863 | swapStep.amountIn = 864 | reachTargetPrice && baseInput 865 | ? swapStep.amountIn 866 | : LiquidityMath.getTokenAmountBFromLiquidity( 867 | sqrtPriceX64Current, 868 | swapStep.sqrtPriceX64Next, 869 | liquidity, 870 | true 871 | ); 872 | swapStep.amountOut = 873 | reachTargetPrice && !baseInput 874 | ? swapStep.amountOut 875 | : LiquidityMath.getTokenAmountAFromLiquidity( 876 | sqrtPriceX64Current, 877 | swapStep.sqrtPriceX64Next, 878 | liquidity, 879 | false 880 | ); 881 | } 882 | 883 | if ( 884 | !baseInput && 885 | swapStep.amountOut.gt(amountRemaining.mul(NEGATIVE_ONE)) 886 | ) { 887 | swapStep.amountOut = amountRemaining.mul(NEGATIVE_ONE); 888 | } 889 | if (baseInput && !swapStep.sqrtPriceX64Next.eq(sqrtPriceX64Target)) { 890 | swapStep.feeAmount = amountRemaining.sub(swapStep.amountIn); 891 | } else { 892 | swapStep.feeAmount = MathUtil.mulDivCeil( 893 | swapStep.amountIn, 894 | new BN(feeRate), 895 | FEE_RATE_DENOMINATOR.sub(new BN(feeRate)) 896 | ); 897 | } 898 | return [ 899 | swapStep.sqrtPriceX64Next, 900 | swapStep.amountIn, 901 | swapStep.amountOut, 902 | swapStep.feeAmount, 903 | ]; 904 | } 905 | } 906 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.10.5", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2": 6 | version "7.20.1" 7 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9" 8 | integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg== 9 | dependencies: 10 | regenerator-runtime "^0.13.10" 11 | 12 | "@esbuild/android-arm@0.15.13": 13 | version "0.15.13" 14 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.13.tgz#ce11237a13ee76d5eae3908e47ba4ddd380af86a" 15 | integrity sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw== 16 | 17 | "@esbuild/linux-loong64@0.15.13": 18 | version "0.15.13" 19 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz#64e8825bf0ce769dac94ee39d92ebe6272020dfc" 20 | integrity sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag== 21 | 22 | "@noble/ed25519@^1.7.0": 23 | version "1.7.1" 24 | resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.1.tgz#6899660f6fbb97798a6fbd227227c4589a454724" 25 | integrity sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw== 26 | 27 | "@noble/hashes@^1.1.2": 28 | version "1.1.3" 29 | resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.3.tgz#360afc77610e0a61f3417e497dcf36862e4f8111" 30 | integrity sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A== 31 | 32 | "@noble/secp256k1@^1.6.3": 33 | version "1.7.0" 34 | resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.0.tgz#d15357f7c227e751d90aa06b05a0e5cf993ba8c1" 35 | integrity sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw== 36 | 37 | "@nodelib/fs.scandir@2.1.5": 38 | version "2.1.5" 39 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 40 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 41 | dependencies: 42 | "@nodelib/fs.stat" "2.0.5" 43 | run-parallel "^1.1.9" 44 | 45 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 46 | version "2.0.5" 47 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 48 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 49 | 50 | "@nodelib/fs.walk@^1.2.3": 51 | version "1.2.8" 52 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 53 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 54 | dependencies: 55 | "@nodelib/fs.scandir" "2.1.5" 56 | fastq "^1.6.0" 57 | 58 | "@project-serum/anchor@0.24.2": 59 | version "0.24.2" 60 | resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.24.2.tgz#a3c52a99605c80735f446ca9b3a4885034731004" 61 | integrity sha512-0/718g8/DnEuwAidUwh5wLYphUYXhUbiClkuRNhvNoa+1Y8a4g2tJyxoae+emV+PG/Gikd/QUBNMkIcimiIRTA== 62 | dependencies: 63 | "@project-serum/borsh" "^0.2.5" 64 | "@solana/web3.js" "^1.36.0" 65 | base64-js "^1.5.1" 66 | bn.js "^5.1.2" 67 | bs58 "^4.0.1" 68 | buffer-layout "^1.2.2" 69 | camelcase "^5.3.1" 70 | cross-fetch "^3.1.5" 71 | crypto-hash "^1.3.0" 72 | eventemitter3 "^4.0.7" 73 | js-sha256 "^0.9.0" 74 | pako "^2.0.3" 75 | snake-case "^3.0.4" 76 | toml "^3.0.0" 77 | 78 | "@project-serum/borsh@^0.2.5": 79 | version "0.2.5" 80 | resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.5.tgz#6059287aa624ecebbfc0edd35e4c28ff987d8663" 81 | integrity sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q== 82 | dependencies: 83 | bn.js "^5.1.2" 84 | buffer-layout "^1.2.0" 85 | 86 | "@solana/buffer-layout@^4.0.0": 87 | version "4.0.0" 88 | resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz#75b1b11adc487234821c81dfae3119b73a5fd734" 89 | integrity sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ== 90 | dependencies: 91 | buffer "~6.0.3" 92 | 93 | "@solana/spl-token@0.1.8": 94 | version "0.1.8" 95 | resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.1.8.tgz#f06e746341ef8d04165e21fc7f555492a2a0faa6" 96 | integrity sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ== 97 | dependencies: 98 | "@babel/runtime" "^7.10.5" 99 | "@solana/web3.js" "^1.21.0" 100 | bn.js "^5.1.0" 101 | buffer "6.0.3" 102 | buffer-layout "^1.2.0" 103 | dotenv "10.0.0" 104 | 105 | "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.66.2": 106 | version "1.66.2" 107 | resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.66.2.tgz#80b43c5868b846124fe3ebac7d3943930c3fa60c" 108 | integrity sha512-RyaHMR2jGmaesnYP045VLeBGfR/gAW3cvZHzMFGg7bkO+WOYOYp1nEllf0/la4U4qsYGKCsO9eEevR5fhHiVHg== 109 | dependencies: 110 | "@babel/runtime" "^7.12.5" 111 | "@noble/ed25519" "^1.7.0" 112 | "@noble/hashes" "^1.1.2" 113 | "@noble/secp256k1" "^1.6.3" 114 | "@solana/buffer-layout" "^4.0.0" 115 | bigint-buffer "^1.1.5" 116 | bn.js "^5.0.0" 117 | borsh "^0.7.0" 118 | bs58 "^4.0.1" 119 | buffer "6.0.1" 120 | fast-stable-stringify "^1.0.0" 121 | jayson "^3.4.4" 122 | node-fetch "2" 123 | rpc-websockets "^7.5.0" 124 | superstruct "^0.14.2" 125 | 126 | "@types/connect@^3.4.33": 127 | version "3.4.35" 128 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" 129 | integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== 130 | dependencies: 131 | "@types/node" "*" 132 | 133 | "@types/node@*": 134 | version "18.11.9" 135 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" 136 | integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== 137 | 138 | "@types/node@^12.12.54": 139 | version "12.20.55" 140 | resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" 141 | integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== 142 | 143 | "@types/ws@^7.4.4": 144 | version "7.4.7" 145 | resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" 146 | integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== 147 | dependencies: 148 | "@types/node" "*" 149 | 150 | JSONStream@^1.3.5: 151 | version "1.3.5" 152 | resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" 153 | integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== 154 | dependencies: 155 | jsonparse "^1.2.0" 156 | through ">=2.2.7 <3" 157 | 158 | any-promise@^1.0.0: 159 | version "1.3.0" 160 | resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" 161 | integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== 162 | 163 | anymatch@~3.1.2: 164 | version "3.1.2" 165 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 166 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 167 | dependencies: 168 | normalize-path "^3.0.0" 169 | picomatch "^2.0.4" 170 | 171 | array-union@^2.1.0: 172 | version "2.1.0" 173 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" 174 | integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 175 | 176 | balanced-match@^1.0.0: 177 | version "1.0.2" 178 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 179 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 180 | 181 | base-x@^3.0.2: 182 | version "3.0.9" 183 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" 184 | integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== 185 | dependencies: 186 | safe-buffer "^5.0.1" 187 | 188 | base64-js@^1.3.1, base64-js@^1.5.1: 189 | version "1.5.1" 190 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 191 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 192 | 193 | bigint-buffer@^1.1.5: 194 | version "1.1.5" 195 | resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" 196 | integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== 197 | dependencies: 198 | bindings "^1.3.0" 199 | 200 | binary-extensions@^2.0.0: 201 | version "2.2.0" 202 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 203 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 204 | 205 | bindings@^1.3.0: 206 | version "1.5.0" 207 | resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" 208 | integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== 209 | dependencies: 210 | file-uri-to-path "1.0.0" 211 | 212 | bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.2.0: 213 | version "5.2.1" 214 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" 215 | integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== 216 | 217 | borsh@^0.7.0: 218 | version "0.7.0" 219 | resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" 220 | integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== 221 | dependencies: 222 | bn.js "^5.2.0" 223 | bs58 "^4.0.0" 224 | text-encoding-utf-8 "^1.0.2" 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 | braces@^3.0.2, braces@~3.0.2: 235 | version "3.0.2" 236 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 237 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 238 | dependencies: 239 | fill-range "^7.0.1" 240 | 241 | bs58@^4.0.0, bs58@^4.0.1: 242 | version "4.0.1" 243 | resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" 244 | integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== 245 | dependencies: 246 | base-x "^3.0.2" 247 | 248 | buffer-layout@^1.2.0, buffer-layout@^1.2.2: 249 | version "1.2.2" 250 | resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" 251 | integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== 252 | 253 | buffer@6.0.1: 254 | version "6.0.1" 255 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" 256 | integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== 257 | dependencies: 258 | base64-js "^1.3.1" 259 | ieee754 "^1.2.1" 260 | 261 | buffer@6.0.3, buffer@~6.0.3: 262 | version "6.0.3" 263 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" 264 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== 265 | dependencies: 266 | base64-js "^1.3.1" 267 | ieee754 "^1.2.1" 268 | 269 | bufferutil@^4.0.1: 270 | version "4.0.7" 271 | resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" 272 | integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== 273 | dependencies: 274 | node-gyp-build "^4.3.0" 275 | 276 | bundle-require@^3.1.2: 277 | version "3.1.2" 278 | resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-3.1.2.tgz#1374a7bdcb8b330a7ccc862ccbf7c137cc43ad27" 279 | integrity sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA== 280 | dependencies: 281 | load-tsconfig "^0.2.0" 282 | 283 | cac@^6.7.12: 284 | version "6.7.14" 285 | resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" 286 | integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== 287 | 288 | camelcase@^5.3.1: 289 | version "5.3.1" 290 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 291 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 292 | 293 | chokidar@^3.5.1: 294 | version "3.5.3" 295 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 296 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 297 | dependencies: 298 | anymatch "~3.1.2" 299 | braces "~3.0.2" 300 | glob-parent "~5.1.2" 301 | is-binary-path "~2.1.0" 302 | is-glob "~4.0.1" 303 | normalize-path "~3.0.0" 304 | readdirp "~3.6.0" 305 | optionalDependencies: 306 | fsevents "~2.3.2" 307 | 308 | commander@^2.20.3: 309 | version "2.20.3" 310 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 311 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 312 | 313 | commander@^4.0.0: 314 | version "4.1.1" 315 | resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" 316 | integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== 317 | 318 | concat-map@0.0.1: 319 | version "0.0.1" 320 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 321 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 322 | 323 | cross-fetch@^3.1.5: 324 | version "3.1.5" 325 | resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" 326 | integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== 327 | dependencies: 328 | node-fetch "2.6.7" 329 | 330 | cross-spawn@^7.0.3: 331 | version "7.0.3" 332 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 333 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 334 | dependencies: 335 | path-key "^3.1.0" 336 | shebang-command "^2.0.0" 337 | which "^2.0.1" 338 | 339 | crypto-hash@^1.3.0: 340 | version "1.3.0" 341 | resolved "https://registry.yarnpkg.com/crypto-hash/-/crypto-hash-1.3.0.tgz#b402cb08f4529e9f4f09346c3e275942f845e247" 342 | integrity sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg== 343 | 344 | debug@^4.3.1: 345 | version "4.3.4" 346 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 347 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 348 | dependencies: 349 | ms "2.1.2" 350 | 351 | decimal.js@^10.3.1: 352 | version "10.4.2" 353 | resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e" 354 | integrity sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA== 355 | 356 | delay@^5.0.0: 357 | version "5.0.0" 358 | resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" 359 | integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== 360 | 361 | dir-glob@^3.0.1: 362 | version "3.0.1" 363 | resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" 364 | integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== 365 | dependencies: 366 | path-type "^4.0.0" 367 | 368 | dot-case@^3.0.4: 369 | version "3.0.4" 370 | resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" 371 | integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== 372 | dependencies: 373 | no-case "^3.0.4" 374 | tslib "^2.0.3" 375 | 376 | dotenv@10.0.0: 377 | version "10.0.0" 378 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" 379 | integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== 380 | 381 | es6-promise@^4.0.3: 382 | version "4.2.8" 383 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" 384 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 385 | 386 | es6-promisify@^5.0.0: 387 | version "5.0.0" 388 | resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" 389 | integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== 390 | dependencies: 391 | es6-promise "^4.0.3" 392 | 393 | esbuild-android-64@0.15.13: 394 | version "0.15.13" 395 | resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz#5f25864055dbd62e250f360b38b4c382224063af" 396 | integrity sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g== 397 | 398 | esbuild-android-arm64@0.15.13: 399 | version "0.15.13" 400 | resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz#d8820f999314efbe8e0f050653a99ff2da632b0f" 401 | integrity sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w== 402 | 403 | esbuild-darwin-64@0.15.13: 404 | version "0.15.13" 405 | resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz#99ae7fdaa43947b06cd9d1a1c3c2c9f245d81fd0" 406 | integrity sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg== 407 | 408 | esbuild-darwin-arm64@0.15.13: 409 | version "0.15.13" 410 | resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz#bafa1814354ad1a47adcad73de416130ef7f55e3" 411 | integrity sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A== 412 | 413 | esbuild-freebsd-64@0.15.13: 414 | version "0.15.13" 415 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz#84ef85535c5cc38b627d1c5115623b088d1de161" 416 | integrity sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA== 417 | 418 | esbuild-freebsd-arm64@0.15.13: 419 | version "0.15.13" 420 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz#033f21de434ec8e0c478054b119af8056763c2d8" 421 | integrity sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q== 422 | 423 | esbuild-linux-32@0.15.13: 424 | version "0.15.13" 425 | resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz#54290ea8035cba0faf1791ce9ae6693005512535" 426 | integrity sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w== 427 | 428 | esbuild-linux-64@0.15.13: 429 | version "0.15.13" 430 | resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz#4264249281ea388ead948614b57fb1ddf7779a2c" 431 | integrity sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A== 432 | 433 | esbuild-linux-arm64@0.15.13: 434 | version "0.15.13" 435 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz#9323c333924f97a02bdd2ae8912b36298acb312d" 436 | integrity sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ== 437 | 438 | esbuild-linux-arm@0.15.13: 439 | version "0.15.13" 440 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz#b407f47b3ae721fe4e00e19e9f19289bef87a111" 441 | integrity sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ== 442 | 443 | esbuild-linux-mips64le@0.15.13: 444 | version "0.15.13" 445 | resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz#bdf905aae5c0bcaa8f83567fe4c4c1bdc1f14447" 446 | integrity sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A== 447 | 448 | esbuild-linux-ppc64le@0.15.13: 449 | version "0.15.13" 450 | resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz#2911eae1c90ff58a3bd3259cb557235df25aa3b4" 451 | integrity sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA== 452 | 453 | esbuild-linux-riscv64@0.15.13: 454 | version "0.15.13" 455 | resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz#1837c660be12b1d20d2a29c7189ea703f93e9265" 456 | integrity sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow== 457 | 458 | esbuild-linux-s390x@0.15.13: 459 | version "0.15.13" 460 | resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz#d52880ece229d1bd10b2d936b792914ffb07c7fc" 461 | integrity sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag== 462 | 463 | esbuild-netbsd-64@0.15.13: 464 | version "0.15.13" 465 | resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz#de14da46f1d20352b43e15d97a80a8788275e6ed" 466 | integrity sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ== 467 | 468 | esbuild-openbsd-64@0.15.13: 469 | version "0.15.13" 470 | resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz#45e8a5fd74d92ad8f732c43582369c7990f5a0ac" 471 | integrity sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w== 472 | 473 | esbuild-sunos-64@0.15.13: 474 | version "0.15.13" 475 | resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz#f646ac3da7aac521ee0fdbc192750c87da697806" 476 | integrity sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw== 477 | 478 | esbuild-windows-32@0.15.13: 479 | version "0.15.13" 480 | resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz#fb4fe77c7591418880b3c9b5900adc4c094f2401" 481 | integrity sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA== 482 | 483 | esbuild-windows-64@0.15.13: 484 | version "0.15.13" 485 | resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz#1fca8c654392c0c31bdaaed168becfea80e20660" 486 | integrity sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ== 487 | 488 | esbuild-windows-arm64@0.15.13: 489 | version "0.15.13" 490 | resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz#4ffd01b6b2888603f1584a2fe96b1f6a6f2b3dd8" 491 | integrity sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg== 492 | 493 | esbuild@^0.15.1: 494 | version "0.15.13" 495 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.13.tgz#7293480038feb2bafa91d3f6a20edab3ba6c108a" 496 | integrity sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ== 497 | optionalDependencies: 498 | "@esbuild/android-arm" "0.15.13" 499 | "@esbuild/linux-loong64" "0.15.13" 500 | esbuild-android-64 "0.15.13" 501 | esbuild-android-arm64 "0.15.13" 502 | esbuild-darwin-64 "0.15.13" 503 | esbuild-darwin-arm64 "0.15.13" 504 | esbuild-freebsd-64 "0.15.13" 505 | esbuild-freebsd-arm64 "0.15.13" 506 | esbuild-linux-32 "0.15.13" 507 | esbuild-linux-64 "0.15.13" 508 | esbuild-linux-arm "0.15.13" 509 | esbuild-linux-arm64 "0.15.13" 510 | esbuild-linux-mips64le "0.15.13" 511 | esbuild-linux-ppc64le "0.15.13" 512 | esbuild-linux-riscv64 "0.15.13" 513 | esbuild-linux-s390x "0.15.13" 514 | esbuild-netbsd-64 "0.15.13" 515 | esbuild-openbsd-64 "0.15.13" 516 | esbuild-sunos-64 "0.15.13" 517 | esbuild-windows-32 "0.15.13" 518 | esbuild-windows-64 "0.15.13" 519 | esbuild-windows-arm64 "0.15.13" 520 | 521 | eventemitter3@^4.0.7: 522 | version "4.0.7" 523 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" 524 | integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== 525 | 526 | execa@^5.0.0: 527 | version "5.1.1" 528 | resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" 529 | integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== 530 | dependencies: 531 | cross-spawn "^7.0.3" 532 | get-stream "^6.0.0" 533 | human-signals "^2.1.0" 534 | is-stream "^2.0.0" 535 | merge-stream "^2.0.0" 536 | npm-run-path "^4.0.1" 537 | onetime "^5.1.2" 538 | signal-exit "^3.0.3" 539 | strip-final-newline "^2.0.0" 540 | 541 | eyes@^0.1.8: 542 | version "0.1.8" 543 | resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" 544 | integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== 545 | 546 | fast-glob@^3.2.9: 547 | version "3.2.12" 548 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" 549 | integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== 550 | dependencies: 551 | "@nodelib/fs.stat" "^2.0.2" 552 | "@nodelib/fs.walk" "^1.2.3" 553 | glob-parent "^5.1.2" 554 | merge2 "^1.3.0" 555 | micromatch "^4.0.4" 556 | 557 | fast-stable-stringify@^1.0.0: 558 | version "1.0.0" 559 | resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" 560 | integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== 561 | 562 | fastq@^1.6.0: 563 | version "1.13.0" 564 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" 565 | integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== 566 | dependencies: 567 | reusify "^1.0.4" 568 | 569 | file-uri-to-path@1.0.0: 570 | version "1.0.0" 571 | resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" 572 | integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== 573 | 574 | fill-range@^7.0.1: 575 | version "7.0.1" 576 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 577 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 578 | dependencies: 579 | to-regex-range "^5.0.1" 580 | 581 | fs.realpath@^1.0.0: 582 | version "1.0.0" 583 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 584 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 585 | 586 | fsevents@~2.3.2: 587 | version "2.3.2" 588 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 589 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 590 | 591 | get-stream@^6.0.0: 592 | version "6.0.1" 593 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" 594 | integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== 595 | 596 | glob-parent@^5.1.2, glob-parent@~5.1.2: 597 | version "5.1.2" 598 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 599 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 600 | dependencies: 601 | is-glob "^4.0.1" 602 | 603 | glob@7.1.6: 604 | version "7.1.6" 605 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 606 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 607 | dependencies: 608 | fs.realpath "^1.0.0" 609 | inflight "^1.0.4" 610 | inherits "2" 611 | minimatch "^3.0.4" 612 | once "^1.3.0" 613 | path-is-absolute "^1.0.0" 614 | 615 | globby@^11.0.3: 616 | version "11.1.0" 617 | resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" 618 | integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== 619 | dependencies: 620 | array-union "^2.1.0" 621 | dir-glob "^3.0.1" 622 | fast-glob "^3.2.9" 623 | ignore "^5.2.0" 624 | merge2 "^1.4.1" 625 | slash "^3.0.0" 626 | 627 | human-signals@^2.1.0: 628 | version "2.1.0" 629 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" 630 | integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== 631 | 632 | ieee754@^1.2.1: 633 | version "1.2.1" 634 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 635 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 636 | 637 | ignore@^5.2.0: 638 | version "5.2.0" 639 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" 640 | integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== 641 | 642 | inflight@^1.0.4: 643 | version "1.0.6" 644 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 645 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 646 | dependencies: 647 | once "^1.3.0" 648 | wrappy "1" 649 | 650 | inherits@2: 651 | version "2.0.4" 652 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 653 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 654 | 655 | is-binary-path@~2.1.0: 656 | version "2.1.0" 657 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 658 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 659 | dependencies: 660 | binary-extensions "^2.0.0" 661 | 662 | is-extglob@^2.1.1: 663 | version "2.1.1" 664 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 665 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 666 | 667 | is-glob@^4.0.1, is-glob@~4.0.1: 668 | version "4.0.3" 669 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 670 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 671 | dependencies: 672 | is-extglob "^2.1.1" 673 | 674 | is-number@^7.0.0: 675 | version "7.0.0" 676 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 677 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 678 | 679 | is-stream@^2.0.0: 680 | version "2.0.1" 681 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 682 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 683 | 684 | isexe@^2.0.0: 685 | version "2.0.0" 686 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 687 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 688 | 689 | isomorphic-ws@^4.0.1: 690 | version "4.0.1" 691 | resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" 692 | integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== 693 | 694 | jayson@^3.4.4: 695 | version "3.7.0" 696 | resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" 697 | integrity sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ== 698 | dependencies: 699 | "@types/connect" "^3.4.33" 700 | "@types/node" "^12.12.54" 701 | "@types/ws" "^7.4.4" 702 | JSONStream "^1.3.5" 703 | commander "^2.20.3" 704 | delay "^5.0.0" 705 | es6-promisify "^5.0.0" 706 | eyes "^0.1.8" 707 | isomorphic-ws "^4.0.1" 708 | json-stringify-safe "^5.0.1" 709 | lodash "^4.17.20" 710 | uuid "^8.3.2" 711 | ws "^7.4.5" 712 | 713 | joycon@^3.0.1: 714 | version "3.1.1" 715 | resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" 716 | integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== 717 | 718 | js-sha256@^0.9.0: 719 | version "0.9.0" 720 | resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" 721 | integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== 722 | 723 | json-stringify-safe@^5.0.1: 724 | version "5.0.1" 725 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 726 | integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== 727 | 728 | jsonparse@^1.2.0: 729 | version "1.3.1" 730 | resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" 731 | integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== 732 | 733 | lilconfig@^2.0.5: 734 | version "2.0.6" 735 | resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" 736 | integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== 737 | 738 | lines-and-columns@^1.1.6: 739 | version "1.2.4" 740 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" 741 | integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== 742 | 743 | load-tsconfig@^0.2.0: 744 | version "0.2.3" 745 | resolved "https://registry.yarnpkg.com/load-tsconfig/-/load-tsconfig-0.2.3.tgz#08af3e7744943caab0c75f8af7f1703639c3ef1f" 746 | integrity sha512-iyT2MXws+dc2Wi6o3grCFtGXpeMvHmJqS27sMPGtV2eUu4PeFnG+33I8BlFK1t1NWMjOpcx9bridn5yxLDX2gQ== 747 | 748 | lodash.sortby@^4.7.0: 749 | version "4.7.0" 750 | resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" 751 | integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== 752 | 753 | lodash@^4.17.20: 754 | version "4.17.21" 755 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 756 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 757 | 758 | lower-case@^2.0.2: 759 | version "2.0.2" 760 | resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" 761 | integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== 762 | dependencies: 763 | tslib "^2.0.3" 764 | 765 | merge-stream@^2.0.0: 766 | version "2.0.0" 767 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 768 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 769 | 770 | merge2@^1.3.0, merge2@^1.4.1: 771 | version "1.4.1" 772 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 773 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 774 | 775 | micromatch@^4.0.4: 776 | version "4.0.5" 777 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" 778 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== 779 | dependencies: 780 | braces "^3.0.2" 781 | picomatch "^2.3.1" 782 | 783 | mimic-fn@^2.1.0: 784 | version "2.1.0" 785 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 786 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 787 | 788 | minimatch@^3.0.4: 789 | version "3.1.2" 790 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 791 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 792 | dependencies: 793 | brace-expansion "^1.1.7" 794 | 795 | ms@2.1.2: 796 | version "2.1.2" 797 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 798 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 799 | 800 | mz@^2.7.0: 801 | version "2.7.0" 802 | resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" 803 | integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== 804 | dependencies: 805 | any-promise "^1.0.0" 806 | object-assign "^4.0.1" 807 | thenify-all "^1.0.0" 808 | 809 | no-case@^3.0.4: 810 | version "3.0.4" 811 | resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" 812 | integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== 813 | dependencies: 814 | lower-case "^2.0.2" 815 | tslib "^2.0.3" 816 | 817 | node-fetch@2, node-fetch@2.6.7: 818 | version "2.6.7" 819 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" 820 | integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== 821 | dependencies: 822 | whatwg-url "^5.0.0" 823 | 824 | node-gyp-build@^4.3.0: 825 | version "4.5.0" 826 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" 827 | integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== 828 | 829 | normalize-path@^3.0.0, normalize-path@~3.0.0: 830 | version "3.0.0" 831 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 832 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 833 | 834 | npm-run-path@^4.0.1: 835 | version "4.0.1" 836 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" 837 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== 838 | dependencies: 839 | path-key "^3.0.0" 840 | 841 | object-assign@^4.0.1: 842 | version "4.1.1" 843 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 844 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 845 | 846 | once@^1.3.0: 847 | version "1.4.0" 848 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 849 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 850 | dependencies: 851 | wrappy "1" 852 | 853 | onetime@^5.1.2: 854 | version "5.1.2" 855 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 856 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 857 | dependencies: 858 | mimic-fn "^2.1.0" 859 | 860 | pako@^2.0.3: 861 | version "2.0.4" 862 | resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" 863 | integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== 864 | 865 | path-is-absolute@^1.0.0: 866 | version "1.0.1" 867 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 868 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 869 | 870 | path-key@^3.0.0, path-key@^3.1.0: 871 | version "3.1.1" 872 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 873 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 874 | 875 | path-type@^4.0.0: 876 | version "4.0.0" 877 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 878 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 879 | 880 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: 881 | version "2.3.1" 882 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 883 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 884 | 885 | pirates@^4.0.1: 886 | version "4.0.5" 887 | resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" 888 | integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== 889 | 890 | postcss-load-config@^3.0.1: 891 | version "3.1.4" 892 | resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" 893 | integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== 894 | dependencies: 895 | lilconfig "^2.0.5" 896 | yaml "^1.10.2" 897 | 898 | punycode@^2.1.0: 899 | version "2.1.1" 900 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 901 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 902 | 903 | queue-microtask@^1.2.2: 904 | version "1.2.3" 905 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 906 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 907 | 908 | readdirp@~3.6.0: 909 | version "3.6.0" 910 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 911 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 912 | dependencies: 913 | picomatch "^2.2.1" 914 | 915 | regenerator-runtime@^0.13.10: 916 | version "0.13.10" 917 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" 918 | integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== 919 | 920 | resolve-from@^5.0.0: 921 | version "5.0.0" 922 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" 923 | integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== 924 | 925 | reusify@^1.0.4: 926 | version "1.0.4" 927 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 928 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 929 | 930 | rollup@^3.2.5: 931 | version "3.2.5" 932 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.2.5.tgz#9452168ac083218c8212bf53d2448bdc6b8b0de7" 933 | integrity sha512-/Ha7HhVVofduy+RKWOQJrxe4Qb3xyZo+chcpYiD8SoQa4AG7llhupUtyfKSSrdBM2mWJjhM8wZwmbY23NmlIYw== 934 | optionalDependencies: 935 | fsevents "~2.3.2" 936 | 937 | rpc-websockets@^7.5.0: 938 | version "7.5.0" 939 | resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.0.tgz#bbeb87572e66703ff151e50af1658f98098e2748" 940 | integrity sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ== 941 | dependencies: 942 | "@babel/runtime" "^7.17.2" 943 | eventemitter3 "^4.0.7" 944 | uuid "^8.3.2" 945 | ws "^8.5.0" 946 | optionalDependencies: 947 | bufferutil "^4.0.1" 948 | utf-8-validate "^5.0.2" 949 | 950 | run-parallel@^1.1.9: 951 | version "1.2.0" 952 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 953 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 954 | dependencies: 955 | queue-microtask "^1.2.2" 956 | 957 | safe-buffer@^5.0.1: 958 | version "5.2.1" 959 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 960 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 961 | 962 | shebang-command@^2.0.0: 963 | version "2.0.0" 964 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 965 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 966 | dependencies: 967 | shebang-regex "^3.0.0" 968 | 969 | shebang-regex@^3.0.0: 970 | version "3.0.0" 971 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 972 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 973 | 974 | signal-exit@^3.0.3: 975 | version "3.0.7" 976 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 977 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 978 | 979 | slash@^3.0.0: 980 | version "3.0.0" 981 | resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" 982 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 983 | 984 | snake-case@^3.0.4: 985 | version "3.0.4" 986 | resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" 987 | integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== 988 | dependencies: 989 | dot-case "^3.0.4" 990 | tslib "^2.0.3" 991 | 992 | source-map@0.8.0-beta.0: 993 | version "0.8.0-beta.0" 994 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" 995 | integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== 996 | dependencies: 997 | whatwg-url "^7.0.0" 998 | 999 | strip-final-newline@^2.0.0: 1000 | version "2.0.0" 1001 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" 1002 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== 1003 | 1004 | sucrase@^3.20.3: 1005 | version "3.28.0" 1006 | resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.28.0.tgz#7fd8b3118d2155fcdf291088ab77fa6eefd63c4c" 1007 | integrity sha512-TK9600YInjuiIhVM3729rH4ZKPOsGeyXUwY+Ugu9eilNbdTFyHr6XcAGYbRVZPDgWj6tgI7bx95aaJjHnbffag== 1008 | dependencies: 1009 | commander "^4.0.0" 1010 | glob "7.1.6" 1011 | lines-and-columns "^1.1.6" 1012 | mz "^2.7.0" 1013 | pirates "^4.0.1" 1014 | ts-interface-checker "^0.1.9" 1015 | 1016 | superstruct@^0.14.2: 1017 | version "0.14.2" 1018 | resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" 1019 | integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== 1020 | 1021 | text-encoding-utf-8@^1.0.2: 1022 | version "1.0.2" 1023 | resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" 1024 | integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== 1025 | 1026 | thenify-all@^1.0.0: 1027 | version "1.6.0" 1028 | resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" 1029 | integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== 1030 | dependencies: 1031 | thenify ">= 3.1.0 < 4" 1032 | 1033 | "thenify@>= 3.1.0 < 4": 1034 | version "3.3.1" 1035 | resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" 1036 | integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== 1037 | dependencies: 1038 | any-promise "^1.0.0" 1039 | 1040 | "through@>=2.2.7 <3": 1041 | version "2.3.8" 1042 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1043 | integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== 1044 | 1045 | to-regex-range@^5.0.1: 1046 | version "5.0.1" 1047 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1048 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1049 | dependencies: 1050 | is-number "^7.0.0" 1051 | 1052 | toml@^3.0.0: 1053 | version "3.0.0" 1054 | resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" 1055 | integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== 1056 | 1057 | tr46@^1.0.1: 1058 | version "1.0.1" 1059 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" 1060 | integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== 1061 | dependencies: 1062 | punycode "^2.1.0" 1063 | 1064 | tr46@~0.0.3: 1065 | version "0.0.3" 1066 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 1067 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 1068 | 1069 | tree-kill@^1.2.2: 1070 | version "1.2.2" 1071 | resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" 1072 | integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== 1073 | 1074 | ts-interface-checker@^0.1.9: 1075 | version "0.1.13" 1076 | resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" 1077 | integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== 1078 | 1079 | tslib@^2.0.3: 1080 | version "2.4.1" 1081 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" 1082 | integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== 1083 | 1084 | tsup@^6.4.0: 1085 | version "6.4.0" 1086 | resolved "https://registry.yarnpkg.com/tsup/-/tsup-6.4.0.tgz#d860955c5b248a61959a97dbae5e0365129b9fa4" 1087 | integrity sha512-4OlbqIK/SF+cJp0mMqPM2pKULvgj/1S2Gm3I1aFoFGIryUOyIqPZBoqKkqVQT6uFtWJ5AHftIv0riXKfHox1zQ== 1088 | dependencies: 1089 | bundle-require "^3.1.2" 1090 | cac "^6.7.12" 1091 | chokidar "^3.5.1" 1092 | debug "^4.3.1" 1093 | esbuild "^0.15.1" 1094 | execa "^5.0.0" 1095 | globby "^11.0.3" 1096 | joycon "^3.0.1" 1097 | postcss-load-config "^3.0.1" 1098 | resolve-from "^5.0.0" 1099 | rollup "^3.2.5" 1100 | source-map "0.8.0-beta.0" 1101 | sucrase "^3.20.3" 1102 | tree-kill "^1.2.2" 1103 | 1104 | typescript@^4.4.4: 1105 | version "4.8.4" 1106 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" 1107 | integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== 1108 | 1109 | utf-8-validate@^5.0.2: 1110 | version "5.0.10" 1111 | resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" 1112 | integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== 1113 | dependencies: 1114 | node-gyp-build "^4.3.0" 1115 | 1116 | uuid@^8.3.2: 1117 | version "8.3.2" 1118 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" 1119 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 1120 | 1121 | webidl-conversions@^3.0.0: 1122 | version "3.0.1" 1123 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 1124 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 1125 | 1126 | webidl-conversions@^4.0.2: 1127 | version "4.0.2" 1128 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" 1129 | integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== 1130 | 1131 | whatwg-url@^5.0.0: 1132 | version "5.0.0" 1133 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 1134 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 1135 | dependencies: 1136 | tr46 "~0.0.3" 1137 | webidl-conversions "^3.0.0" 1138 | 1139 | whatwg-url@^7.0.0: 1140 | version "7.1.0" 1141 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" 1142 | integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== 1143 | dependencies: 1144 | lodash.sortby "^4.7.0" 1145 | tr46 "^1.0.1" 1146 | webidl-conversions "^4.0.2" 1147 | 1148 | which@^2.0.1: 1149 | version "2.0.2" 1150 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1151 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1152 | dependencies: 1153 | isexe "^2.0.0" 1154 | 1155 | wrappy@1: 1156 | version "1.0.2" 1157 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1158 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1159 | 1160 | ws@^7.4.5: 1161 | version "7.5.9" 1162 | resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" 1163 | integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== 1164 | 1165 | ws@^8.5.0: 1166 | version "8.10.0" 1167 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.10.0.tgz#00a28c09dfb76eae4eb45c3b565f771d6951aa51" 1168 | integrity sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw== 1169 | 1170 | yaml@^1.10.2: 1171 | version "1.10.2" 1172 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" 1173 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== 1174 | --------------------------------------------------------------------------------