From b4b2fd2853e662a94b91d4448b0d32c978323c63 Mon Sep 17 00:00:00 2001 From: chizor iwuh Date: Tue, 29 Oct 2024 11:09:09 +0100 Subject: [PATCH] token-swap/steel --- Cargo.lock | 223 ++- Cargo.toml | 1 + tokens/token-swap/steel/cicd.sh | 8 + tokens/token-swap/steel/package.json | 25 + tokens/token-swap/steel/pnpm-lock.yaml | 1492 +++++++++++++++++ tokens/token-swap/steel/program/Cargo.toml | 15 + tokens/token-swap/steel/program/src/consts.rs | 5 + tokens/token-swap/steel/program/src/error.rs | 22 + .../program/src/instructions/create_amm.rs | 45 + .../program/src/instructions/create_pool.rs | 120 ++ .../src/instructions/deposit_liquidity.rs | 153 ++ .../steel/program/src/instructions/mod.rs | 23 + .../swap_exact_tokens_for_tokens.rs | 193 +++ .../src/instructions/withdraw_liquidity.rs | 101 ++ tokens/token-swap/steel/program/src/lib.rs | 35 + .../token-swap/steel/program/src/state/amm.rs | 20 + .../token-swap/steel/program/src/state/mod.rs | 14 + .../steel/program/src/state/pool.rs | 18 + .../steel/tests/instruction/create_amm.ts | 61 + .../steel/tests/instruction/create_pool.ts | 107 ++ .../tests/instruction/deposit_liquidity.ts | 137 ++ .../steel/tests/instruction/index.ts | 5 + .../steel/tests/instruction/instruction.ts | 15 + .../swap_exact_tokens_for_tokens.ts | 130 ++ .../tests/instruction/withdraw_liquidity.ts | 134 ++ tokens/token-swap/steel/tests/test.ts | 164 ++ tokens/token-swap/steel/tests/utils.ts | 192 +++ tokens/token-swap/steel/tsconfig.json | 10 + 28 files changed, 3426 insertions(+), 42 deletions(-) create mode 100644 tokens/token-swap/steel/cicd.sh create mode 100644 tokens/token-swap/steel/package.json create mode 100644 tokens/token-swap/steel/pnpm-lock.yaml create mode 100644 tokens/token-swap/steel/program/Cargo.toml create mode 100644 tokens/token-swap/steel/program/src/consts.rs create mode 100644 tokens/token-swap/steel/program/src/error.rs create mode 100644 tokens/token-swap/steel/program/src/instructions/create_amm.rs create mode 100644 tokens/token-swap/steel/program/src/instructions/create_pool.rs create mode 100644 tokens/token-swap/steel/program/src/instructions/deposit_liquidity.rs create mode 100644 tokens/token-swap/steel/program/src/instructions/mod.rs create mode 100644 tokens/token-swap/steel/program/src/instructions/swap_exact_tokens_for_tokens.rs create mode 100644 tokens/token-swap/steel/program/src/instructions/withdraw_liquidity.rs create mode 100644 tokens/token-swap/steel/program/src/lib.rs create mode 100644 tokens/token-swap/steel/program/src/state/amm.rs create mode 100644 tokens/token-swap/steel/program/src/state/mod.rs create mode 100644 tokens/token-swap/steel/program/src/state/pool.rs create mode 100644 tokens/token-swap/steel/tests/instruction/create_amm.ts create mode 100644 tokens/token-swap/steel/tests/instruction/create_pool.ts create mode 100644 tokens/token-swap/steel/tests/instruction/deposit_liquidity.ts create mode 100644 tokens/token-swap/steel/tests/instruction/index.ts create mode 100644 tokens/token-swap/steel/tests/instruction/instruction.ts create mode 100644 tokens/token-swap/steel/tests/instruction/swap_exact_tokens_for_tokens.ts create mode 100644 tokens/token-swap/steel/tests/instruction/withdraw_liquidity.ts create mode 100644 tokens/token-swap/steel/tests/test.ts create mode 100644 tokens/token-swap/steel/tests/utils.ts create mode 100644 tokens/token-swap/steel/tsconfig.json diff --git a/Cargo.lock b/Cargo.lock index f54b45b7b..47148bf83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -219,7 +219,7 @@ dependencies = [ "borsh 0.10.3", "bytemuck", "getrandom 0.2.15", - "solana-program", + "solana-program 1.18.17", "thiserror", ] @@ -439,6 +439,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + [[package]] name = "base64" version = "0.12.3" @@ -451,6 +457,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bincode" version = "1.3.3" @@ -738,7 +750,7 @@ dependencies = [ name = "checking-accounts-program" version = "0.1.0" dependencies = [ - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -765,7 +777,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -807,7 +819,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "shank", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -815,7 +827,7 @@ name = "counter-solana-native" version = "0.1.0" dependencies = [ "borsh 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -838,7 +850,7 @@ dependencies = [ name = "create-account-program" version = "0.1.0" dependencies = [ - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -1060,6 +1072,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" +[[package]] +name = "fixed" +version = "1.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc715d38bea7b5bf487fcd79bcf8c209f0b58014f3018a7a19c2b855f472048" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1103,6 +1127,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hand" version = "0.1.0" @@ -1154,7 +1188,7 @@ dependencies = [ name = "hello-solana-program" version = "0.1.0" dependencies = [ - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -1571,7 +1605,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -1674,7 +1708,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -1683,7 +1717,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -1692,7 +1726,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -1830,7 +1864,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -1884,7 +1918,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -2202,13 +2236,59 @@ dependencies = [ "sha3 0.10.8", "solana-frozen-abi", "solana-frozen-abi-macro", - "solana-sdk-macro", + "solana-sdk-macro 1.18.17", "thiserror", "tiny-bip39", "wasm-bindgen", "zeroize", ] +[[package]] +name = "solana-program" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2625a23c3813b620141ee447819b08d1b9a5f1c69a309754834e3f35798a21fb" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.22.1", + "bincode", + "bitflags", + "blake3", + "borsh 0.10.3", + "borsh 1.5.1", + "bs58 0.5.1", + "bv", + "bytemuck", + "bytemuck_derive", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.15", + "js-sys", + "lazy_static", + "libsecp256k1", + "log", + "memoffset", + "num-bigint", + "num-derive 0.4.2", + "num-traits", + "parking_lot", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.8", + "sha3 0.10.8", + "solana-sdk-macro 2.0.14", + "thiserror", + "wasm-bindgen", +] + [[package]] name = "solana-sdk" version = "1.18.17" @@ -2257,8 +2337,8 @@ dependencies = [ "solana-frozen-abi", "solana-frozen-abi-macro", "solana-logger", - "solana-program", - "solana-sdk-macro", + "solana-program 1.18.17", + "solana-sdk-macro 1.18.17", "thiserror", "uriparse", "wasm-bindgen", @@ -2277,6 +2357,19 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "solana-sdk-macro" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93a5a1eabc890415d326707afe62cd7a2009236e8d899c1519566fc8f7e3977b" +dependencies = [ + "bs58 0.5.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.72", +] + [[package]] name = "solana-security-txt" version = "1.1.1" @@ -2305,7 +2398,7 @@ dependencies = [ "serde", "serde_json", "sha3 0.9.1", - "solana-program", + "solana-program 1.18.17", "solana-sdk", "subtle", "thiserror", @@ -2322,7 +2415,7 @@ dependencies = [ "borsh 0.10.3", "num-derive 0.4.2", "num-traits", - "solana-program", + "solana-program 1.18.17", "spl-token", "spl-token-2022 1.0.0", "thiserror", @@ -2335,7 +2428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.17", "spl-discriminator-derive", ] @@ -2369,7 +2462,7 @@ version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325" dependencies = [ - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -2378,7 +2471,7 @@ version = "4.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a49f49f95f2d02111ded31696ab38a081fab623d4c76bd4cb074286db4560836" dependencies = [ - "solana-program", + "solana-program 1.18.17", ] [[package]] @@ -2389,7 +2482,7 @@ checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" dependencies = [ "borsh 0.10.3", "bytemuck", - "solana-program", + "solana-program 1.18.17", "solana-zk-token-sdk", "spl-program-error 0.3.0", ] @@ -2402,7 +2495,7 @@ checksum = "af92f74cd3b0fdfda59fef4b571a92123e4df0f67cc43f73163975d31118ef82" dependencies = [ "num-derive 0.3.3", "num-traits", - "solana-program", + "solana-program 1.18.17", "spl-program-error-derive 0.2.0", "thiserror", ] @@ -2415,7 +2508,7 @@ checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" dependencies = [ "num-derive 0.4.2", "num-traits", - "solana-program", + "solana-program 1.18.17", "spl-program-error-derive 0.3.2", "thiserror", ] @@ -2450,7 +2543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82149a5a06b5f158d03904066375eaf0c8a2422557cc3d5a25d277260d9a3b16" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.17", "spl-discriminator", "spl-program-error 0.2.0", "spl-type-length-value 0.2.0", @@ -2463,7 +2556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "615d381f48ddd2bb3c57c7f7fb207591a2a05054639b18a62e785117dd7a8683" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.17", "spl-discriminator", "spl-pod", "spl-program-error 0.3.0", @@ -2481,7 +2574,7 @@ dependencies = [ "num-derive 0.4.2", "num-traits", "num_enum 0.7.3", - "solana-program", + "solana-program 1.18.17", "thiserror", ] @@ -2496,7 +2589,7 @@ dependencies = [ "num-derive 0.3.3", "num-traits", "num_enum 0.6.1", - "solana-program", + "solana-program 1.18.17", "solana-zk-token-sdk", "spl-memo 3.0.1", "spl-token", @@ -2515,7 +2608,7 @@ dependencies = [ "num-derive 0.4.2", "num-traits", "num_enum 0.7.3", - "solana-program", + "solana-program 1.18.17", "solana-security-txt", "solana-zk-token-sdk", "spl-memo 4.0.4", @@ -2535,7 +2628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.17", "spl-discriminator", "spl-pod", "spl-program-error 0.3.0", @@ -2548,7 +2641,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" dependencies = [ "borsh 0.10.3", - "solana-program", + "solana-program 1.18.17", "spl-discriminator", "spl-pod", "spl-program-error 0.3.0", @@ -2566,7 +2659,7 @@ dependencies = [ "num-derive 0.3.3", "num-traits", "num_enum 0.6.1", - "solana-program", + "solana-program 1.18.17", "spl-discriminator", "spl-tlv-account-resolution 0.2.0", "spl-type-length-value 0.2.0", @@ -2581,7 +2674,7 @@ checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" dependencies = [ "arrayref", "bytemuck", - "solana-program", + "solana-program 1.18.17", "spl-discriminator", "spl-pod", "spl-program-error 0.3.0", @@ -2596,7 +2689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1d085f426b33b8365fb98383d1b8b3925e21bdfe579c851ceaa7f511dbec191" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.17", "spl-discriminator", "spl-program-error 0.2.0", ] @@ -2608,12 +2701,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.17", "spl-discriminator", "spl-pod", "spl-program-error 0.3.0", ] +[[package]] +name = "steel" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d88c610ca9fd5e4e51bdb6e9964114133a42f006713fe38aff37266fac91e1be" +dependencies = [ + "bytemuck", + "num_enum 0.7.3", + "solana-program 1.18.17", + "thiserror", +] + +[[package]] +name = "steel" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ca3cc310b7b71ce7944af64fb4fdaa5d0c2848ac79616d75e401913b6f781" +dependencies = [ + "bytemuck", + "num_enum 0.7.3", + "solana-program 1.18.17", + "spl-associated-token-account", + "spl-token", + "thiserror", +] + +[[package]] +name = "steel-hello-solana" +version = "0.1.0" +dependencies = [ + "solana-program 2.0.14", + "steel 1.3.0", +] + [[package]] name = "strsim" version = "0.11.1" @@ -2729,7 +2856,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", "spl-associated-token-account", "spl-token-2022 0.7.0", ] @@ -2740,7 +2867,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", "spl-associated-token-account", "spl-token-2022 0.7.0", ] @@ -2751,7 +2878,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", "spl-associated-token-account", "spl-token-2022 0.7.0", ] @@ -2762,7 +2889,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", "spl-associated-token-account", "spl-token-2022 0.7.0", ] @@ -2773,11 +2900,23 @@ version = "0.1.0" dependencies = [ "borsh 0.10.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", "spl-associated-token-account", "spl-token-2022 0.7.0", ] +[[package]] +name = "token-swap-steel-program" +version = "0.1.0" +dependencies = [ + "bytemuck", + "fixed", + "num_enum 0.7.3", + "solana-program 1.18.17", + "spl-token", + "steel 2.1.1", +] + [[package]] name = "toml" version = "0.5.11" @@ -2856,7 +2995,7 @@ version = "0.1.0" dependencies = [ "borsh 0.9.3", "borsh-derive 0.9.3", - "solana-program", + "solana-program 1.18.17", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c13e8b8c0..3a23bcbae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ members = [ "basics/repository-layout/anchor/programs/*", "basics/transfer-sol/native/program", "basics/transfer-sol/anchor/programs/*", + "tokens/token-swap/steel/program", "tokens/token-2022/mint-close-authority/native/program", "tokens/token-2022/non-transferable/native/program", "tokens/token-2022/default-account-state/native/program", diff --git a/tokens/token-swap/steel/cicd.sh b/tokens/token-swap/steel/cicd.sh new file mode 100644 index 000000000..0903cf896 --- /dev/null +++ b/tokens/token-swap/steel/cicd.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This script is for quick building & deploying of the program. +# It also serves as a reference for the commands used for building & deploying Solana programs. +# Run this bad boy with "bash cicd.sh" or "./cicd.sh" + +cargo build-sbf --manifest-path=./program/Cargo.toml --bpf-out-dir=./program/target/so +solana program deploy ./program/target/so/program.so diff --git a/tokens/token-swap/steel/package.json b/tokens/token-swap/steel/package.json new file mode 100644 index 000000000..1258b7725 --- /dev/null +++ b/tokens/token-swap/steel/package.json @@ -0,0 +1,25 @@ +{ + "scripts": { + "test": "pnpm ts-mocha -p ./tsconfig.json -t 1000000 ./tests/test.ts", + "build-and-test": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./tests/fixtures && pnpm test", + "build": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so", + "deploy": "solana program deploy ./program/target/so/program.so" + }, + "dependencies": { + "@solana/web3.js": "^1.47.3", + "@solana/spl-token": "^0.3.7", + "fs": "^0.0.1-security" + }, + "devDependencies": { + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.1", + "@types/mocha": "^9.1.1", + "@coral-xyz/borsh": "0.30.1", + "borsh": "0.7.0", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "solana-bankrun": "^0.3.0", + "ts-mocha": "^10.0.0", + "typescript": "^4.3.5" + } +} diff --git a/tokens/token-swap/steel/pnpm-lock.yaml b/tokens/token-swap/steel/pnpm-lock.yaml new file mode 100644 index 000000000..bc4c153ba --- /dev/null +++ b/tokens/token-swap/steel/pnpm-lock.yaml @@ -0,0 +1,1492 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@solana/spl-token': + specifier: ^0.3.7 + version: 0.3.11(@solana/web3.js@1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': + specifier: ^1.47.3 + version: 1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs: + specifier: ^0.0.1-security + version: 0.0.1-security + devDependencies: + '@coral-xyz/borsh': + specifier: 0.30.1 + version: 0.30.1(@solana/web3.js@1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@types/bn.js': + specifier: ^5.1.0 + version: 5.1.5 + '@types/chai': + specifier: ^4.3.1 + version: 4.3.16 + '@types/mocha': + specifier: ^9.1.1 + version: 9.1.1 + borsh: + specifier: 0.7.0 + version: 0.7.0 + chai: + specifier: ^4.3.4 + version: 4.4.1 + mocha: + specifier: ^9.0.3 + version: 9.2.2 + solana-bankrun: + specifier: ^0.3.0 + version: 0.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ts-mocha: + specifier: ^10.0.0 + version: 10.0.0(mocha@9.2.2) + typescript: + specifier: ^4.3.5 + version: 4.9.5 + +packages: + + '@babel/runtime@7.24.5': + resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} + engines: {node: '>=6.9.0'} + + '@coral-xyz/borsh@0.30.1': + resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + + '@noble/curves@1.4.0': + resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@solana/buffer-layout-utils@0.2.0': + resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} + engines: {node: '>= 10'} + + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + + '@solana/codecs-core@2.0.0-rc.1': + resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-data-structures@2.0.0-rc.1': + resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-numbers@2.0.0-rc.1': + resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-strings@2.0.0-rc.1': + resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5' + + '@solana/codecs@2.0.0-rc.1': + resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + peerDependencies: + typescript: '>=5' + + '@solana/errors@2.0.0-rc.1': + resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} + hasBin: true + peerDependencies: + typescript: '>=5' + + '@solana/options@2.0.0-rc.1': + resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + peerDependencies: + typescript: '>=5' + + '@solana/spl-token-metadata@0.1.6': + resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token@0.3.11': + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + + '@solana/web3.js@1.91.8': + resolution: {integrity: sha512-USa6OS1jbh8zOapRJ/CBZImZ8Xb7AJjROZl5adql9TpOoBN9BUzyyouS5oPuZHft7S7eB8uJPuXWYjMi6BHgOw==} + + '@types/bn.js@5.1.5': + resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==} + + '@types/chai@4.3.16': + resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/mocha@9.1.1': + resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@20.12.11': + resolution: {integrity: sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==} + + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + + '@ungap/promise-all-settled@1.1.2': + resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} + + JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + + agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-layout@1.2.2: + resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} + engines: {node: '>=4.5'} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + debug@4.3.3: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + + diff@3.5.0: + resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} + engines: {node: '>=0.3.1'} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fs@0.0.1-security: + resolution: {integrity: sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + + growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + jayson@4.1.0: + resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} + engines: {node: '>=8'} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@4.2.1: + resolution: {integrity: sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==} + engines: {node: '>=10'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mocha@9.2.2: + resolution: {integrity: sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==} + engines: {node: '>= 12.0.0'} + hasBin: true + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.1: + resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.1: + resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + rpc-websockets@7.11.0: + resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + solana-bankrun-darwin-arm64@0.3.0: + resolution: {integrity: sha512-+NbDncf0U6l3knuacRBiqpjZ2DSp+5lZaAU518gH7/x6qubbui/d000STaIBK+uNTPBS/AL/bCN+7PkXqmA3lA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + solana-bankrun-darwin-universal@0.3.0: + resolution: {integrity: sha512-1/F0xdMa4qvc5o6z16FCCbZ5jbdvKvxpx5kyPcMWRiRPwyvi+zltMxciPAYMlg3wslQqGz88uFhrBEzq2eTumQ==} + engines: {node: '>= 10'} + os: [darwin] + + solana-bankrun-darwin-x64@0.3.0: + resolution: {integrity: sha512-U6CANjkmMl+lgNA7UH0GKs5V7LtVIUDzJBZefGGqLfqUNv3EjA/PrrToM0hAOWJgkxSwdz6zW+p5sw5FmnbXtg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + solana-bankrun-linux-x64-gnu@0.3.0: + resolution: {integrity: sha512-qJSkCFs0k2n4XtTnyxGMiZsuqO2TiqTYgWjQ+3mZhGNUAMys/Vq8bd7/SyBm6RR7EfVuRXRxZvh+F8oKZ77V4w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + solana-bankrun-linux-x64-musl@0.3.0: + resolution: {integrity: sha512-xsS2CS2xb1Sw4ivNXM0gPz/qpW9BX0neSvt/pnok5L330Nu9xlTnKAY8FhzzqOP9P9sJlGRM787Y6d0yYwt6xQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + solana-bankrun@0.3.0: + resolution: {integrity: sha512-YkH7sa8TB/AoRPzG17CXJtYsRIQHEkEqGLz1Vwc13taXhDBkjO7z6NI5JYw7n0ybRymDHwMYTc7sd+5J40TyVQ==} + engines: {node: '>= 10'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-mocha@10.0.0: + resolution: {integrity: sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==} + engines: {node: '>= 6.X.X'} + hasBin: true + peerDependencies: + mocha: ^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X + + ts-node@7.0.1: + resolution: {integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==} + engines: {node: '>=4.2.0'} + hasBin: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + workerpool@6.2.0: + resolution: {integrity: sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.0: + resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yn@2.0.0: + resolution: {integrity: sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==} + engines: {node: '>=4'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@babel/runtime@7.24.5': + dependencies: + regenerator-runtime: 0.14.1 + + '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@solana/web3.js': 1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bn.js: 5.2.1 + buffer-layout: 1.2.2 + + '@noble/curves@1.4.0': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/hashes@1.4.0': {} + + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/web3.js': 1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bigint-buffer: 1.1.5 + bignumber.js: 9.1.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + '@solana/buffer-layout@4.0.1': + dependencies: + buffer: 6.0.3 + + '@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5)': + dependencies: + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 4.9.5 + + '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@2.0.0-rc.1(typescript@4.9.5)': + dependencies: + chalk: 5.3.0 + commander: 12.1.0 + typescript: 4.9.5 + + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + dependencies: + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + + '@solana/spl-token@0.3.11(@solana/web3.js@1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + + '@solana/web3.js@1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.24.5 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + node-fetch: 2.7.0 + rpc-websockets: 7.11.0 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + '@types/bn.js@5.1.5': + dependencies: + '@types/node': 20.12.11 + + '@types/chai@4.3.16': {} + + '@types/connect@3.4.38': + dependencies: + '@types/node': 12.20.55 + + '@types/json5@0.0.29': + optional: true + + '@types/mocha@9.1.1': {} + + '@types/node@12.20.55': {} + + '@types/node@20.12.11': + dependencies: + undici-types: 5.26.5 + + '@types/ws@7.4.7': + dependencies: + '@types/node': 12.20.55 + + '@ungap/promise-all-settled@1.1.2': {} + + JSONStream@1.3.5: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + + agentkeepalive@4.5.0: + dependencies: + humanize-ms: 1.2.1 + + ansi-colors@4.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@2.0.1: {} + + arrify@1.0.1: {} + + assertion-error@1.1.0: {} + + balanced-match@1.0.2: {} + + base-x@3.0.9: + dependencies: + safe-buffer: 5.2.1 + + base64-js@1.5.1: {} + + bigint-buffer@1.1.5: + dependencies: + bindings: 1.5.0 + + bignumber.js@9.1.2: {} + + binary-extensions@2.3.0: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bn.js@5.2.1: {} + + borsh@0.7.0: + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.2: + dependencies: + fill-range: 7.0.1 + + browser-stdout@1.3.1: {} + + bs58@4.0.1: + dependencies: + base-x: 3.0.9 + + buffer-from@1.1.2: {} + + buffer-layout@1.2.2: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.8.1 + optional: true + + camelcase@6.3.0: {} + + chai@4.4.1: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@12.1.0: {} + + commander@2.20.3: {} + + concat-map@0.0.1: {} + + debug@4.3.3(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + decamelize@4.0.0: {} + + deep-eql@4.1.3: + dependencies: + type-detect: 4.0.8 + + delay@5.0.0: {} + + diff@3.5.0: {} + + diff@5.0.0: {} + + emoji-regex@8.0.0: {} + + es6-promise@4.2.8: {} + + es6-promisify@5.0.0: + dependencies: + es6-promise: 4.2.8 + + escalade@3.1.2: {} + + escape-string-regexp@4.0.0: {} + + eventemitter3@4.0.7: {} + + eyes@0.1.8: {} + + fast-stable-stringify@1.0.0: {} + + fastestsmallesttextencoderdecoder@1.0.22: {} + + file-uri-to-path@1.0.0: {} + + fill-range@7.0.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat@5.0.2: {} + + fs.realpath@1.0.0: {} + + fs@0.0.1-security: {} + + fsevents@2.3.3: + optional: true + + get-caller-file@2.0.5: {} + + get-func-name@2.0.2: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + growl@1.10.5: {} + + has-flag@4.0.0: {} + + he@1.2.0: {} + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + ieee754@1.2.1: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-plain-obj@2.1.0: {} + + is-unicode-supported@0.1.0: {} + + isexe@2.0.0: {} + + isomorphic-ws@4.0.1(ws@7.5.9(bufferutil@4.0.8)(utf-8-validate@5.0.10)): + dependencies: + ws: 7.5.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) + + jayson@4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.9(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-stringify-safe@5.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + optional: true + + jsonparse@1.3.1: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + make-error@1.3.6: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@4.2.1: + dependencies: + brace-expansion: 1.1.11 + + minimist@1.2.8: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mocha@9.2.2: + dependencies: + '@ungap/promise-all-settled': 1.1.2 + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.3(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + growl: 1.10.5 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 4.2.1 + ms: 2.1.3 + nanoid: 3.3.1 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + which: 2.0.2 + workerpool: 6.2.0 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + + ms@2.1.2: {} + + ms@2.1.3: {} + + nanoid@3.3.1: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-gyp-build@4.8.1: + optional: true + + normalize-path@3.0.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + pathval@1.1.1: {} + + picomatch@2.3.1: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + regenerator-runtime@0.14.1: {} + + require-directory@2.1.1: {} + + rpc-websockets@7.11.0: + dependencies: + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + safe-buffer@5.2.1: {} + + serialize-javascript@6.0.0: + dependencies: + randombytes: 2.1.0 + + solana-bankrun-darwin-arm64@0.3.0: + optional: true + + solana-bankrun-darwin-universal@0.3.0: + optional: true + + solana-bankrun-darwin-x64@0.3.0: + optional: true + + solana-bankrun-linux-x64-gnu@0.3.0: + optional: true + + solana-bankrun-linux-x64-musl@0.3.0: + optional: true + + solana-bankrun@0.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@solana/web3.js': 1.91.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bs58: 4.0.1 + optionalDependencies: + solana-bankrun-darwin-arm64: 0.3.0 + solana-bankrun-darwin-universal: 0.3.0 + solana-bankrun-darwin-x64: 0.3.0 + solana-bankrun-linux-x64-gnu: 0.3.0 + solana-bankrun-linux-x64-musl: 0.3.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: + optional: true + + strip-json-comments@3.1.1: {} + + superstruct@0.14.2: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + text-encoding-utf-8@1.0.2: {} + + through@2.3.8: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + ts-mocha@10.0.0(mocha@9.2.2): + dependencies: + mocha: 9.2.2 + ts-node: 7.0.1 + optionalDependencies: + tsconfig-paths: 3.15.0 + + ts-node@7.0.1: + dependencies: + arrify: 1.0.1 + buffer-from: 1.1.2 + diff: 3.5.0 + make-error: 1.3.6 + minimist: 1.2.8 + mkdirp: 0.5.6 + source-map-support: 0.5.21 + yn: 2.0.0 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + optional: true + + type-detect@4.0.8: {} + + typescript@4.9.5: {} + + undici-types@5.26.5: {} + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.1 + optional: true + + uuid@8.3.2: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + workerpool@6.2.0: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@7.5.9(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@8.17.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + y18n@5.0.8: {} + + yargs-parser@20.2.4: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + + yn@2.0.0: {} + + yocto-queue@0.1.0: {} diff --git a/tokens/token-swap/steel/program/Cargo.toml b/tokens/token-swap/steel/program/Cargo.toml new file mode 100644 index 000000000..7eafd4e44 --- /dev/null +++ b/tokens/token-swap/steel/program/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "token-swap-steel-program" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] + +[dependencies] +solana-program = "=1.18.17" +steel = {version ="2.0", features=["spl"]} +bytemuck = "1.14" +num_enum = "0.7" +fixed = "=1.27.0" +spl-token = { version = "4.0.0", features = [ "no-entrypoint" ] } \ No newline at end of file diff --git a/tokens/token-swap/steel/program/src/consts.rs b/tokens/token-swap/steel/program/src/consts.rs new file mode 100644 index 000000000..89e384590 --- /dev/null +++ b/tokens/token-swap/steel/program/src/consts.rs @@ -0,0 +1,5 @@ +pub const MINIMUM_LIQUIDITY: u64 = 100; + +pub const AUTHORITY_SEED: &[u8] = b"authority"; + +pub const LIQUIDITY_SEED: &[u8] = b"liquidity"; diff --git a/tokens/token-swap/steel/program/src/error.rs b/tokens/token-swap/steel/program/src/error.rs new file mode 100644 index 000000000..5a6e495cb --- /dev/null +++ b/tokens/token-swap/steel/program/src/error.rs @@ -0,0 +1,22 @@ +use steel::*; + +#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)] +#[repr(u32)] +pub enum SteelError { + #[error("Invalid fee value")] + InvalidFee, + + #[error("Invalid mint for the pool")] + InvalidMint, + + #[error("Depositing too little liquidity")] + DepositTooSmall, + + #[error("Output is below the minimum expected")] + OutputTooSmall, + + #[error("Invariant does not hold")] + InvariantViolated, +} + +error!(SteelError); diff --git a/tokens/token-swap/steel/program/src/instructions/create_amm.rs b/tokens/token-swap/steel/program/src/instructions/create_amm.rs new file mode 100644 index 000000000..d001ea87e --- /dev/null +++ b/tokens/token-swap/steel/program/src/instructions/create_amm.rs @@ -0,0 +1,45 @@ +use crate::{state::*, SteelInstruction}; +use steel::*; + +instruction!(SteelInstruction, CreateAmm); + +#[repr(C, packed)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct CreateAmm { + id: Pubkey, + fee: u16, +} + +impl CreateAmm { + pub fn process( + program_id: &Pubkey, + accounts: &[AccountInfo<'_>], + data: &[u8], + ) -> ProgramResult { + let args = Self::try_from_bytes(data)?; + + let [amm_info, admin, payer, system_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + payer.is_writable()?; + system_program.is_program(&system_program::ID)?; + + // create amm + create_account::( + amm_info, + system_program, + payer, + program_id, + &[args.id.as_ref()], + )?; + + let amm = amm_info.as_account_mut::(program_id)?; + + amm.admin = *admin.key; + amm.fee = args.fee; + amm.id = args.id; + + Ok(()) + } +} diff --git a/tokens/token-swap/steel/program/src/instructions/create_pool.rs b/tokens/token-swap/steel/program/src/instructions/create_pool.rs new file mode 100644 index 000000000..384ce1f6b --- /dev/null +++ b/tokens/token-swap/steel/program/src/instructions/create_pool.rs @@ -0,0 +1,120 @@ +use { + crate::{consts::*, state::*, SteelInstruction}, + solana_program::{msg, program_pack::Pack}, + spl_token::state::Mint, + steel::*, +}; + +instruction!(SteelInstruction, CreatePool); + +#[repr(C, packed)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct CreatePool {} + +impl CreatePool { + pub fn process(program_id: &Pubkey, accounts: &[AccountInfo<'_>]) -> ProgramResult { + let [amm, pool_info, pool_authority, mint_liquidity, mint_a, mint_b, pool_account_a, pool_account_b, payer, token_program, associated_token_program, system_program, rent] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + payer.is_writable()?; + system_program.is_program(&system_program::ID)?; + mint_liquidity.has_seeds( + &[ + amm.key.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + LIQUIDITY_SEED, + ], + program_id, + )?; + + create_account::( + pool_info, + system_program, + payer, + program_id, + &[amm.key.as_ref(), mint_a.key.as_ref(), mint_b.key.as_ref()], + )?; + + // First create the account for the Mint + // + let (_, bump) = Pubkey::find_program_address( + &[ + amm.key.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + LIQUIDITY_SEED, + ], + program_id, + ); + + allocate_account_with_bump( + mint_liquidity, + system_program, + payer, + Mint::LEN, + token_program.key, + &[ + amm.key.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + LIQUIDITY_SEED, + ], + bump, + )?; + + // Now initialize that account as a Mint (standard Mint) + // + msg!("Initializing mint account..."); + msg!("Mint: {}", mint_liquidity.key); + + initialize_mint_signed_with_bump( + mint_liquidity, + pool_authority, + Some(pool_authority), + token_program, + rent, + 6, + &[ + amm.key.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + LIQUIDITY_SEED, + ], + bump, + )?; + + msg!("Mint success: {}", mint_liquidity.key); + + create_associated_token_account( + payer, + pool_authority, + pool_account_a, + mint_a, + system_program, + token_program, + associated_token_program, + )?; + + create_associated_token_account( + payer, + pool_authority, + pool_account_b, + mint_b, + system_program, + token_program, + associated_token_program, + )?; + + let pool = pool_info.as_account_mut::(program_id)?; + + pool.amm = *amm.key; + pool.mint_a = *mint_a.key; + pool.mint_b = *mint_b.key; + + Ok(()) + } +} diff --git a/tokens/token-swap/steel/program/src/instructions/deposit_liquidity.rs b/tokens/token-swap/steel/program/src/instructions/deposit_liquidity.rs new file mode 100644 index 000000000..8e618d635 --- /dev/null +++ b/tokens/token-swap/steel/program/src/instructions/deposit_liquidity.rs @@ -0,0 +1,153 @@ +use { + crate::{consts::*, error::*, state::*, SteelInstruction}, + fixed::types::I64F64, + solana_program::msg, + steel::*, +}; + +instruction!(SteelInstruction, DepositLiquidity); + +#[repr(C, packed)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct DepositLiquidity { + pub amount_a: u64, + pub amount_b: u64, +} + +impl DepositLiquidity { + pub fn process( + program_id: &Pubkey, + accounts: &[AccountInfo<'_>], + data: &[u8], + ) -> ProgramResult { + let args = DepositLiquidity::try_from_bytes(data)?; + + let amount_a = args.amount_a; + let amount_b = args.amount_b; + + let [_amm, pool, pool_authority, depositor, mint_liquidity, mint_a, mint_b, pool_account_a, pool_account_b, depositor_account_liquidity, depositor_account_a, depositor_account_b, payer, token_program, associated_token_program, system_program, _rent] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + if depositor_account_liquidity.lamports() == 0 { + create_associated_token_account( + payer, + depositor, + depositor_account_liquidity, + mint_liquidity, + system_program, + token_program, + associated_token_program, + )?; + } + + // Prevent depositing assets the depositor does not own + let mut amount_a = if amount_a > depositor_account_a.as_token_account()?.amount { + depositor_account_a.as_token_account()?.amount + } else { + amount_a + }; + + let mut amount_b = if amount_b > depositor_account_b.as_token_account()?.amount { + depositor_account_a.as_token_account()?.amount + } else { + amount_b + }; + + // Making sure they are provided in the same proportion as existing liquidity + let pool_a = pool_account_a.as_token_account()?; + let pool_b = pool_account_b.as_token_account()?; + + // Defining pool creation like this allows attackers to frontrun pool creation with bad ratios + let pool_creation = pool_a.amount == 0 && pool_b.amount == 0; + + (amount_a, amount_b) = if pool_creation { + // Add as is if there is no liquidity + (amount_a, amount_b) + } else { + let ratio = I64F64::from_num(pool_a.amount) + .checked_mul(I64F64::from_num(pool_b.amount)) + .unwrap(); + if pool_a.amount > pool_b.amount { + ( + I64F64::from_num(amount_b) + .checked_mul(ratio) + .unwrap() + .to_num::(), + amount_b, + ) + } else { + ( + amount_a, + I64F64::from_num(amount_a) + .checked_div(ratio) + .unwrap() + .to_num::(), + ) + } + }; + + // Computing the amount of liquidity about to be deposited + let mut liquidity = I64F64::from_num(amount_a) + .checked_mul(I64F64::from_num(amount_b)) + .unwrap() + .sqrt() + .to_num::(); + + // Lock some minimum liquidity on the first deposit + if pool_creation { + if liquidity < MINIMUM_LIQUIDITY { + return Err(SteelError::DepositTooSmall.into()); + } + + liquidity -= MINIMUM_LIQUIDITY; + } + + // Transfer tokens to the pool + transfer( + depositor, + depositor_account_a, + pool_account_a, + token_program, + amount_a, + )?; + transfer( + depositor, + depositor_account_b, + pool_account_b, + token_program, + amount_b, + )?; + + let pool = pool.as_account::(program_id)?; + + msg!("pool amm: {}", pool.amm.to_string()); + + let (_, bump) = Pubkey::find_program_address( + &[ + pool.amm.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + AUTHORITY_SEED, + ], + program_id, + ); + + mint_to_signed_with_bump( + mint_liquidity, + depositor_account_liquidity, + pool_authority, + token_program, + liquidity, + &[ + pool.amm.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + AUTHORITY_SEED, + ], + bump, + ) + } +} diff --git a/tokens/token-swap/steel/program/src/instructions/mod.rs b/tokens/token-swap/steel/program/src/instructions/mod.rs new file mode 100644 index 000000000..b1d78502a --- /dev/null +++ b/tokens/token-swap/steel/program/src/instructions/mod.rs @@ -0,0 +1,23 @@ +pub mod create_amm; +pub mod create_pool; +pub mod deposit_liquidity; +pub mod swap_exact_tokens_for_tokens; +pub mod withdraw_liquidity; + +pub use create_amm::*; +pub use create_pool::*; +pub use deposit_liquidity::*; +pub use swap_exact_tokens_for_tokens::*; +pub use withdraw_liquidity::*; + +use steel::*; + +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)] +pub enum SteelInstruction { + CreateAmm = 0, + CreatePool = 1, + DepositLiquidity = 2, + SwapExactTokensForTokens = 3, + WithdrawLiquidity = 4, +} diff --git a/tokens/token-swap/steel/program/src/instructions/swap_exact_tokens_for_tokens.rs b/tokens/token-swap/steel/program/src/instructions/swap_exact_tokens_for_tokens.rs new file mode 100644 index 000000000..51c2d74f2 --- /dev/null +++ b/tokens/token-swap/steel/program/src/instructions/swap_exact_tokens_for_tokens.rs @@ -0,0 +1,193 @@ +use { + crate::{consts::*, error::*, state::*, SteelInstruction}, + fixed::types::I64F64, + steel::*, +}; + +instruction!(SteelInstruction, SwapExactTokensForTokens); + +#[repr(C, packed)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct SwapExactTokensForTokens { + pub swap_a: u8, + pub input_amount: u64, + pub min_output_amount: u64, +} + +impl SwapExactTokensForTokens { + pub fn process( + program_id: &Pubkey, + accounts: &[AccountInfo<'_>], + data: &[u8], + ) -> ProgramResult { + let args = Self::try_from_bytes(data)?; + + let swap_a = args.swap_a.to_bool()?; + let input_amount = args.input_amount; + let min_output_amount = args.min_output_amount; + + let [amm_info, _pool, pool_authority, trader, mint_a, mint_b, pool_account_a, pool_account_b, trader_account_a, trader_account_b, payer, token_program, associated_token_program, system_program, _rent] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + // Prevent depositing assets the depositor does not own + let input = if swap_a && input_amount > trader_account_a.as_token_account()?.amount { + trader_account_a.as_token_account()?.amount + } else if !swap_a && input_amount > trader_account_b.as_token_account()?.amount { + trader_account_b.as_token_account()?.amount + } else { + input_amount + }; + + let amm = amm_info.as_account::(program_id)?; + let taxed_input = input - input * amm.fee as u64 / 10000; + + let pool_a = pool_account_a.as_token_account()?; + let pool_b = pool_account_b.as_token_account()?; + + let output = if swap_a { + I64F64::from_num(taxed_input) + .checked_mul(I64F64::from_num(pool_b.amount)) + .unwrap() + .checked_div( + I64F64::from_num(pool_a.amount) + .checked_add(I64F64::from_num(taxed_input)) + .unwrap(), + ) + .unwrap() + } else { + I64F64::from_num(taxed_input) + .checked_mul(I64F64::from_num(pool_a.amount)) + .unwrap() + .checked_div( + I64F64::from_num(pool_b.amount) + .checked_add(I64F64::from_num(taxed_input)) + .unwrap(), + ) + .unwrap() + } + .to_num::(); + + if output < min_output_amount { + return Err(SteelError::OutputTooSmall.into()); + } + + // Compute the invariant before the trade + let invariant = pool_a.amount * pool_b.amount; + + let pool_seeds = &[ + amm_info.key.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + AUTHORITY_SEED, + ]; + + let (_, bump) = Pubkey::find_program_address( + &[ + amm_info.key.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + AUTHORITY_SEED, + ], + program_id, + ); + + // init if needed + if trader_account_a.lamports() == 0 { + create_associated_token_account( + payer, + trader, + trader_account_a, + mint_a, + system_program, + token_program, + associated_token_program, + )?; + } + + // init if needed + if trader_account_b.lamports() == 0 { + create_associated_token_account( + payer, + trader, + trader_account_b, + mint_b, + system_program, + token_program, + associated_token_program, + )?; + } + + // Transfer tokens to the pool + if swap_a { + transfer( + trader, + trader_account_a, + pool_account_a, + token_program, + input, + )?; + transfer_signed_with_bump( + pool_authority, + pool_account_b, + trader_account_b, + token_program, + output, + pool_seeds, + bump + )?; + } else { + transfer( + trader, + trader_account_b, + pool_account_b, + token_program, + input, + )?; + transfer_signed_with_bump( + pool_authority, + pool_account_a, + trader_account_a, + token_program, + output, + pool_seeds, + bump + )?; + } + + solana_program::msg!( + "Traded {} tokens ({} after fees) for {}", + input, + taxed_input, + output + ); + + // Verify the invariant still holds + // Reload accounts because of the CPIs + // We tolerate if the new invariant is higher because it means a rounding error for LPs + let pool_a = pool_account_a.as_token_account()?; + let pool_b = pool_account_b.as_token_account()?; + + if invariant > pool_a.amount * pool_b.amount { + return Err(SteelError::InvariantViolated.into()); + } + + Ok(()) + } +} + +trait Boolean { + fn to_bool(&self) -> Result; +} + +impl Boolean for u8 { + fn to_bool(&self) -> Result { + match *self { + 0 => Ok(false), + 1 => Ok(true), + _ => Err(ProgramError::InvalidArgument), + } + } +} diff --git a/tokens/token-swap/steel/program/src/instructions/withdraw_liquidity.rs b/tokens/token-swap/steel/program/src/instructions/withdraw_liquidity.rs new file mode 100644 index 000000000..141e62fc8 --- /dev/null +++ b/tokens/token-swap/steel/program/src/instructions/withdraw_liquidity.rs @@ -0,0 +1,101 @@ +use { + crate::{consts::*, SteelInstruction}, + fixed::types::I64F64, + steel::*, +}; + +instruction!(SteelInstruction, WithdrawLiquidity); + +#[repr(C, packed)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct WithdrawLiquidity { + pub amount: u64, +} + +impl WithdrawLiquidity { + pub fn process( + program_id: &Pubkey, + accounts: &[AccountInfo<'_>], + data: &[u8], + ) -> ProgramResult { + let args = Self::try_from_bytes(data)?; + + let amount = args.amount; + + let [amm_info, _pool, pool_authority, depositor, mint_liquidity, mint_a, mint_b, pool_account_a, pool_account_b, depositor_account_liquidity, depositor_account_a, depositor_account_b, _payer, token_program, _associated_token_program, _system_program, _rent] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + let pool_seeds = &[ + amm_info.key.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + AUTHORITY_SEED, + ]; + + let (_, bump) = Pubkey::find_program_address( + &[ + amm_info.key.as_ref(), + mint_a.key.as_ref(), + mint_b.key.as_ref(), + AUTHORITY_SEED, + ], + program_id, + ); + + + // Transfer tokens from the pool + let amount_a = I64F64::from_num(amount) + .checked_mul(I64F64::from_num(pool_account_a.as_token_account()?.amount)) + .unwrap() + .checked_div(I64F64::from_num( + mint_liquidity.as_mint()?.supply + MINIMUM_LIQUIDITY, + )) + .unwrap() + .floor() + .to_num::(); + + transfer_signed_with_bump( + pool_authority, + pool_account_a, + depositor_account_a, + token_program, + amount_a, + pool_seeds, + bump, + )?; + + // Transfer tokens from the pool + let amount_b = I64F64::from_num(amount) + .checked_mul(I64F64::from_num(pool_account_b.as_token_account()?.amount)) + .unwrap() + .checked_div(I64F64::from_num( + mint_liquidity.as_mint()?.supply + MINIMUM_LIQUIDITY, + )) + .unwrap() + .floor() + .to_num::(); + + transfer_signed_with_bump( + pool_authority, + pool_account_b, + depositor_account_b, + token_program, + amount_b, + pool_seeds, + bump + )?; + + burn( + depositor_account_liquidity, + mint_liquidity, + depositor, + token_program, + amount, + // pool_seeds, + // bump + ) + } +} diff --git a/tokens/token-swap/steel/program/src/lib.rs b/tokens/token-swap/steel/program/src/lib.rs new file mode 100644 index 000000000..53ef7f052 --- /dev/null +++ b/tokens/token-swap/steel/program/src/lib.rs @@ -0,0 +1,35 @@ +mod consts; +mod error; +mod instructions; +mod state; + +use instructions::*; +use steel::*; + +declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35"); + +entrypoint!(process_instruction); + +pub fn process_instruction( + program_id: &Pubkey, + accounts: &[AccountInfo], + data: &[u8], +) -> ProgramResult { + let (ix, data) = parse_instruction(program_id, program_id, data)?; + + match ix { + SteelInstruction::CreateAmm => CreateAmm::process(program_id, accounts, data)?, + SteelInstruction::CreatePool => CreatePool::process(program_id, accounts)?, + SteelInstruction::DepositLiquidity => { + DepositLiquidity::process(program_id, accounts, data)? + } + SteelInstruction::SwapExactTokensForTokens => { + SwapExactTokensForTokens::process(program_id, accounts, data)? + } + SteelInstruction::WithdrawLiquidity => { + WithdrawLiquidity::process(program_id, accounts, data)? + } + } + + Ok(()) +} diff --git a/tokens/token-swap/steel/program/src/state/amm.rs b/tokens/token-swap/steel/program/src/state/amm.rs new file mode 100644 index 000000000..a9764e576 --- /dev/null +++ b/tokens/token-swap/steel/program/src/state/amm.rs @@ -0,0 +1,20 @@ +use steel::*; + +use super::SteelAccount; + +account!(SteelAccount, Amm); + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] +pub struct Amm { + /// The primary key of the AMM + pub id: Pubkey, + + /// Account that has admin authority over the AMM + pub admin: Pubkey, + + /// The LP fee taken on each trade, in basis points + pub fee: u16, +} + + diff --git a/tokens/token-swap/steel/program/src/state/mod.rs b/tokens/token-swap/steel/program/src/state/mod.rs new file mode 100644 index 000000000..875a48008 --- /dev/null +++ b/tokens/token-swap/steel/program/src/state/mod.rs @@ -0,0 +1,14 @@ +pub mod amm; +pub mod pool; + +pub use amm::*; +pub use pool::*; + +use steel::*; + +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)] +pub enum SteelAccount { + Amm = 0, + Pool = 1, +} diff --git a/tokens/token-swap/steel/program/src/state/pool.rs b/tokens/token-swap/steel/program/src/state/pool.rs new file mode 100644 index 000000000..c45be54a0 --- /dev/null +++ b/tokens/token-swap/steel/program/src/state/pool.rs @@ -0,0 +1,18 @@ +use steel::*; + +use super::SteelAccount; + +account!(SteelAccount, Pool); + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] +pub struct Pool { + /// Primary key of the AMM + pub amm: Pubkey, + + /// Mint of token A + pub mint_a: Pubkey, + + /// Mint of token B + pub mint_b: Pubkey, +} diff --git a/tokens/token-swap/steel/tests/instruction/create_amm.ts b/tokens/token-swap/steel/tests/instruction/create_amm.ts new file mode 100644 index 000000000..28714a51b --- /dev/null +++ b/tokens/token-swap/steel/tests/instruction/create_amm.ts @@ -0,0 +1,61 @@ +import { PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js'; +import * as borsh from 'borsh'; +import { Assignable, TokenSwapInstruction } from './instruction'; + +class CreateAmm extends Assignable { + toBuffer() { + return Buffer.from(borsh.serialize(CreateAmmSchema, this)); + } +} + +const CreateAmmSchema = new Map([ + [ + CreateAmm, + { + kind: 'struct', + fields: [ + ['instruction', 'u8'], + ['id', [32]], + ['fee', 'u16'], + ], + }, + ], +]); + +export function buildCreateAmmInstruction(props: { + id: PublicKey; + fee: number; + amm: PublicKey; + admin: PublicKey; + payer: PublicKey; + programId: PublicKey; +}) { + const ix = new CreateAmm({ + instruction: TokenSwapInstruction.CreateAmm, + id: props.id.toBytes(), + fee: props.fee, + }); + + return new TransactionInstruction({ + keys: [ + { + pubkey: props.amm, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.admin, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.payer, + isSigner: true, + isWritable: true, + }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + programId: props.programId, + data: ix.toBuffer(), + }); +} diff --git a/tokens/token-swap/steel/tests/instruction/create_pool.ts b/tokens/token-swap/steel/tests/instruction/create_pool.ts new file mode 100644 index 000000000..3a1a6d3c7 --- /dev/null +++ b/tokens/token-swap/steel/tests/instruction/create_pool.ts @@ -0,0 +1,107 @@ +import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { PublicKey, SYSVAR_RENT_PUBKEY, SystemProgram, TransactionInstruction } from '@solana/web3.js'; +import * as borsh from 'borsh'; +import { Assignable, TokenSwapInstruction } from './instruction'; + +export class CreatePool extends Assignable { + toBuffer() { + return Buffer.from(borsh.serialize(CreatePoolSchema, this)); + } +} +const CreatePoolSchema = new Map([ + [ + CreatePool, + { + kind: 'struct', + fields: [ + ['instruction', 'u8'], + // ["mint_decimals", "u8"], + ], + }, + ], +]); + +export function buildCreatePoolInstruction(props: { + amm: PublicKey; + pool: PublicKey; + poolAuthority: PublicKey; + mintLiquidity: PublicKey; + mintA: PublicKey; + mintB: PublicKey; + poolTokenAccountA: PublicKey; + poolTokenAccountB: PublicKey; + payer: PublicKey; + programId: PublicKey; +}) { + const ix = new CreatePool({ + instruction: TokenSwapInstruction.CreatePool, + }); + + return new TransactionInstruction({ + keys: [ + { + pubkey: props.amm, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.pool, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolAuthority, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintLiquidity, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolTokenAccountA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolTokenAccountB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.payer, + isSigner: true, + isWritable: true, + }, + { + pubkey: TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { + pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { + pubkey: SYSVAR_RENT_PUBKEY, + isSigner: false, + isWritable: false, + }, + ], + programId: props.programId, + data: ix.toBuffer(), + }); +} diff --git a/tokens/token-swap/steel/tests/instruction/deposit_liquidity.ts b/tokens/token-swap/steel/tests/instruction/deposit_liquidity.ts new file mode 100644 index 000000000..b9b63e415 --- /dev/null +++ b/tokens/token-swap/steel/tests/instruction/deposit_liquidity.ts @@ -0,0 +1,137 @@ +import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { PublicKey, SYSVAR_RENT_PUBKEY, SystemProgram, TransactionInstruction } from '@solana/web3.js'; +import BN from 'bn.js'; +import * as borsh from 'borsh'; +import { Assignable, TokenSwapInstruction } from './instruction'; + +export class DepositLiquidity extends Assignable { + toBuffer() { + return Buffer.from(borsh.serialize(DepositLiquiditySchema, this)); + } +} +const DepositLiquiditySchema = new Map([ + [ + DepositLiquidity, + { + kind: 'struct', + fields: [ + ['instruction', 'u8'], + ['amount_a', 'u64'], + ['amount_b', 'u64'], + ], + }, + ], +]); + +export function buildDepositLiquidityInstruction(props: { + amount_a: BN; + amount_b: BN; + amm: PublicKey; + pool: PublicKey; + poolAuthority: PublicKey; + depositor: PublicKey; + mintLiquidity: PublicKey; + mintA: PublicKey; + mintB: PublicKey; + poolTokenAccountA: PublicKey; + poolTokenAccountB: PublicKey; + depositorTokenAccountLiquidity: PublicKey; + depositorTokenAccountA: PublicKey; + depositorTokenAccountB: PublicKey; + payer: PublicKey; + programId: PublicKey; +}) { + const ix = new DepositLiquidity({ + instruction: TokenSwapInstruction.DepositLiquidity, + amount_a: props.amount_a, + amount_b: props.amount_b, + }); + + return new TransactionInstruction({ + keys: [ + { + pubkey: props.amm, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.pool, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolAuthority, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.depositor, + isSigner: true, + isWritable: true, + }, + { + pubkey: props.mintLiquidity, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolTokenAccountA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolTokenAccountB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.depositorTokenAccountLiquidity, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.depositorTokenAccountA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.depositorTokenAccountB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.payer, + isSigner: true, + isWritable: true, + }, + { + pubkey: TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { + pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { + pubkey: SYSVAR_RENT_PUBKEY, + isSigner: false, + isWritable: false, + }, + ], + programId: props.programId, + data: ix.toBuffer(), + }); +} diff --git a/tokens/token-swap/steel/tests/instruction/index.ts b/tokens/token-swap/steel/tests/instruction/index.ts new file mode 100644 index 000000000..b457b0491 --- /dev/null +++ b/tokens/token-swap/steel/tests/instruction/index.ts @@ -0,0 +1,5 @@ +export * from './create_amm'; +export * from './create_pool'; +export * from './deposit_liquidity'; +export * from './swap_exact_tokens_for_tokens'; +export * from './withdraw_liquidity'; diff --git a/tokens/token-swap/steel/tests/instruction/instruction.ts b/tokens/token-swap/steel/tests/instruction/instruction.ts new file mode 100644 index 000000000..e28e250f8 --- /dev/null +++ b/tokens/token-swap/steel/tests/instruction/instruction.ts @@ -0,0 +1,15 @@ +export class Assignable { + constructor(properties) { + for (const [key, value] of Object.entries(properties)) { + this[key] = value; + } + } +} + +export enum TokenSwapInstruction { + CreateAmm = 0, + CreatePool = 1, + DepositLiquidity = 2, + SwapExactTokensForTokens = 3, + WithdrawLiquidity = 4, +} diff --git a/tokens/token-swap/steel/tests/instruction/swap_exact_tokens_for_tokens.ts b/tokens/token-swap/steel/tests/instruction/swap_exact_tokens_for_tokens.ts new file mode 100644 index 000000000..af3da466b --- /dev/null +++ b/tokens/token-swap/steel/tests/instruction/swap_exact_tokens_for_tokens.ts @@ -0,0 +1,130 @@ +import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { PublicKey, SYSVAR_RENT_PUBKEY, SystemProgram, TransactionInstruction } from '@solana/web3.js'; +import BN from 'bn.js'; +import * as borsh from 'borsh'; +import { Assignable, TokenSwapInstruction } from './instruction'; + +export class SwapExactTokensForTokens extends Assignable { + toBuffer() { + return Buffer.from(borsh.serialize(SwapExactTokensForTokensSchema, this)); + } +} +const SwapExactTokensForTokensSchema = new Map([ + [ + SwapExactTokensForTokens, + { + kind: 'struct', + fields: [ + ['instruction', 'u8'], + ['swap_a', 'u8'], + ['input_amount', 'u64'], + ['min_output_amount', 'u64'], + ], + }, + ], +]); + +export function buildSwapExactTokensForTokensInstruction(props: { + swap_a: boolean; + input_amount: BN; + min_output_amount: BN; + amm: PublicKey; + pool: PublicKey; + poolAuthority: PublicKey; + trader: PublicKey; + mintLiquidity: PublicKey; + mintA: PublicKey; + mintB: PublicKey; + poolTokenAccountA: PublicKey; + poolTokenAccountB: PublicKey; + traderTokenAccountLiquidity: PublicKey; + traderTokenAccountA: PublicKey; + traderTokenAccountB: PublicKey; + payer: PublicKey; + programId: PublicKey; +}) { + const ix = new SwapExactTokensForTokens({ + instruction: TokenSwapInstruction.SwapExactTokensForTokens, + swap_a: props.swap_a, + input_amount: props.input_amount, + min_output_amount: props.min_output_amount, + }); + + return new TransactionInstruction({ + keys: [ + { + pubkey: props.amm, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.pool, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolAuthority, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.trader, + isSigner: true, + isWritable: true, + }, + { + pubkey: props.mintA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolTokenAccountA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolTokenAccountB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.traderTokenAccountA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.traderTokenAccountB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.payer, + isSigner: true, + isWritable: true, + }, + { + pubkey: TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { + pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { + pubkey: SYSVAR_RENT_PUBKEY, + isSigner: false, + isWritable: false, + }, + ], + programId: props.programId, + data: ix.toBuffer(), + }); +} diff --git a/tokens/token-swap/steel/tests/instruction/withdraw_liquidity.ts b/tokens/token-swap/steel/tests/instruction/withdraw_liquidity.ts new file mode 100644 index 000000000..763d00ebd --- /dev/null +++ b/tokens/token-swap/steel/tests/instruction/withdraw_liquidity.ts @@ -0,0 +1,134 @@ +import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { PublicKey, SYSVAR_RENT_PUBKEY, SystemProgram, TransactionInstruction } from '@solana/web3.js'; +import BN from 'bn.js'; +import * as borsh from 'borsh'; +import { Assignable, TokenSwapInstruction } from './instruction'; + +export class WithdrawLiquidity extends Assignable { + toBuffer() { + return Buffer.from(borsh.serialize(WithdrawLiquiditySchema, this)); + } +} +const WithdrawLiquiditySchema = new Map([ + [ + WithdrawLiquidity, + { + kind: 'struct', + fields: [ + ['instruction', 'u8'], + ['amount', 'u64'], + ], + }, + ], +]); + +export function buildWithdrawLiquidityInstruction(props: { + amount: BN; + amm: PublicKey; + pool: PublicKey; + poolAuthority: PublicKey; + depositor: PublicKey; + mintLiquidity: PublicKey; + mintA: PublicKey; + mintB: PublicKey; + poolTokenAccountA: PublicKey; + poolTokenAccountB: PublicKey; + depositorTokenAccountLiquidity: PublicKey; + depositorTokenAccountA: PublicKey; + depositorTokenAccountB: PublicKey; + payer: PublicKey; + programId: PublicKey; +}) { + const ix = new WithdrawLiquidity({ + instruction: TokenSwapInstruction.WithdrawLiquidity, + amount: props.amount, + }); + + return new TransactionInstruction({ + keys: [ + { + pubkey: props.amm, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.pool, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolAuthority, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.depositor, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintLiquidity, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.mintB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolTokenAccountA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.poolTokenAccountB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.depositorTokenAccountLiquidity, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.depositorTokenAccountA, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.depositorTokenAccountB, + isSigner: false, + isWritable: true, + }, + { + pubkey: props.payer, + isSigner: true, + isWritable: true, + }, + { + pubkey: TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { + pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { + pubkey: SYSVAR_RENT_PUBKEY, + isSigner: false, + isWritable: false, + }, + ], + programId: props.programId, + data: ix.toBuffer(), + }); +} diff --git a/tokens/token-swap/steel/tests/test.ts b/tokens/token-swap/steel/tests/test.ts new file mode 100644 index 000000000..461cff7ec --- /dev/null +++ b/tokens/token-swap/steel/tests/test.ts @@ -0,0 +1,164 @@ +import { Buffer } from 'node:buffer'; +import { describe, test } from 'node:test'; +import { Transaction } from '@solana/web3.js'; +import { BN } from 'bn.js'; +import { start } from 'solana-bankrun'; +import { + buildCreateAmmInstruction, + buildCreatePoolInstruction, + buildDepositLiquidityInstruction, + buildSwapExactTokensForTokensInstruction, + buildWithdrawLiquidityInstruction, +} from './instruction'; +import { createValues, mintingTokens } from './utils'; + +describe('Account Data!', async () => { + const values = createValues(); + + const context = await start([{ name: 'token_swap_steel_program', programId: values.programId }], []); + + const client = context.banksClient; + const payer = context.payer; + + console.log(`Program Address : ${values.programId}`); + console.log(`Payer Address : ${payer.publicKey}`); + + test('Create Amm', async () => { + console.log('===================== CREATE AMM ======================'); + const ix = buildCreateAmmInstruction({ + admin: values.admin.publicKey, + amm: values.ammKey, + fee: values.fee, + id: values.id, + payer: payer.publicKey, + programId: values.programId, + }); + + const blockhash = context.lastBlockhash; + + const tx = new Transaction(); + tx.recentBlockhash = blockhash; + tx.add(ix).sign(payer); + await client.processTransaction(tx); + }); + + test(async () => { + console.log('===================== Minting Tokens Before Tests ======================'); + await mintingTokens({ + context, + creator: values.admin, + mintAKeypair: values.mintAKeypair, + mintBKeypair: values.mintBKeypair, + }); + }); + + test('Create Amm Pool', async () => { + console.log('===================== CREATE AMM POOL ======================'); + const ix = buildCreatePoolInstruction({ + amm: values.ammKey, + mintA: values.mintAKeypair.publicKey, + mintB: values.mintBKeypair.publicKey, + mintLiquidity: values.mintLiquidity, + payer: payer.publicKey, + pool: values.poolKey, + poolAuthority: values.poolAuthority, + poolTokenAccountA: values.poolAccountA, + poolTokenAccountB: values.poolAccountB, + programId: values.programId, + }); + + const blockhash = context.lastBlockhash; + + const tx = new Transaction(); + tx.recentBlockhash = blockhash; + tx.add(ix).sign(payer); + await client.processTransaction(tx); + }); + + test('Deposit to amm pool', async () => { + console.log('===================== DEPOSIT ======================'); + const ix = buildDepositLiquidityInstruction({ + amm: values.ammKey, + mintA: values.mintAKeypair.publicKey, + mintB: values.mintBKeypair.publicKey, + mintLiquidity: values.mintLiquidity, + payer: payer.publicKey, + pool: values.poolKey, + poolAuthority: values.poolAuthority, + poolTokenAccountA: values.poolAccountA, + poolTokenAccountB: values.poolAccountB, + programId: values.programId, + amount_a: values.depositAmountA, + amount_b: values.depositAmountB, + depositor: values.admin.publicKey, + depositorTokenAccountA: values.holderAccountA, + depositorTokenAccountB: values.holderAccountB, + depositorTokenAccountLiquidity: values.liquidityAccount, + }); + + const blockhash = context.lastBlockhash; + + const tx = new Transaction(); + tx.recentBlockhash = blockhash; + tx.add(ix).sign(payer, values.admin); + await client.processTransaction(tx); + }); + + test('Swap tokens for Tokens', async () => { + console.log('===================== SWAP ======================'); + const ix = buildSwapExactTokensForTokensInstruction({ + amm: values.ammKey, + mintA: values.mintAKeypair.publicKey, + mintB: values.mintBKeypair.publicKey, + mintLiquidity: values.mintLiquidity, + payer: payer.publicKey, + pool: values.poolKey, + poolAuthority: values.poolAuthority, + poolTokenAccountA: values.poolAccountA, + poolTokenAccountB: values.poolAccountB, + programId: values.programId, + input_amount: new BN(10 ** 6), + min_output_amount: new BN(100), + swap_a: true, + trader: values.admin.publicKey, + traderTokenAccountA: values.holderAccountA, + traderTokenAccountB: values.holderAccountB, + traderTokenAccountLiquidity: values.liquidityAccount, + }); + + const blockhash = context.lastBlockhash; + + const tx = new Transaction(); + tx.recentBlockhash = blockhash; + tx.add(ix).sign(payer, values.admin); + await client.processTransaction(tx); + }); + + test('Withdraw from amm pool', async () => { + console.log('===================== WITHDRAW ======================'); + const ix = buildWithdrawLiquidityInstruction({ + amm: values.ammKey, + mintA: values.mintAKeypair.publicKey, + mintB: values.mintBKeypair.publicKey, + mintLiquidity: values.mintLiquidity, + payer: payer.publicKey, + pool: values.poolKey, + poolAuthority: values.poolAuthority, + poolTokenAccountA: values.poolAccountA, + poolTokenAccountB: values.poolAccountB, + programId: values.programId, + depositor: values.admin.publicKey, + depositorTokenAccountA: values.holderAccountA, + depositorTokenAccountB: values.holderAccountB, + depositorTokenAccountLiquidity: values.liquidityAccount, + amount: new BN(1000), + }); + + const blockhash = context.lastBlockhash; + + const tx = new Transaction(); + tx.recentBlockhash = blockhash; + tx.add(ix).sign(payer, values.admin); + await client.processTransaction(tx); + }); +}); diff --git a/tokens/token-swap/steel/tests/utils.ts b/tokens/token-swap/steel/tests/utils.ts new file mode 100644 index 000000000..669967606 --- /dev/null +++ b/tokens/token-swap/steel/tests/utils.ts @@ -0,0 +1,192 @@ +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + MINT_SIZE, + TOKEN_PROGRAM_ID, + createAssociatedTokenAccountIdempotentInstruction, + createInitializeMint2Instruction, + createMintToInstruction, + getAssociatedTokenAddressSync, + mintTo, +} from '@solana/spl-token'; +import { Keypair, PublicKey, type Signer, SystemProgram, Transaction } from '@solana/web3.js'; +import BN from 'bn.js'; +import { ProgramTestContext } from 'solana-bankrun'; + +export async function sleep(seconds: number) { + new Promise((resolve) => setTimeout(resolve, seconds * 1000)); +} + +export const expectRevert = async (promise: Promise) => { + try { + await promise; + throw new Error('Expected a revert'); + } catch { + return; + } +}; + +export const mintingTokens = async ({ + context, + creator, + holder = creator, + mintAKeypair, + mintBKeypair, + mintedAmount = 100, + decimals = 6, +}: { + context: ProgramTestContext; + creator: Signer; + holder?: Signer; + mintAKeypair: Keypair; + mintBKeypair: Keypair; + mintedAmount?: number; + decimals?: number; +}) => { + async function createMint(context: ProgramTestContext, mint: Keypair, decimals: number) { + const rent = await context.banksClient.getRent(); + + const lamports = rent.minimumBalance(BigInt(MINT_SIZE)); + + const transaction = new Transaction().add( + SystemProgram.createAccount({ + fromPubkey: context.payer.publicKey, + newAccountPubkey: mint.publicKey, + space: MINT_SIZE, + lamports: new BN(lamports.toString()).toNumber(), + programId: TOKEN_PROGRAM_ID, + }), + createInitializeMint2Instruction(mint.publicKey, decimals, context.payer.publicKey, context.payer.publicKey, TOKEN_PROGRAM_ID), + ); + transaction.recentBlockhash = context.lastBlockhash; + transaction.sign(context.payer, mint); + + await context.banksClient.processTransaction(transaction); + } + + async function createAssociatedTokenAccountIfNeeded(context: ProgramTestContext, mint: PublicKey, owner: PublicKey) { + const associatedToken = getAssociatedTokenAddressSync(mint, owner, true); + + const rent = await context.banksClient.getRent(); + + rent.minimumBalance(BigInt(MINT_SIZE)); + + const transaction = new Transaction().add( + createAssociatedTokenAccountIdempotentInstruction( + context.payer.publicKey, + associatedToken, + owner, + mint, + TOKEN_PROGRAM_ID, + ASSOCIATED_TOKEN_PROGRAM_ID, + ), + ); + transaction.recentBlockhash = context.lastBlockhash; + transaction.sign(context.payer); + + await context.banksClient.processTransaction(transaction); + } + + async function mintTo(context: ProgramTestContext, mint: PublicKey, destination: PublicKey, amount: number | bigint) { + const transaction = new Transaction().add(createMintToInstruction(mint, destination, context.payer.publicKey, amount, [], TOKEN_PROGRAM_ID)); + transaction.recentBlockhash = context.lastBlockhash; + transaction.sign(context.payer); + + await context.banksClient.processTransaction(transaction); + } + + // creator creates the mint + await createMint(context, mintAKeypair, decimals); + await createMint(context, mintBKeypair, decimals); + + // create holder token account + await createAssociatedTokenAccountIfNeeded(context, mintAKeypair.publicKey, holder.publicKey); + await createAssociatedTokenAccountIfNeeded(context, mintBKeypair.publicKey, holder.publicKey); + + // mint to holders token account + await mintTo( + context, + mintAKeypair.publicKey, + getAssociatedTokenAddressSync(mintAKeypair.publicKey, holder.publicKey, true), + mintedAmount * 10 ** decimals, + ); + await mintTo( + context, + mintBKeypair.publicKey, + getAssociatedTokenAddressSync(mintBKeypair.publicKey, holder.publicKey, true), + mintedAmount * 10 ** decimals, + ); +}; + +export interface TestValues { + id: PublicKey; + fee: number; + admin: Keypair; + mintAKeypair: Keypair; + mintBKeypair: Keypair; + defaultSupply: BN; + ammKey: PublicKey; + minimumLiquidity: BN; + poolKey: PublicKey; + poolAuthority: PublicKey; + mintLiquidity: PublicKey; + depositAmountA: BN; + depositAmountB: BN; + liquidityAccount: PublicKey; + poolAccountA: PublicKey; + poolAccountB: PublicKey; + holderAccountA: PublicKey; + holderAccountB: PublicKey; + programId: PublicKey; +} + +type TestValuesDefaults = { + [K in keyof TestValues]+?: TestValues[K]; +}; +export function createValues(defaults?: TestValuesDefaults): TestValues { + const programId = PublicKey.unique(); + const id = defaults?.id || Keypair.generate().publicKey; + const admin = Keypair.generate(); + const ammKey = PublicKey.findProgramAddressSync([id.toBuffer()], programId)[0]; + + // Making sure tokens are in the right order + const mintAKeypair = Keypair.generate(); + let mintBKeypair = Keypair.generate(); + while (new BN(mintBKeypair.publicKey.toBytes()).lt(new BN(mintAKeypair.publicKey.toBytes()))) { + mintBKeypair = Keypair.generate(); + } + + const poolAuthority = PublicKey.findProgramAddressSync( + [ammKey.toBuffer(), mintAKeypair.publicKey.toBuffer(), mintBKeypair.publicKey.toBuffer(), Buffer.from('authority')], + programId, + )[0]; + const mintLiquidity = PublicKey.findProgramAddressSync( + [ammKey.toBuffer(), mintAKeypair.publicKey.toBuffer(), mintBKeypair.publicKey.toBuffer(), Buffer.from('liquidity')], + programId, + )[0]; + const poolKey = PublicKey.findProgramAddressSync( + [ammKey.toBuffer(), mintAKeypair.publicKey.toBuffer(), mintBKeypair.publicKey.toBuffer()], + programId, + )[0]; + + return { + id, + fee: 500, + admin, + ammKey, + mintAKeypair, + mintBKeypair, + mintLiquidity, + poolKey, + poolAuthority, + poolAccountA: getAssociatedTokenAddressSync(mintAKeypair.publicKey, poolAuthority, true), + poolAccountB: getAssociatedTokenAddressSync(mintBKeypair.publicKey, poolAuthority, true), + liquidityAccount: getAssociatedTokenAddressSync(mintLiquidity, admin.publicKey, true), + holderAccountA: getAssociatedTokenAddressSync(mintAKeypair.publicKey, admin.publicKey, true), + holderAccountB: getAssociatedTokenAddressSync(mintBKeypair.publicKey, admin.publicKey, true), + depositAmountA: new BN(4 * 10 ** 6), + depositAmountB: new BN(1 * 10 ** 6), + minimumLiquidity: new BN(100), + defaultSupply: new BN(100 * 10 ** 6), + programId, + }; +} diff --git a/tokens/token-swap/steel/tsconfig.json b/tokens/token-swap/steel/tsconfig.json new file mode 100644 index 000000000..cd5d2e3d0 --- /dev/null +++ b/tokens/token-swap/steel/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2015"], + "module": "commonjs", + "target": "es6", + "esModuleInterop": true + } +}