add raven adapter

This commit is contained in:
Maximilian Schneider 2023-11-06 12:39:33 +01:00
parent e8c0ee62c2
commit 6f4ca6359f
7 changed files with 1076 additions and 212 deletions

View File

@ -15,10 +15,11 @@
},
"dependencies": {
"@blockworks-foundation/mango-v4": "^0.9.5",
"@coral-xyz/anchor": "^0.26.0",
"@coral-xyz/borsh": "^0.29.0",
"@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",
@ -28,5 +29,9 @@
"express": "^4.18.2",
"express-prom-bundle": "^6.6.0",
"prom-client": "^14.1.1"
},
"resolutions": {
"**/@solana/web3.js/node-fetch": "npm:@blockworks-foundation/node-fetch@2.6.11",
"**/cross-fetch/node-fetch": "npm:@blockworks-foundation/node-fetch@2.6.11"
}
}

421
src/idl/raven.json Normal file
View File

@ -0,0 +1,421 @@
{
"version": "0.1.0",
"name": "raven",
"instructions": [
{
"name": "initMangoAccount",
"accounts": [
{
"name": "group",
"isMut": false,
"isSigner": false
},
{
"name": "account",
"isMut": true,
"isSigner": false
},
{
"name": "owner",
"isMut": false,
"isSigner": false,
"pda": {
"seeds": [
{
"kind": "const",
"type": "string",
"value": "pda"
}
]
}
},
{
"name": "payer",
"isMut": true,
"isSigner": true
},
{
"name": "systemProgram",
"isMut": false,
"isSigner": false
},
{
"name": "mangoProgram",
"isMut": false,
"isSigner": false
}
],
"args": [
{
"name": "accountNum",
"type": "u32"
},
{
"name": "tokenCount",
"type": "u8"
},
{
"name": "serum3Count",
"type": "u8"
},
{
"name": "perpCount",
"type": "u8"
},
{
"name": "perpOoCount",
"type": "u8"
},
{
"name": "tokenConditionalSwapCount",
"type": "u8"
},
{
"name": "name",
"type": "string"
}
]
},
{
"name": "deposit",
"accounts": [
{
"name": "group",
"isMut": false,
"isSigner": false
},
{
"name": "account",
"isMut": true,
"isSigner": false
},
{
"name": "owner",
"isMut": false,
"isSigner": false,
"pda": {
"seeds": [
{
"kind": "const",
"type": "string",
"value": "pda"
}
]
}
},
{
"name": "bank",
"isMut": true,
"isSigner": false
},
{
"name": "vault",
"isMut": true,
"isSigner": false
},
{
"name": "oracle",
"isMut": false,
"isSigner": false
},
{
"name": "tokenAccount",
"isMut": true,
"isSigner": false
},
{
"name": "tokenAuthority",
"isMut": false,
"isSigner": true
},
{
"name": "tokenProgram",
"isMut": false,
"isSigner": false
},
{
"name": "mangoProgram",
"isMut": false,
"isSigner": false
}
],
"args": [
{
"name": "amount",
"type": "u64"
},
{
"name": "reduceOnly",
"type": "bool"
}
]
},
{
"name": "collectFees",
"accounts": [
{
"name": "group",
"isMut": false,
"isSigner": false
},
{
"name": "account",
"isMut": true,
"isSigner": false
},
{
"name": "owner",
"isMut": false,
"isSigner": false,
"pda": {
"seeds": [
{
"kind": "const",
"type": "string",
"value": "pda"
}
]
}
},
{
"name": "bank",
"isMut": true,
"isSigner": false
},
{
"name": "vault",
"isMut": true,
"isSigner": false
},
{
"name": "oracle",
"isMut": false,
"isSigner": false
},
{
"name": "tokenAccount",
"isMut": true,
"isSigner": false
},
{
"name": "payer",
"isMut": false,
"isSigner": true
},
{
"name": "tokenProgram",
"isMut": false,
"isSigner": false
},
{
"name": "mangoProgram",
"isMut": false,
"isSigner": false
}
],
"args": [
{
"name": "amount",
"type": "u64"
},
{
"name": "allowBorrow",
"type": "bool"
}
]
},
{
"name": "accountEdit",
"accounts": [
{
"name": "group",
"isMut": false,
"isSigner": false
},
{
"name": "account",
"isMut": true,
"isSigner": false
},
{
"name": "owner",
"isMut": false,
"isSigner": false,
"pda": {
"seeds": [
{
"kind": "const",
"type": "string",
"value": "pda"
}
]
}
},
{
"name": "payer",
"isMut": false,
"isSigner": true
},
{
"name": "mangoProgram",
"isMut": false,
"isSigner": false
}
],
"args": [
{
"name": "nameOpt",
"type": {
"option": "string"
}
},
{
"name": "delegateOpt",
"type": {
"option": "publicKey"
}
},
{
"name": "temporaryDelegateOpt",
"type": {
"option": "publicKey"
}
},
{
"name": "temporaryDelegateExpiryOpt",
"type": {
"option": "u64"
}
}
]
},
{
"name": "tradeJupiter",
"accounts": [
{
"name": "trader",
"isMut": false,
"isSigner": true
},
{
"name": "owner",
"isMut": false,
"isSigner": false,
"pda": {
"seeds": [
{
"kind": "const",
"type": "string",
"value": "pda"
}
]
}
},
{
"name": "account",
"isMut": true,
"isSigner": false
},
{
"name": "perpMarket",
"isMut": true,
"isSigner": false
},
{
"name": "eventQueue",
"isMut": true,
"isSigner": false
},
{
"name": "bids",
"isMut": true,
"isSigner": false
},
{
"name": "asks",
"isMut": true,
"isSigner": false
},
{
"name": "baseBank",
"isMut": true,
"isSigner": false
},
{
"name": "quoteBank",
"isMut": true,
"isSigner": false
},
{
"name": "baseVault",
"isMut": true,
"isSigner": false
},
{
"name": "quoteVault",
"isMut": true,
"isSigner": false
},
{
"name": "baseOracle",
"isMut": false,
"isSigner": false,
"docs": [
"We still verify that it is the correct oracle both for spot and perp"
]
},
{
"name": "quoteOracle",
"isMut": false,
"isSigner": false,
"docs": [
"We still verify that it is the correct oracle both for spot and perp"
]
},
{
"name": "perpOracle",
"isMut": false,
"isSigner": false,
"docs": [
"We still verify that it is the correct oracle both for spot and perp"
]
},
{
"name": "group",
"isMut": false,
"isSigner": false
},
{
"name": "baseToken",
"isMut": true,
"isSigner": false
},
{
"name": "quoteToken",
"isMut": true,
"isSigner": false
},
{
"name": "mangoProgram",
"isMut": false,
"isSigner": false
},
{
"name": "tokenProgram",
"isMut": false,
"isSigner": false
}
],
"args": [
{
"name": "amountInLots",
"type": "i64"
},
{
"name": "isBase",
"type": "bool"
}
]
}
]
}

