Command-line tools to manage fee payer accounts and helper functions in payer-utils (#16)

* add CLI

* Refactor CLI and decouple fee payer utils to payer-utils in core

* restore original config

* add cli command to generate config for one token

* fix swap-tokens-to-sol cli command description

* use TokenFee in new endpoints as well
This commit is contained in:
Seva Zhidkov 2022-09-09 01:06:16 +03:00 committed by GitHub
parent 2dbbe9c0b2
commit f06b842982
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 964 additions and 75 deletions

View File

@ -10,7 +10,8 @@
"test:live": "lerna run test:live",
"test:live-with-test-validator": "lerna run test:live-with-test-validator",
"lint": "lerna run --stream --no-bail lint",
"lint:fix": "lerna run --stream --no-bail lint:fix"
"lint:fix": "lerna run --stream --no-bail lint:fix",
"cli": "lerna run --stream cli --scope @solana/octane-server --no-prefix -- --"
},
"devDependencies": {
"lerna": "^5.4.0",

View File

@ -29,7 +29,8 @@
"@solana/web3.js": "^1.34.0",
"bs58": "^4.0.1",
"cache-manager": "^3.6.0",
"encoding": "^0.1.13"
"encoding": "^0.1.13",
"axios": "^0.27.2"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",

View File

@ -1,6 +1,6 @@
import { Connection, Keypair, Transaction } from '@solana/web3.js';
import {
AllowedToken,
TokenFee,
sha256,
simulateRawTransaction,
validateAccountInitializationInstructions,
@ -31,7 +31,7 @@ export async function createAccountIfTokenFeePaid(
feePayer: Keypair,
maxSignatures: number,
lamportsPerSignature: number,
allowedTokens: AllowedToken[],
allowedTokens: TokenFee[],
cache: Cache,
sameSourceTimeout = 5000
) {

View File

@ -6,7 +6,7 @@ import {
simulateRawTransaction,
validateTransaction,
validateTransfer,
AllowedToken,
TokenFee,
validateInstructions,
} from '../core';
@ -30,7 +30,7 @@ export async function signWithTokenFee(
feePayer: Keypair,
maxSignatures: number,
lamportsPerSignature: number,
allowedTokens: AllowedToken[],
allowedTokens: TokenFee[],
cache: Cache,
sameSourceTimeout = 5000
): Promise<{ signature: string }> {

View File

@ -2,6 +2,7 @@ export * from './clusters';
export * from './messageToken';
export * from './sha256';
export * from './simulateRawTransaction';
export * from './tokenFee';
export * from './validateAccountInitialization';
export * from './validateInstructions';
export * from './validateTransaction';

View File

@ -0,0 +1,40 @@
import { PublicKey } from '@solana/web3.js';
type SerializableTokenFee = {
mint: string;
account: string;
decimals: number;
fee: number;
}
export class TokenFee {
public mint: PublicKey;
public account: PublicKey;
public decimals: number;
public fee: bigint;
constructor(mint: PublicKey, account: PublicKey, decimals: number, fee: bigint) {
this.mint = mint;
this.account = account;
this.decimals = decimals;
this.fee = fee;
}
toSerializable(): SerializableTokenFee {
return {
mint: this.mint.toBase58(),
account: this.account.toBase58(),
decimals: this.decimals,
fee: Number(this.fee)
};
}
static fromSerializable(serializableToken: SerializableTokenFee): TokenFee {
return new TokenFee(
new PublicKey(serializableToken.mint),
new PublicKey(serializableToken.account),
serializableToken.decimals,
BigInt(serializableToken.fee)
);
}
}

View File

@ -6,20 +6,14 @@ import {
isTransferCheckedInstruction,
isTransferInstruction,
} from '@solana/spl-token';
import { Connection, PublicKey, Transaction } from '@solana/web3.js';
export type AllowedToken = {
mint: PublicKey;
account: PublicKey;
decimals: number; // Token account to receive fee payments
fee: bigint;
};
import { Connection, Transaction } from '@solana/web3.js';
import { TokenFee } from './tokenFee';
// Check that a transaction contains a valid transfer to Octane's token account
export async function validateTransfer(
connection: Connection,
transaction: Transaction,
allowedTokens: AllowedToken[]
allowedTokens: TokenFee[]
): Promise<DecodedTransferInstruction | DecodedTransferCheckedInstruction> {
// Get the first instruction of the transaction
const [first] = transaction.instructions;

View File

@ -1,3 +1,4 @@
export * from './actions';
export * as core from './core';
export * as PayerUtils from './payer-utils';
export * from './swapProviders';

View File

@ -0,0 +1,65 @@
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import { TokenFee } from '../core';
import { createAssociatedTokenAccount, getAssociatedTokenAddress } from '@solana/spl-token';
export type CreateAccount = {
address: PublicKey;
mint: PublicKey;
};
export type CreateAccountResult = {
address: PublicKey;
mint: PublicKey;
error: Error | null;
};
export async function buildCreateAccountListFromTokenFees(
connection: Connection,
feePayer: PublicKey,
tokenFees: TokenFee[]
): Promise<CreateAccount[]> {
let createAccounts: CreateAccount[] = [];
for (const tokenFee of tokenFees) {
const alreadyCreated = await connection.getAccountInfo(tokenFee.account);
if (alreadyCreated) {
continue;
}
const associatedWithFeePayer = tokenFee.account.equals(
await getAssociatedTokenAddress(tokenFee.mint, feePayer)
);
if (!associatedWithFeePayer) {
continue;
}
createAccounts.push({ mint: tokenFee.mint, address: tokenFee.account });
}
return createAccounts;
}
export async function createAccounts(
connection: Connection,
feePayer: Keypair,
accounts: CreateAccount[]
): Promise<CreateAccountResult[]> {
let results: CreateAccountResult[] = [];
for (const account of accounts) {
let error: Error | null = null;
try {
await createAssociatedTokenAccount(
connection,
feePayer,
account.mint,
feePayer.publicKey,
);
} catch (e) {
error = e as Error;
}
results.push({...account, error})
}
return results;
}

View File

@ -0,0 +1,4 @@
export * from './accounts';
export * from './tokenFees';
export * from './jupiter';
export * from './swaps';

View File

@ -0,0 +1,120 @@
import axios from 'axios';
import { PublicKey, Transaction } from '@solana/web3.js';
import { NATIVE_MINT } from '@solana/spl-token';
export type TokenPriceInfo = {
id: string;
mintSymbol: string;
vsToken: string;
vsTokenSymbol: string;
price: number;
}
type TokenPriceInfoResponse = {
data: TokenPriceInfo;
timeTaken: number;
}
export type Route = {
inAmount: number;
outAmount: number;
amount: number;
otherAmountThreshold: number;
outAmountWithSlippage: number;
swapMode: string;
priceImpactPct: number;
marketInfos: RouteMarketInfo[];
}
export type RouteMarketInfo = {
id: string;
label: string;
inputMint: string;
outputMint: string;
inAmount: number;
outAmount: number;
lpFee: RouteFee;
platformFee: RouteFee;
notEnoughLiquidity: boolean;
priceImpactPct: number;
minInAmount?: number;
minOutAmount?: number;
}
export type RouteFee = {
amount: number;
mint: string;
pct: number;
}
type RoutesResponse = {
data: Route[];
timeTaken: number;
contextSlot: string;
}
export type SwapTransactions = {
setup: Transaction | null;
swap: Transaction | null;
cleanup: Transaction | null;
}
type SwapTransactionsResponse = {
setupTransaction: string | null;
swapTransaction: string | null;
cleanupTransaction: string | null;
}
export async function getPopularTokens(count: number, excludeNative = true): Promise<PublicKey[]> {
const response = await axios.get('https://cache.jup.ag/top-tokens');
const mints = response.data.map((mint: string) => new PublicKey(mint)) as PublicKey[];
const filteredMints = excludeNative ? mints.filter(value => !value.equals(NATIVE_MINT)) : mints;
return filteredMints.slice(0, count);
}
export async function getTokenToNativePriceInfo(mint: PublicKey): Promise<TokenPriceInfo> {
const priceInfoResponse = (
await axios.get('https://price.jup.ag/v1/price', {params: {id: 'SOL', vsToken: mint.toBase58()}})
).data as TokenPriceInfoResponse;
return priceInfoResponse.data;
}
export async function getRoutes(
inputMint: PublicKey,
outputMint: PublicKey,
amount: BigInt,
slippage: number
): Promise<Route[]> {
const params = {
inputMint: inputMint.toBase58(),
outputMint: outputMint.toBase58(),
amount: amount,
slippage: slippage,
};
const routesResponse = (await axios.get(
'https://quote-api.jup.ag/v1/quote', { params }
)).data as RoutesResponse;
return routesResponse.data;
}
export async function getSwapTransactions(wallet: PublicKey, route: Route): Promise<SwapTransactions> {
const decodeTransactionOrNull = (serialized: string | null) => (
serialized !== null ? Transaction.from(Buffer.from(serialized, 'base64')) : null
);
const response = (
await axios.post('https://quote-api.jup.ag/v1/swap', {
route,
userPublicKey: wallet.toString(),
wrapUnwrapSOL: true,
}, {
headers: { 'Content-Type': 'application/json' }
})
).data as SwapTransactionsResponse;
return {
setup: decodeTransactionOrNull(response.setupTransaction),
swap: decodeTransactionOrNull(response.swapTransaction),
cleanup: decodeTransactionOrNull(response.cleanupTransaction),
}
}

View File

@ -0,0 +1,45 @@
import { Connection, Keypair } from '@solana/web3.js';
import { getAccount, NATIVE_MINT } from '@solana/spl-token';
import { TokenFee } from '../core';
import { getRoutes, getSwapTransactions, Route } from './jupiter';
export async function loadSwapRoutesForTokenFees(
connection: Connection,
tokenFees: TokenFee[],
thresholdInLamports: number,
slippage: number = 0.5
): Promise<Route[]> {
let routes = [];
for (const tokenFee of tokenFees) {
const account = await getAccount(connection, tokenFee.account);
if (account.amount === 0n) {
continue;
}
const route = (await getRoutes(
tokenFee.mint, NATIVE_MINT, account.amount, slippage
))[0];
if (route.outAmount < thresholdInLamports) {
continue;
}
routes.push(route);
}
return routes;
}
export async function executeSwapByRoute(connection: Connection, feePayer: Keypair, route: Route): Promise<string[]> {
const transactions = await getSwapTransactions(feePayer.publicKey, route);
let txids = [];
for (const transaction of [transactions.setup, transactions.swap, transactions.cleanup]) {
if (transaction === null) {
continue;
}
const txid = await connection.sendTransaction(
transaction,
[feePayer],
{ skipPreflight: true }
);
await connection.confirmTransaction(txid);
txids.push(txid);
}
return txids;
}

View File

@ -0,0 +1,60 @@
import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, Transaction } from '@solana/web3.js';
import { TokenFee } from '../core';
import { TokenPriceInfo } from './jupiter';
import { getAssociatedTokenAddress, getMint, Mint } from '@solana/spl-token';
export type TokenWithPriceInfo = {
mint: PublicKey;
priceInfo: TokenPriceInfo;
}
export type PricingParams = {
costInLamports: number; // might be more than transaction fee when building config for creating account
margin: number;
}
export async function getLamportsPerSignature(connection: Connection): Promise<number> {
const transaction = new Transaction();
transaction.feePayer = Keypair.generate().publicKey;
transaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
return (await connection.getFeeForMessage(transaction.compileMessage())).value;
}
export function createTokenFee(
mint: PublicKey,
priceInfo: TokenPriceInfo,
mintInfo: Mint,
associatedAccount: PublicKey,
params: PricingParams
): TokenFee {
// convert params.costInLamports (price in SOL) to price in token
const tokenPricePerSignature = priceInfo.price / LAMPORTS_PER_SOL * params.costInLamports;
// add desired margin
// for example, price is 0.01, margin is 0.9, then (1 / (1 - margin)) = 10 and price after margin is 0.1.
const tokenPriceAfterMargin = tokenPricePerSignature * (1 / (1 - params.margin));
// convert to int per decimals setting of token
const tokenPriceInDecimalNotation = Math.floor(tokenPriceAfterMargin * (10 ** mintInfo.decimals)) + 1;
return new TokenFee(
mint, associatedAccount, mintInfo.decimals, BigInt(tokenPriceInDecimalNotation)
);
}
export function buildTokenFeeList(
connection: Connection,
feePayer: PublicKey,
tokens: TokenWithPriceInfo[],
params: PricingParams
): Promise<TokenFee[]> {
return Promise.all(tokens.map(
async token => createTokenFee(
token.mint,
token.priceInfo,
await getMint(connection, token.mint),
await getAssociatedTokenAddress(token.mint, feePayer),
params,
)
));
}

View File

@ -17,7 +17,7 @@ import {
createAssociatedTokenAccountInstruction,
} from '@solana/spl-token';
import { createAccountIfTokenFeePaid } from '../../src';
import { AllowedToken } from '../../src/core';
import { TokenFee } from '../../src/core';
import { airdropLamports } from '../common';
use(chaiAsPromised);
@ -29,7 +29,7 @@ if (process.env.TEST_LIVE) {
let tokenKeypair: Keypair; // Token owner
let mint: PublicKey;
let feePayerTokenAccount: Account; // Account for fees in tokens
let baseAllowedTokens: AllowedToken[];
let baseAllowedTokens: TokenFee[];
let cache: cacheManager.Cache;
before(async () => {
cache = cacheManager.caching({ store: MemoryStore, max: 1000, ttl: 120 });
@ -45,12 +45,7 @@ if (process.env.TEST_LIVE) {
feePayerKeypair.publicKey
);
baseAllowedTokens = [
{
mint: mint,
account: feePayerTokenAccount.address,
decimals: 9,
fee: BigInt(100),
},
new TokenFee(mint, feePayerTokenAccount.address, 9, BigInt(100)),
];
});

View File

@ -15,7 +15,7 @@ import {
getAccount,
} from '@solana/spl-token';
import { signWithTokenFee } from '../../src';
import { AllowedToken } from '../../src/core';
import { TokenFee } from '../../src/core';
import { airdropLamports, sleep } from '../common';
use(chaiAsPromised);
@ -27,7 +27,7 @@ if (process.env.TEST_LIVE) {
let tokenKeypair: Keypair; // Token owner
let mint: PublicKey;
let feePayerTokenAccount: Account; // Account for fees in tokens
let baseAllowedTokens: AllowedToken[];
let baseAllowedTokens: TokenFee[];
let cache: cacheManager.Cache;
before(async () => {
cache = cacheManager.caching({ store: MemoryStore, max: 1000, ttl: 120 });
@ -43,12 +43,7 @@ if (process.env.TEST_LIVE) {
feePayerKeypair.publicKey
);
baseAllowedTokens = [
{
mint: mint,
account: feePayerTokenAccount.address,
decimals: 9,
fee: BigInt(100),
},
new TokenFee(mint, feePayerTokenAccount.address, 9, BigInt(100))
];
});

View File

@ -348,6 +348,11 @@ async@3.2.3:
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
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@^0.21.1:
version "0.21.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
@ -355,6 +360,14 @@ axios@^0.21.1:
dependencies:
follow-redirects "^1.14.0"
axios@^0.27.2:
version "0.27.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
dependencies:
follow-redirects "^1.14.9"
form-data "^4.0.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -576,6 +589,13 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
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"
@ -643,6 +663,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==
diff@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
@ -914,11 +939,20 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2"
integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
follow-redirects@^1.14.0:
follow-redirects@^1.14.0, follow-redirects@^1.14.9:
version "1.15.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
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"
from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
@ -1293,6 +1327,18 @@ merge-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
mime-db@1.52.0:
version "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.12:
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==
dependencies:
mime-db "1.52.0"
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"

View File

@ -0,0 +1,19 @@
const path = require('path');
module.exports = {
webpack: (config, { isServer, nextRuntime }) => {
if (isServer && nextRuntime !== 'edge') {
return {
...config,
entry() {
return config.entry().then((entry) => ({
...entry,
// adding custom entry points
cli: path.resolve(process.cwd(), 'src/cli.ts'),
}));
}
};
}
return config;
},
};

View File

@ -15,7 +15,7 @@
"lint": "next lint && prettier --check '{*,**/*}.{js,ts,jsx,tsx,json}'",
"lint:fix": "eslint --fix --ext .ts . && yarn fmt",
"fmt": "prettier --write '{*,**/*}.{js,ts,jsx,tsx,json}'",
"nuke": "shx rm -rf node_modules yarn.lock"
"cli": "dotenv -c -- node .next/server/cli.js"
},
"dependencies": {
"@solana/octane-core": "*",
@ -23,6 +23,7 @@
"@solana/web3.js": "^1.48.0",
"bs58": "^5.0.0",
"cache-manager": "^4.1.0",
"commander": "^9.4.0",
"cors": "^2.8.5",
"express": "^4.18.1",
"express-rate-limit": "^6.4.0",
@ -34,10 +35,13 @@
"@next/eslint-plugin-next": "^12.2.3",
"@types/bs58": "^4.0.1",
"@types/cache-manager": "^3.4.2",
"@types/commander": "^2.12.2",
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/express-rate-limit": "^5.1.3",
"@types/react": "^18.0.15",
"dotenv": "^16.0.1",
"dotenv-cli": "^6.0.0",
"eslint": "^8.4.1",
"prettier": "^2.5.1",
"shx": "^0.3.3",

View File

@ -7,7 +7,7 @@ import { PublicKey } from '@solana/web3.js';
import { getAssociatedTokenAddress } from '@solana/spl-token';
import { Percentage } from '@orca-so/common-sdk';
import { buildWhirlpoolsSwapToSOL } from '@solana/octane-core';
import { buildWhirlpoolsSwapToSOL, core } from '@solana/octane-core';
import { cache, connection, ENV_SECRET_KEYPAIR, cors, rateLimit } from '../../src';
import config from '../../../../config.json';
@ -49,12 +49,7 @@ export default async function (request: NextApiRequest, response: NextApiRespons
}
const tokenFees = (
config.endpoints.whirlpoolsSwap.tokens
.map((tokenFee) => ({
...tokenFee,
mint: new PublicKey(tokenFee.mint),
account: new PublicKey(tokenFee.account),
}))
config.endpoints.whirlpoolsSwap.tokens.map((token) => core.TokenFee.fromSerializable(token))
.filter((tokenFee) => tokenFee.mint.equals(sourceMint))
);
if (tokenFees.length === 0) {
@ -74,7 +69,7 @@ export default async function (request: NextApiRequest, response: NextApiRespons
cache,
3000,
{
amount: tokenFee.fee,
amount: Number(tokenFee.fee),
sourceAccount: await getAssociatedTokenAddress(sourceMint, user),
destinationAccount: tokenFee.account
}

View File

@ -1,9 +1,9 @@
import { PublicKey, sendAndConfirmRawTransaction, Transaction } from '@solana/web3.js';
import { sendAndConfirmRawTransaction, Transaction } from '@solana/web3.js';
import type { NextApiRequest, NextApiResponse } from 'next';
import base58 from 'bs58';
import { ENV_SECRET_KEYPAIR, cors, rateLimit, connection, cache } from '../../src';
import config from '../../../../config.json';
import { createAccountIfTokenFeePaid } from '@solana/octane-core';
import { core, createAccountIfTokenFeePaid } from '@solana/octane-core';
// Endpoint to create associated token account with transaction fees and account initialization fees paid by SPL tokens
export default async function (request: NextApiRequest, response: NextApiResponse) {
@ -32,12 +32,7 @@ export default async function (request: NextApiRequest, response: NextApiRespons
ENV_SECRET_KEYPAIR,
config.maxSignatures,
config.lamportsPerSignature,
config.endpoints.createAssociatedTokenAccount.tokens.map((token) => ({
mint: new PublicKey(token.mint),
account: new PublicKey(token.account),
decimals: token.decimals,
fee: BigInt(token.fee),
})),
config.endpoints.createAssociatedTokenAccount.tokens.map((token) => core.TokenFee.fromSerializable(token)),
cache
);

View File

@ -1,7 +1,7 @@
import { PublicKey, sendAndConfirmRawTransaction, Transaction } from '@solana/web3.js';
import type { NextApiRequest, NextApiResponse } from 'next';
import base58 from 'bs58';
import { signWithTokenFee } from '@solana/octane-core';
import { signWithTokenFee, core } from '@solana/octane-core';
import { cache, connection, ENV_SECRET_KEYPAIR, cors, rateLimit } from '../../src';
import config from '../../../../config.json';
@ -32,12 +32,7 @@ export default async function (request: NextApiRequest, response: NextApiRespons
ENV_SECRET_KEYPAIR,
config.maxSignatures,
config.lamportsPerSignature,
config.endpoints.transfer.tokens.map((token) => ({
mint: new PublicKey(token.mint),
account: new PublicKey(token.account),
decimals: token.decimals,
fee: BigInt(token.fee),
})),
config.endpoints.transfer.tokens.map((token) => core.TokenFee.fromSerializable(token)),
cache
);

174
packages/server/src/cli.ts Normal file
View File

@ -0,0 +1,174 @@
import { Command } from 'commander';
import { PublicKey } from '@solana/web3.js';
import {
getMinimumBalanceForRentExemptAccount,
} from '@solana/spl-token';
import { PayerUtils, core } from '@solana/octane-core';
import { connection, ENV_SECRET_KEYPAIR } from './index';
import config from '../../../config.json';
const MAINNET_BETA_GENESIS_HASH = '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d';
const program = new Command();
program
.command('create-config-with-popular-tokens')
.option(
'-t, --tokens-from-top <number>',
'Tokens from the top of Jupiter aggregator to include',
'10'
)
.option(
'-m, --margin <number>',
'Part of total user-paid fee that fee payers takes as a surplus to transaction costs. ' +
'From 0 to 1. For example, 0.5 would mean that user pays 2x the SOL signature fee and 0.9 would mean that user pays 10x the fee.',
'0.9'
)
.option(
'-a, --include-account-fees',
'Includes creating a associated token account in each fee. Use this flag when filling out the endpoints.createAccount part of config.',
''
)
.addHelpText(
'beforeAll',
'Loads popular tokens from Jupiter aggregator, calculates fees and outputs token entries to put in config'
)
.action(async ({tokensFromTop, margin, includeAccountFees}) => {
if ((await connection.getGenesisHash()) != MAINNET_BETA_GENESIS_HASH) {
console.log('CLI is designed to work only with mainnet-beta cluster. Change "rpcUrl" in config.json.')
return;
}
const popularTokenMints = await PayerUtils.getPopularTokens(tokensFromTop);
const lamportsPerSignature = await PayerUtils.getLamportsPerSignature(connection);
let cost: number;
if (includeAccountFees) {
cost = lamportsPerSignature + await getMinimumBalanceForRentExemptAccount(connection);
} else {
cost = lamportsPerSignature;
}
const tokensWithPriceInfo = await Promise.all(popularTokenMints.map(async mint => ({
mint: mint,
priceInfo: await PayerUtils.getTokenToNativePriceInfo(mint)
})));
const pricingParams = {
costInLamports: cost,
margin: margin,
};
const tokenFees = await PayerUtils.buildTokenFeeList(
connection,
ENV_SECRET_KEYPAIR.publicKey,
tokensWithPriceInfo,
pricingParams,
);
console.log(`lamportsPerSignature: ${lamportsPerSignature}`);
console.log(JSON.stringify(tokenFees.map(tokenFee => tokenFee.toSerializable())));
});
program
.command('generate-config-for-token')
.argument('<mint>')
.option(
'-m, --margin <number>',
'Part of total user-paid fee that fee payers takes as a surplus to transaction costs. ' +
'From 0 to 1. For example, 0.5 would mean that user pays 2x the SOL signature fee and 0.9 would mean that user pays 10x the fee.',
'0.9'
)
.option(
'-a, --include-account-fees',
'Includes creating a associated token account in each fee. Use this flag when filling out the endpoints.createAccount part of config.',
''
)
.action(async (mintAsString, {margin, includeAccountFees}) => {
const mint = new PublicKey(mintAsString);
const lamportsPerSignature = await PayerUtils.getLamportsPerSignature(connection);
let cost: number;
if (includeAccountFees) {
cost = lamportsPerSignature + await getMinimumBalanceForRentExemptAccount(connection);
} else {
cost = lamportsPerSignature;
}
const priceInfo = await PayerUtils.getTokenToNativePriceInfo(mint);
const pricingParams = {
costInLamports: cost,
margin: margin,
};
const tokenFee = (await PayerUtils.buildTokenFeeList(
connection,
ENV_SECRET_KEYPAIR.publicKey,
[{ mint, priceInfo }],
pricingParams,
))[0];
console.log(`lamportsPerSignature: ${lamportsPerSignature}`);
console.log(JSON.stringify(tokenFee.toSerializable()));
});
program
.command('create-accounts')
.option(
'-d, --dry-run',
'Outputs accounts to be created',
''
)
.addHelpText('beforeAll', 'Creates fee collection accounts for fees listed in config')
.action(async ({ dryRun }) => {
const createAccounts = await PayerUtils.buildCreateAccountListFromTokenFees(
connection,
ENV_SECRET_KEYPAIR.publicKey,
config.endpoints.transfer.tokens.map((tokenFee) => core.TokenFee.fromSerializable(tokenFee))
);
console.log('accounts to create:', createAccounts);
if (!dryRun) {
const result = await PayerUtils.createAccounts(connection, ENV_SECRET_KEYPAIR, createAccounts);
const errors = result.filter(value => value.error !== null);
if (errors) {
console.log('create results with errors:', errors);
}
}
});
program
.command('swap-tokens-to-sol')
.option(
'-d, --dry-run',
'Outputs swap transactions to be executed',
''
)
.option(
'-t, --threshold <number>',
'Minimum value of tokens to exchange, in SOL lamports',
'100000000'
)
.action(async ({ dryRun, threshold }) => {
const routesToSwap = await PayerUtils.loadSwapRoutesForTokenFees(
connection,
config.endpoints.transfer.tokens.map(token => core.TokenFee.fromSerializable(token)),
parseInt(threshold),
0.5
);
if (!routesToSwap) {
console.log('No tokens to swap');
}
console.log('Tokens to swap:', routesToSwap);
if (!dryRun) {
for (const route of routesToSwap) {
const txids = await PayerUtils.executeSwapByRoute(connection, ENV_SECRET_KEYPAIR, route);
console.log(`Executed transactions:`, txids);
}
}
});
program.parse();

View File

@ -45,6 +45,18 @@
"@ethersproject/logger" "^5.6.0"
hash.js "1.1.7"
"@hapi/hoek@^9.0.0":
version "9.3.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb"
integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==
"@hapi/topo@^5.0.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012"
integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==
dependencies:
"@hapi/hoek" "^9.0.0"
"@humanwhocodes/config-array@^0.9.2":
version "0.9.5"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7"
@ -129,6 +141,33 @@
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.2.tgz#7460be700a60d75816f01109400b51fe929d7e89"
integrity sha512-2D2iinWUL6xx8D9LYVZ5qi7FP6uLAoWymt8m8aaG2Ld/Ka8/k723fJfiklfuAcwOxfufPJI+nRbT5VcgHGzHAQ==
"@sideway/address@^4.1.3":
version "4.1.4"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==
dependencies:
"@hapi/hoek" "^9.0.0"
"@sideway/formula@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c"
integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==
"@sideway/pinpoint@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
"@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"
integrity sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==
dependencies:
"@solana/buffer-layout" "^4.0.0"
"@solana/web3.js" "^1.32.0"
bigint-buffer "^1.1.5"
bignumber.js "^9.0.1"
"@solana/buffer-layout@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz#75b1b11adc487234821c81dfae3119b73a5fd734"
@ -136,7 +175,17 @@
dependencies:
buffer "~6.0.3"
"@solana/web3.js@^1.48.0":
"@solana/spl-token@^0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.2.0.tgz#329bb6babb5de0f9c40035ddb1657f01a8347acd"
integrity sha512-RWcn31OXtdqIxmkzQfB2R+WpsJOVS6rKuvpxJFjvik2LyODd+WN58ZP3Rpjpro03fscGAkzlFuP3r42doRJgyQ==
dependencies:
"@solana/buffer-layout" "^4.0.0"
"@solana/buffer-layout-utils" "^0.2.0"
"@solana/web3.js" "^1.32.0"
start-server-and-test "^1.14.0"
"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.48.0":
version "1.48.0"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.48.0.tgz#331281b2d80640431fb3b6fdc6b704ec325917aa"
integrity sha512-Gb6XvdhGjGI7CdAXLmlMIEvEYvrwqc78JOtwCsSrTqzz7Ek/BhJpZ/Cv89gxRDrWxf6kHegAfaN2FxwuYMmDZQ==
@ -186,6 +235,13 @@
resolved "https://registry.yarnpkg.com/@types/cache-manager/-/cache-manager-3.4.3.tgz#eba99bf795b997ad0c309658101398c34d7faecb"
integrity sha512-71aBXoFYXZW4TnDHHH8gExw2lS28BZaWeKefgsiJI7QYZeJfUEbMKw6CQtzGjlYQcGIWwB76hcCrkVA3YHSvsw==
"@types/commander@^2.12.2":
version "2.12.2"
resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae"
integrity sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==
dependencies:
commander "*"
"@types/connect@*", "@types/connect@^3.4.33":
version "3.4.35"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
@ -351,6 +407,13 @@ async@3.2.3:
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
axios@^0.21.1:
version "0.21.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
dependencies:
follow-redirects "^1.14.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -380,6 +443,11 @@ bigint-buffer@^1.1.5:
dependencies:
bindings "^1.3.0"
bignumber.js@^9.0.1:
version "9.0.2"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673"
integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==
bindings@^1.3.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
@ -387,6 +455,11 @@ bindings@^1.3.0:
dependencies:
file-uri-to-path "1.0.0"
bluebird@3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
bn.js@^4.11.9:
version "4.12.0"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
@ -522,6 +595,11 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
check-more-types@2.24.0:
version "2.24.0"
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@ -534,6 +612,11 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
commander@*, commander@^9.4.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c"
integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==
commander@^2.20.3:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@ -574,7 +657,7 @@ cors@^2.8.5:
object-assign "^4"
vary "^1"
cross-spawn@^7.0.2:
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@ -595,6 +678,13 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
debug@4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
dependencies:
ms "2.1.2"
debug@^4.1.1, debug@^4.3.2:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
@ -629,6 +719,31 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
dotenv-cli@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-6.0.0.tgz#8a30cbc59d0a8aaa166b2fee0a9a55e23a1223ab"
integrity sha512-qXlCOi3UMDhCWFKe0yq5sg3X+pJAz+RQDiFN38AMSbUrnY3uZshSfDJUAge951OS7J9gwLZGfsBlWRSOYz/TRg==
dependencies:
cross-spawn "^7.0.3"
dotenv "^16.0.0"
dotenv-expand "^8.0.1"
minimist "^1.2.5"
dotenv-expand@^8.0.1:
version "8.0.3"
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-8.0.3.tgz#29016757455bcc748469c83a19b36aaf2b83dd6e"
integrity sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==
dotenv@^16.0.0, dotenv@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d"
integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==
duplexer@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -778,11 +893,39 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
event-stream@=3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
integrity sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==
dependencies:
duplexer "~0.1.1"
from "~0"
map-stream "~0.1.0"
pause-stream "0.0.11"
split "0.3"
stream-combiner "~0.0.4"
through "~2.3.1"
eventemitter3@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
execa@5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
dependencies:
cross-spawn "^7.0.3"
get-stream "^6.0.0"
human-signals "^2.1.0"
is-stream "^2.0.0"
merge-stream "^2.0.0"
npm-run-path "^4.0.1"
onetime "^5.1.2"
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
express-rate-limit@^6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-6.4.0.tgz#b7066afe21157a012ed2b7c9adde386e712485cd"
@ -888,6 +1031,11 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2"
integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
follow-redirects@^1.14.0:
version "1.15.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@ -898,6 +1046,11 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -922,6 +1075,11 @@ get-intrinsic@^1.0.2:
has "^1.0.3"
has-symbols "^1.0.3"
get-stream@^6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
glob-parent@^6.0.1:
version "6.0.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
@ -993,6 +1151,11 @@ http-errors@2.0.0:
statuses "2.0.1"
toidentifier "1.0.1"
human-signals@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@ -1065,6 +1228,11 @@ is-glob@^4.0.0, is-glob@^4.0.3:
dependencies:
is-extglob "^2.1.1"
is-stream@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@ -1096,6 +1264,17 @@ jayson@^3.4.4:
uuid "^8.3.2"
ws "^7.4.5"
joi@^17.4.0:
version "17.6.0"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.6.0.tgz#0bb54f2f006c09a96e75ce687957bd04290054b2"
integrity sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==
dependencies:
"@hapi/hoek" "^9.0.0"
"@hapi/topo" "^5.0.0"
"@sideway/address" "^4.1.3"
"@sideway/formula" "^3.0.0"
"@sideway/pinpoint" "^2.0.0"
js-sha3@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
@ -1133,6 +1312,11 @@ jsonparse@^1.2.0:
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==
lazy-ass@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513"
integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
@ -1151,7 +1335,7 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
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==
@ -1168,6 +1352,11 @@ lru-cache@^7.10.1:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.13.0.tgz#c8178692969fb680cad948db4aad54066590a65a"
integrity sha512-SNFKDOORR41fkWP3DXiIUvXvfzDRPg3bxD1+29iRyP2ZW+Njp2o6zhx9YkEpq1tbP0AEDNW2VBUedzDIxmNhdg==
map-stream@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
integrity sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@ -1178,6 +1367,11 @@ merge-descriptors@1.0.1:
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
@ -1200,6 +1394,11 @@ mime@1.6.0:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -1217,7 +1416,7 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.3:
minimist@^1.2.3, minimist@^1.2.5:
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
@ -1295,6 +1494,13 @@ node-gyp-build@^4.2.0, node-gyp-build@^4.3.0:
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40"
integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==
npm-run-path@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
dependencies:
path-key "^3.0.0"
object-assign@^4, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@ -1319,6 +1525,13 @@ once@^1.3.0:
dependencies:
wrappy "1"
onetime@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
dependencies:
mimic-fn "^2.1.0"
optionator@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
@ -1348,7 +1561,7 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-key@^3.1.0:
path-key@^3.0.0, path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
@ -1363,6 +1576,13 @@ path-to-regexp@0.1.7:
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
pause-stream@0.0.11:
version "0.0.11"
resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==
dependencies:
through "~2.3"
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
@ -1395,6 +1615,13 @@ proxy-addr@~2.0.7:
forwarded "0.2.0"
ipaddr.js "1.9.1"
ps-tree@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd"
integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==
dependencies:
event-stream "=3.3.4"
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
@ -1497,6 +1724,13 @@ rpc-websockets@^7.5.0:
bufferutil "^4.0.1"
utf-8-validate "^5.0.2"
rxjs@^7.1.0:
version "7.5.6"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc"
integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==
dependencies:
tslib "^2.1.0"
safe-buffer@5.2.1, safe-buffer@^5.0.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
@ -1596,16 +1830,48 @@ side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
signal-exit@^3.0.3:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
source-map-js@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
split@0.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
integrity sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==
dependencies:
through "2"
start-server-and-test@^1.14.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-1.14.0.tgz#c57f04f73eac15dd51733b551d775b40837fdde3"
integrity sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw==
dependencies:
bluebird "3.7.2"
check-more-types "2.24.0"
debug "4.3.2"
execa "5.1.1"
lazy-ass "1.6.0"
ps-tree "1.2.0"
wait-on "6.0.0"
statuses@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
stream-combiner@~0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
integrity sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==
dependencies:
duplexer "~0.1.1"
strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
@ -1613,6 +1879,11 @@ strip-ansi@^6.0.1:
dependencies:
ansi-regex "^5.0.1"
strip-final-newline@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
@ -1650,7 +1921,7 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
"through@>=2.2.7 <3":
through@2, "through@>=2.2.7 <3", through@~2.3, through@~2.3.1:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
@ -1665,7 +1936,7 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
tslib@^2.4.0:
tslib@^2.1.0, tslib@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
@ -1744,6 +2015,17 @@ vary@^1, vary@~1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
wait-on@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7"
integrity sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw==
dependencies:
axios "^0.21.1"
joi "^17.4.0"
lodash "^4.17.21"
minimist "^1.2.5"
rxjs "^7.1.0"
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"

View File

@ -1298,15 +1298,6 @@
"@solana/web3.js" "^1.32.0"
start-server-and-test "^1.14.0"
"@solana/spl-token@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.2.tgz#3403a8c0d17589881490b500669251c63b47f6db"
integrity sha512-qEGCUdfzWV9JBfkOdty211QmQGi6qEo6L+jM6vEaC8yM4kaHvj9GXTB5v1vRft/h02p0GnhYdChUP802MOwt/w==
dependencies:
"@solana/buffer-layout" "^4.0.0"
"@solana/buffer-layout-utils" "^0.2.0"
buffer "^6.0.3"
"@solana/web3.js@^1.21.0", "@solana/web3.js@^1.31.0", "@solana/web3.js@^1.36.0":
version "1.53.0"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.53.0.tgz#24a6341e4026fc2b993656141361c54bec917c07"
@ -1424,6 +1415,13 @@
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04"
integrity sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==
"@types/commander@^2.12.2":
version "2.12.2"
resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae"
integrity sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==
dependencies:
commander "*"
"@types/connect@*", "@types/connect@^3.4.33":
version "3.4.35"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
@ -1838,6 +1836,11 @@ async@3.2.3:
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
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==
at-least-node@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
@ -1850,6 +1853,14 @@ axios@^0.21.1:
dependencies:
follow-redirects "^1.14.0"
axios@^0.27.2:
version "0.27.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
dependencies:
follow-redirects "^1.14.9"
form-data "^4.0.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -2028,7 +2039,7 @@ buffer@6.0.1:
base64-js "^1.3.1"
ieee754 "^1.2.1"
buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3:
buffer@6.0.3, buffer@~6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
@ -2331,6 +2342,18 @@ columnify@^1.6.0:
strip-ansi "^6.0.1"
wcwidth "^1.0.0"
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@*, commander@^9.4.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c"
integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==
commander@^2.20.3:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@ -2636,6 +2659,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==
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
@ -2725,11 +2753,31 @@ dot-prop@^6.0.1:
dependencies:
is-obj "^2.0.0"
dotenv-cli@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-6.0.0.tgz#8a30cbc59d0a8aaa166b2fee0a9a55e23a1223ab"
integrity sha512-qXlCOi3UMDhCWFKe0yq5sg3X+pJAz+RQDiFN38AMSbUrnY3uZshSfDJUAge951OS7J9gwLZGfsBlWRSOYz/TRg==
dependencies:
cross-spawn "^7.0.3"
dotenv "^16.0.0"
dotenv-expand "^8.0.1"
minimist "^1.2.5"
dotenv-expand@^8.0.1:
version "8.0.3"
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-8.0.3.tgz#29016757455bcc748469c83a19b36aaf2b83dd6e"
integrity sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==
dotenv@10.0.0, dotenv@~10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
dotenv@^16.0.0, dotenv@^16.0.1:
version "16.0.2"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.2.tgz#0b0f8652c016a3858ef795024508cddc4bffc5bf"
integrity sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==
duplexer@^0.1.1, duplexer@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
@ -3190,11 +3238,20 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2"
integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
follow-redirects@^1.14.0:
follow-redirects@^1.14.0, follow-redirects@^1.14.9:
version "1.15.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
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"
@ -4281,7 +4338,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==