├── Cargo.toml ├── .gitignore ├── programs └── sol-nft-staking │ ├── Xargo.toml │ ├── Cargo.toml │ └── src │ ├── errors.rs │ ├── anchor_metaplex.rs │ ├── state.rs │ └── lib.rs ├── test-keypair.json ├── tsconfig.json ├── migrations └── deploy.ts ├── package.json ├── Anchor.toml ├── ts ├── package.json ├── tsconfig.json └── cli.ts ├── LICENSE ├── README.md ├── tests └── sol-nft-staking.ts ├── Cargo.lock └── yarn.lock /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | -------------------------------------------------------------------------------- /programs/sol-nft-staking/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /test-keypair.json: -------------------------------------------------------------------------------- 1 | [158,121,121,184,39,67,191,89,198,146,190,25,131,192,195,105,177,163,66,160,225,88,199,135,195,19,37,146,246,100,209,4,150,64,51,201,194,68,209,84,132,227,124,253,219,246,78,153,39,19,199,140,135,78,69,211,174,209,131,38,220,26,155,189] -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | } 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@project-serum/anchor": "^0.18.2" 4 | }, 5 | "devDependencies": { 6 | "@metaplex-foundation/mpl-token-metadata": "0.0.2", 7 | "@metaplex/js": "^4.9.0", 8 | "@solana/spl-token": "^0.1.8", 9 | "@types/chai": "^4.2.22", 10 | "@types/mocha": "^9.0.0", 11 | "chai": "^4.3.4", 12 | "mocha": "^9.0.3", 13 | "ts-mocha": "^8.0.0", 14 | "typescript": "^4.3.5" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /programs/sol-nft-staking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sol-nft-staking" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "sol_nft_staking" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | cpi = ["no-entrypoint"] 15 | default = [] 16 | 17 | [dependencies] 18 | anchor-lang = "0.18.2" 19 | anchor-spl = "0.18.2" 20 | metaplex-token-metadata = {version = "0.0.1", features = ["no-entrypoint"]} 21 | spl-token = "3.2.0" 22 | -------------------------------------------------------------------------------- /Anchor.toml: -------------------------------------------------------------------------------- 1 | [programs.localnet] 2 | sol_nft_staking = "3zPPaZhN3tAkSJhjcEcyT7kAM6b2stQmJf65Fw9sMZa3" 3 | 4 | [registry] 5 | url = "https://anchor.projectserum.com" 6 | 7 | [provider] 8 | cluster = "localnet" 9 | wallet = "./test-keypair.json" 10 | 11 | [test] 12 | # Clone the metadata program and the executable account associated with it 13 | # for use in integration tests 14 | clone = [ 15 | {address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"}, 16 | {address = "PwDiXFxQsGra4sFFTT8r1QWRMd4vfumiWC1jfWNfdYT"} 17 | ] 18 | validator = {url = "mainnet-beta"} 19 | 20 | [scripts] 21 | test = "npx ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 22 | -------------------------------------------------------------------------------- /ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sol-nft-staking-cli", 3 | "version": "1.0.0", 4 | "description": "CLI for interacting with the sol-nft-staking Solana program", 5 | "main": "cli.ts", 6 | "scripts": { 7 | "start": "ts-node cli.ts", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "VegetarianOrc", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@project-serum/anchor": "^0.18.2", 14 | "@solana/spl-token": "^0.1.8", 15 | "commander": "^8.3.0" 16 | }, 17 | "devDependencies": { 18 | "@babel/preset-env": "^7.16.4", 19 | "@babel/preset-typescript": "^7.16.0", 20 | "@types/commander": "^2.12.2", 21 | "ts-node": "^10.4.0", 22 | "typescript": "^4.5.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "declaration": false, 6 | "esModuleInterop": true, 7 | "noImplicitAny": false, 8 | "removeComments": false, 9 | "isolatedModules": false, 10 | "experimentalDecorators": true, 11 | "downlevelIteration": true, 12 | "emitDecoratorMetadata": true, 13 | "noLib": false, 14 | "preserveConstEnums": true, 15 | "suppressImplicitAnyIndexErrors": true, 16 | "resolveJsonModule": true, 17 | "lib": [ 18 | "dom", 19 | "es2019" 20 | ] 21 | }, 22 | "exclude": [ 23 | "node_modules", 24 | "typings/browser", 25 | "typings/browser.d.ts" 26 | ], 27 | "atom": { 28 | "rewriteTsconfig": false 29 | } 30 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alex Mazzeo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /programs/sol-nft-staking/src/errors.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | #[error] 4 | pub enum StakingError { 5 | #[msg("The provided reward mint doesn't have the correct minting authority")] 6 | RewarderNotMintAuthority, 7 | 8 | #[msg("The provided authority is not valid for the rewarder")] 9 | InvalidRewarderAuthority, 10 | 11 | #[msg("The provided rewarder does not match the stake account")] 12 | InvalidRewarder, 13 | 14 | #[msg("The provided owner does not own the stake account")] 15 | InvalidOwnerForStakeAccount, 16 | 17 | #[msg("The provided Mint is not valid for the provided Rewarder")] 18 | InvalidRewardMint, 19 | 20 | #[msg("The provided reward token account is not owned by the provided owner")] 21 | InvalidOwnerForRewardToken, 22 | 23 | #[msg("The provided reward token account is not for the reward token mint")] 24 | InvalidRewardTokenAccount, 25 | 26 | #[msg("The provided NFT Mint has a supply that isn't 1")] 27 | InvalidNFTMintSupply, 28 | 29 | #[msg("The provided NFT token account is not owned by the provided owner")] 30 | InvalidNFTOwner, 31 | 32 | #[msg("The provided NFT token account is not for the NFT mint")] 33 | InvalidNFTAccountMint, 34 | 35 | #[msg("The provided NFT token account does not have the token")] 36 | NFTAccountEmpty, 37 | 38 | #[msg("The provided NFT token account is not owned by the provided stake account")] 39 | InvalidStakedNFTOwner, 40 | 41 | #[msg("There was no Metaplex Metadata account supplied")] 42 | MetadataAccountNotFound, 43 | 44 | #[msg("The Metaplex Metadata account is not owned by the Metaplex Token Metadata program")] 45 | MetadataAccountNotOwnedByCorrectProgram, 46 | 47 | #[msg("The Metaplex Metadata account failed to deserialze")] 48 | InvalidMetadataAccountData, 49 | 50 | #[msg("The Metaplex Metadata account did not have the expected PDA seeds")] 51 | InvalidMetadataAccountAddress, 52 | 53 | #[msg("The Metaplex Metadata account did not have the expected update authority")] 54 | InvalidMetadataUpdateAuthority, 55 | 56 | #[msg("The Metaplex Metadata account did not have a name beginning with the collection")] 57 | InvalidMetadataCollectionPrefix, 58 | 59 | #[msg("The Metaplex Metadata account did not have the expected creators")] 60 | InvalidMetadataCreators, 61 | } 62 | -------------------------------------------------------------------------------- /programs/sol-nft-staking/src/anchor_metaplex.rs: -------------------------------------------------------------------------------- 1 | use std::ops::{Deref, DerefMut}; 2 | 3 | use anchor_lang::prelude::{ProgramError, Pubkey}; 4 | use anchor_lang::solana_program::borsh::try_from_slice_unchecked; 5 | use metaplex_token_metadata::state::{Key as MetaplexKey, Metadata, MAX_METADATA_LEN}; 6 | use metaplex_token_metadata::utils::try_from_slice_checked; 7 | 8 | pub use metaplex_token_metadata::state::PREFIX as PDAPrefix; 9 | pub use metaplex_token_metadata::ID; 10 | 11 | #[derive(Clone)] 12 | pub struct MetaplexTokenMetadata; 13 | 14 | impl anchor_lang::AccountDeserialize for MetaplexTokenMetadata { 15 | fn try_deserialize(buf: &mut &[u8]) -> Result { 16 | MetaplexTokenMetadata::try_deserialize_unchecked(buf) 17 | } 18 | 19 | fn try_deserialize_unchecked(_buf: &mut &[u8]) -> Result { 20 | Ok(MetaplexTokenMetadata) 21 | } 22 | } 23 | 24 | impl anchor_lang::Id for MetaplexTokenMetadata { 25 | fn id() -> Pubkey { 26 | ID 27 | } 28 | } 29 | 30 | #[derive(Clone)] 31 | pub struct MetadataAccount(Metadata); 32 | 33 | impl MetadataAccount { 34 | pub const LEN: usize = MAX_METADATA_LEN; 35 | } 36 | 37 | impl anchor_lang::AccountDeserialize for MetadataAccount { 38 | fn try_deserialize(buf: &mut &[u8]) -> Result { 39 | try_from_slice_checked(buf, MetaplexKey::MetadataV1, MAX_METADATA_LEN).map(MetadataAccount) 40 | } 41 | 42 | fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result { 43 | let metadata: Metadata = try_from_slice_unchecked(buf) 44 | .map_err(|err| ProgramError::BorshIoError(err.to_string()))?; 45 | Ok(MetadataAccount(metadata)) 46 | } 47 | } 48 | 49 | impl anchor_lang::AccountSerialize for MetadataAccount { 50 | fn try_serialize(&self, _writer: &mut W) -> Result<(), ProgramError> { 51 | // no-op 52 | Ok(()) 53 | } 54 | } 55 | 56 | impl anchor_lang::Owner for MetadataAccount { 57 | fn owner() -> Pubkey { 58 | ID 59 | } 60 | } 61 | 62 | impl Deref for MetadataAccount { 63 | type Target = Metadata; 64 | 65 | fn deref(&self) -> &Self::Target { 66 | &self.0 67 | } 68 | } 69 | 70 | impl DerefMut for MetadataAccount { 71 | fn deref_mut(&mut self) -> &mut Self::Target { 72 | &mut self.0 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /programs/sol-nft-staking/src/state.rs: -------------------------------------------------------------------------------- 1 | use std::mem::size_of; 2 | 3 | use anchor_lang::prelude::*; 4 | use metaplex_token_metadata::state::Creator; 5 | 6 | pub trait Len { 7 | const LEN: usize; 8 | } 9 | 10 | impl Len for T 11 | where 12 | T: AnchorDeserialize + AnchorSerialize, 13 | { 14 | const LEN: usize = 8 + size_of::(); 15 | } 16 | 17 | #[account] 18 | pub struct NftStakeRewarder { 19 | pub authority: Pubkey, 20 | pub reward_mint: Pubkey, 21 | pub reward_authority_bump: u8, 22 | /// tokens rewarded per staked NFT per second 23 | pub reward_rate: u64, 24 | /// the update authority required in NFTs being staked 25 | pub allowed_update_authority: Pubkey, 26 | /// the creators required for the NFTs being staked 27 | pub creators: Vec, 28 | /// the collection name required for the NFTs being staked 29 | pub collection: String, 30 | /// flag to verify metadata of NFT against rewarder settings 31 | /// useful to have set to false during testing 32 | pub enforce_metadata: bool, 33 | /// The total number of NFTs staked with this rewarder. 34 | pub total_staked: u32, 35 | } 36 | 37 | impl NftStakeRewarder { 38 | pub fn calculate_len(num_creators: usize, collection: &str) -> usize { 39 | let mut size = size_of::() * 3; //stored pubkeys 40 | size += 1; // authority bump 41 | size += 8; // reward rate 42 | size += 4; //total staked 43 | size += 1; //enforced metadata 44 | 45 | let creator_size = size_of::() * num_creators; 46 | size += creator_size; 47 | let collection_size = size_of::() + collection.len(); 48 | size += collection_size; 49 | 50 | size 51 | } 52 | } 53 | 54 | #[derive(Debug, AnchorDeserialize, AnchorSerialize, Default, Clone)] 55 | pub struct CreatorStruct { 56 | address: Pubkey, 57 | verified: bool, 58 | share: u8, 59 | } 60 | 61 | impl PartialEq for &CreatorStruct { 62 | fn eq(&self, other: &Creator) -> bool { 63 | self.address == other.address 64 | && self.verified == other.verified 65 | && self.share == other.share 66 | } 67 | } 68 | 69 | #[account] 70 | pub struct NftStakeAccount { 71 | pub owner: Pubkey, 72 | pub rewarder: Pubkey, 73 | pub num_staked: u16, 74 | pub bump: u8, 75 | pub last_claimed: i64, 76 | } 77 | -------------------------------------------------------------------------------- /ts/cli.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program, web3 } from "@project-serum/anchor"; 3 | import { SolNftStaking } from "../target/types/sol_nft_staking"; 4 | import { Command, program as cliProgram } from "commander"; 5 | import * as fs from "fs"; 6 | import * as splToken from "@solana/spl-token"; 7 | 8 | const SOL_NFT_STAKING_PROGRAM_ID = new web3.PublicKey( 9 | "3zPPaZhN3tAkSJhjcEcyT7kAM6b2stQmJf65Fw9sMZa3" 10 | ); 11 | 12 | const systemProgram = anchor.web3.SystemProgram.programId; 13 | const rentSysvar = anchor.web3.SYSVAR_RENT_PUBKEY; 14 | const clockSysvar = anchor.web3.SYSVAR_CLOCK_PUBKEY; 15 | 16 | function cliCommand(name: string): Command { 17 | return cliProgram 18 | .command(name) 19 | .option( 20 | "-e, --env ", 21 | "Solana cluster env name", 22 | "devnet" //mainnet-beta, testnet, devnet 23 | ) 24 | .option( 25 | "-k, --keypair ", 26 | `Solana wallet location`, 27 | "--keypair not provided" 28 | ); 29 | } 30 | 31 | function loadWalletKey(keypair): web3.Keypair { 32 | if (!keypair || keypair == "") { 33 | throw new Error("Keypair is required!"); 34 | } 35 | const loaded = web3.Keypair.fromSecretKey( 36 | new Uint8Array(JSON.parse(fs.readFileSync(keypair).toString())) 37 | ); 38 | console.log(`wallet public key: ${loaded.publicKey}`); 39 | return loaded; 40 | } 41 | 42 | interface Creator { 43 | address: web3.PublicKey; 44 | verified: boolean; 45 | share: number; 46 | } 47 | 48 | function loadCreators(creators): Creator[] { 49 | let parsedCreators = []; 50 | 51 | return parsedCreators; 52 | } 53 | 54 | async function getRewarderAddress( 55 | collectionName: string 56 | ): Promise<[web3.PublicKey, number]> { 57 | return await anchor.web3.PublicKey.findProgramAddress( 58 | [ 59 | Buffer.from(collectionName), 60 | SOL_NFT_STAKING_PROGRAM_ID.toBuffer(), 61 | Buffer.from("rewarder"), 62 | ], 63 | SOL_NFT_STAKING_PROGRAM_ID 64 | ); 65 | } 66 | 67 | async function getRewarderAuthority( 68 | collectionName: string, 69 | rewarderAddress: web3.PublicKey 70 | ): Promise<[web3.PublicKey, number]> { 71 | return await anchor.web3.PublicKey.findProgramAddress( 72 | [ 73 | Buffer.from(collectionName), 74 | SOL_NFT_STAKING_PROGRAM_ID.toBuffer(), 75 | Buffer.from("rewarder"), 76 | rewarderAddress.toBuffer(), 77 | ], 78 | SOL_NFT_STAKING_PROGRAM_ID 79 | ); 80 | } 81 | 82 | function printRewarder(address: web3.PublicKey, rewarder: any) { 83 | const toLog = { 84 | authority: rewarder.authority.toBase58(), 85 | rewardMint: rewarder.rewardMint.toBase58(), 86 | rewardAuthorityBump: rewarder.rewardAuthorityBump, 87 | rewardRate: rewarder.rewardRate.toNumber(), 88 | allowedUpdateAuthority: rewarder.allowedUpdateAuthority.toBase58(), 89 | creators: rewarder.creators, 90 | collection: rewarder.collection, 91 | enforceMetadata: rewarder.enforceMetadata, 92 | totalStaked: rewarder.totalStaked, 93 | }; 94 | console.log( 95 | `Rewarder ${address.toBase58()}\n${JSON.stringify(toLog, null, 2)}` 96 | ); 97 | } 98 | 99 | cliProgram.version("0.0.1"); 100 | 101 | const rewarderCommand = cliCommand("rewarder"); 102 | 103 | rewarderCommand 104 | .command("get") 105 | .option("-a, --address ", "The address of the rewarder", null) 106 | .option( 107 | "-n, --name ", 108 | "The name of the NFT collection the rewarder is for", 109 | null 110 | ) 111 | .action(async (directory: string, cmd: Command) => { 112 | const { env } = cmd.parent.opts(); 113 | const { name, address } = cmd.opts(); 114 | const connection = new web3.Connection(web3.clusterApiUrl(env)); 115 | 116 | if ((!address || address.length === 0) && (!name || name.length === 0)) { 117 | console.log("Either address or name is required"); 118 | return; 119 | } 120 | 121 | let key; 122 | if (address && address.length !== 0) { 123 | key = new web3.PublicKey(address); 124 | } else { 125 | const [rewarderAddress, _] = await getRewarderAddress(name); 126 | key = rewarderAddress; 127 | } 128 | 129 | anchor.setProvider( 130 | new anchor.Provider(connection, null, { commitment: "confirmed" }) 131 | ); 132 | 133 | const solNftStakingProgram = (await Program.at( 134 | SOL_NFT_STAKING_PROGRAM_ID 135 | )) as Program; 136 | 137 | const rewarder = await solNftStakingProgram.account.nftStakeRewarder.fetch( 138 | key 139 | ); 140 | printRewarder(key, rewarder); 141 | }); 142 | 143 | rewarderCommand 144 | .command("create") 145 | .requiredOption( 146 | "-d, --decimals ", 147 | "The number of decimals for the reward token" 148 | ) 149 | .requiredOption( 150 | "-r, --rewardRate ", 151 | "The number reward per second per nft staked for the rewarder" 152 | ) 153 | .requiredOption( 154 | "-n, --name ", 155 | "The name of the NFT collection the rewarder is for" 156 | ) 157 | .option( 158 | "-c, --creators ", 159 | "the path to a json array of nft creator objects" 160 | ) 161 | .action(async (directory: string, cmd: Command) => { 162 | const { env, keypair } = cmd.parent.opts(); 163 | const { decimals, name, rewardRate, creators } = cmd.opts(); 164 | const collectionName = name; 165 | const connection = new web3.Connection(web3.clusterApiUrl(env)); 166 | const walletKeyPair = loadWalletKey(keypair); 167 | const wallet = new anchor.Wallet(walletKeyPair); 168 | 169 | anchor.setProvider( 170 | new anchor.Provider(connection, wallet, { 171 | commitment: "confirmed", 172 | }) 173 | ); 174 | 175 | const parsedCreators = loadCreators(creators); 176 | 177 | const solNftStakingProgram = (await Program.at( 178 | SOL_NFT_STAKING_PROGRAM_ID 179 | )) as Program; 180 | console.log(`Creating rewarder for '${name}'`); 181 | 182 | console.log(`Finding PDAs for rewarder and mint authority`); 183 | const [rewarder, rewarderBump] = await getRewarderAddress(collectionName); 184 | const [rewardAuthority, rewardAuthorityBump] = await getRewarderAuthority( 185 | collectionName, 186 | rewarder 187 | ); 188 | console.log(`creating reward mint`); 189 | const rewardMint = await splToken.Token.createMint( 190 | connection, 191 | walletKeyPair, //payer 192 | rewardAuthority, //mint authority 193 | null, //freeze authority 194 | decimals, //deicmals 195 | splToken.TOKEN_PROGRAM_ID 196 | ); 197 | console.log(`Reward mint created: ${rewardMint.publicKey.toBase58()} `); 198 | 199 | const initRewarderTxId = await solNftStakingProgram.rpc.initializeRewarder( 200 | rewarderBump, 201 | rewardAuthorityBump, 202 | new anchor.BN(rewardRate), 203 | Buffer.from(collectionName), 204 | parsedCreators, 205 | wallet.publicKey, 206 | false, 207 | { 208 | accounts: { 209 | rewarder: rewarder, 210 | authority: wallet.publicKey, 211 | rewardAuthority: rewardAuthority, 212 | rewardMint: rewardMint.publicKey, 213 | systemProgram, 214 | rent: rentSysvar, 215 | }, 216 | signers: [walletKeyPair], 217 | } 218 | ); 219 | 220 | await connection.confirmTransaction(initRewarderTxId, "confirmed"); 221 | console.log( 222 | `Rewarder created. Address: ${rewarder.toBase58()}, creation transaction ID: ${initRewarderTxId}` 223 | ); 224 | }); 225 | 226 | cliProgram.parse(process.argv); 227 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NFT Staking 2 | 3 | This repo contains the [Anchor](https://github.com/project-serum/anchor) program that powers NFT staking rewards on [Solana](https://solana.com/). Users opt to lock up their NFTs with the protocol in exchange for periodic rewards in the form of a [Token](https://spl.solana.com/token) created exclusively for the purpose of rewarding NFT stakers. 4 | 5 | ### **Note** 6 | 7 | **The author(s) of this software do not claim that there is any monetary value in the token rewards distributed by this protocol.** 8 | 9 | ## Deployed Program Addresses 10 | 11 | | Cluster | Address | 12 | | ------- | -------------------------------------------- | 13 | | devnet | 3zPPaZhN3tAkSJhjcEcyT7kAM6b2stQmJf65Fw9sMZa3 | 14 | 15 | ## Overview 16 | 17 | This NFT Staking Protocol consists of two main components, the **Rewarder** and user **Stake Accounts**. A **Rewarder** has information on the reward token, the reward rate, and the NFT metada that is allowed to earn rewards. A **Stake Account** has information on the owner of the account, the last time the owner claimed their rewards, and also acts as the wallet for any staked NFTs. NFT Owners can always view staked NFTs by finding associated NFT accounts for their **Stake Account**. 18 | 19 | ### Rewarder 20 | 21 | The **Rewarder** is an on-chain [account](https://docs.solana.com/developing/programming-model/accounts) that stores about the Token that is awarded to stakers, the rate at which tokens are awarded, and the NFTs that are allowed to be staked to earn rewards with the Rewarder. 22 | 23 | Rewards are currently calculated in a straightforward fashion where stakers earn the `rewardRate` in the reward token every second per staked NFT. There is no limit on the supply of the reward token as more will always be minted to award to stakers. 24 | 25 | ``` 26 | rewardEarned = elapsedSeconds * rewardRate * numStakedNFTs 27 | ``` 28 | 29 | Rewarders are created per collection at the [Program Derived Address](https://docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses) derived from the following seeds: 30 | 31 | ``` 32 | [collectionName, StakingProgramID, "rewarder"] 33 | ``` 34 | 35 | #### Verifying NFT Authenticity 36 | 37 | To ensure that only NFTs from the desired collection can earn rewards the protocol inspects associated [Metaplex Token Metadata](https://docs.metaplex.com/architecture/contracts#token-metadata) for staked NFTs. When `enforceMetadata` is set to true, the protocol will compare 3 fields from the metadata to verify authenticity: 38 | 39 | - UpdateAuthority 40 | - Creators 41 | - Collection Name 42 | 43 | The metadata for staked NFTs must have matching update authority and creators to those stored in the Rewarder. The name of the NFT is compared to the `collection` field of the Rewarder where the name must begin with the `collection`. For example if the `collection` is `"gmoot"` the an NFT with the name `"gmoot bag #69"` will be allowed. **Rewarder operators should always ensure that at least 1 creator is verified using the [SignMetadata](https://github.com/metaplex-foundation/metaplex/blob/master/rust/token-metadata/program/src/instruction.rs#L148) instruction to ensure only verified NFTs can be staked.** 44 | 45 | #### Rewarder Account Layout 46 | 47 | | Name | Type | Description | 48 | | ------------------------ | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 49 | | authority | Pubkey | The owner of the Rewarder. Can sign transactions to update the Rewarder | 50 | | reward_mint | Pubkey | The address of the reward [Token Mint](https://spl.solana.com/token#creating-a-new-token-type) that is used to reward stakers | 51 | | reward_authority_bump | u8 | The PDA bump for the address that is used to sign [MintTo](https://github.com/solana-labs/solana-program-library/blob/master/token/program/src/instruction.rs#L174) instructions when rewarding stakers. Stored to save on-chain compute of recalculating | 52 | | reward_rate | u64 | The amount of reward tokens earned per second per staked NFT | 53 | | allowed_update_authority | Pubkey | The Pubkey required to match the [Metaplex Token Metadata](https://docs.metaplex.com/architecture/contracts#token-metadata) update authority | 54 | | creators | Array\ | The allowed list of creators for verified NFTs. Creator matches the Metaplex definition of `{address: Pubkey, verified: bool, share: u8}` | 55 | | collection | string | The name of the NFT collection that is allowed to earn rewards. Staked NFTs must have this value as the first part of the name in the [Metaplex Token Metadata](https://docs.metaplex.com/architecture/contracts#token-metadata). For example if the `collection` is `"gmoot"` the an NFT with the name `"gmoot bag #69"` will be allowed | 56 | | enforce_metadata | bool | A flag indicating whether or not the [Metaplex Token Metadata](https://docs.metaplex.com/architecture/contracts#token-metadata) is required for the `Stake` instruction. When set to `false` any NFT will be allowed to earn rewards. | 57 | | total_staked | u32 | The number of NFTs currently staked to this Rewarder | 58 | 59 | #### Creating a Rewarder 60 | 61 | A basic typescript client is provided in this repo at `ts/cli.ts` to facilitate the creation and fetching of a Rewarder. From the `ts` directory, you can run `npm i` to install dependencies and then execute the CLI with: 62 | 63 | ```sh 64 | npm start -- rewarder create -h 65 | 66 | #Output 67 | 68 | Usage: cli rewarder create [options] 69 | 70 | Options: 71 | -d, --decimals The number of decimals for the reward token 72 | -r, --rewardRate The number reward per second per nft staked for the rewarder 73 | -n, --name The name of the NFT collection the rewarder is for 74 | -c, --creators the path to a json array of nft creator objects 75 | -h, --help display help for command 76 | ``` 77 | 78 | ### Stake Accounts 79 | 80 | The user **Stake Account** is a [PDA](https://docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses) stores the information that is used to calculate the earned rewards for the total number of staked NFTs for the owner. The **Stake Account** holds any locked up NFTs and allows integrations to list any staked NFTs in the same way you would for another wallet, given the stake account address. 81 | 82 | The Stake Account address is calculated using the following seeds: 83 | 84 | ``` 85 | [collectionName, StakingProgramID, "stake_account", rewarderPubkey, ownerPubkey] 86 | ``` 87 | 88 | #### Stake Account Layout 89 | 90 | | Name | Type | Description | 91 | | ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------ | 92 | | owner | Pubkey | The owner of the stake account. Required signer for updating the stake account in anyway | 93 | | rewarder | Pubkey | The Rewarder that this stake account is associated with | 94 | | num_staked | u16 | The number of nfts the owner has staked with this stake account | 95 | | bump | u8 | The PDA bump of this stake account that is used to sign transaction when unstaking NFTs. Stored to save on-chain compute | 96 | | last_claimed | i64 | The unix timestamp of the last time that the owner claimed rewards for this stake account | 97 | -------------------------------------------------------------------------------- /tests/sol-nft-staking.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { SolNftStaking } from "../target/types/sol_nft_staking"; 4 | import * as splToken from "@solana/spl-token"; 5 | import { expect } from "chai"; 6 | import { programs, actions } from "@metaplex/js"; 7 | import { Metadata } from "@metaplex-foundation/mpl-token-metadata"; 8 | 9 | describe("sol-nft-staking", () => { 10 | // Configure the client to use the local cluster. 11 | anchor.setProvider(anchor.Provider.env()); 12 | const provider = anchor.getProvider(); 13 | 14 | const solNftStakingProgram = anchor.workspace 15 | .SolNftStaking as Program; 16 | const systemProgram = anchor.web3.SystemProgram.programId; 17 | const rentSysvar = anchor.web3.SYSVAR_RENT_PUBKEY; 18 | const clockSysvar = anchor.web3.SYSVAR_CLOCK_PUBKEY; 19 | 20 | const mintNFT = async ( 21 | connection: anchor.web3.Connection, 22 | owner: anchor.web3.Keypair, 23 | creator: anchor.web3.Keypair 24 | ): Promise<[splToken.Token, anchor.web3.PublicKey]> => { 25 | console.log("creating NFT mint"); 26 | 27 | const mintkeypair = anchor.web3.Keypair.generate(); 28 | const mintBalance = await splToken.Token.getMinBalanceRentForExemptMint( 29 | connection 30 | ); 31 | 32 | const tx = new anchor.web3.Transaction(); 33 | //add create account instruction 34 | tx.add( 35 | anchor.web3.SystemProgram.createAccount({ 36 | fromPubkey: owner.publicKey, 37 | newAccountPubkey: mintkeypair.publicKey, 38 | lamports: mintBalance, 39 | space: splToken.MintLayout.span, 40 | programId: splToken.TOKEN_PROGRAM_ID, 41 | }) 42 | ); 43 | //add init mint instruction 44 | tx.add( 45 | splToken.Token.createInitMintInstruction( 46 | splToken.TOKEN_PROGRAM_ID, 47 | mintkeypair.publicKey, 48 | 0, 49 | owner.publicKey, 50 | null 51 | ) 52 | ); 53 | 54 | //add create token account instruction 55 | const nftTokenAccount = await splToken.Token.getAssociatedTokenAddress( 56 | splToken.ASSOCIATED_TOKEN_PROGRAM_ID, 57 | splToken.TOKEN_PROGRAM_ID, 58 | mintkeypair.publicKey, 59 | owner.publicKey, 60 | false 61 | ); 62 | tx.add( 63 | splToken.Token.createAssociatedTokenAccountInstruction( 64 | splToken.ASSOCIATED_TOKEN_PROGRAM_ID, 65 | splToken.TOKEN_PROGRAM_ID, 66 | mintkeypair.publicKey, 67 | nftTokenAccount, 68 | owner.publicKey, 69 | owner.publicKey 70 | ) 71 | ); 72 | 73 | //add mint to instruction 74 | tx.add( 75 | splToken.Token.createMintToInstruction( 76 | splToken.TOKEN_PROGRAM_ID, 77 | mintkeypair.publicKey, 78 | nftTokenAccount, 79 | owner.publicKey, 80 | [], 81 | 1 82 | ) 83 | ); 84 | 85 | const txSig = await connection.sendTransaction(tx, [owner, mintkeypair]); 86 | await connection.confirmTransaction(txSig, "confirmed"); 87 | 88 | //create metadata 89 | const metadataTx = await actions.createMetadata({ 90 | connection, 91 | wallet: new anchor.Wallet(owner), 92 | editionMint: mintkeypair.publicKey, 93 | updateAuthority: creator.publicKey, 94 | metadataData: new programs.metadata.MetadataDataData({ 95 | name: "test #420", 96 | symbol: "", 97 | uri: "testing", 98 | sellerFeeBasisPoints: 0, 99 | creators: [ 100 | new programs.metadata.Creator({ 101 | address: creator.publicKey.toBase58(), 102 | verified: false, 103 | share: 100, 104 | }), 105 | ], 106 | }), 107 | }); 108 | await connection.confirmTransaction(metadataTx, "confirmed"); 109 | 110 | const signTx = await actions.signMetadata({ 111 | connection, 112 | editionMint: mintkeypair.publicKey, 113 | wallet: new anchor.Wallet(owner), 114 | signer: creator, 115 | }); 116 | await connection.confirmTransaction(signTx, "confirmed"); 117 | 118 | const nftMint = new splToken.Token( 119 | connection, 120 | mintkeypair.publicKey, 121 | splToken.TOKEN_PROGRAM_ID, 122 | owner 123 | ); 124 | 125 | //remove minting authority 126 | nftMint.setAuthority(mintkeypair.publicKey, null, "MintTokens", owner, []); 127 | 128 | return [nftMint, nftTokenAccount]; 129 | }; 130 | 131 | describe("end to end test", async () => { 132 | const owner = anchor.web3.Keypair.generate(); 133 | const creator = anchor.web3.Keypair.generate(); 134 | const collectionName = "test"; 135 | const [rewarder, rewarderBump] = 136 | await anchor.web3.PublicKey.findProgramAddress( 137 | [ 138 | Buffer.from(collectionName), 139 | solNftStakingProgram.programId.toBuffer(), 140 | Buffer.from("rewarder"), 141 | ], 142 | solNftStakingProgram.programId 143 | ); 144 | const [rewardAuthority, rewardAuthorityBump] = 145 | await anchor.web3.PublicKey.findProgramAddress( 146 | [ 147 | Buffer.from(collectionName), 148 | solNftStakingProgram.programId.toBuffer(), 149 | Buffer.from("rewarder"), 150 | rewarder.toBuffer(), 151 | ], 152 | solNftStakingProgram.programId 153 | ); 154 | const [stakeAccount, stakeAccountBump] = 155 | await anchor.web3.PublicKey.findProgramAddress( 156 | [ 157 | Buffer.from(collectionName), 158 | solNftStakingProgram.programId.toBuffer(), 159 | Buffer.from("stake_account"), 160 | rewarder.toBuffer(), 161 | owner.publicKey.toBuffer(), 162 | ], 163 | solNftStakingProgram.programId 164 | ); 165 | const rewardRate = 10; 166 | let rewardMint = null; 167 | let rewardTokenAccount = null; 168 | let nftMint = null; 169 | let nftTokenAccount = null; 170 | 171 | before(async () => { 172 | console.log("airdropping to owner"); 173 | //airdrop tokens 174 | await provider.connection.confirmTransaction( 175 | await provider.connection.requestAirdrop(owner.publicKey, 1000000000), 176 | "confirmed" 177 | ); 178 | 179 | console.log("creating reward mint"); 180 | rewardMint = await splToken.Token.createMint( 181 | provider.connection, 182 | owner, //payer 183 | rewardAuthority, //mint authority 184 | null, //freeze authority 185 | 3, //deicmals 186 | splToken.TOKEN_PROGRAM_ID 187 | ); 188 | 189 | console.log("creating reward token account"); 190 | rewardTokenAccount = await rewardMint.createAssociatedTokenAccount( 191 | owner.publicKey 192 | ); 193 | 194 | console.log("minting NFT"); 195 | [nftMint, nftTokenAccount] = await mintNFT( 196 | provider.connection, 197 | owner, 198 | creator 199 | ); 200 | }); 201 | 202 | it("initializes a rewarder", async () => { 203 | const creators = [ 204 | { address: creator.publicKey, verified: true, share: 100 }, 205 | ]; 206 | 207 | await solNftStakingProgram.rpc.initializeRewarder( 208 | rewarderBump, 209 | rewardAuthorityBump, 210 | new anchor.BN(rewardRate), 211 | Buffer.from(collectionName), 212 | creators, 213 | creator.publicKey, 214 | true, 215 | { 216 | accounts: { 217 | rewarder: rewarder, 218 | authority: owner.publicKey, 219 | rewardAuthority: rewardAuthority, 220 | rewardMint: rewardMint.publicKey, 221 | systemProgram, 222 | rent: rentSysvar, 223 | }, 224 | signers: [owner], 225 | } 226 | ); 227 | }); 228 | 229 | it("initialized a stake account", async () => { 230 | await solNftStakingProgram.rpc.initializeStakeAccount(stakeAccountBump, { 231 | accounts: { 232 | owner: owner.publicKey, 233 | stakeAccount, 234 | rewarder, 235 | systemProgram, 236 | rent: rentSysvar, 237 | }, 238 | signers: [owner], 239 | }); 240 | }); 241 | 242 | it("stakes an NFT", async () => { 243 | const nftMetadata = await Metadata.getPDA(nftMint.publicKey); 244 | await solNftStakingProgram.rpc.stakeNft({ 245 | accounts: { 246 | owner: owner.publicKey, 247 | rewarder, 248 | rewardAuthority, 249 | stakeAccount, 250 | rewardMint: rewardMint.publicKey, 251 | rewardTokenAccount, 252 | nftMint: nftMint.publicKey, 253 | nftTokenAccount, 254 | tokenProgram: splToken.TOKEN_PROGRAM_ID, 255 | systemProgram, 256 | rent: rentSysvar, 257 | clock: clockSysvar, 258 | }, 259 | remainingAccounts: [ 260 | { pubkey: nftMetadata, isSigner: false, isWritable: false }, 261 | ], 262 | signers: [owner], 263 | }); 264 | 265 | let nftAccount = await nftMint.getAccountInfo(nftTokenAccount); 266 | expect(nftAccount.owner.toBase58()).to.equal(stakeAccount.toBase58()); 267 | }); 268 | 269 | it("claims pending rewards", async () => { 270 | console.log( 271 | "confirming 2 seconds on clock sysvar to let rewards accumulate" 272 | ); 273 | const seconds = 2; 274 | //wait to allow rewards to accumulate 275 | await sleep(provider.connection, seconds); 276 | 277 | await solNftStakingProgram.rpc.claim({ 278 | accounts: { 279 | owner: owner.publicKey, 280 | rewarder, 281 | rewardAuthority, 282 | stakeAccount, 283 | rewardMint: rewardMint.publicKey, 284 | rewardAccount: rewardTokenAccount, 285 | tokenProgram: splToken.TOKEN_PROGRAM_ID, 286 | clock: clockSysvar, 287 | }, 288 | signers: [owner], 289 | }); 290 | 291 | const rewardTokenAccountData = await rewardMint.getAccountInfo( 292 | rewardTokenAccount 293 | ); 294 | expect(rewardTokenAccountData.amount.toNumber()).to.equal( 295 | seconds * rewardRate 296 | ); 297 | }); 298 | 299 | it("unstakes an NFT", async () => { 300 | //sleep one more second to check that we claim pending rewards on unstake 301 | await sleep(provider.connection, 1); 302 | 303 | await solNftStakingProgram.rpc.unstakeNft({ 304 | accounts: { 305 | owner: owner.publicKey, 306 | rewarder, 307 | rewardAuthority, 308 | stakeAccount, 309 | rewardMint: rewardMint.publicKey, 310 | rewardTokenAccount, 311 | nftMint: nftMint.publicKey, 312 | nftTokenAccount, 313 | tokenProgram: splToken.TOKEN_PROGRAM_ID, 314 | clock: clockSysvar, 315 | }, 316 | signers: [owner], 317 | }); 318 | const rewardTokenAccountData = await rewardMint.getAccountInfo( 319 | rewardTokenAccount 320 | ); 321 | console.log(`claimed ${rewardTokenAccountData.amount.toNumber()} tokens`); 322 | expect(rewardTokenAccountData.amount.toNumber()).to.equal(3 * rewardRate); 323 | let nftAccount = await nftMint.getAccountInfo(nftTokenAccount); 324 | expect(nftAccount.owner.toBase58()).to.equal(owner.publicKey.toBase58()); 325 | }); 326 | }); 327 | }); 328 | 329 | // Polls the network and returns once the block time has increased by seconds. 330 | const sleep = async ( 331 | connection: anchor.web3.Connection, 332 | seconds: number, 333 | startTime: number | null = null 334 | ) => { 335 | let time = startTime; 336 | if (time == null) { 337 | let slot = await connection.getSlot(); 338 | time = await connection.getBlockTime(slot); 339 | } 340 | let elapsed = 0; 341 | while (elapsed < seconds) { 342 | let slot = await connection.getSlot(); 343 | let newTime = await connection.getBlockTime(slot); 344 | elapsed += newTime - time; 345 | time = newTime; 346 | } 347 | }; 348 | -------------------------------------------------------------------------------- /programs/sol-nft-staking/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | pub mod anchor_metaplex; 4 | pub mod errors; 5 | pub mod state; 6 | 7 | use anchor_metaplex::MetadataAccount; 8 | use anchor_spl::associated_token::get_associated_token_address; 9 | use anchor_spl::token::{self, Mint, MintTo, SetAuthority, Token, TokenAccount}; 10 | use errors::*; 11 | use spl_token::instruction::AuthorityType; 12 | use state::*; 13 | 14 | const REWARDER_PREFIX: &[u8] = b"rewarder"; 15 | const ACCOUNT_PREFIX: &[u8] = b"stake_account"; 16 | 17 | declare_id!("3zPPaZhN3tAkSJhjcEcyT7kAM6b2stQmJf65Fw9sMZa3"); 18 | 19 | #[program] 20 | pub mod sol_nft_staking { 21 | 22 | use super::*; 23 | pub fn initialize_rewarder( 24 | ctx: Context, 25 | _rewarder_bump: u8, 26 | reward_authority_bump: u8, 27 | reward_rate: u64, 28 | collection: String, 29 | creators: Vec, 30 | nft_update_authority: Pubkey, 31 | enforce_metadata: bool, 32 | ) -> ProgramResult { 33 | let rewarder = &mut ctx.accounts.rewarder; 34 | 35 | rewarder.authority = ctx.accounts.authority.key(); 36 | rewarder.reward_mint = ctx.accounts.reward_mint.key(); 37 | rewarder.reward_authority_bump = reward_authority_bump; 38 | rewarder.reward_rate = reward_rate; 39 | rewarder.allowed_update_authority = nft_update_authority; 40 | rewarder.creators = creators; 41 | rewarder.collection = collection; 42 | rewarder.total_staked = 0; 43 | rewarder.enforce_metadata = enforce_metadata; 44 | 45 | Ok(()) 46 | } 47 | 48 | pub fn update_reward_rate(ctx: Context, new_rate: u64) -> ProgramResult { 49 | let rewarder = &mut ctx.accounts.rewarder; 50 | 51 | rewarder.reward_rate = new_rate; 52 | 53 | Ok(()) 54 | } 55 | 56 | pub fn initialize_stake_account( 57 | ctx: Context, 58 | bump: u8, 59 | ) -> ProgramResult { 60 | let stake_account = &mut ctx.accounts.stake_account; 61 | 62 | stake_account.owner = ctx.accounts.owner.key(); 63 | stake_account.rewarder = ctx.accounts.rewarder.key(); 64 | stake_account.num_staked = 0; 65 | stake_account.bump = bump; 66 | stake_account.last_claimed = 0; 67 | 68 | Ok(()) 69 | } 70 | 71 | pub fn stake_nft(ctx: Context) -> ProgramResult { 72 | let owner = &ctx.accounts.owner; 73 | let rewarder = &mut ctx.accounts.rewarder; 74 | let stake_account = &mut ctx.accounts.stake_account; 75 | let reward_mint = &ctx.accounts.reward_mint; 76 | let reward_autority = &ctx.accounts.reward_authority; 77 | let reward_token_account = &ctx.accounts.reward_token_account; 78 | let nft_mint = &ctx.accounts.nft_mint; 79 | let nft_token_account = &ctx.accounts.nft_token_account; 80 | // let nft_vault = &ctx.accounts.nft_vault; 81 | 82 | let token_program = &ctx.accounts.token_program; 83 | let clock = &ctx.accounts.clock; 84 | 85 | if rewarder.enforce_metadata { 86 | let remaining = ctx.remaining_accounts; 87 | let metadata = get_metadata_account(remaining)?; 88 | check_metadata(&metadata, &nft_mint.key(), rewarder)?; 89 | } 90 | 91 | // Calculate and claim any pending rewards 92 | let to_reward = calculate_reward( 93 | rewarder.reward_rate, 94 | stake_account.num_staked, 95 | stake_account.last_claimed, 96 | clock.unix_timestamp, 97 | ); 98 | 99 | transfer_reward( 100 | to_reward, 101 | rewarder, 102 | reward_mint, 103 | reward_token_account, 104 | reward_autority, 105 | token_program, 106 | )?; 107 | stake_account.last_claimed = clock.unix_timestamp; 108 | 109 | //increase the number of staked nfts by 1 110 | stake_account.num_staked += 1; 111 | rewarder.total_staked += 1; 112 | 113 | //transfer nft ownership to vault 114 | let authority_accounts = SetAuthority { 115 | current_authority: owner.to_account_info(), 116 | account_or_mint: nft_token_account.to_account_info(), 117 | }; 118 | let authority_ctx = CpiContext::new(token_program.to_account_info(), authority_accounts); 119 | token::set_authority( 120 | authority_ctx, 121 | AuthorityType::AccountOwner, 122 | Some(stake_account.key()), 123 | )?; 124 | 125 | Ok(()) 126 | } 127 | 128 | pub fn unstake_nft(ctx: Context) -> ProgramResult { 129 | let owner = &ctx.accounts.owner; 130 | let rewarder = &mut ctx.accounts.rewarder; 131 | let stake_account = &mut ctx.accounts.stake_account; 132 | let reward_mint = &ctx.accounts.reward_mint; 133 | let reward_autority = &ctx.accounts.reward_authority; 134 | let reward_token_account = &ctx.accounts.reward_token_account; 135 | let nft_token_account = &ctx.accounts.nft_token_account; 136 | // let nft_vault = &ctx.accounts.nft_vault; 137 | 138 | let token_program = &ctx.accounts.token_program; 139 | let clock = &ctx.accounts.clock; 140 | 141 | // Calculate and claim any pending rewards 142 | 143 | let to_reward = calculate_reward( 144 | rewarder.reward_rate, 145 | stake_account.num_staked, 146 | stake_account.last_claimed, 147 | clock.unix_timestamp, 148 | ); 149 | 150 | transfer_reward( 151 | to_reward, 152 | rewarder, 153 | reward_mint, 154 | reward_token_account, 155 | reward_autority, 156 | token_program, 157 | )?; 158 | stake_account.last_claimed = clock.unix_timestamp; 159 | 160 | //descrease the number of staked nfts by 1 161 | stake_account.num_staked = stake_account.num_staked.checked_sub(1).unwrap_or(0); 162 | rewarder.total_staked = rewarder.total_staked.checked_sub(1).unwrap_or(0); 163 | 164 | let stake_account_seeds = &[ 165 | rewarder.collection.as_bytes(), 166 | &id().to_bytes(), 167 | ACCOUNT_PREFIX, 168 | &rewarder.key().to_bytes(), 169 | &owner.key().to_bytes(), 170 | &[stake_account.bump], 171 | ]; 172 | 173 | let stake_account_signer = &[&stake_account_seeds[..]]; 174 | 175 | //transfer nft to vault 176 | let authority_accounts = SetAuthority { 177 | current_authority: stake_account.to_account_info(), 178 | account_or_mint: nft_token_account.to_account_info(), 179 | }; 180 | let authority_ctx = CpiContext::new_with_signer( 181 | token_program.to_account_info(), 182 | authority_accounts, 183 | stake_account_signer, 184 | ); 185 | token::set_authority( 186 | authority_ctx, 187 | AuthorityType::AccountOwner, 188 | Some(owner.key()), 189 | )?; 190 | 191 | Ok(()) 192 | } 193 | 194 | pub fn claim(ctx: Context) -> ProgramResult { 195 | let rewarder = &ctx.accounts.rewarder; 196 | let stake_account = &mut ctx.accounts.stake_account; 197 | let reward_mint = &ctx.accounts.reward_mint; 198 | let reward_autority = &ctx.accounts.reward_authority; 199 | let reward_token_account = &ctx.accounts.reward_account; 200 | 201 | let token_program = &ctx.accounts.token_program; 202 | let clock = &ctx.accounts.clock; 203 | 204 | let to_reward = calculate_reward( 205 | rewarder.reward_rate, 206 | stake_account.num_staked, 207 | stake_account.last_claimed, 208 | clock.unix_timestamp, 209 | ); 210 | 211 | transfer_reward( 212 | to_reward, 213 | rewarder, 214 | reward_mint, 215 | reward_token_account, 216 | reward_autority, 217 | token_program, 218 | )?; 219 | stake_account.last_claimed = clock.unix_timestamp; 220 | 221 | Ok(()) 222 | } 223 | } 224 | 225 | pub fn calculate_reward( 226 | reward_rate: u64, 227 | num_staked: u16, 228 | last_claimed: i64, 229 | current_time: i64, 230 | ) -> u64 { 231 | if num_staked == 0 { 232 | return 0; 233 | } 234 | 235 | let elapsed_time = current_time - last_claimed; 236 | 237 | if elapsed_time <= 0 { 238 | return 0; 239 | } 240 | 241 | reward_rate * elapsed_time as u64 * num_staked as u64 242 | } 243 | 244 | pub fn transfer_reward<'info>( 245 | earned_reward: u64, 246 | rewarder: &Account<'info, NftStakeRewarder>, 247 | reward_mint: &Account<'info, Mint>, 248 | reward_account: &Account<'info, TokenAccount>, 249 | mint_authority: &AccountInfo<'info>, 250 | token_program: &AccountInfo<'info>, 251 | ) -> ProgramResult { 252 | let mint_authority_seeds = &[ 253 | rewarder.collection.as_bytes(), 254 | &id().to_bytes(), 255 | REWARDER_PREFIX, 256 | &rewarder.key().to_bytes(), 257 | &[rewarder.reward_authority_bump], 258 | ]; 259 | let mint_authority_signer = &[&mint_authority_seeds[..]]; 260 | let mint_accounts = MintTo { 261 | mint: reward_mint.to_account_info(), 262 | to: reward_account.to_account_info(), 263 | authority: mint_authority.to_account_info(), 264 | }; 265 | let mint_ctx = CpiContext::new_with_signer( 266 | token_program.to_account_info(), 267 | mint_accounts, 268 | mint_authority_signer, 269 | ); 270 | token::mint_to(mint_ctx, earned_reward) 271 | } 272 | 273 | #[derive(Accounts)] 274 | #[instruction(_rewarder_bump: u8, reward_authority_bump: u8, reward_rate: u64, collection: String, creators: Vec)] 275 | pub struct InitializeRewarder<'info> { 276 | /// The new rewarder account to create 277 | #[account( 278 | init, 279 | space = NftStakeRewarder::calculate_len(creators.len(), &collection), 280 | payer = authority, 281 | seeds = [collection.as_bytes(), &id().to_bytes(), REWARDER_PREFIX], 282 | bump = _rewarder_bump, 283 | )] 284 | pub rewarder: Account<'info, NftStakeRewarder>, 285 | 286 | /// The owner of the rewarder account 287 | #[account(mut, signer)] 288 | pub authority: AccountInfo<'info>, 289 | 290 | /// PDA used for minting rewards 291 | #[account( 292 | seeds = [collection.as_bytes(), &id().to_bytes(), REWARDER_PREFIX, &rewarder.key().to_bytes()], 293 | bump = reward_authority_bump, 294 | )] 295 | pub reward_authority: AccountInfo<'info>, 296 | 297 | /// The SPL Mint of the reward token. Must have the reward authority mint authority 298 | #[account( 299 | constraint = reward_mint.mint_authority.contains(&reward_authority.key()) @ StakingError::RewarderNotMintAuthority 300 | )] 301 | pub reward_mint: Account<'info, Mint>, 302 | 303 | pub system_program: Program<'info, System>, 304 | pub rent: Sysvar<'info, Rent>, 305 | } 306 | 307 | #[derive(Accounts)] 308 | pub struct UpdateRewardRate<'info> { 309 | /// The new rewarder account to updtae 310 | #[account( 311 | mut, 312 | has_one = authority @ StakingError::InvalidRewarderAuthority, 313 | )] 314 | pub rewarder: Account<'info, NftStakeRewarder>, 315 | 316 | /// The owner of the rewarder account 317 | #[account(signer)] 318 | pub authority: AccountInfo<'info>, 319 | } 320 | 321 | #[derive(Accounts)] 322 | #[instruction(bump: u8)] 323 | pub struct InitializeStakeAccount<'info> { 324 | /// The owner of the stake account 325 | #[account(mut, signer)] 326 | pub owner: AccountInfo<'info>, 327 | 328 | /// The new stake account to initialize 329 | #[account( 330 | init, 331 | payer = owner, 332 | space = NftStakeAccount::LEN, 333 | seeds = [rewarder.collection.as_bytes(), &id().to_bytes(), ACCOUNT_PREFIX, &rewarder.key().to_bytes(), &owner.key().to_bytes()], 334 | bump = bump, 335 | )] 336 | pub stake_account: Account<'info, NftStakeAccount>, 337 | 338 | /// The rewarder associated with this stake account 339 | pub rewarder: Account<'info, NftStakeRewarder>, 340 | 341 | pub system_program: Program<'info, System>, 342 | pub rent: Sysvar<'info, Rent>, 343 | } 344 | 345 | #[derive(Accounts)] 346 | // #[instruction(_vault_bump: u8)] 347 | pub struct StakeNft<'info> { 348 | /// The owner of the stake account 349 | #[account(mut, signer)] 350 | pub owner: AccountInfo<'info>, 351 | 352 | /// The rewarder account for the collection 353 | #[account(mut)] 354 | pub rewarder: Box>, 355 | 356 | /// PDA that has the authority to mint reward tokens 357 | #[account( 358 | seeds = [rewarder.collection.as_bytes(), &id().to_bytes(), REWARDER_PREFIX, &rewarder.key().to_bytes()], 359 | bump = rewarder.reward_authority_bump, 360 | )] 361 | pub reward_authority: AccountInfo<'info>, 362 | 363 | /// The stake account for the owner 364 | #[account( 365 | mut, 366 | has_one = rewarder @ StakingError::InvalidRewarder, 367 | has_one = owner @ StakingError::InvalidOwnerForStakeAccount, 368 | seeds = [rewarder.collection.as_bytes(), &id().to_bytes(), ACCOUNT_PREFIX, &rewarder.key().to_bytes(), &owner.key().to_bytes()], 369 | bump = stake_account.bump, 370 | )] 371 | pub stake_account: Account<'info, NftStakeAccount>, 372 | 373 | /// The Mint of the rewarded token 374 | #[account( 375 | mut, 376 | address = rewarder.reward_mint @ StakingError::InvalidRewardMint, 377 | )] 378 | pub reward_mint: Box>, 379 | 380 | /// The token account from the owner 381 | #[account( 382 | mut, 383 | has_one = owner @ StakingError::InvalidOwnerForRewardToken, 384 | constraint = reward_token_account.mint == rewarder.reward_mint @ StakingError::InvalidRewardTokenAccount, 385 | )] 386 | pub reward_token_account: Account<'info, TokenAccount>, 387 | 388 | /// The Mint of the NFT 389 | #[account( 390 | constraint = nft_mint.supply == 1 @ StakingError::InvalidNFTMintSupply, 391 | )] 392 | pub nft_mint: Box>, 393 | 394 | /// The token account from the owner 395 | #[account( 396 | mut, 397 | has_one = owner @ StakingError::InvalidNFTOwner, 398 | constraint = nft_token_account.mint == nft_mint.key() @ StakingError::InvalidNFTAccountMint, 399 | constraint = nft_token_account.amount == 1 @ StakingError::NFTAccountEmpty, 400 | )] 401 | pub nft_token_account: Account<'info, TokenAccount>, 402 | 403 | pub token_program: Program<'info, Token>, 404 | pub system_program: Program<'info, System>, 405 | pub rent: Sysvar<'info, Rent>, 406 | pub clock: Sysvar<'info, Clock>, 407 | } 408 | 409 | #[derive(Accounts)] 410 | pub struct UnstakeNft<'info> { 411 | /// The owner of the stake account 412 | #[account(mut, signer)] 413 | pub owner: AccountInfo<'info>, 414 | 415 | /// The rewarder account for the collection 416 | #[account(mut)] 417 | pub rewarder: Account<'info, NftStakeRewarder>, 418 | 419 | /// PDA that has the authority to mint reward tokens 420 | #[account( 421 | seeds = [rewarder.collection.as_bytes(), &id().to_bytes(), REWARDER_PREFIX, &rewarder.key().to_bytes()], 422 | bump = rewarder.reward_authority_bump, 423 | )] 424 | pub reward_authority: AccountInfo<'info>, 425 | 426 | /// The stake account for the owner 427 | #[account( 428 | mut, 429 | has_one = rewarder @ StakingError::InvalidRewarder, 430 | has_one = owner @ StakingError::InvalidOwnerForStakeAccount, 431 | seeds = [rewarder.collection.as_bytes(), &id().to_bytes(), ACCOUNT_PREFIX, &rewarder.key().to_bytes(), &owner.key().to_bytes()], 432 | bump = stake_account.bump, 433 | )] 434 | pub stake_account: Account<'info, NftStakeAccount>, 435 | 436 | /// The Mint of the rewarded token 437 | #[account( 438 | mut, 439 | address = rewarder.reward_mint @ StakingError::InvalidRewardMint, 440 | )] 441 | pub reward_mint: Box>, 442 | 443 | /// The token account from the owner 444 | #[account( 445 | mut, 446 | has_one = owner @ StakingError::InvalidOwnerForRewardToken, 447 | constraint = reward_token_account.mint == rewarder.reward_mint @ StakingError::InvalidRewardTokenAccount, 448 | )] 449 | pub reward_token_account: Account<'info, TokenAccount>, 450 | 451 | /// The Mint of the NFT 452 | #[account( 453 | constraint = nft_mint.supply == 1 @ StakingError::InvalidNFTMintSupply, 454 | )] 455 | pub nft_mint: Box>, 456 | 457 | /// The token account from the owner 458 | #[account( 459 | mut, 460 | constraint = nft_token_account.owner == stake_account.key() @ StakingError::InvalidStakedNFTOwner, 461 | constraint = nft_token_account.mint == nft_mint.key() @ StakingError::InvalidNFTAccountMint, 462 | address = get_associated_token_address(&owner.key(), &nft_mint.key()), 463 | )] 464 | pub nft_token_account: Account<'info, TokenAccount>, 465 | 466 | pub token_program: Program<'info, Token>, 467 | pub clock: Sysvar<'info, Clock>, 468 | } 469 | 470 | #[derive(Accounts)] 471 | pub struct Claim<'info> { 472 | /// The owner of the stake account 473 | #[account(signer)] 474 | pub owner: AccountInfo<'info>, 475 | 476 | /// The rewarder account for the collection 477 | #[account()] 478 | pub rewarder: Account<'info, NftStakeRewarder>, 479 | 480 | /// The stake account for the owner 481 | #[account( 482 | mut, 483 | has_one = rewarder @ StakingError::InvalidRewarder, 484 | has_one = owner @ StakingError::InvalidOwnerForStakeAccount, 485 | seeds = [rewarder.collection.as_bytes(), &id().to_bytes(), ACCOUNT_PREFIX, &rewarder.key().to_bytes(), &owner.key().to_bytes()], 486 | bump = stake_account.bump, 487 | )] 488 | pub stake_account: Account<'info, NftStakeAccount>, 489 | 490 | /// The Mint of the rewarded token 491 | #[account( 492 | mut, 493 | address = rewarder.reward_mint @ StakingError::InvalidRewardMint, 494 | )] 495 | pub reward_mint: Account<'info, Mint>, 496 | 497 | /// The token account for the reward mint for the owner 498 | #[account( 499 | mut, 500 | has_one = owner @ StakingError::InvalidOwnerForRewardToken, 501 | constraint = reward_account.mint == rewarder.reward_mint @ StakingError::InvalidRewardTokenAccount, 502 | )] 503 | pub reward_account: Account<'info, TokenAccount>, 504 | 505 | /// PDA that has the authority to mint reward tokens 506 | #[account( 507 | seeds = [rewarder.collection.as_bytes(), &id().to_bytes(), REWARDER_PREFIX, &rewarder.key().to_bytes()], 508 | bump = rewarder.reward_authority_bump, 509 | )] 510 | pub reward_authority: AccountInfo<'info>, 511 | 512 | pub token_program: Program<'info, Token>, 513 | pub clock: Sysvar<'info, Clock>, 514 | } 515 | 516 | pub fn check_metadata<'a, 'b, 'c, 'info>( 517 | metadata: &'a Account<'info, MetadataAccount>, 518 | nft_mint_key: &'b Pubkey, 519 | rewarder: &'c NftStakeRewarder, 520 | ) -> std::result::Result<(), ProgramError> { 521 | let (expected_address, _) = Pubkey::find_program_address( 522 | &[ 523 | anchor_metaplex::PDAPrefix.as_bytes(), 524 | &anchor_metaplex::ID.to_bytes(), 525 | &nft_mint_key.to_bytes(), 526 | ], 527 | &anchor_metaplex::ID, 528 | ); 529 | 530 | if metadata.key() != expected_address { 531 | return Err(StakingError::InvalidMetadataAccountAddress.into()); 532 | } 533 | 534 | if metadata.update_authority != rewarder.allowed_update_authority { 535 | return Err(StakingError::InvalidMetadataUpdateAuthority.into()); 536 | } 537 | 538 | if !metadata.data.name.starts_with(&rewarder.collection) { 539 | return Err(StakingError::InvalidMetadataCollectionPrefix.into()); 540 | } 541 | 542 | if let Some(creators) = &metadata.data.creators { 543 | if creators.len() != rewarder.creators.len() { 544 | return Err(StakingError::InvalidMetadataCreators.into()); 545 | } 546 | 547 | for creator in creators.iter() { 548 | let found_match = rewarder 549 | .creators 550 | .iter() 551 | .find(|known_creator| known_creator == creator); 552 | if found_match.is_none() { 553 | return Err(StakingError::InvalidMetadataCreators.into()); 554 | } 555 | } 556 | } else { 557 | return Err(StakingError::InvalidMetadataCreators.into()); 558 | } 559 | 560 | Ok(()) 561 | } 562 | 563 | pub fn get_metadata_account<'a, 'b>( 564 | accounts: &'a [AccountInfo<'b>], 565 | ) -> std::result::Result, StakingError> { 566 | let accounts_iter = &mut accounts.iter(); 567 | let metadata_info = 568 | next_account_info(accounts_iter).or(Err(StakingError::MetadataAccountNotFound))?; 569 | 570 | if *metadata_info.owner != anchor_metaplex::ID { 571 | return Err(StakingError::MetadataAccountNotOwnedByCorrectProgram); 572 | } 573 | 574 | Ok(Account::try_from_unchecked(&metadata_info) 575 | .or(Err(StakingError::InvalidMetadataAccountData))?) 576 | } 577 | 578 | #[cfg(test)] 579 | mod tests { 580 | use super::*; 581 | 582 | #[test] 583 | pub fn test_reward_calculation() { 584 | let current_time = 100_i64; 585 | let reward_rate = 10_u64; 586 | let last_claimed = 0_i64; 587 | let mut num_staked = 0; 588 | 589 | //if num staked is 0 always return 0 rewards 590 | let earned_rewared = calculate_reward(reward_rate, num_staked, last_claimed, current_time); 591 | assert_eq!(earned_rewared, 0); 592 | 593 | num_staked += 1; 594 | let earned_rewared = calculate_reward(reward_rate, num_staked, last_claimed, current_time); 595 | assert_eq!(earned_rewared, 1000); 596 | 597 | //twice the number staked recieves twice the reward 598 | num_staked += 1; 599 | let earned_rewared = calculate_reward(reward_rate, num_staked, last_claimed, current_time); 600 | assert_eq!(earned_rewared, 2000); 601 | } 602 | } 603 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.4.7" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" 10 | 11 | [[package]] 12 | name = "aho-corasick" 13 | version = "0.7.18" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 16 | dependencies = [ 17 | "memchr", 18 | ] 19 | 20 | [[package]] 21 | name = "anchor-attribute-access-control" 22 | version = "0.18.2" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "13e53fd8d0aa034bb2e647c39eec4e399095438dbc83526949ac6a072e3c4ce7" 25 | dependencies = [ 26 | "anchor-syn", 27 | "anyhow", 28 | "proc-macro2", 29 | "quote", 30 | "regex", 31 | "syn", 32 | ] 33 | 34 | [[package]] 35 | name = "anchor-attribute-account" 36 | version = "0.18.2" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "362b1b119372b38cdd45949bd8f09a8f5c56a701d49a747fc43d7a59393b647f" 39 | dependencies = [ 40 | "anchor-syn", 41 | "anyhow", 42 | "bs58 0.4.0", 43 | "proc-macro2", 44 | "quote", 45 | "rustversion", 46 | "syn", 47 | ] 48 | 49 | [[package]] 50 | name = "anchor-attribute-error" 51 | version = "0.18.2" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "41c8be43ca34309afcafb24274bba6733b6b5d59be47f1cc11ef3afe9584e5cd" 54 | dependencies = [ 55 | "anchor-syn", 56 | "proc-macro2", 57 | "quote", 58 | "syn", 59 | ] 60 | 61 | [[package]] 62 | name = "anchor-attribute-event" 63 | version = "0.18.2" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "899640f277f8296da82d6505312b03a4cd4901c3c6d6fe8eb3ca2db33f26ebb9" 66 | dependencies = [ 67 | "anchor-syn", 68 | "anyhow", 69 | "proc-macro2", 70 | "quote", 71 | "syn", 72 | ] 73 | 74 | [[package]] 75 | name = "anchor-attribute-interface" 76 | version = "0.18.2" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "f514a6502a0ad56f321df492f1c699ee8ad3912c6354acd087f3d28431a0fac4" 79 | dependencies = [ 80 | "anchor-syn", 81 | "anyhow", 82 | "heck", 83 | "proc-macro2", 84 | "quote", 85 | "syn", 86 | ] 87 | 88 | [[package]] 89 | name = "anchor-attribute-program" 90 | version = "0.18.2" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "fadc2f9bcaeb3be4a8efb76c455bc772b5d257c01796b415eb3aa4bd93ed43fe" 93 | dependencies = [ 94 | "anchor-syn", 95 | "anyhow", 96 | "proc-macro2", 97 | "quote", 98 | "syn", 99 | ] 100 | 101 | [[package]] 102 | name = "anchor-attribute-state" 103 | version = "0.18.2" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "adbff8f1a2b53a42ef547f3188e25f7e3d6933113ab0f94b11afb825eee80f47" 106 | dependencies = [ 107 | "anchor-syn", 108 | "anyhow", 109 | "proc-macro2", 110 | "quote", 111 | "syn", 112 | ] 113 | 114 | [[package]] 115 | name = "anchor-derive-accounts" 116 | version = "0.18.2" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "458185d8bd23559f6ed35c4a7a7d0f83ac4d7837b2e790d90e50cafc9371503e" 119 | dependencies = [ 120 | "anchor-syn", 121 | "anyhow", 122 | "proc-macro2", 123 | "quote", 124 | "syn", 125 | ] 126 | 127 | [[package]] 128 | name = "anchor-lang" 129 | version = "0.18.2" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "46dd615c2eb55d88de8800c46fa7ed51ef045d76ed669222a798976d0a447f59" 132 | dependencies = [ 133 | "anchor-attribute-access-control", 134 | "anchor-attribute-account", 135 | "anchor-attribute-error", 136 | "anchor-attribute-event", 137 | "anchor-attribute-interface", 138 | "anchor-attribute-program", 139 | "anchor-attribute-state", 140 | "anchor-derive-accounts", 141 | "base64 0.13.0", 142 | "borsh", 143 | "bytemuck", 144 | "solana-program", 145 | "thiserror", 146 | ] 147 | 148 | [[package]] 149 | name = "anchor-spl" 150 | version = "0.18.2" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "a6d6c8fbc834319618581a4e19807a30e76326b9981abd069addb55acf0647db" 153 | dependencies = [ 154 | "anchor-lang", 155 | "solana-program", 156 | "spl-associated-token-account", 157 | "spl-token", 158 | ] 159 | 160 | [[package]] 161 | name = "anchor-syn" 162 | version = "0.18.2" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "77faec86e3bf8e15568d026bd586e381910610544aa0b2642b942b37698029e5" 165 | dependencies = [ 166 | "anyhow", 167 | "bs58 0.3.1", 168 | "heck", 169 | "proc-macro2", 170 | "proc-macro2-diagnostics", 171 | "quote", 172 | "serde", 173 | "serde_json", 174 | "sha2", 175 | "syn", 176 | "thiserror", 177 | ] 178 | 179 | [[package]] 180 | name = "anyhow" 181 | version = "1.0.47" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "38d9ff5d688f1c13395289f67db01d4826b46dd694e7580accdc3e8430f2d98e" 184 | 185 | [[package]] 186 | name = "arrayref" 187 | version = "0.3.6" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 190 | 191 | [[package]] 192 | name = "arrayvec" 193 | version = "0.5.2" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 196 | 197 | [[package]] 198 | name = "atty" 199 | version = "0.2.14" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 202 | dependencies = [ 203 | "hermit-abi", 204 | "libc", 205 | "winapi", 206 | ] 207 | 208 | [[package]] 209 | name = "autocfg" 210 | version = "1.0.1" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 213 | 214 | [[package]] 215 | name = "base64" 216 | version = "0.12.3" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 219 | 220 | [[package]] 221 | name = "base64" 222 | version = "0.13.0" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 225 | 226 | [[package]] 227 | name = "bincode" 228 | version = "1.3.3" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 231 | dependencies = [ 232 | "serde", 233 | ] 234 | 235 | [[package]] 236 | name = "blake3" 237 | version = "0.3.8" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3" 240 | dependencies = [ 241 | "arrayref", 242 | "arrayvec", 243 | "cc", 244 | "cfg-if 0.1.10", 245 | "constant_time_eq", 246 | "crypto-mac", 247 | "digest 0.9.0", 248 | ] 249 | 250 | [[package]] 251 | name = "block-buffer" 252 | version = "0.9.0" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 255 | dependencies = [ 256 | "block-padding", 257 | "generic-array 0.14.4", 258 | ] 259 | 260 | [[package]] 261 | name = "block-padding" 262 | version = "0.2.1" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 265 | 266 | [[package]] 267 | name = "borsh" 268 | version = "0.9.1" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "18dda7dc709193c0d86a1a51050a926dc3df1cf262ec46a23a25dba421ea1924" 271 | dependencies = [ 272 | "borsh-derive", 273 | "hashbrown", 274 | ] 275 | 276 | [[package]] 277 | name = "borsh-derive" 278 | version = "0.9.1" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "684155372435f578c0fa1acd13ebbb182cc19d6b38b64ae7901da4393217d264" 281 | dependencies = [ 282 | "borsh-derive-internal", 283 | "borsh-schema-derive-internal", 284 | "proc-macro-crate 0.1.5", 285 | "proc-macro2", 286 | "syn", 287 | ] 288 | 289 | [[package]] 290 | name = "borsh-derive-internal" 291 | version = "0.9.1" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "2102f62f8b6d3edeab871830782285b64cc1830168094db05c8e458f209bc5c3" 294 | dependencies = [ 295 | "proc-macro2", 296 | "quote", 297 | "syn", 298 | ] 299 | 300 | [[package]] 301 | name = "borsh-schema-derive-internal" 302 | version = "0.9.1" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "196c978c4c9b0b142d446ef3240690bf5a8a33497074a113ff9a337ccb750483" 305 | dependencies = [ 306 | "proc-macro2", 307 | "quote", 308 | "syn", 309 | ] 310 | 311 | [[package]] 312 | name = "bs58" 313 | version = "0.3.1" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" 316 | 317 | [[package]] 318 | name = "bs58" 319 | version = "0.4.0" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 322 | 323 | [[package]] 324 | name = "bv" 325 | version = "0.11.1" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" 328 | dependencies = [ 329 | "feature-probe", 330 | "serde", 331 | ] 332 | 333 | [[package]] 334 | name = "bytemuck" 335 | version = "1.7.2" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" 338 | dependencies = [ 339 | "bytemuck_derive", 340 | ] 341 | 342 | [[package]] 343 | name = "bytemuck_derive" 344 | version = "1.0.1" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" 347 | dependencies = [ 348 | "proc-macro2", 349 | "quote", 350 | "syn", 351 | ] 352 | 353 | [[package]] 354 | name = "byteorder" 355 | version = "1.4.3" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 358 | 359 | [[package]] 360 | name = "cc" 361 | version = "1.0.72" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" 364 | 365 | [[package]] 366 | name = "cfg-if" 367 | version = "0.1.10" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 370 | 371 | [[package]] 372 | name = "cfg-if" 373 | version = "1.0.0" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 376 | 377 | [[package]] 378 | name = "constant_time_eq" 379 | version = "0.1.5" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 382 | 383 | [[package]] 384 | name = "cpufeatures" 385 | version = "0.2.1" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" 388 | dependencies = [ 389 | "libc", 390 | ] 391 | 392 | [[package]] 393 | name = "crunchy" 394 | version = "0.2.2" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 397 | 398 | [[package]] 399 | name = "crypto-mac" 400 | version = "0.8.0" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" 403 | dependencies = [ 404 | "generic-array 0.14.4", 405 | "subtle", 406 | ] 407 | 408 | [[package]] 409 | name = "curve25519-dalek" 410 | version = "2.1.3" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" 413 | dependencies = [ 414 | "byteorder", 415 | "digest 0.8.1", 416 | "rand_core", 417 | "subtle", 418 | "zeroize", 419 | ] 420 | 421 | [[package]] 422 | name = "derivative" 423 | version = "2.2.0" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 426 | dependencies = [ 427 | "proc-macro2", 428 | "quote", 429 | "syn", 430 | ] 431 | 432 | [[package]] 433 | name = "digest" 434 | version = "0.8.1" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" 437 | dependencies = [ 438 | "generic-array 0.12.4", 439 | ] 440 | 441 | [[package]] 442 | name = "digest" 443 | version = "0.9.0" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 446 | dependencies = [ 447 | "generic-array 0.14.4", 448 | ] 449 | 450 | [[package]] 451 | name = "either" 452 | version = "1.6.1" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 455 | 456 | [[package]] 457 | name = "env_logger" 458 | version = "0.8.4" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" 461 | dependencies = [ 462 | "atty", 463 | "humantime", 464 | "log", 465 | "regex", 466 | "termcolor", 467 | ] 468 | 469 | [[package]] 470 | name = "feature-probe" 471 | version = "0.1.1" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" 474 | 475 | [[package]] 476 | name = "generic-array" 477 | version = "0.12.4" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" 480 | dependencies = [ 481 | "typenum", 482 | ] 483 | 484 | [[package]] 485 | name = "generic-array" 486 | version = "0.14.4" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" 489 | dependencies = [ 490 | "serde", 491 | "typenum", 492 | "version_check", 493 | ] 494 | 495 | [[package]] 496 | name = "getrandom" 497 | version = "0.1.16" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 500 | dependencies = [ 501 | "cfg-if 1.0.0", 502 | "libc", 503 | "wasi", 504 | ] 505 | 506 | [[package]] 507 | name = "hashbrown" 508 | version = "0.9.1" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" 511 | dependencies = [ 512 | "ahash", 513 | ] 514 | 515 | [[package]] 516 | name = "heck" 517 | version = "0.3.3" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 520 | dependencies = [ 521 | "unicode-segmentation", 522 | ] 523 | 524 | [[package]] 525 | name = "hermit-abi" 526 | version = "0.1.19" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 529 | dependencies = [ 530 | "libc", 531 | ] 532 | 533 | [[package]] 534 | name = "hex" 535 | version = "0.4.3" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 538 | 539 | [[package]] 540 | name = "hmac" 541 | version = "0.8.1" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" 544 | dependencies = [ 545 | "crypto-mac", 546 | "digest 0.9.0", 547 | ] 548 | 549 | [[package]] 550 | name = "hmac-drbg" 551 | version = "0.3.0" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" 554 | dependencies = [ 555 | "digest 0.9.0", 556 | "generic-array 0.14.4", 557 | "hmac", 558 | ] 559 | 560 | [[package]] 561 | name = "humantime" 562 | version = "2.1.0" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 565 | 566 | [[package]] 567 | name = "itertools" 568 | version = "0.9.0" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" 571 | dependencies = [ 572 | "either", 573 | ] 574 | 575 | [[package]] 576 | name = "itoa" 577 | version = "0.4.8" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" 580 | 581 | [[package]] 582 | name = "keccak" 583 | version = "0.1.0" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" 586 | 587 | [[package]] 588 | name = "lazy_static" 589 | version = "1.4.0" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 592 | 593 | [[package]] 594 | name = "libc" 595 | version = "0.2.107" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" 598 | 599 | [[package]] 600 | name = "libsecp256k1" 601 | version = "0.5.0" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "bd1137239ab33b41aa9637a88a28249e5e70c40a42ccc92db7f12cc356c1fcd7" 604 | dependencies = [ 605 | "arrayref", 606 | "base64 0.12.3", 607 | "digest 0.9.0", 608 | "hmac-drbg", 609 | "libsecp256k1-core", 610 | "libsecp256k1-gen-ecmult", 611 | "libsecp256k1-gen-genmult", 612 | "rand", 613 | "serde", 614 | "sha2", 615 | "typenum", 616 | ] 617 | 618 | [[package]] 619 | name = "libsecp256k1-core" 620 | version = "0.2.2" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" 623 | dependencies = [ 624 | "crunchy", 625 | "digest 0.9.0", 626 | "subtle", 627 | ] 628 | 629 | [[package]] 630 | name = "libsecp256k1-gen-ecmult" 631 | version = "0.2.1" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" 634 | dependencies = [ 635 | "libsecp256k1-core", 636 | ] 637 | 638 | [[package]] 639 | name = "libsecp256k1-gen-genmult" 640 | version = "0.2.1" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" 643 | dependencies = [ 644 | "libsecp256k1-core", 645 | ] 646 | 647 | [[package]] 648 | name = "log" 649 | version = "0.4.14" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 652 | dependencies = [ 653 | "cfg-if 1.0.0", 654 | ] 655 | 656 | [[package]] 657 | name = "memchr" 658 | version = "2.4.1" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 661 | 662 | [[package]] 663 | name = "memmap2" 664 | version = "0.1.0" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a" 667 | dependencies = [ 668 | "libc", 669 | ] 670 | 671 | [[package]] 672 | name = "metaplex-token-metadata" 673 | version = "0.0.1" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "abcc939f0afdc6db054b9998a1292d0a016244b382462e61cfc7c570624982cb" 676 | dependencies = [ 677 | "arrayref", 678 | "borsh", 679 | "metaplex-token-vault", 680 | "num-derive", 681 | "num-traits", 682 | "solana-program", 683 | "spl-token", 684 | "thiserror", 685 | ] 686 | 687 | [[package]] 688 | name = "metaplex-token-vault" 689 | version = "0.0.1" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "a5211991ba3273df89cd5e0f6f558bc8d7453c87c0546f915b4a319e1541df33" 692 | dependencies = [ 693 | "borsh", 694 | "num-derive", 695 | "num-traits", 696 | "solana-program", 697 | "spl-token", 698 | "thiserror", 699 | ] 700 | 701 | [[package]] 702 | name = "num-derive" 703 | version = "0.3.3" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" 706 | dependencies = [ 707 | "proc-macro2", 708 | "quote", 709 | "syn", 710 | ] 711 | 712 | [[package]] 713 | name = "num-traits" 714 | version = "0.2.14" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 717 | dependencies = [ 718 | "autocfg", 719 | ] 720 | 721 | [[package]] 722 | name = "num_enum" 723 | version = "0.5.4" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" 726 | dependencies = [ 727 | "derivative", 728 | "num_enum_derive", 729 | ] 730 | 731 | [[package]] 732 | name = "num_enum_derive" 733 | version = "0.5.4" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" 736 | dependencies = [ 737 | "proc-macro-crate 1.1.0", 738 | "proc-macro2", 739 | "quote", 740 | "syn", 741 | ] 742 | 743 | [[package]] 744 | name = "opaque-debug" 745 | version = "0.3.0" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 748 | 749 | [[package]] 750 | name = "ppv-lite86" 751 | version = "0.2.15" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" 754 | 755 | [[package]] 756 | name = "proc-macro-crate" 757 | version = "0.1.5" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 760 | dependencies = [ 761 | "toml", 762 | ] 763 | 764 | [[package]] 765 | name = "proc-macro-crate" 766 | version = "1.1.0" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" 769 | dependencies = [ 770 | "thiserror", 771 | "toml", 772 | ] 773 | 774 | [[package]] 775 | name = "proc-macro2" 776 | version = "1.0.32" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" 779 | dependencies = [ 780 | "unicode-xid", 781 | ] 782 | 783 | [[package]] 784 | name = "proc-macro2-diagnostics" 785 | version = "0.9.1" 786 | source = "registry+https://github.com/rust-lang/crates.io-index" 787 | checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" 788 | dependencies = [ 789 | "proc-macro2", 790 | "quote", 791 | "syn", 792 | "version_check", 793 | "yansi", 794 | ] 795 | 796 | [[package]] 797 | name = "quote" 798 | version = "1.0.10" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" 801 | dependencies = [ 802 | "proc-macro2", 803 | ] 804 | 805 | [[package]] 806 | name = "rand" 807 | version = "0.7.3" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 810 | dependencies = [ 811 | "getrandom", 812 | "libc", 813 | "rand_chacha", 814 | "rand_core", 815 | "rand_hc", 816 | ] 817 | 818 | [[package]] 819 | name = "rand_chacha" 820 | version = "0.2.2" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 823 | dependencies = [ 824 | "ppv-lite86", 825 | "rand_core", 826 | ] 827 | 828 | [[package]] 829 | name = "rand_core" 830 | version = "0.5.1" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 833 | dependencies = [ 834 | "getrandom", 835 | ] 836 | 837 | [[package]] 838 | name = "rand_hc" 839 | version = "0.2.0" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 842 | dependencies = [ 843 | "rand_core", 844 | ] 845 | 846 | [[package]] 847 | name = "regex" 848 | version = "1.5.4" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" 851 | dependencies = [ 852 | "aho-corasick", 853 | "memchr", 854 | "regex-syntax", 855 | ] 856 | 857 | [[package]] 858 | name = "regex-syntax" 859 | version = "0.6.25" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 862 | 863 | [[package]] 864 | name = "rustc_version" 865 | version = "0.2.3" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 868 | dependencies = [ 869 | "semver", 870 | ] 871 | 872 | [[package]] 873 | name = "rustversion" 874 | version = "1.0.5" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" 877 | 878 | [[package]] 879 | name = "ryu" 880 | version = "1.0.5" 881 | source = "registry+https://github.com/rust-lang/crates.io-index" 882 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 883 | 884 | [[package]] 885 | name = "semver" 886 | version = "0.9.0" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 889 | dependencies = [ 890 | "semver-parser", 891 | ] 892 | 893 | [[package]] 894 | name = "semver-parser" 895 | version = "0.7.0" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 898 | 899 | [[package]] 900 | name = "serde" 901 | version = "1.0.130" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" 904 | dependencies = [ 905 | "serde_derive", 906 | ] 907 | 908 | [[package]] 909 | name = "serde_bytes" 910 | version = "0.11.5" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" 913 | dependencies = [ 914 | "serde", 915 | ] 916 | 917 | [[package]] 918 | name = "serde_derive" 919 | version = "1.0.130" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" 922 | dependencies = [ 923 | "proc-macro2", 924 | "quote", 925 | "syn", 926 | ] 927 | 928 | [[package]] 929 | name = "serde_json" 930 | version = "1.0.71" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19" 933 | dependencies = [ 934 | "itoa", 935 | "ryu", 936 | "serde", 937 | ] 938 | 939 | [[package]] 940 | name = "sha2" 941 | version = "0.9.8" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" 944 | dependencies = [ 945 | "block-buffer", 946 | "cfg-if 1.0.0", 947 | "cpufeatures", 948 | "digest 0.9.0", 949 | "opaque-debug", 950 | ] 951 | 952 | [[package]] 953 | name = "sha3" 954 | version = "0.9.1" 955 | source = "registry+https://github.com/rust-lang/crates.io-index" 956 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" 957 | dependencies = [ 958 | "block-buffer", 959 | "digest 0.9.0", 960 | "keccak", 961 | "opaque-debug", 962 | ] 963 | 964 | [[package]] 965 | name = "sol-nft-staking" 966 | version = "0.1.0" 967 | dependencies = [ 968 | "anchor-lang", 969 | "anchor-spl", 970 | "metaplex-token-metadata", 971 | "spl-token", 972 | ] 973 | 974 | [[package]] 975 | name = "solana-frozen-abi" 976 | version = "1.8.5" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "bc1012d3d2ab907d942511eefa9e49dc411eeefda964c744ab431e5a4788decd" 979 | dependencies = [ 980 | "bs58 0.3.1", 981 | "bv", 982 | "generic-array 0.14.4", 983 | "log", 984 | "memmap2", 985 | "rustc_version", 986 | "serde", 987 | "serde_derive", 988 | "sha2", 989 | "solana-frozen-abi-macro", 990 | "solana-logger", 991 | "thiserror", 992 | ] 993 | 994 | [[package]] 995 | name = "solana-frozen-abi-macro" 996 | version = "1.8.5" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "2c02e8365ddbab83f2004041032a48e2b9e3b42a3fc44c318aebc96dce6bf920" 999 | dependencies = [ 1000 | "proc-macro2", 1001 | "quote", 1002 | "rustc_version", 1003 | "syn", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "solana-logger" 1008 | version = "1.8.5" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | checksum = "298885f4c7c704df17fa48ddf1a1582032e13174bc7e0e8ada57ca62740e8a98" 1011 | dependencies = [ 1012 | "env_logger", 1013 | "lazy_static", 1014 | "log", 1015 | ] 1016 | 1017 | [[package]] 1018 | name = "solana-program" 1019 | version = "1.8.5" 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" 1021 | checksum = "d115ccafc326625e378cd8b4122a2e6a6666ad7907d165e9384a76ecbdb7b745" 1022 | dependencies = [ 1023 | "base64 0.13.0", 1024 | "bincode", 1025 | "blake3", 1026 | "borsh", 1027 | "borsh-derive", 1028 | "bs58 0.3.1", 1029 | "bv", 1030 | "bytemuck", 1031 | "curve25519-dalek", 1032 | "hex", 1033 | "itertools", 1034 | "lazy_static", 1035 | "libsecp256k1", 1036 | "log", 1037 | "num-derive", 1038 | "num-traits", 1039 | "rand", 1040 | "rustc_version", 1041 | "rustversion", 1042 | "serde", 1043 | "serde_bytes", 1044 | "serde_derive", 1045 | "sha2", 1046 | "sha3", 1047 | "solana-frozen-abi", 1048 | "solana-frozen-abi-macro", 1049 | "solana-logger", 1050 | "solana-sdk-macro", 1051 | "thiserror", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "solana-sdk-macro" 1056 | version = "1.8.5" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "91983679137d5a342cc99f56dbb418def7af5712a5edb2636d3637c897962f9b" 1059 | dependencies = [ 1060 | "bs58 0.3.1", 1061 | "proc-macro2", 1062 | "quote", 1063 | "rustversion", 1064 | "syn", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "spl-associated-token-account" 1069 | version = "1.0.3" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "393e2240d521c3dd770806bff25c2c00d761ac962be106e14e22dd912007f428" 1072 | dependencies = [ 1073 | "solana-program", 1074 | "spl-token", 1075 | ] 1076 | 1077 | [[package]] 1078 | name = "spl-token" 1079 | version = "3.2.0" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "93bfdd5bd7c869cb565c7d7635c4fafe189b988a0bdef81063cd9585c6b8dc01" 1082 | dependencies = [ 1083 | "arrayref", 1084 | "num-derive", 1085 | "num-traits", 1086 | "num_enum", 1087 | "solana-program", 1088 | "thiserror", 1089 | ] 1090 | 1091 | [[package]] 1092 | name = "subtle" 1093 | version = "2.4.1" 1094 | source = "registry+https://github.com/rust-lang/crates.io-index" 1095 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1096 | 1097 | [[package]] 1098 | name = "syn" 1099 | version = "1.0.81" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" 1102 | dependencies = [ 1103 | "proc-macro2", 1104 | "quote", 1105 | "unicode-xid", 1106 | ] 1107 | 1108 | [[package]] 1109 | name = "termcolor" 1110 | version = "1.1.2" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" 1113 | dependencies = [ 1114 | "winapi-util", 1115 | ] 1116 | 1117 | [[package]] 1118 | name = "thiserror" 1119 | version = "1.0.30" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 1122 | dependencies = [ 1123 | "thiserror-impl", 1124 | ] 1125 | 1126 | [[package]] 1127 | name = "thiserror-impl" 1128 | version = "1.0.30" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 1131 | dependencies = [ 1132 | "proc-macro2", 1133 | "quote", 1134 | "syn", 1135 | ] 1136 | 1137 | [[package]] 1138 | name = "toml" 1139 | version = "0.5.8" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" 1142 | dependencies = [ 1143 | "serde", 1144 | ] 1145 | 1146 | [[package]] 1147 | name = "typenum" 1148 | version = "1.14.0" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" 1151 | 1152 | [[package]] 1153 | name = "unicode-segmentation" 1154 | version = "1.8.0" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" 1157 | 1158 | [[package]] 1159 | name = "unicode-xid" 1160 | version = "0.2.2" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1163 | 1164 | [[package]] 1165 | name = "version_check" 1166 | version = "0.9.3" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 1169 | 1170 | [[package]] 1171 | name = "wasi" 1172 | version = "0.9.0+wasi-snapshot-preview1" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1175 | 1176 | [[package]] 1177 | name = "winapi" 1178 | version = "0.3.9" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1181 | dependencies = [ 1182 | "winapi-i686-pc-windows-gnu", 1183 | "winapi-x86_64-pc-windows-gnu", 1184 | ] 1185 | 1186 | [[package]] 1187 | name = "winapi-i686-pc-windows-gnu" 1188 | version = "0.4.0" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1191 | 1192 | [[package]] 1193 | name = "winapi-util" 1194 | version = "0.1.5" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1197 | dependencies = [ 1198 | "winapi", 1199 | ] 1200 | 1201 | [[package]] 1202 | name = "winapi-x86_64-pc-windows-gnu" 1203 | version = "0.4.0" 1204 | source = "registry+https://github.com/rust-lang/crates.io-index" 1205 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1206 | 1207 | [[package]] 1208 | name = "yansi" 1209 | version = "0.5.0" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" 1212 | 1213 | [[package]] 1214 | name = "zeroize" 1215 | version = "1.4.3" 1216 | source = "registry+https://github.com/rust-lang/crates.io-index" 1217 | checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" 1218 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5": 6 | version "7.16.3" 7 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" 8 | integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== 9 | dependencies: 10 | regenerator-runtime "^0.13.4" 11 | 12 | "@ethersproject/bytes@^5.5.0": 13 | version "5.5.0" 14 | resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.5.0.tgz#cb11c526de657e7b45d2e0f0246fb3b9d29a601c" 15 | integrity sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog== 16 | dependencies: 17 | "@ethersproject/logger" "^5.5.0" 18 | 19 | "@ethersproject/logger@^5.5.0": 20 | version "5.5.0" 21 | resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d" 22 | integrity sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg== 23 | 24 | "@ethersproject/sha2@^5.5.0": 25 | version "5.5.0" 26 | resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.5.0.tgz#a40a054c61f98fd9eee99af2c3cc6ff57ec24db7" 27 | integrity sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA== 28 | dependencies: 29 | "@ethersproject/bytes" "^5.5.0" 30 | "@ethersproject/logger" "^5.5.0" 31 | hash.js "1.1.7" 32 | 33 | "@project-serum/anchor@^0.18.0": 34 | version "0.18.2" 35 | resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.18.2.tgz#0f13b5c2046446b7c24cf28763eec90febb28485" 36 | integrity sha512-uyjiN/3Ipp+4hrZRm/hG18HzGLZyvP790LXrCsGO3IWxSl28YRhiGEpKnZycfMW94R7nxdUoE3wY67V+ZHSQBQ== 37 | dependencies: 38 | "@project-serum/borsh" "^0.2.2" 39 | "@solana/web3.js" "^1.17.0" 40 | base64-js "^1.5.1" 41 | bn.js "^5.1.2" 42 | bs58 "^4.0.1" 43 | buffer-layout "^1.2.0" 44 | camelcase "^5.3.1" 45 | crypto-hash "^1.3.0" 46 | eventemitter3 "^4.0.7" 47 | find "^0.3.0" 48 | js-sha256 "^0.9.0" 49 | pako "^2.0.3" 50 | snake-case "^3.0.4" 51 | toml "^3.0.0" 52 | 53 | "@project-serum/borsh@^0.2.2": 54 | version "0.2.2" 55 | resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.2.tgz#63e558f2d6eb6ab79086bf499dea94da3182498f" 56 | integrity sha512-Ms+aWmGVW6bWd3b0+MWwoaYig2QD0F90h0uhr7AzY3dpCb5e2S6RsRW02vFTfa085pY2VLB7nTZNbFECQ1liTg== 57 | dependencies: 58 | bn.js "^5.1.2" 59 | buffer-layout "^1.2.0" 60 | 61 | "@solana/buffer-layout@^3.0.0": 62 | version "3.0.0" 63 | resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz#b9353caeb9a1589cb77a1b145bcb1a9a93114326" 64 | integrity sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w== 65 | dependencies: 66 | buffer "~6.0.3" 67 | 68 | "@solana/web3.js@^1.17.0": 69 | version "1.30.2" 70 | resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.30.2.tgz#e85da75e0825dc64f53eb64a1ff0115b27bec135" 71 | integrity sha512-hznCj+rkfvM5taRP3Z+l5lumB7IQnDrB4l55Wpsg4kDU9Zds8pE5YOH5Z9bbF/pUzZJKQjyBjnY/6kScBm3Ugg== 72 | dependencies: 73 | "@babel/runtime" "^7.12.5" 74 | "@ethersproject/sha2" "^5.5.0" 75 | "@solana/buffer-layout" "^3.0.0" 76 | bn.js "^5.0.0" 77 | borsh "^0.4.0" 78 | bs58 "^4.0.1" 79 | buffer "6.0.1" 80 | cross-fetch "^3.1.4" 81 | jayson "^3.4.4" 82 | js-sha3 "^0.8.0" 83 | rpc-websockets "^7.4.2" 84 | secp256k1 "^4.0.2" 85 | superstruct "^0.14.2" 86 | tweetnacl "^1.0.0" 87 | 88 | "@types/bn.js@^4.11.5": 89 | version "4.11.6" 90 | resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" 91 | integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== 92 | dependencies: 93 | "@types/node" "*" 94 | 95 | "@types/connect@^3.4.33": 96 | version "3.4.35" 97 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" 98 | integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== 99 | dependencies: 100 | "@types/node" "*" 101 | 102 | "@types/express-serve-static-core@^4.17.9": 103 | version "4.17.25" 104 | resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.25.tgz#e42f7046adc65ece2eb6059b77aecfbe9e9f82e0" 105 | integrity sha512-OUJIVfRMFijZukGGwTpKNFprqCCXk5WjNGvUgB/CxxBR40QWSjsNK86+yvGKlCOGc7sbwfHLaXhkG+NsytwBaQ== 106 | dependencies: 107 | "@types/node" "*" 108 | "@types/qs" "*" 109 | "@types/range-parser" "*" 110 | 111 | "@types/json5@^0.0.29": 112 | version "0.0.29" 113 | resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" 114 | integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= 115 | 116 | "@types/lodash@^4.14.159": 117 | version "4.14.177" 118 | resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.177.tgz#f70c0d19c30fab101cad46b52be60363c43c4578" 119 | integrity sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw== 120 | 121 | "@types/mocha@^9.0.0": 122 | version "9.0.0" 123 | resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.0.0.tgz#3205bcd15ada9bc681ac20bef64e9e6df88fd297" 124 | integrity sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA== 125 | 126 | "@types/node@*": 127 | version "16.11.8" 128 | resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.8.tgz#a1aeb23f0aa33cb111e64ccaa1687b2ae0423b69" 129 | integrity sha512-hmT5gfpRkkHr7DZZHMf3jBe/zNcVGN+jXSL2f8nAsYfBPxQFToKwQlS/zES4Sjp488Bi73i+p6bvrNRRGU0x9Q== 130 | 131 | "@types/node@^12.12.54": 132 | version "12.20.37" 133 | resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.37.tgz#abb38afa9d6e8a2f627a8cb52290b3c80fbe61ed" 134 | integrity sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA== 135 | 136 | "@types/qs@*": 137 | version "6.9.7" 138 | resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" 139 | integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== 140 | 141 | "@types/range-parser@*": 142 | version "1.2.4" 143 | resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" 144 | integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== 145 | 146 | "@types/ws@^7.4.4": 147 | version "7.4.7" 148 | resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" 149 | integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== 150 | dependencies: 151 | "@types/node" "*" 152 | 153 | "@ungap/promise-all-settled@1.1.2": 154 | version "1.1.2" 155 | resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" 156 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 157 | 158 | JSONStream@^1.3.5: 159 | version "1.3.5" 160 | resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" 161 | integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== 162 | dependencies: 163 | jsonparse "^1.2.0" 164 | through ">=2.2.7 <3" 165 | 166 | ansi-colors@4.1.1: 167 | version "4.1.1" 168 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 169 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 170 | 171 | ansi-regex@^5.0.1: 172 | version "5.0.1" 173 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 174 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 175 | 176 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 177 | version "4.3.0" 178 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 179 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 180 | dependencies: 181 | color-convert "^2.0.1" 182 | 183 | anymatch@~3.1.2: 184 | version "3.1.2" 185 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 186 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 187 | dependencies: 188 | normalize-path "^3.0.0" 189 | picomatch "^2.0.4" 190 | 191 | argparse@^2.0.1: 192 | version "2.0.1" 193 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 194 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 195 | 196 | arrify@^1.0.0: 197 | version "1.0.1" 198 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 199 | integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= 200 | 201 | assertion-error@^1.1.0: 202 | version "1.1.0" 203 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 204 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 205 | 206 | balanced-match@^1.0.0: 207 | version "1.0.2" 208 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 209 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 210 | 211 | base-x@^3.0.2: 212 | version "3.0.9" 213 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" 214 | integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== 215 | dependencies: 216 | safe-buffer "^5.0.1" 217 | 218 | base64-js@^1.3.1, base64-js@^1.5.1: 219 | version "1.5.1" 220 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 221 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 222 | 223 | binary-extensions@^2.0.0: 224 | version "2.2.0" 225 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 226 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 227 | 228 | bn.js@^4.11.9: 229 | version "4.12.0" 230 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" 231 | integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== 232 | 233 | bn.js@^5.0.0, bn.js@^5.1.2: 234 | version "5.2.0" 235 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" 236 | integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== 237 | 238 | borsh@^0.4.0: 239 | version "0.4.0" 240 | resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.4.0.tgz#9dd6defe741627f1315eac2a73df61421f6ddb9f" 241 | integrity sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g== 242 | dependencies: 243 | "@types/bn.js" "^4.11.5" 244 | bn.js "^5.0.0" 245 | bs58 "^4.0.0" 246 | text-encoding-utf-8 "^1.0.2" 247 | 248 | brace-expansion@^1.1.7: 249 | version "1.1.11" 250 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 251 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 252 | dependencies: 253 | balanced-match "^1.0.0" 254 | concat-map "0.0.1" 255 | 256 | braces@~3.0.2: 257 | version "3.0.2" 258 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 259 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 260 | dependencies: 261 | fill-range "^7.0.1" 262 | 263 | brorand@^1.1.0: 264 | version "1.1.0" 265 | resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" 266 | integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= 267 | 268 | browser-stdout@1.3.1: 269 | version "1.3.1" 270 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 271 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 272 | 273 | bs58@^4.0.0, bs58@^4.0.1: 274 | version "4.0.1" 275 | resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" 276 | integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= 277 | dependencies: 278 | base-x "^3.0.2" 279 | 280 | buffer-from@^1.0.0, buffer-from@^1.1.0: 281 | version "1.1.2" 282 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" 283 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 284 | 285 | buffer-layout@^1.2.0: 286 | version "1.2.2" 287 | resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" 288 | integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== 289 | 290 | buffer@6.0.1: 291 | version "6.0.1" 292 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" 293 | integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== 294 | dependencies: 295 | base64-js "^1.3.1" 296 | ieee754 "^1.2.1" 297 | 298 | buffer@~6.0.3: 299 | version "6.0.3" 300 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" 301 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== 302 | dependencies: 303 | base64-js "^1.3.1" 304 | ieee754 "^1.2.1" 305 | 306 | bufferutil@^4.0.1: 307 | version "4.0.5" 308 | resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028" 309 | integrity sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A== 310 | dependencies: 311 | node-gyp-build "^4.3.0" 312 | 313 | camelcase@^5.3.1: 314 | version "5.3.1" 315 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 316 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 317 | 318 | camelcase@^6.0.0: 319 | version "6.2.1" 320 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" 321 | integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== 322 | 323 | chai@^4.3.4: 324 | version "4.3.4" 325 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" 326 | integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== 327 | dependencies: 328 | assertion-error "^1.1.0" 329 | check-error "^1.0.2" 330 | deep-eql "^3.0.1" 331 | get-func-name "^2.0.0" 332 | pathval "^1.1.1" 333 | type-detect "^4.0.5" 334 | 335 | chalk@^4.1.0: 336 | version "4.1.2" 337 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 338 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 339 | dependencies: 340 | ansi-styles "^4.1.0" 341 | supports-color "^7.1.0" 342 | 343 | check-error@^1.0.2: 344 | version "1.0.2" 345 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 346 | integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= 347 | 348 | chokidar@3.5.2: 349 | version "3.5.2" 350 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" 351 | integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== 352 | dependencies: 353 | anymatch "~3.1.2" 354 | braces "~3.0.2" 355 | glob-parent "~5.1.2" 356 | is-binary-path "~2.1.0" 357 | is-glob "~4.0.1" 358 | normalize-path "~3.0.0" 359 | readdirp "~3.6.0" 360 | optionalDependencies: 361 | fsevents "~2.3.2" 362 | 363 | circular-json@^0.5.9: 364 | version "0.5.9" 365 | resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" 366 | integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== 367 | 368 | cliui@^7.0.2: 369 | version "7.0.4" 370 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 371 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 372 | dependencies: 373 | string-width "^4.2.0" 374 | strip-ansi "^6.0.0" 375 | wrap-ansi "^7.0.0" 376 | 377 | color-convert@^2.0.1: 378 | version "2.0.1" 379 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 380 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 381 | dependencies: 382 | color-name "~1.1.4" 383 | 384 | color-name@~1.1.4: 385 | version "1.1.4" 386 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 387 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 388 | 389 | commander@^2.20.3: 390 | version "2.20.3" 391 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 392 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 393 | 394 | concat-map@0.0.1: 395 | version "0.0.1" 396 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 397 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 398 | 399 | cross-fetch@^3.1.4: 400 | version "3.1.4" 401 | resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" 402 | integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== 403 | dependencies: 404 | node-fetch "2.6.1" 405 | 406 | crypto-hash@^1.3.0: 407 | version "1.3.0" 408 | resolved "https://registry.yarnpkg.com/crypto-hash/-/crypto-hash-1.3.0.tgz#b402cb08f4529e9f4f09346c3e275942f845e247" 409 | integrity sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg== 410 | 411 | debug@4.3.2: 412 | version "4.3.2" 413 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" 414 | integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== 415 | dependencies: 416 | ms "2.1.2" 417 | 418 | decamelize@^4.0.0: 419 | version "4.0.0" 420 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 421 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 422 | 423 | deep-eql@^3.0.1: 424 | version "3.0.1" 425 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 426 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 427 | dependencies: 428 | type-detect "^4.0.0" 429 | 430 | delay@^5.0.0: 431 | version "5.0.0" 432 | resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" 433 | integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== 434 | 435 | diff@5.0.0: 436 | version "5.0.0" 437 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" 438 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 439 | 440 | diff@^3.1.0: 441 | version "3.5.0" 442 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 443 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 444 | 445 | dot-case@^3.0.4: 446 | version "3.0.4" 447 | resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" 448 | integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== 449 | dependencies: 450 | no-case "^3.0.4" 451 | tslib "^2.0.3" 452 | 453 | elliptic@^6.5.2: 454 | version "6.5.4" 455 | resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" 456 | integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== 457 | dependencies: 458 | bn.js "^4.11.9" 459 | brorand "^1.1.0" 460 | hash.js "^1.0.0" 461 | hmac-drbg "^1.0.1" 462 | inherits "^2.0.4" 463 | minimalistic-assert "^1.0.1" 464 | minimalistic-crypto-utils "^1.0.1" 465 | 466 | emoji-regex@^8.0.0: 467 | version "8.0.0" 468 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 469 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 470 | 471 | es6-promise@^4.0.3: 472 | version "4.2.8" 473 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" 474 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 475 | 476 | es6-promisify@^5.0.0: 477 | version "5.0.0" 478 | resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" 479 | integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= 480 | dependencies: 481 | es6-promise "^4.0.3" 482 | 483 | escalade@^3.1.1: 484 | version "3.1.1" 485 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 486 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 487 | 488 | escape-string-regexp@4.0.0: 489 | version "4.0.0" 490 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 491 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 492 | 493 | eventemitter3@^4.0.7: 494 | version "4.0.7" 495 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" 496 | integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== 497 | 498 | eyes@^0.1.8: 499 | version "0.1.8" 500 | resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" 501 | integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= 502 | 503 | fill-range@^7.0.1: 504 | version "7.0.1" 505 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 506 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 507 | dependencies: 508 | to-regex-range "^5.0.1" 509 | 510 | find-up@5.0.0: 511 | version "5.0.0" 512 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 513 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 514 | dependencies: 515 | locate-path "^6.0.0" 516 | path-exists "^4.0.0" 517 | 518 | find@^0.3.0: 519 | version "0.3.0" 520 | resolved "https://registry.yarnpkg.com/find/-/find-0.3.0.tgz#4082e8fc8d8320f1a382b5e4f521b9bc50775cb8" 521 | integrity sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw== 522 | dependencies: 523 | traverse-chain "~0.1.0" 524 | 525 | flat@^5.0.2: 526 | version "5.0.2" 527 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 528 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 529 | 530 | fs.realpath@^1.0.0: 531 | version "1.0.0" 532 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 533 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 534 | 535 | fsevents@~2.3.2: 536 | version "2.3.2" 537 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 538 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 539 | 540 | get-caller-file@^2.0.5: 541 | version "2.0.5" 542 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 543 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 544 | 545 | get-func-name@^2.0.0: 546 | version "2.0.0" 547 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 548 | integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= 549 | 550 | glob-parent@~5.1.2: 551 | version "5.1.2" 552 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 553 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 554 | dependencies: 555 | is-glob "^4.0.1" 556 | 557 | glob@7.1.7: 558 | version "7.1.7" 559 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" 560 | integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== 561 | dependencies: 562 | fs.realpath "^1.0.0" 563 | inflight "^1.0.4" 564 | inherits "2" 565 | minimatch "^3.0.4" 566 | once "^1.3.0" 567 | path-is-absolute "^1.0.0" 568 | 569 | growl@1.10.5: 570 | version "1.10.5" 571 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 572 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 573 | 574 | has-flag@^4.0.0: 575 | version "4.0.0" 576 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 577 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 578 | 579 | hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: 580 | version "1.1.7" 581 | resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" 582 | integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== 583 | dependencies: 584 | inherits "^2.0.3" 585 | minimalistic-assert "^1.0.1" 586 | 587 | he@1.2.0: 588 | version "1.2.0" 589 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 590 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 591 | 592 | hmac-drbg@^1.0.1: 593 | version "1.0.1" 594 | resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" 595 | integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= 596 | dependencies: 597 | hash.js "^1.0.3" 598 | minimalistic-assert "^1.0.0" 599 | minimalistic-crypto-utils "^1.0.1" 600 | 601 | ieee754@^1.2.1: 602 | version "1.2.1" 603 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 604 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 605 | 606 | inflight@^1.0.4: 607 | version "1.0.6" 608 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 609 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 610 | dependencies: 611 | once "^1.3.0" 612 | wrappy "1" 613 | 614 | inherits@2, inherits@^2.0.3, inherits@^2.0.4: 615 | version "2.0.4" 616 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 617 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 618 | 619 | is-binary-path@~2.1.0: 620 | version "2.1.0" 621 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 622 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 623 | dependencies: 624 | binary-extensions "^2.0.0" 625 | 626 | is-extglob@^2.1.1: 627 | version "2.1.1" 628 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 629 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 630 | 631 | is-fullwidth-code-point@^3.0.0: 632 | version "3.0.0" 633 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 634 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 635 | 636 | is-glob@^4.0.1, is-glob@~4.0.1: 637 | version "4.0.3" 638 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 639 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 640 | dependencies: 641 | is-extglob "^2.1.1" 642 | 643 | is-number@^7.0.0: 644 | version "7.0.0" 645 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 646 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 647 | 648 | is-plain-obj@^2.1.0: 649 | version "2.1.0" 650 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 651 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 652 | 653 | is-unicode-supported@^0.1.0: 654 | version "0.1.0" 655 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 656 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 657 | 658 | isexe@^2.0.0: 659 | version "2.0.0" 660 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 661 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 662 | 663 | isomorphic-ws@^4.0.1: 664 | version "4.0.1" 665 | resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" 666 | integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== 667 | 668 | jayson@^3.4.4: 669 | version "3.6.5" 670 | resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.6.5.tgz#e560bcad4daf098c7391f46ba8efc9d6f34a4102" 671 | integrity sha512-wmOjX+eQcnCDyPF4KORomaIj9wj3h0B5VEbeD0+2VHfTfErB+h1zpR7oBkgCZp36AFjp3+a4CLz6U72BYpFHAw== 672 | dependencies: 673 | "@types/connect" "^3.4.33" 674 | "@types/express-serve-static-core" "^4.17.9" 675 | "@types/lodash" "^4.14.159" 676 | "@types/node" "^12.12.54" 677 | "@types/ws" "^7.4.4" 678 | JSONStream "^1.3.5" 679 | commander "^2.20.3" 680 | delay "^5.0.0" 681 | es6-promisify "^5.0.0" 682 | eyes "^0.1.8" 683 | isomorphic-ws "^4.0.1" 684 | json-stringify-safe "^5.0.1" 685 | lodash "^4.17.20" 686 | uuid "^3.4.0" 687 | ws "^7.4.5" 688 | 689 | js-sha256@^0.9.0: 690 | version "0.9.0" 691 | resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" 692 | integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== 693 | 694 | js-sha3@^0.8.0: 695 | version "0.8.0" 696 | resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" 697 | integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== 698 | 699 | js-yaml@4.1.0: 700 | version "4.1.0" 701 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 702 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 703 | dependencies: 704 | argparse "^2.0.1" 705 | 706 | json-stringify-safe@^5.0.1: 707 | version "5.0.1" 708 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 709 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 710 | 711 | json5@^1.0.1: 712 | version "1.0.1" 713 | resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" 714 | integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== 715 | dependencies: 716 | minimist "^1.2.0" 717 | 718 | jsonparse@^1.2.0: 719 | version "1.3.1" 720 | resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" 721 | integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= 722 | 723 | locate-path@^6.0.0: 724 | version "6.0.0" 725 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 726 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 727 | dependencies: 728 | p-locate "^5.0.0" 729 | 730 | lodash@^4.17.20: 731 | version "4.17.21" 732 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 733 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 734 | 735 | log-symbols@4.1.0: 736 | version "4.1.0" 737 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 738 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 739 | dependencies: 740 | chalk "^4.1.0" 741 | is-unicode-supported "^0.1.0" 742 | 743 | lower-case@^2.0.2: 744 | version "2.0.2" 745 | resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" 746 | integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== 747 | dependencies: 748 | tslib "^2.0.3" 749 | 750 | make-error@^1.1.1: 751 | version "1.3.6" 752 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 753 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 754 | 755 | minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: 756 | version "1.0.1" 757 | resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" 758 | integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== 759 | 760 | minimalistic-crypto-utils@^1.0.1: 761 | version "1.0.1" 762 | resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" 763 | integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= 764 | 765 | minimatch@3.0.4, minimatch@^3.0.4: 766 | version "3.0.4" 767 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 768 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 769 | dependencies: 770 | brace-expansion "^1.1.7" 771 | 772 | minimist@^1.2.0, minimist@^1.2.5: 773 | version "1.2.5" 774 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 775 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 776 | 777 | mkdirp@^0.5.1: 778 | version "0.5.5" 779 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" 780 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 781 | dependencies: 782 | minimist "^1.2.5" 783 | 784 | mocha@^9.0.3: 785 | version "9.1.3" 786 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.3.tgz#8a623be6b323810493d8c8f6f7667440fa469fdb" 787 | integrity sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw== 788 | dependencies: 789 | "@ungap/promise-all-settled" "1.1.2" 790 | ansi-colors "4.1.1" 791 | browser-stdout "1.3.1" 792 | chokidar "3.5.2" 793 | debug "4.3.2" 794 | diff "5.0.0" 795 | escape-string-regexp "4.0.0" 796 | find-up "5.0.0" 797 | glob "7.1.7" 798 | growl "1.10.5" 799 | he "1.2.0" 800 | js-yaml "4.1.0" 801 | log-symbols "4.1.0" 802 | minimatch "3.0.4" 803 | ms "2.1.3" 804 | nanoid "3.1.25" 805 | serialize-javascript "6.0.0" 806 | strip-json-comments "3.1.1" 807 | supports-color "8.1.1" 808 | which "2.0.2" 809 | workerpool "6.1.5" 810 | yargs "16.2.0" 811 | yargs-parser "20.2.4" 812 | yargs-unparser "2.0.0" 813 | 814 | ms@2.1.2: 815 | version "2.1.2" 816 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 817 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 818 | 819 | ms@2.1.3: 820 | version "2.1.3" 821 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 822 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 823 | 824 | nanoid@3.1.25: 825 | version "3.1.25" 826 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" 827 | integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== 828 | 829 | no-case@^3.0.4: 830 | version "3.0.4" 831 | resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" 832 | integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== 833 | dependencies: 834 | lower-case "^2.0.2" 835 | tslib "^2.0.3" 836 | 837 | node-addon-api@^2.0.0: 838 | version "2.0.2" 839 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" 840 | integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== 841 | 842 | node-fetch@2.6.1: 843 | version "2.6.1" 844 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" 845 | integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== 846 | 847 | node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: 848 | version "4.3.0" 849 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" 850 | integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== 851 | 852 | normalize-path@^3.0.0, normalize-path@~3.0.0: 853 | version "3.0.0" 854 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 855 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 856 | 857 | once@^1.3.0: 858 | version "1.4.0" 859 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 860 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 861 | dependencies: 862 | wrappy "1" 863 | 864 | p-limit@^3.0.2: 865 | version "3.1.0" 866 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 867 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 868 | dependencies: 869 | yocto-queue "^0.1.0" 870 | 871 | p-locate@^5.0.0: 872 | version "5.0.0" 873 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 874 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 875 | dependencies: 876 | p-limit "^3.0.2" 877 | 878 | pako@^2.0.3: 879 | version "2.0.4" 880 | resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" 881 | integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== 882 | 883 | path-exists@^4.0.0: 884 | version "4.0.0" 885 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 886 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 887 | 888 | path-is-absolute@^1.0.0: 889 | version "1.0.1" 890 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 891 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 892 | 893 | pathval@^1.1.1: 894 | version "1.1.1" 895 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" 896 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 897 | 898 | picomatch@^2.0.4, picomatch@^2.2.1: 899 | version "2.3.0" 900 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" 901 | integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== 902 | 903 | randombytes@^2.1.0: 904 | version "2.1.0" 905 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 906 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 907 | dependencies: 908 | safe-buffer "^5.1.0" 909 | 910 | readdirp@~3.6.0: 911 | version "3.6.0" 912 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 913 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 914 | dependencies: 915 | picomatch "^2.2.1" 916 | 917 | regenerator-runtime@^0.13.4: 918 | version "0.13.9" 919 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" 920 | integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== 921 | 922 | require-directory@^2.1.1: 923 | version "2.1.1" 924 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 925 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 926 | 927 | rpc-websockets@^7.4.2: 928 | version "7.4.16" 929 | resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.4.16.tgz#eb701cdef577d4357ba5f526d50e25f370396fac" 930 | integrity sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ== 931 | dependencies: 932 | "@babel/runtime" "^7.11.2" 933 | circular-json "^0.5.9" 934 | eventemitter3 "^4.0.7" 935 | uuid "^8.3.0" 936 | ws "^7.4.5" 937 | optionalDependencies: 938 | bufferutil "^4.0.1" 939 | utf-8-validate "^5.0.2" 940 | 941 | safe-buffer@^5.0.1, safe-buffer@^5.1.0: 942 | version "5.2.1" 943 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 944 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 945 | 946 | secp256k1@^4.0.2: 947 | version "4.0.2" 948 | resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" 949 | integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== 950 | dependencies: 951 | elliptic "^6.5.2" 952 | node-addon-api "^2.0.0" 953 | node-gyp-build "^4.2.0" 954 | 955 | serialize-javascript@6.0.0: 956 | version "6.0.0" 957 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" 958 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 959 | dependencies: 960 | randombytes "^2.1.0" 961 | 962 | snake-case@^3.0.4: 963 | version "3.0.4" 964 | resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" 965 | integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== 966 | dependencies: 967 | dot-case "^3.0.4" 968 | tslib "^2.0.3" 969 | 970 | source-map-support@^0.5.6: 971 | version "0.5.20" 972 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" 973 | integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== 974 | dependencies: 975 | buffer-from "^1.0.0" 976 | source-map "^0.6.0" 977 | 978 | source-map@^0.6.0: 979 | version "0.6.1" 980 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 981 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 982 | 983 | string-width@^4.1.0, string-width@^4.2.0: 984 | version "4.2.3" 985 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 986 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 987 | dependencies: 988 | emoji-regex "^8.0.0" 989 | is-fullwidth-code-point "^3.0.0" 990 | strip-ansi "^6.0.1" 991 | 992 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 993 | version "6.0.1" 994 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 995 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 996 | dependencies: 997 | ansi-regex "^5.0.1" 998 | 999 | strip-bom@^3.0.0: 1000 | version "3.0.0" 1001 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 1002 | integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= 1003 | 1004 | strip-json-comments@3.1.1: 1005 | version "3.1.1" 1006 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1007 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1008 | 1009 | superstruct@^0.14.2: 1010 | version "0.14.2" 1011 | resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" 1012 | integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== 1013 | 1014 | supports-color@8.1.1: 1015 | version "8.1.1" 1016 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 1017 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1018 | dependencies: 1019 | has-flag "^4.0.0" 1020 | 1021 | supports-color@^7.1.0: 1022 | version "7.2.0" 1023 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1024 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1025 | dependencies: 1026 | has-flag "^4.0.0" 1027 | 1028 | text-encoding-utf-8@^1.0.2: 1029 | version "1.0.2" 1030 | resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" 1031 | integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== 1032 | 1033 | "through@>=2.2.7 <3": 1034 | version "2.3.8" 1035 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1036 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 1037 | 1038 | to-regex-range@^5.0.1: 1039 | version "5.0.1" 1040 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1041 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1042 | dependencies: 1043 | is-number "^7.0.0" 1044 | 1045 | toml@^3.0.0: 1046 | version "3.0.0" 1047 | resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" 1048 | integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== 1049 | 1050 | traverse-chain@~0.1.0: 1051 | version "0.1.0" 1052 | resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1" 1053 | integrity sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE= 1054 | 1055 | ts-mocha@^8.0.0: 1056 | version "8.0.0" 1057 | resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-8.0.0.tgz#962d0fa12eeb6468aa1a6b594bb3bbc818da3ef0" 1058 | integrity sha512-Kou1yxTlubLnD5C3unlCVO7nh0HERTezjoVhVw/M5S1SqoUec0WgllQvPk3vzPMc6by8m6xD1uR1yRf8lnVUbA== 1059 | dependencies: 1060 | ts-node "7.0.1" 1061 | optionalDependencies: 1062 | tsconfig-paths "^3.5.0" 1063 | 1064 | ts-node@7.0.1: 1065 | version "7.0.1" 1066 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" 1067 | integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== 1068 | dependencies: 1069 | arrify "^1.0.0" 1070 | buffer-from "^1.1.0" 1071 | diff "^3.1.0" 1072 | make-error "^1.1.1" 1073 | minimist "^1.2.0" 1074 | mkdirp "^0.5.1" 1075 | source-map-support "^0.5.6" 1076 | yn "^2.0.0" 1077 | 1078 | tsconfig-paths@^3.5.0: 1079 | version "3.11.0" 1080 | resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" 1081 | integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== 1082 | dependencies: 1083 | "@types/json5" "^0.0.29" 1084 | json5 "^1.0.1" 1085 | minimist "^1.2.0" 1086 | strip-bom "^3.0.0" 1087 | 1088 | tslib@^2.0.3: 1089 | version "2.3.1" 1090 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" 1091 | integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== 1092 | 1093 | tweetnacl@^1.0.0: 1094 | version "1.0.3" 1095 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" 1096 | integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== 1097 | 1098 | type-detect@^4.0.0, type-detect@^4.0.5: 1099 | version "4.0.8" 1100 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 1101 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 1102 | 1103 | typescript@^4.3.5: 1104 | version "4.5.2" 1105 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998" 1106 | integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw== 1107 | 1108 | utf-8-validate@^5.0.2: 1109 | version "5.0.7" 1110 | resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.7.tgz#c15a19a6af1f7ad9ec7ddc425747ca28c3644922" 1111 | integrity sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q== 1112 | dependencies: 1113 | node-gyp-build "^4.3.0" 1114 | 1115 | uuid@^3.4.0: 1116 | version "3.4.0" 1117 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 1118 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 1119 | 1120 | uuid@^8.3.0: 1121 | version "8.3.2" 1122 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" 1123 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 1124 | 1125 | which@2.0.2: 1126 | version "2.0.2" 1127 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1128 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1129 | dependencies: 1130 | isexe "^2.0.0" 1131 | 1132 | workerpool@6.1.5: 1133 | version "6.1.5" 1134 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" 1135 | integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== 1136 | 1137 | wrap-ansi@^7.0.0: 1138 | version "7.0.0" 1139 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1140 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1141 | dependencies: 1142 | ansi-styles "^4.0.0" 1143 | string-width "^4.1.0" 1144 | strip-ansi "^6.0.0" 1145 | 1146 | wrappy@1: 1147 | version "1.0.2" 1148 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1149 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1150 | 1151 | ws@^7.4.5: 1152 | version "7.5.5" 1153 | resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" 1154 | integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== 1155 | 1156 | y18n@^5.0.5: 1157 | version "5.0.8" 1158 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1159 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1160 | 1161 | yargs-parser@20.2.4: 1162 | version "20.2.4" 1163 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" 1164 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1165 | 1166 | yargs-parser@^20.2.2: 1167 | version "20.2.9" 1168 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 1169 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1170 | 1171 | yargs-unparser@2.0.0: 1172 | version "2.0.0" 1173 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 1174 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 1175 | dependencies: 1176 | camelcase "^6.0.0" 1177 | decamelize "^4.0.0" 1178 | flat "^5.0.2" 1179 | is-plain-obj "^2.1.0" 1180 | 1181 | yargs@16.2.0: 1182 | version "16.2.0" 1183 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 1184 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1185 | dependencies: 1186 | cliui "^7.0.2" 1187 | escalade "^3.1.1" 1188 | get-caller-file "^2.0.5" 1189 | require-directory "^2.1.1" 1190 | string-width "^4.2.0" 1191 | y18n "^5.0.5" 1192 | yargs-parser "^20.2.2" 1193 | 1194 | yn@^2.0.0: 1195 | version "2.0.0" 1196 | resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" 1197 | integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo= 1198 | 1199 | yocto-queue@^0.1.0: 1200 | version "0.1.0" 1201 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1202 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1203 | --------------------------------------------------------------------------------