Raydium CLMM (#7)
* raydium_clamm in mango-router --------- Co-authored-by: Maximilian Schneider <mail@maximilianschneider.net>
This commit is contained in:
parent
36a28e979e
commit
20c4c2bebd
|
@ -15,12 +15,15 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@blockworks-foundation/mango-v4": "^0.9.5",
|
||||
"@noble/hashes": "^1.3.1",
|
||||
"@orca-so/common-sdk": "^0.1.12",
|
||||
"@orca-so/whirlpools-sdk": "^0.8.2",
|
||||
"@project-serum/anchor": "^0.26.0",
|
||||
"@raydium-io/raydium-sdk": "^1.3.1-beta.8",
|
||||
"@solana/web3.js": "^1.70.1",
|
||||
"@types/bn.js": "^5.1.1",
|
||||
"@types/node": "^18.11.18",
|
||||
"bs58": "^5.0.0",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.18.2",
|
||||
"express-prom-bundle": "^6.6.0",
|
||||
|
|
282
src/router.ts
282
src/router.ts
|
@ -16,8 +16,12 @@ import {
|
|||
swapQuoteByOutputToken,
|
||||
} from "@orca-so/whirlpools-sdk";
|
||||
import { AnchorProvider, BorshAccountsCoder, Idl } from "@project-serum/anchor";
|
||||
import { PublicKey, TransactionInstruction } from "@solana/web3.js";
|
||||
import { AmmV3, AmmV3PoolInfo, ApiAmmV3PoolsItem, MAINNET_PROGRAM_ID, PoolInfoLayout, ReturnTypeComputeAmountOut, ReturnTypeComputeAmountOutBaseOut, ReturnTypeFetchMultipleMintInfos, ReturnTypeFetchMultiplePoolInfos, ReturnTypeFetchMultiplePoolTickArrays, SqrtPriceMath, fetchMultipleMintInfos } from "@raydium-io/raydium-sdk";
|
||||
import { Connection, EpochInfo, PublicKey, TransactionInstruction } from "@solana/web3.js";
|
||||
import { sha256 } from "@noble/hashes/sha256";
|
||||
import BN from "bn.js";
|
||||
import bs58 from 'bs58';
|
||||
|
||||
|
||||
export interface DepthResult {
|
||||
label: string;
|
||||
|
@ -199,6 +203,158 @@ class WhirlpoolEdge implements Edge {
|
|||
}
|
||||
}
|
||||
|
||||
class RaydiumEdge implements Edge {
|
||||
constructor(
|
||||
public label: string,
|
||||
public inputMint: PublicKey,
|
||||
public outputMint: PublicKey,
|
||||
public poolPk: PublicKey,
|
||||
public raydiumCache: RaydiumCache,
|
||||
) {}
|
||||
|
||||
static pairFromPool(poolInfo: AmmV3PoolInfo, raydiumCache: RaydiumCache): Edge[] {
|
||||
const label = "raydium: " + poolInfo.id;
|
||||
const fwd = new RaydiumEdge(
|
||||
label,
|
||||
new PublicKey(poolInfo.mintA.mint),
|
||||
new PublicKey(poolInfo.mintB.mint),
|
||||
new PublicKey(poolInfo.id),
|
||||
raydiumCache,
|
||||
);
|
||||
const bwd = new RaydiumEdge(
|
||||
label,
|
||||
new PublicKey(poolInfo.mintB.mint),
|
||||
new PublicKey(poolInfo.mintA.mint),
|
||||
new PublicKey(poolInfo.id),
|
||||
raydiumCache,
|
||||
);
|
||||
return [fwd, bwd];
|
||||
}
|
||||
|
||||
async swap(
|
||||
amount: BN,
|
||||
otherAmountThreshold: BN,
|
||||
mode: SwapMode,
|
||||
slippage: number
|
||||
): Promise<SwapResult> {
|
||||
try {
|
||||
let ok: boolean = false;
|
||||
let fee: BN;
|
||||
let maxAmtIn: BN;
|
||||
let minAmtOut: BN;
|
||||
let feeRate: number;
|
||||
|
||||
if (mode === SwapMode.ExactIn) {
|
||||
let amountOut: ReturnTypeComputeAmountOut = AmmV3.computeAmountOut(
|
||||
{
|
||||
poolInfo: this.raydiumCache.poolInfos[this.poolPk.toBase58()].state,
|
||||
tickArrayCache: this.raydiumCache.tickArrayByPoolIds[this.poolPk.toBase58()],
|
||||
baseMint: this.inputMint,
|
||||
token2022Infos: this.raydiumCache.mintInfos,
|
||||
epochInfo: this.raydiumCache.epochInfo,
|
||||
amountIn: amount,
|
||||
slippage: slippage,
|
||||
}
|
||||
);
|
||||
ok = otherAmountThreshold.lte(amountOut.amountOut.amount);
|
||||
fee = amountOut.fee;
|
||||
maxAmtIn = amountOut.realAmountIn.amount;
|
||||
feeRate = fee.toNumber() / maxAmtIn.toNumber();
|
||||
minAmtOut = amountOut.minAmountOut.amount;
|
||||
} else {
|
||||
let amountIn: ReturnTypeComputeAmountOutBaseOut = AmmV3.computeAmountIn(
|
||||
{
|
||||
poolInfo: this.raydiumCache.poolInfos[this.poolPk.toBase58()].state,
|
||||
tickArrayCache: this.raydiumCache.tickArrayByPoolIds[this.poolPk.toBase58()],
|
||||
baseMint: this.outputMint,
|
||||
token2022Infos: this.raydiumCache.mintInfos,
|
||||
epochInfo: this.raydiumCache.epochInfo,
|
||||
amountOut: amount,
|
||||
slippage: slippage,
|
||||
}
|
||||
);
|
||||
ok = otherAmountThreshold.lte(amountIn.amountIn.amount);
|
||||
fee = amountIn.fee;
|
||||
maxAmtIn = amountIn.maxAmountIn.amount;
|
||||
feeRate = fee.toNumber() / maxAmtIn.toNumber();
|
||||
minAmtOut = amountIn.realAmountOut.amount;
|
||||
}
|
||||
|
||||
let instructions = async (wallet: PublicKey) => {
|
||||
const tokenIn = await getAssociatedTokenAddress(this.inputMint, wallet);
|
||||
const tokenOut = await getAssociatedTokenAddress(
|
||||
this.outputMint,
|
||||
wallet
|
||||
);
|
||||
|
||||
const swapIx = AmmV3.makeSwapBaseInInstructions({
|
||||
poolInfo: this.raydiumCache.poolInfos[this.poolPk.toBase58()].state,
|
||||
ownerInfo: {
|
||||
wallet: wallet,
|
||||
tokenAccountA: tokenIn,
|
||||
tokenAccountB: tokenOut,
|
||||
},
|
||||
inputMint: this.inputMint,
|
||||
amountIn: amount,
|
||||
amountOutMin: otherAmountThreshold,
|
||||
sqrtPriceLimitX64: new BN(slippage),
|
||||
remainingAccounts: [],
|
||||
});
|
||||
return swapIx.innerTransaction.instructions;
|
||||
};
|
||||
|
||||
return {
|
||||
ok: ok,
|
||||
instructions,
|
||||
label: this.poolPk.toString(),
|
||||
marketInfos: [
|
||||
{
|
||||
label: "Raydium",
|
||||
fee: {
|
||||
amount: fee,
|
||||
mint: this.inputMint,
|
||||
rate: feeRate,
|
||||
},
|
||||
},
|
||||
],
|
||||
maxAmtIn: maxAmtIn,
|
||||
minAmtOut: minAmtOut,
|
||||
mints: [this.inputMint, this.outputMint],
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
ok: false,
|
||||
label: "",
|
||||
marketInfos: [],
|
||||
maxAmtIn: amount,
|
||||
minAmtOut: otherAmountThreshold,
|
||||
mints: [this.inputMint, this.outputMint],
|
||||
instructions: async () => [],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class RaydiumCache {
|
||||
epochInfo: EpochInfo;
|
||||
mintInfos: ReturnTypeFetchMultipleMintInfos;
|
||||
|
||||
poolInfos: ReturnTypeFetchMultiplePoolInfos;
|
||||
tickArrayByPoolIds: ReturnTypeFetchMultiplePoolTickArrays;
|
||||
|
||||
constructor(
|
||||
epochInfo: EpochInfo,
|
||||
mintInfos: ReturnTypeFetchMultipleMintInfos,
|
||||
poolInfos: ReturnTypeFetchMultiplePoolInfos,
|
||||
tickArrayByPoolIds: ReturnTypeFetchMultiplePoolTickArrays,
|
||||
) {
|
||||
this.epochInfo = epochInfo;
|
||||
this.mintInfos = mintInfos;
|
||||
this.poolInfos = poolInfos;
|
||||
this.tickArrayByPoolIds = tickArrayByPoolIds;
|
||||
}
|
||||
}
|
||||
|
||||
export class Router {
|
||||
minTvl: number;
|
||||
routes: Map<string, Map<string, Edge[]>>;
|
||||
|
@ -206,12 +362,17 @@ export class Router {
|
|||
whirlpoolClient: WhirlpoolClient;
|
||||
whirlpoolSub?: number;
|
||||
|
||||
connection: Connection;
|
||||
raydiumCache?: RaydiumCache;
|
||||
raydiumPoolInfoSub?: number;
|
||||
|
||||
constructor(anchorProvider: AnchorProvider, minTvl: number) {
|
||||
this.minTvl = minTvl;
|
||||
this.routes = new Map();
|
||||
this.whirlpoolClient = buildWhirlpoolClient(
|
||||
WhirlpoolContext.withProvider(anchorProvider, ORCA_WHIRLPOOL_PROGRAM_ID)
|
||||
);
|
||||
this.connection = anchorProvider.connection;
|
||||
}
|
||||
|
||||
public async start(): Promise<void> {
|
||||
|
@ -235,6 +396,60 @@ export class Router {
|
|||
},
|
||||
"processed"
|
||||
);
|
||||
|
||||
await this.indexRaydium();
|
||||
|
||||
// Only the poolInfo is worth updating. tickArray and mintInfos should not change.
|
||||
const poolInfoDiscriminator = Buffer.from(
|
||||
sha256("account:PoolState")
|
||||
).slice(0, 8);
|
||||
this.raydiumPoolInfoSub = this.connection.onProgramAccountChange(
|
||||
MAINNET_PROGRAM_ID.CLMM,
|
||||
(p) => {
|
||||
const key = p.accountId.toBase58();
|
||||
const accountData = p.accountInfo.data;
|
||||
const layoutAccountInfo = PoolInfoLayout.decode(accountData);
|
||||
|
||||
// Cache only holds those filtered with enough TVL.
|
||||
if (!(key in this.raydiumCache!.poolInfos)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Most of these fields dont matter, but update anyways.
|
||||
this.raydiumCache!.poolInfos[key] = {
|
||||
state: {
|
||||
...this.raydiumCache!.poolInfos[key].state,
|
||||
observationId: layoutAccountInfo.observationId,
|
||||
creator: layoutAccountInfo.creator,
|
||||
version: 6,
|
||||
tickSpacing: layoutAccountInfo.tickSpacing,
|
||||
liquidity: layoutAccountInfo.liquidity,
|
||||
sqrtPriceX64: layoutAccountInfo.sqrtPriceX64,
|
||||
currentPrice: SqrtPriceMath.sqrtPriceX64ToPrice(
|
||||
layoutAccountInfo.sqrtPriceX64,
|
||||
layoutAccountInfo.mintDecimalsA,
|
||||
layoutAccountInfo.mintDecimalsB
|
||||
),
|
||||
tickCurrent: layoutAccountInfo.tickCurrent,
|
||||
observationIndex: layoutAccountInfo.observationIndex,
|
||||
observationUpdateDuration:
|
||||
layoutAccountInfo.observationUpdateDuration,
|
||||
feeGrowthGlobalX64A: layoutAccountInfo.feeGrowthGlobalX64A,
|
||||
feeGrowthGlobalX64B: layoutAccountInfo.feeGrowthGlobalX64B,
|
||||
protocolFeesTokenA: layoutAccountInfo.protocolFeesTokenA,
|
||||
protocolFeesTokenB: layoutAccountInfo.protocolFeesTokenB,
|
||||
swapInAmountTokenA: layoutAccountInfo.swapInAmountTokenA,
|
||||
swapOutAmountTokenB: layoutAccountInfo.swapOutAmountTokenB,
|
||||
swapInAmountTokenB: layoutAccountInfo.swapInAmountTokenB,
|
||||
swapOutAmountTokenA: layoutAccountInfo.swapOutAmountTokenA,
|
||||
tickArrayBitmap: layoutAccountInfo.tickArrayBitmap,
|
||||
startTime: layoutAccountInfo.startTime.toNumber(),
|
||||
},
|
||||
};
|
||||
},
|
||||
"processed",
|
||||
[{ memcmp: { offset: 0, bytes: bs58.encode(poolInfoDiscriminator) } }]
|
||||
);
|
||||
}
|
||||
|
||||
public async stop(): Promise<void> {
|
||||
|
@ -243,6 +458,9 @@ export class Router {
|
|||
.getContext()
|
||||
.connection.removeProgramAccountChangeListener(this.whirlpoolSub);
|
||||
}
|
||||
if (this.raydiumPoolInfoSub) {
|
||||
await this.connection.removeProgramAccountChangeListener(this.raydiumPoolInfoSub);
|
||||
}
|
||||
}
|
||||
|
||||
addEdge(edge: Edge) {
|
||||
|
@ -267,6 +485,66 @@ export class Router {
|
|||
}
|
||||
}
|
||||
|
||||
async indexRaydium(): Promise<void> {
|
||||
const response = await fetch('https://api.raydium.io/v2/ammV3/ammPools', {
|
||||
method: 'GET'
|
||||
});
|
||||
const poolData = (await response.json()).data as ApiAmmV3PoolsItem[];
|
||||
|
||||
// TODO: Do not trust the tvl and instead look it up like with jupiter prices
|
||||
const poolsFilteredByTvl = poolData.filter((p: ApiAmmV3PoolsItem) => {
|
||||
return p.tvl > this.minTvl;
|
||||
});
|
||||
console.log(
|
||||
"found",
|
||||
poolData.length,
|
||||
"raydium pools.",
|
||||
poolsFilteredByTvl.length,
|
||||
"of those with TVL >",
|
||||
this.minTvl,
|
||||
"USD"
|
||||
);
|
||||
|
||||
this.routes = new Map();
|
||||
|
||||
const poolInfos = await AmmV3.fetchMultiplePoolInfos(
|
||||
{
|
||||
connection: this.connection,
|
||||
poolKeys: poolsFilteredByTvl,
|
||||
ownerInfo: undefined,
|
||||
chainTime: 0,
|
||||
batchRequest: false,
|
||||
updateOwnerRewardAndFee: true
|
||||
}
|
||||
);
|
||||
const poolTickArrays = await AmmV3.fetchMultiplePoolTickArrays(
|
||||
{
|
||||
connection: this.connection,
|
||||
poolKeys: poolsFilteredByTvl.map((p) => poolInfos[p.id].state),
|
||||
batchRequest: false
|
||||
}
|
||||
);
|
||||
const mints = poolsFilteredByTvl.map((p) => [new PublicKey(p.mintA), new PublicKey(p.mintB)]).flat();
|
||||
const mintInfos = await fetchMultipleMintInfos(
|
||||
{
|
||||
connection: this.connection,
|
||||
mints: mints,
|
||||
}
|
||||
);
|
||||
|
||||
this.raydiumCache = new RaydiumCache(
|
||||
await this.connection.getEpochInfo(),
|
||||
mintInfos,
|
||||
poolInfos,
|
||||
poolTickArrays,
|
||||
)
|
||||
|
||||
for (const pool of poolsFilteredByTvl) {
|
||||
const poolInfo = poolInfos[pool.id].state;
|
||||
this.addEdges(RaydiumEdge.pairFromPool(poolInfo, this.raydiumCache));
|
||||
}
|
||||
}
|
||||
|
||||
async indexWhirpools(): Promise<void> {
|
||||
const poolsPks = (
|
||||
await this.whirlpoolClient.getContext().program.account.whirlpool.all()
|
||||
|
@ -339,7 +617,7 @@ export class Router {
|
|||
console.log(
|
||||
"found",
|
||||
poolsPks.length,
|
||||
"pools.",
|
||||
"orca pools.",
|
||||
filtered.length,
|
||||
"of those with TVL >",
|
||||
this.minTvl,
|
||||
|
|
102
yarn.lock
102
yarn.lock
|
@ -108,6 +108,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11"
|
||||
integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ==
|
||||
|
||||
"@noble/hashes@^1.3.1":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9"
|
||||
integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==
|
||||
|
||||
"@noble/secp256k1@^1.6.3":
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.0.tgz#d15357f7c227e751d90aa06b05a0e5cf993ba8c1"
|
||||
|
@ -245,6 +250,22 @@
|
|||
"@coral-xyz/anchor" "^0.26.0"
|
||||
buffer "^6.0.1"
|
||||
|
||||
"@raydium-io/raydium-sdk@^1.3.1-beta.8":
|
||||
version "1.3.1-beta.8"
|
||||
resolved "https://registry.yarnpkg.com/@raydium-io/raydium-sdk/-/raydium-sdk-1.3.1-beta.8.tgz#f3af2e6c04cfe36677310e7a3cb37d2b2ec9e2f6"
|
||||
integrity sha512-emBu9sxyKOgUIdy1706+6VxqhXA7BmTjG+jhF+G+BDiuu6olYJ3hFoceMHzNMlNYbWkGBo3GSKKyzjaX0u6D5w==
|
||||
dependencies:
|
||||
"@solana/buffer-layout" "^4.0.1"
|
||||
"@solana/spl-token" "^0.3.7"
|
||||
axios "^1.2.6"
|
||||
big.js "^6.2.1"
|
||||
bn.js "^5.2.1"
|
||||
decimal.js "^10.4.3"
|
||||
decimal.js-light "^2.5.1"
|
||||
fecha "^4.2.3"
|
||||
lodash "^4.17.21"
|
||||
toformat "^2.0.0"
|
||||
|
||||
"@solana/buffer-layout-utils@^0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca"
|
||||
|
@ -255,7 +276,7 @@
|
|||
bigint-buffer "^1.1.5"
|
||||
bignumber.js "^9.0.1"
|
||||
|
||||
"@solana/buffer-layout@^4.0.0":
|
||||
"@solana/buffer-layout@^4.0.0", "@solana/buffer-layout@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15"
|
||||
integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==
|
||||
|
@ -283,6 +304,15 @@
|
|||
"@solana/buffer-layout-utils" "^0.2.0"
|
||||
buffer "^6.0.3"
|
||||
|
||||
"@solana/spl-token@^0.3.7":
|
||||
version "0.3.8"
|
||||
resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.8.tgz#8e9515ea876e40a4cc1040af865f61fc51d27edf"
|
||||
integrity sha512-ogwGDcunP9Lkj+9CODOWMiVJEdRtqHAtX2rWF62KxnnSWtMZtV9rDhTrZFshiyJmxDnRL/1nKE1yJHg4jjs3gg==
|
||||
dependencies:
|
||||
"@solana/buffer-layout" "^4.0.0"
|
||||
"@solana/buffer-layout-utils" "^0.2.0"
|
||||
buffer "^6.0.3"
|
||||
|
||||
"@solana/web3.js@1.66.0":
|
||||
version "1.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.66.0.tgz#ab76e59b369815fc6114c784a48e91726c1ae6c5"
|
||||
|
@ -516,6 +546,20 @@ array-flatten@1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||
|
||||
axios@^1.2.6:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
|
||||
integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
|
||||
dependencies:
|
||||
follow-redirects "^1.15.0"
|
||||
form-data "^4.0.0"
|
||||
proxy-from-env "^1.1.0"
|
||||
|
||||
base-x@^3.0.2:
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320"
|
||||
|
@ -533,7 +577,7 @@ base64-js@^1.3.1, base64-js@^1.5.1:
|
|||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
big.js@^6.1.1:
|
||||
big.js@^6.1.1, big.js@^6.2.1:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f"
|
||||
integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==
|
||||
|
@ -575,7 +619,7 @@ bintrees@1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.2.tgz#49f896d6e858a4a499df85c38fb399b9aff840f8"
|
||||
integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==
|
||||
|
||||
bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.2.0:
|
||||
bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
|
||||
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
|
||||
|
@ -672,6 +716,13 @@ camelcase@^6.3.0:
|
|||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
|
||||
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^2.20.3:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
|
@ -743,7 +794,12 @@ debug@4, debug@^4.1.0:
|
|||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
decimal.js@^10.3.1:
|
||||
decimal.js-light@^2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934"
|
||||
integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==
|
||||
|
||||
decimal.js@^10.3.1, decimal.js@^10.4.3:
|
||||
version "10.4.3"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
|
||||
integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==
|
||||
|
@ -753,6 +809,11 @@ delay@^5.0.0:
|
|||
resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d"
|
||||
integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
depd@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
|
@ -883,6 +944,11 @@ fast-stable-stringify@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313"
|
||||
integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==
|
||||
|
||||
fecha@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
|
||||
integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
|
@ -908,6 +974,20 @@ find@^0.3.0:
|
|||
dependencies:
|
||||
traverse-chain "~0.1.0"
|
||||
|
||||
follow-redirects@^1.15.0:
|
||||
version "1.15.2"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
|
||||
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
forwarded@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
|
||||
|
@ -1051,7 +1131,7 @@ lodash.zipobject@^4.1.3:
|
|||
resolved "https://registry.yarnpkg.com/lodash.zipobject/-/lodash.zipobject-4.1.3.tgz#b399f5aba8ff62a746f6979bf20b214f964dbef8"
|
||||
integrity sha512-A9SzX4hMKWS25MyalwcOnNoplyHbkNVsjidhTp8ru0Sj23wY9GWBKS8gAIGDSAqeWjIjvE4KBEl24XXAs+v4wQ==
|
||||
|
||||
lodash@^4.17.20:
|
||||
lodash@^4.17.20, lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
@ -1088,7 +1168,7 @@ mime-db@1.52.0:
|
|||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||
|
||||
mime-types@~2.1.24, mime-types@~2.1.34:
|
||||
mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34:
|
||||
version "2.1.35"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||
|
@ -1206,6 +1286,11 @@ proxy-addr@~2.0.7:
|
|||
forwarded "0.2.0"
|
||||
ipaddr.js "1.9.1"
|
||||
|
||||
proxy-from-env@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
qs@6.11.0:
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
|
||||
|
@ -1362,6 +1447,11 @@ tiny-invariant@^1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
|
||||
integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==
|
||||
|
||||
toformat@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/toformat/-/toformat-2.0.0.tgz#7a043fd2dfbe9021a4e36e508835ba32056739d8"
|
||||
integrity sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==
|
||||
|
||||
toidentifier@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
||||
|
|
Loading…
Reference in New Issue