View File

@ -10,7 +10,7 @@ import {
Wallet,
BN,
BorshAccountsCoder,
} from "@project-serum/anchor";
} from "@coral-xyz/anchor";
import {
Connection,
Cluster,

View File

@ -1,4 +1,10 @@
import {
BookSide,
BookSideType,
MANGO_V4_ID,
MangoClient,
PerpMarket,
createAssociatedTokenAccountIdempotentInstruction,
getAssociatedTokenAddress,
toUiDecimals,
} from "@blockworks-foundation/mango-v4";
@ -15,13 +21,41 @@ import {
swapQuoteByInputToken,
swapQuoteByOutputToken,
} from "@orca-so/whirlpools-sdk";
import { AnchorProvider, BorshAccountsCoder, Idl } from "@project-serum/anchor";
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 {
AnchorProvider,
BorshAccountsCoder,
Idl,
Program,
Wallet,
} from "@coral-xyz/anchor";
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
AmmV3,
AmmV3PoolInfo,
ApiAmmV3PoolsItem,
MAINNET_PROGRAM_ID,
PoolInfoLayout,
ReturnTypeComputeAmountOut,
ReturnTypeComputeAmountOutBaseOut,
ReturnTypeFetchMultipleMintInfos,
ReturnTypeFetchMultiplePoolInfos,
ReturnTypeFetchMultiplePoolTickArrays,
SqrtPriceMath,
TOKEN_PROGRAM_ID,
bits,
fetchMultipleMintInfos,
} from "@raydium-io/raydium-sdk";
import {
Connection,
EpochInfo,
Keypair,
PublicKey,
TransactionInstruction,
} from "@solana/web3.js";
import { sha256 } from "@noble/hashes/sha256";
import BN from "bn.js";
import bs58 from 'bs58';
import bs58 from "bs58";
import ravenIdl from "./idl/raven.json";
export interface DepthResult {
label: string;
@ -209,24 +243,27 @@ class RaydiumEdge implements Edge {
public inputMint: PublicKey,
public outputMint: PublicKey,
public poolPk: PublicKey,
public raydiumCache: RaydiumCache,
public raydiumCache: RaydiumCache
) {}
static pairFromPool(poolInfo: AmmV3PoolInfo, raydiumCache: RaydiumCache): Edge[] {
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,
raydiumCache
);
const bwd = new RaydiumEdge(
label,
new PublicKey(poolInfo.mintB.mint),
new PublicKey(poolInfo.mintA.mint),
new PublicKey(poolInfo.id),
raydiumCache,
raydiumCache
);
return [fwd, bwd];
}
@ -245,17 +282,16 @@ class RaydiumEdge implements Edge {
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,
}
);
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;
@ -265,7 +301,8 @@ class RaydiumEdge implements Edge {
let amountIn: ReturnTypeComputeAmountOutBaseOut = AmmV3.computeAmountIn(
{
poolInfo: this.raydiumCache.poolInfos[this.poolPk.toBase58()].state,
tickArrayCache: this.raydiumCache.tickArrayByPoolIds[this.poolPk.toBase58()],
tickArrayCache:
this.raydiumCache.tickArrayByPoolIds[this.poolPk.toBase58()],
baseMint: this.outputMint,
token2022Infos: this.raydiumCache.mintInfos,
epochInfo: this.raydiumCache.epochInfo,
@ -335,34 +372,34 @@ class RaydiumEdge implements Edge {
}
}
export class RavenCache {
constructor(
public market: PerpMarket,
public bids: BookSide,
public asks: BookSide
) {}
}
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;
}
constructor(
public epochInfo: EpochInfo,
public mintInfos: ReturnTypeFetchMultipleMintInfos,
public poolInfos: ReturnTypeFetchMultiplePoolInfos,
public tickArrayByPoolIds: ReturnTypeFetchMultiplePoolTickArrays
) {}
}
export class Router {
minTvl: number;
routes: Map<string, Map<string, Edge[]>>;
whirlpoolClient: WhirlpoolClient;
whirlpoolSub?: number;
connection: Connection;
ravenCache?: RavenCache;
ravenBookInfoSub?: number;
raydiumCache?: RaydiumCache;
raydiumPoolInfoSub?: number;
@ -378,6 +415,9 @@ export class Router {
public async start(): Promise<void> {
this.routes = new Map();
await this.indexRaven();
/*
await this.indexWhirpools();
// setup a websocket connection to refresh all whirpool program accounts
@ -400,7 +440,14 @@ export class Router {
};
},
"processed",
[{ memcmp: { offset: 0, bytes: bs58.encode(whirlpoolInfoDiscriminator) } }]
[
{
memcmp: {
offset: 0,
bytes: bs58.encode(whirlpoolInfoDiscriminator),
},
},
]
);
await this.indexRaydium();
@ -456,6 +503,8 @@ export class Router {
"processed",
[{ memcmp: { offset: 0, bytes: bs58.encode(poolInfoDiscriminator) } }]
);
*/
}
public async stop(): Promise<void> {
@ -465,7 +514,12 @@ export class Router {
.connection.removeProgramAccountChangeListener(this.whirlpoolSub);
}
if (this.raydiumPoolInfoSub) {
await this.connection.removeProgramAccountChangeListener(this.raydiumPoolInfoSub);
await this.connection.removeProgramAccountChangeListener(
this.raydiumPoolInfoSub
);
}
if (this.ravenBookInfoSub) {
await this.connection.removeAccountChangeListener(this.ravenBookInfoSub);
}
}
@ -491,9 +545,233 @@ export class Router {
}
}
async indexRaven(): Promise<void> {
// load initial cache state
const user = Keypair.generate();
const userWallet = new Wallet(user);
const userProvider = new AnchorProvider(this.connection, userWallet, {});
const client = MangoClient.connect(
userProvider,
"mainnet-beta",
MANGO_V4_ID["mainnet-beta"],
{
idsSource: "get-program-accounts",
}
);
const group = await client.getGroup(
new PublicKey("78b8f4cGCwmZ9ysPFMWLaLTkkaYnUjwMJYStWe5RTSSX")
);
const market = group.getPerpMarketByName("BTC-PERP");
const bids = await market.loadBids(client, true);
const asks = await market.loadAsks(client, true);
const baseMint = new PublicKey(
"6DNSN2BJsaPFdFFc1zP37kkeNe4Usc1Sqkzr9C9vPWcU"
);
const quoteMint = new PublicKey(
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
);
const baseBank = group.getFirstBankByMint(baseMint);
const quoteBank = group.getFirstBankByMint(quoteMint);
this.ravenCache = new RavenCache(market, bids, asks);
// setup subscription
this.ravenBookInfoSub = this.connection.onAccountChange(
market.bids,
(acc) => {
const side = client.program.account.bookSide.coder.accounts.decode(
"bookSide",
acc.data
);
this.ravenCache!.bids = BookSide.from(
client,
this.ravenCache!.market,
BookSideType.bids,
side
);
},
"processed"
);
// create edges
const edges = [
{
label: "rvn-tBTC-USDC",
inputMint: baseMint,
outputMint: quoteMint,
swap: async (
amount: BN,
otherAmountThreshold: BN,
mode: SwapMode,
slippage: number
): Promise<SwapResult> => {
if (mode === SwapMode.ExactIn) {
let amountInLots = amount
.divn(
Math.pow(
10,
baseBank.mintDecimals - this.ravenCache!.market.baseDecimals
)
)
.div(this.ravenCache!.market.baseLotSize);
// console.log("amt", amount.toString(), amountInLots.toString());
const sumBase = new BN(0);
const sumQuote = new BN(0);
for (const order of this.ravenCache!.bids.items()) {
/*
console.log(
"order",
order.sizeLots.toString(),
order.priceLots.toString(),
sumBase.toString(),
sumQuote.toString()
);
*/
sumBase.iadd(order.sizeLots);
sumQuote.iadd(order.sizeLots.mul(order.priceLots));
const diff = sumBase.sub(amountInLots);
// console.log("diff", diff.toString());
if (!diff.isNeg()) {
sumQuote.isub(diff.mul(order.priceLots));
break;
}
if (diff.isZero()) break;
}
const nativeBase = amountInLots.mul(
this.ravenCache!.market.baseLotSize
);
const nativeQuote = sumQuote
.mul(this.ravenCache!.market.quoteLotSize)
.muln(1000)
.divn(1001);
const feeQuote = sumQuote
.mul(this.ravenCache!.market.quoteLotSize)
.sub(nativeQuote);
if (nativeQuote.gte(otherAmountThreshold)) {
return {
label: "rvn-tBTC-USDC",
marketInfos: [
{
label: "raven",
fee: {
amount: feeQuote,
mint: new PublicKey(
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
),
rate: 0.001,
},
},
],
maxAmtIn: nativeBase,
minAmtOut: nativeQuote,
mints: [],
ok: true,
instructions: async (wallet: PublicKey) => {
const baseToken = await getAssociatedTokenAddress(
baseMint,
wallet
);
const quoteToken = await getAssociatedTokenAddress(
quoteMint,
wallet
);
const program = new Program(
ravenIdl as Idl,
"AXRsZddcKo8BcHrbbBdXyHozSaRGqHc11ePh9ChKuoa1",
userProvider
);
const prepIx =
await createAssociatedTokenAccountIdempotentInstruction(
wallet,
wallet,
quoteMint
);
const tradeIx = await program.methods
.tradeJupiter(amountInLots, true)
.accounts({
trader: wallet,
owner: PublicKey.findProgramAddressSync(
[Buffer.from("pda")],
new PublicKey(
"AXRsZddcKo8BcHrbbBdXyHozSaRGqHc11ePh9ChKuoa1"
)
)[0],
account: new PublicKey(
"GRR9y6yBxfxqVS7xQekRk4c6KUB2ukqSM8fY8GJSSCbo"
),
perpMarket: this.ravenCache!.market.publicKey,
perpOracle: this.ravenCache!.market.oracle,
eventQueue: this.ravenCache!.market.eventQueue,
bids: this.ravenCache!.market.bids,
asks: this.ravenCache!.market.asks,
baseBank: baseBank.publicKey,
quoteBank: quoteBank.publicKey,
baseVault: baseBank.vault,
quoteVault: quoteBank.vault,
baseOracle: baseBank.oracle,
quoteOracle: quoteBank.oracle,
group: group.publicKey,
baseToken,
quoteToken,
mangoProgram: MANGO_V4_ID["mainnet-beta"],
tokenProgram: TOKEN_PROGRAM_ID,
})
.instruction();
return [prepIx, tradeIx];
},
};
}
} else {
// SwapMode.ExactOut
let amountOutLots = amount.div(
this.ravenCache!.market.quoteLotSize
);
const sumBase = new BN(0);
const sumQuote = new BN(0);
for (const order of this.ravenCache!.bids.items()) {
sumBase.iadd(order.sizeLots);
const orderQuoteLots = order.sizeLots.mul(order.priceLots);
sumQuote.iadd(orderQuoteLots);
const diff = sumQuote.sub(amountOutLots);
if (!diff.isNeg()) {
const extra = orderQuoteLots.sub(diff);
sumBase.isub(extra.div(order.priceLots));
break;
}
if (diff.isZero()) break;
}
// const nativeBase = sumBase.mul(this.ravenCache!.m);
}
// error case no swap result has been generated
return {
ok: false,
label: "",
marketInfos: [],
maxAmtIn: amount,
minAmtOut: otherAmountThreshold,
mints: [],
instructions: async () => [],
};
},
},
];
this.addEdges(edges);
}
async indexRaydium(): Promise<void> {
const response = await fetch('https://api.raydium.io/v2/ammV3/ammPools', {
method: 'GET'
const response = await fetch("https://api.raydium.io/v2/ammV3/ammPools", {
method: "GET",
});
const poolData = (await response.json()).data as ApiAmmV3PoolsItem[];
@ -511,37 +789,33 @@ export class Router {
"USD"
);
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,
}
);
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,
)
poolTickArrays
);
for (const pool of poolsFilteredByTvl) {
const poolInfo = poolInfos[pool.id].state;

154
src/taker.ts Normal file
View File

@ -0,0 +1,154 @@
import {
MangoClient,
MANGO_V4_ID,
toNative,
toUiDecimals,
} from "@blockworks-foundation/mango-v4";
import { U64_MAX, ZERO } from "@orca-so/common-sdk";
import {
AnchorProvider,
Wallet,
BN,
BorshAccountsCoder,
} from "@coral-xyz/anchor";
import {
Connection,
Cluster,
clusterApiUrl,
PublicKey,
Keypair,
Transaction,
} from "@solana/web3.js";
import { DepthResult, Router, SwapMode, SwapResult } from "./router";
const { CLUSTER, GROUP, MAX_ROUTES, MIN_TVL, PORT, RPC_URL, KEYPAIR } =
process.env;
const cluster = (CLUSTER || "mainnet-beta") as Cluster;
const groupPk = new PublicKey(
GROUP || "78b8f4cGCwmZ9ysPFMWLaLTkkaYnUjwMJYStWe5RTSSX"
);
const maxRoutes = parseInt(MAX_ROUTES || "1");
const minTvl = parseInt(MIN_TVL || "500");
const port = parseInt(PORT || "5000");
const rpcUrl = RPC_URL || clusterApiUrl(cluster);
const keyPair = Keypair.fromSecretKey(new Uint8Array(JSON.parse(KEYPAIR!)));
const wallet = new Wallet(keyPair);
async function main() {
// init anchor
const connection = new Connection(rpcUrl, "confirmed");
const anchorProvider = new AnchorProvider(connection, wallet, {});
// init mango
const mangoClient = await MangoClient.connect(
anchorProvider,
cluster,
MANGO_V4_ID[cluster],
{
idsSource: "get-program-accounts",
}
);
const group = await mangoClient.getGroup(groupPk);
await group.reloadAll(mangoClient);
const banks = Array.from(group.banksMapByMint, ([, value]) => value);
const coder = new BorshAccountsCoder(mangoClient.program.idl);
const subs = banks.map(([bank]) =>
anchorProvider.connection.onAccountChange(
bank.oracle,
async (ai, ctx) => {
if (!ai)
throw new Error(
`Undefined accountInfo object in onAccountChange(bank.oracle) for ${bank.oracle.toString()}!`
);
const { price, uiPrice } = await group["decodePriceFromOracleAi"](
coder,
bank.oracle,
ai,
group.getMintDecimals(bank.mint),
mangoClient
);
bank._price = price;
bank._uiPrice = uiPrice;
},
"processed"
)
);
// init router
const router = new Router(anchorProvider, minTvl);
await router.start();
const inputMint = "6DNSN2BJsaPFdFFc1zP37kkeNe4Usc1Sqkzr9C9vPWcU";
const inputMintPk = new PublicKey(inputMint);
const outputMint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
const outputMintPk = new PublicKey(outputMint);
const mode = SwapMode.ExactIn;
const slippage = 0.0001;
const amount = new BN(10000);
const otherAmountThreshold = mode == SwapMode.ExactIn ? ZERO : U64_MAX;
let referencePrice: number | undefined;
if (
group.banksMapByMint.has(inputMint) &&
group.banksMapByMint.has(outputMint)
) {
const inputBank = group.banksMapByMint.get(inputMint)![0];
const outputBank = group.banksMapByMint.get(outputMint)![0];
referencePrice =
(10 ** (inputBank.mintDecimals - outputBank.mintDecimals) *
outputBank.uiPrice) /
inputBank.uiPrice;
}
if (mode !== SwapMode.ExactIn && mode !== SwapMode.ExactOut) {
const error = { e: "mode needs to be one of ExactIn or ExactOut" };
return;
}
const results = await router.swap(
inputMintPk,
outputMintPk,
amount,
otherAmountThreshold,
mode,
slippage
);
const filtered = results.filter((r) => r.ok);
let ranked: SwapResult[] = [];
if (mode === SwapMode.ExactIn) {
ranked = filtered.sort((a, b) =>
Number(b.minAmtOut.sub(a.minAmtOut).toString())
);
} else if (mode === SwapMode.ExactOut) {
ranked = filtered.sort((a, b) =>
Number(a.maxAmtIn.sub(b.maxAmtIn).toString())
);
}
const [best] = ranked.slice(0, Math.min(ranked.length, maxRoutes));
const ins = await best.instructions(wallet.publicKey);
let priceImpact: number | undefined = undefined;
if (!!referencePrice) {
const actualPrice =
Number(best.maxAmtIn.toString()) / Number(best.minAmtOut.toString());
priceImpact = actualPrice / referencePrice - 1;
}
const tx = new Transaction();
const response = await connection.getLatestBlockhash("finalized");
tx.recentBlockhash = response.blockhash;
tx.add(...ins);
tx.sign(keyPair);
const sig = await connection.sendTransaction(tx, [keyPair], {
skipPreflight: true,
});
console.log("send", sig);
const confirmationResult = await connection.confirmTransaction(sig);
console.log("confirmed", confirmationResult);
}
main();

View File

@ -35,7 +35,7 @@
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
"resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */

290
yarn.lock
View File

@ -2,17 +2,17 @@
# yarn lockfile v1
"@babel/runtime@^7.10.5", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==
"@babel/runtime@^7.10.5", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.23.2":
version "7.23.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
dependencies:
regenerator-runtime "^0.13.11"
regenerator-runtime "^0.14.0"
"@blockworks-foundation/mango-v4@^0.9.5":
version "0.9.5"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.9.5.tgz#d931a85aa2fa3ff23feaf701dc41d67b0e7aaa01"
integrity sha512-osxZgbz+CNndIOk+eW29PRKI+NAWZzG3sFLAqsBzQOIi7ehHjNWUovX93EXbt6XLElf0HanX7gAH6tUiKsAsnA==
version "0.9.19"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.9.19.tgz#6022158fd64294cdba77b7fee78a665099bdcf35"
integrity sha512-ytBZD+EWp8impo1ndpUL6y3227hTk4G22eWwIDv4pqqn0/FTXwdoDF8jk1/cI5vpu+1zk5HAOBNOG9CdpuYJww==
dependencies:
"@coral-xyz/anchor" "^0.26.0"
"@project-serum/serum" "0.13.65"
@ -56,6 +56,14 @@
bn.js "^5.1.2"
buffer-layout "^1.2.0"
"@coral-xyz/borsh@^0.29.0":
version "0.29.0"
resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.29.0.tgz#79f7045df2ef66da8006d47f5399c7190363e71f"
integrity sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==
dependencies:
bn.js "^5.1.2"
buffer-layout "^1.2.0"
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
@ -98,15 +106,22 @@
"@solana/spl-token" "^0.1.8"
"@solana/web3.js" "^1.31.0"
"@noble/ed25519@^1.7.0":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.1.tgz#6899660f6fbb97798a6fbd227227c4589a454724"
integrity sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw==
"@noble/curves@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35"
integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==
dependencies:
"@noble/hashes" "1.3.2"
"@noble/hashes@^1.1.2":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11"
integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ==
"@noble/ed25519@^1.7.0":
version "1.7.3"
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123"
integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==
"@noble/hashes@1.3.2", "@noble/hashes@^1.1.2":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39"
integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==
"@noble/hashes@^1.3.1":
version "1.3.1"
@ -114,9 +129,9 @@
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"
integrity sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw==
version "1.7.1"
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c"
integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==
"@orca-so/common-sdk@^0.1.10", "@orca-so/common-sdk@^0.1.12":
version "0.1.12"
@ -181,27 +196,6 @@
snake-case "^3.0.4"
toml "^3.0.0"
"@project-serum/anchor@^0.26.0":
version "0.26.0"
resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.26.0.tgz#99e15a3923a5d10514f8185b2d3909e5699d60d5"
integrity sha512-Nq+COIjE1135T7qfnOHEn7E0q39bQTgXLFk837/rgFe6Hkew9WML7eHsS+lSYD2p3OJaTiUOHTAq1lHy36oIqQ==
dependencies:
"@coral-xyz/borsh" "^0.26.0"
"@solana/web3.js" "^1.68.0"
base64-js "^1.5.1"
bn.js "^5.1.2"
bs58 "^4.0.1"
buffer-layout "^1.2.2"
camelcase "^6.3.0"
cross-fetch "^3.1.5"
crypto-hash "^1.3.0"
eventemitter3 "^4.0.7"
js-sha256 "^0.9.0"
pako "^2.0.3"
snake-case "^3.0.4"
superstruct "^0.15.4"
toml "^3.0.0"
"@project-serum/anchor@~0.25.0":
version "0.25.0"
resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.25.0.tgz#88ee4843336005cf5a64c80636ce626f0996f503"
@ -334,7 +328,28 @@
rpc-websockets "^7.5.0"
superstruct "^0.14.2"
"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.31.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.70.1":
"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.2":
version "1.87.3"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.87.3.tgz#36871af8d41221d34bfefcf897f158e1793b3356"
integrity sha512-WGLzTZpi00vP443qGK3gL+LZXQJwaWkh6bzNXYpMTCAH2Z102y3YbPWOoQzJUeRSZWSXKh7MFkA3vDMFlMvGZQ==
dependencies:
"@babel/runtime" "^7.23.2"
"@noble/curves" "^1.2.0"
"@noble/hashes" "^1.3.1"
"@solana/buffer-layout" "^4.0.0"
agentkeepalive "^4.3.0"
bigint-buffer "^1.1.5"
bn.js "^5.2.1"
borsh "^0.7.0"
bs58 "^4.0.1"
buffer "6.0.3"
fast-stable-stringify "^1.0.0"
jayson "^4.1.0"
node-fetch "^2.6.12"
rpc-websockets "^7.5.1"
superstruct "^0.14.2"
"@solana/web3.js@^1.31.0", "@solana/web3.js@^1.70.1":
version "1.73.0"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.73.0.tgz#c65f9f954ac80fca6952765c931dd72e57e1b572"
integrity sha512-YrgX3Py7ylh8NYkbanoINUPCj//bWUjYZ5/WPy9nQ9SK3Cl7QWCR+NmbDjmC/fTspZGR+VO9LTQslM++jr5PRw==
@ -356,28 +371,6 @@
rpc-websockets "^7.5.0"
superstruct "^0.14.2"
"@solana/web3.js@^1.73.2":
version "1.73.3"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.73.3.tgz#60e6bd68f6f364d4be360b1e0a03a0a68468a029"
integrity sha512-vHRMo589XEIpoujpE2sZZ1aMZvfA1ImKfNxobzEFyMb+H5j6mRRUXfdgWD0qJ0sm11e5BcBC7HPeRXJB+7f3Lg==
dependencies:
"@babel/runtime" "^7.12.5"
"@noble/ed25519" "^1.7.0"
"@noble/hashes" "^1.1.2"
"@noble/secp256k1" "^1.6.3"
"@solana/buffer-layout" "^4.0.0"
agentkeepalive "^4.2.1"
bigint-buffer "^1.1.5"
bn.js "^5.0.0"
borsh "^0.7.0"
bs58 "^4.0.1"
buffer "6.0.1"
fast-stable-stringify "^1.0.0"
jayson "^3.4.4"
node-fetch "^2.6.7"
rpc-websockets "^7.5.1"
superstruct "^0.14.2"
"@switchboard-xyz/sbv2-lite@^0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@switchboard-xyz/sbv2-lite/-/sbv2-lite-0.1.6.tgz#dc3fbb5b3b028dbd3c688b991bcc48a670131ddb"
@ -421,13 +414,20 @@
"@types/connect" "*"
"@types/node" "*"
"@types/connect@*", "@types/connect@^3.4.33":
"@types/connect@*":
version "3.4.35"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==
dependencies:
"@types/node" "*"
"@types/connect@^3.4.33":
version "3.4.37"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.37.tgz#c66a96689fd3127c8772eb3e9e5c6028ec1a9af5"
integrity sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==
dependencies:
"@types/node" "*"
"@types/cors@^2.8.13":
version "2.8.13"
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94"
@ -459,16 +459,23 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
"@types/node@*", "@types/node@^18.11.18":
version "18.11.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==
"@types/node@*":
version "20.8.10"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e"
integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==
dependencies:
undici-types "~5.26.4"
"@types/node@^12.12.54":
version "12.20.55"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
"@types/node@^18.11.18":
version "18.11.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==
"@types/qs@*":
version "6.9.7"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
@ -527,13 +534,11 @@ agent-base@6:
dependencies:
debug "4"
agentkeepalive@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717"
integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==
agentkeepalive@^4.2.1, agentkeepalive@^4.3.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923"
integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==
dependencies:
debug "^4.1.0"
depd "^1.1.2"
humanize-ms "^1.2.1"
arg@^4.1.0:
@ -590,14 +595,14 @@ bigint-buffer@^1.1.5:
bindings "^1.3.0"
bignumber.js@^9.0.0, bignumber.js@^9.0.1:
version "9.1.1"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6"
integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==
version "9.1.2"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c"
integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==
binance-api-node@^0.12.0:
version "0.12.2"
resolved "https://registry.yarnpkg.com/binance-api-node/-/binance-api-node-0.12.2.tgz#a7f9b8d94c2d75f64cb709d7b041b80da1e0e79d"
integrity sha512-X9zKjYhcp+smUMxmZvJdcqd22wQnD8gyjRKCmf1dno9Ft/mr9ZavtzHzjJaoXGbHbcGI2gSSg6fa8ozfT6B6Yg==
version "0.12.7"
resolved "https://registry.yarnpkg.com/binance-api-node/-/binance-api-node-0.12.7.tgz#bce64742d5dc5a9398df3cbd861c486b4d4df075"
integrity sha512-hEIPaZg1YwZClOznAJo5Zb1JyxsqdYjT8twG48rhOwhbNVrLJRxkeGj+PTa881wFXOtyOtyrXsDytsEcI2EUHA==
dependencies:
https-proxy-agent "^5.0.0"
isomorphic-fetch "^3.0.0"
@ -687,9 +692,9 @@ buffer@6.0.3, buffer@^6.0.1, buffer@^6.0.3, buffer@~6.0.3:
ieee754 "^1.2.1"
bufferutil@^4.0.1, bufferutil@^4.0.6:
version "4.0.7"
resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad"
integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==
version "4.0.8"
resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.8.tgz#1de6a71092d65d7766c4d8a522b261a6e787e8ea"
integrity sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==
dependencies:
node-gyp-build "^4.3.0"
@ -759,9 +764,9 @@ cors@^2.8.5:
vary "^1"
crc@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/crc/-/crc-4.2.0.tgz#3017c95b2c5f18e9907e80540e1d0a4ea0c00109"
integrity sha512-TpRSRyMXRyVu2LYKgu0uxuYvk026DS7BKAk8hdrJ0deOUxArnUTgsFvbPkQc2i3qHoT0upKPBJ+WoKc6t8kCMg==
version "4.3.2"
resolved "https://registry.yarnpkg.com/crc/-/crc-4.3.2.tgz#49b7821cbf2cf61dfd079ed93863bbebd5469b9a"
integrity sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==
create-require@^1.1.0:
version "1.1.1"
@ -769,11 +774,11 @@ create-require@^1.1.0:
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cross-fetch@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
version "3.1.8"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82"
integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==
dependencies:
node-fetch "2.6.7"
node-fetch "^2.6.12"
crypto-hash@^1.3.0:
version "1.3.0"
@ -787,7 +792,7 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
debug@4, debug@^4.1.0:
debug@4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -819,11 +824,6 @@ depd@2.0.0:
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
depd@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
destroy@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
@ -848,9 +848,9 @@ dotenv@10.0.0:
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
dotenv@^16.0.3:
version "16.0.3"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07"
integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==
version "16.3.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e"
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
ee-first@1.1.1:
version "1.1.1"
@ -1104,6 +1104,24 @@ jayson@^3.4.4:
uuid "^8.3.2"
ws "^7.4.5"
jayson@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.0.tgz#60dc946a85197317f2b1439d672a8b0a99cea2f9"
integrity sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==
dependencies:
"@types/connect" "^3.4.33"
"@types/node" "^12.12.54"
"@types/ws" "^7.4.4"
JSONStream "^1.3.5"
commander "^2.20.3"
delay "^5.0.0"
es6-promisify "^5.0.0"
eyes "^0.1.8"
isomorphic-ws "^4.0.1"
json-stringify-safe "^5.0.1"
uuid "^8.3.2"
ws "^7.4.5"
js-sha256@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966"
@ -1208,24 +1226,24 @@ no-case@^3.0.4:
lower-case "^2.0.2"
tslib "^2.0.3"
node-fetch@2, node-fetch@2.6.7, node-fetch@^2.6.1:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
node-fetch@2, node-fetch@^2.6.12, "node-fetch@npm:@blockworks-foundation/node-fetch@2.6.11":
version "2.6.11"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/node-fetch/-/node-fetch-2.6.11.tgz#fb536ef0e6a960e7b7993f3c1d3b3bba9bdfbc56"
integrity sha512-HeDTxpIypSR4qCoqgUXGr8YL4OG1z7BbV4VhQ9iQs+pt2wV3MtqO+sQk2vXK3WDKu5C6BsbGmWE22BmIrcuOOw==
dependencies:
whatwg-url "^5.0.0"
node-fetch@^2.6.7:
version "2.6.9"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6"
integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==
node-fetch@^2.6.1:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
dependencies:
whatwg-url "^5.0.0"
node-gyp-build@^4.3.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40"
integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==
version "4.6.1"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e"
integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==
node-kraken-api@^2.2.2:
version "2.2.2"
@ -1318,28 +1336,15 @@ reconnecting-websocket@^4.2.0:
resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783"
integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regenerator-runtime@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
rpc-websockets@^7.5.0:
version "7.5.0"
resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.0.tgz#bbeb87572e66703ff151e50af1658f98098e2748"
integrity sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ==
dependencies:
"@babel/runtime" "^7.17.2"
eventemitter3 "^4.0.7"
uuid "^8.3.2"
ws "^8.5.0"
optionalDependencies:
bufferutil "^4.0.1"
utf-8-validate "^5.0.2"
rpc-websockets@^7.5.1:
version "7.5.1"
resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.1.tgz#e0a05d525a97e7efc31a0617f093a13a2e10c401"
integrity sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==
rpc-websockets@^7.5.0, rpc-websockets@^7.5.1:
version "7.6.2"
resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.6.2.tgz#ed82f21ea8290f26d73f10d0dc0f9425dc364b81"
integrity sha512-+M1fOYMPxvOQDHbSItkD/an4fRwPZ1Nft1zv48G84S0TyChG2A1GXmjWkbs3o2NxW+q36H9nM2uLo5yojTrPaA==
dependencies:
"@babel/runtime" "^7.17.2"
eventemitter3 "^4.0.7"
@ -1497,9 +1502,9 @@ ts-node@^10.9.1:
yn "3.1.1"
tslib@^2.0.3:
version "2.4.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
type-is@~1.6.18:
version "1.6.18"
@ -1514,6 +1519,11 @@ typescript@^4.9.4:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78"
integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@ -1557,9 +1567,9 @@ webidl-conversions@^3.0.0:
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
whatwg-fetch@^3.4.1:
version "3.6.2"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c"
integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==
version "3.6.19"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz#caefd92ae630b91c07345537e67f8354db470973"
integrity sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==
whatwg-url@^5.0.0:
version "5.0.0"
@ -1575,9 +1585,9 @@ ws@^7.2.0, ws@^7.4.5:
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
ws@^8.5.0:
version "8.11.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
version "8.14.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f"
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
yn@3.1.1:
version "3.1.1"