From 1152ceccc1d6034e63e3952cf4dd4d7f5b70f1ea Mon Sep 17 00:00:00 2001 From: Wilhelm Thieme Date: Sun, 20 Oct 2024 12:04:04 -0400 Subject: [PATCH] Squashed commit of the following: commit 5f67e17641e7ac863a4b80f20ed4639dcee04213 Author: Wilhelm Thieme Date: Sun Oct 20 11:04:53 2024 -0400 Tweaks commit 30e880699d6ba6a024fdddeb775016dc5dcaac26 Author: Wilhelm Thieme Date: Sun Oct 20 11:00:38 2024 -0400 Test commit 363167a429692718d2a20fd6783dfd869ea8ac30 Author: Wilhelm Thieme Date: Sun Oct 20 10:59:06 2024 -0400 test commit 694373a4901c58e43a95b9f16c3b56673728eb89 Author: Wilhelm Thieme Date: Sun Oct 20 10:58:01 2024 -0400 Test commit a0bee58a3ec6662ade2207ab332a5de895da9dee Author: Wilhelm Thieme Date: Sun Oct 20 10:46:54 2024 -0400 Fixes commit 310a3c97b51b76b7d05000adbd2096c258f17a59 Author: Wilhelm Thieme Date: Sun Oct 20 10:40:23 2024 -0400 Tweak commit 80942dee07282835026842e91b07bb40344c10c1 Author: Wilhelm Thieme Date: Sun Oct 20 10:38:46 2024 -0400 Tweak commit af029c5d98958d005c8c171497061fc2acd7ea5d Author: Wilhelm Thieme Date: Sun Oct 20 10:36:35 2024 -0400 Fix commit 0e74d167f2609c0b7a8bb3194e407313f0517a0a Author: Wilhelm Thieme Date: Sun Oct 20 10:35:30 2024 -0400 Tweaks commit 87adc7d89911b57afe4fabcd0afa6e8a24eeb8b3 Author: Wilhelm Thieme Date: Sun Oct 20 10:29:19 2024 -0400 Tweak commit 805bfd7005e382dd9574a6654dd06653cab16020 Author: Wilhelm Thieme Date: Sun Oct 20 10:24:37 2024 -0400 Fix commit 78c137df716dd4c4359492b5db14a0638cba9687 Author: Wilhelm Thieme Date: Sun Oct 20 10:23:29 2024 -0400 Tweaks commit 907ff55c6302c3c942395adf4a7eec33dc2dbab8 Author: Wilhelm Thieme Date: Sun Oct 20 10:20:39 2024 -0400 Use local anchor setup instead of docker image commit 5b8c691967355fb7364aa8138ab0cd8965d5e154 Author: Wilhelm Thieme Date: Sat Oct 19 21:48:55 2024 -0400 test? commit a02b9e1de4a52802e39ae26ce68e8602a33c9a2a Author: Wilhelm Thieme Date: Sat Oct 19 21:07:52 2024 -0400 Revert test commit 559caa40dad1d0a3316dddeb7839857646f0803d Author: Wilhelm Thieme Date: Sat Oct 19 20:45:48 2024 -0400 test commit f18648dbe827c4464735c7ce90b334d4d93d7cb1 Author: Wilhelm Thieme Date: Sat Oct 19 20:19:51 2024 -0400 Run ci in container commit c51bd9adde437f2de0ccb1b8ef7a2e3965bfee45 Author: Wilhelm Thieme Date: Sat Oct 19 15:30:42 2024 -0400 Tweaks commit e78905824e5bd0e64494b22610fa81e8a872094c Author: Wilhelm Thieme Date: Sat Oct 19 15:27:24 2024 -0400 Tweak commit 174c99ded68fa8cb86fbde118ca4fa8efa2aebbd Author: Wilhelm Thieme Date: Sat Oct 19 11:03:15 2024 -0400 Tweak commit 928580a27c79ae5ad56f3e197fc13f5304fcf90d Author: Wilhelm Thieme Date: Sat Oct 19 09:58:47 2024 -0400 Tweak CI commit 675889bc507876da651cb6bd97ef061675ff9e2c Author: Wilhelm Thieme Date: Sat Oct 19 09:46:06 2024 -0400 Node 22 commit edb7b91fee13d3e799ed886a0b33c6343e60330e Author: Wilhelm Thieme Date: Sat Oct 19 09:34:40 2024 -0400 Tweak commit a3c067f1616eb2a5debe2b05489eb79506fa60a9 Author: Wilhelm Thieme Date: Sat Oct 19 09:26:30 2024 -0400 Build fix commit f36ef1f1b12bade91bfa652f0036a03132bdb677 Author: Wilhelm Thieme Date: Fri Oct 18 23:38:27 2024 -0400 Fix failing tests commit 0073f8da4c173ecfd91e50a542445019744de64d Author: Wilhelm Thieme Date: Fri Oct 18 22:38:35 2024 -0400 vitest commit 564c7013303b4a9b031f6a347fb9cf126d06362d Author: Wilhelm Thieme Date: Fri Oct 18 17:39:36 2024 -0400 Edge case fix commit 7ac67d646fa1be6e05528870d6426bbc6a85c902 Merge: 057136c 1985fac Author: Wilhelm Thieme Date: Fri Oct 18 14:31:07 2024 -0400 Merge branch 'main' into wjthieme/utils-package # Conflicts: # docs/ts/package.json # yarn.lock commit 057136c5ee4bd8add8b5ac00ce7d53dfb4cf43f0 Author: Wilhelm Thieme Date: Fri Oct 18 14:30:24 2024 -0400 Review comments commit 5127075d8a15d937626e1279216d88bf7b165920 Author: calintje Date: Thu Oct 17 14:40:03 2024 +0200 Fix description of slippage tolerance commit de2633755854a852d83e288d58323b25d75502b6 Author: Calin <57701767+calintje@users.noreply.github.com> Date: Thu Oct 17 14:28:40 2024 +0200 Typedocs for TS SDK (#381) * Base typedocs * Update docs * Finish typedocs for PR. Add export keyword for types. Update examples. Update typedocs for types. * Resolve comments --------- Co-authored-by: calintje commit 8ecfdb02c5ef434180945342eaab0f01cb63795b Author: Wilhelm Thieme Date: Tue Oct 15 17:06:02 2024 -0400 Swap tests and logic commit 6a088eb94a77b09a1ac709b6f702e77766ff1c20 Author: Wilhelm Thieme Date: Tue Oct 15 13:39:42 2024 -0400 Tick array sequence function signature commit 81da8155814efd4ba5611134592edb76194549d6 Merge: 5e262b0 cd4fa33 Author: Wilhelm Thieme Date: Tue Oct 15 11:32:52 2024 -0400 Merge branch 'main' into wjthieme/utils-package # Conflicts: # docs/ts/package.json # yarn.lock commit 5e262b0df36b9b3c749d23f402204c641da33060 Author: Wilhelm Thieme Date: Tue Oct 15 11:17:58 2024 -0400 Better swap quote function signature commit 78de1019e4dd2900442e2e221ee05259a19cf8b4 Author: Wilhelm Thieme Date: Tue Oct 15 10:15:09 2024 -0400 Deposit ratio commit 48819ae4bb6bd8d69538427dbb410228e35ec950 Author: Wilhelm Thieme Date: Mon Oct 14 17:12:43 2024 -0400 Fixes commit 11e4a3d5c13b36842caa9375581dd3664219d63e Author: Wilhelm Thieme Date: Mon Oct 14 09:26:13 2024 -0400 High level TS function naming commit 706313fab075e7d6071058d849335cdb069be751 Author: Wilhelm Thieme Date: Sat Oct 12 21:52:36 2024 -0400 Fix some tests commit 4aa3fd23dd95e122107580432f7a335bd49f3cc5 Author: Wilhelm Thieme Date: Sat Oct 12 21:42:41 2024 -0400 Refactor macros commit 3e659083dbe28d703adb21c778a44255223ac49d Author: Wilhelm Thieme Date: Sat Oct 12 15:17:22 2024 -0400 Fix some tests commit d95f035083f400de2f573a9ac4c9c99b321d168f Author: Wilhelm Thieme Date: Sat Oct 12 14:37:02 2024 -0400 Format commit 5f5b111cf39a72e3200a49c621689b0038344062 Author: Wilhelm Thieme Date: Sat Oct 12 12:58:05 2024 -0400 Merge commit 33cf14c7ad791d4b4516c398fd47d28c76475b9e Author: Wilhelm Thieme Date: Sat Oct 12 10:44:07 2024 -0400 Squashed commit of the following: commit 6f5088397c21f6da8ff25eb21394faf6b3aef9b4 Author: Wilhelm Thieme Date: Thu Oct 10 11:13:31 2024 -0400 Create pool naming commit f54d406926bfc11ea9b78004f577e61edb578f8b Author: Wilhelm Thieme Date: Wed Oct 9 11:45:09 2024 -0400 Fix build commit 04e0dab10168c9c1cbf107e3872dd0fab500dd10 Author: Wilhelm Thieme Date: Wed Oct 9 09:13:34 2024 -0400 Squashed commit of the following: commit 05cad83f7c43bfba14ab28cb198b5db7bb00103e Author: Wilhelm Thieme Date: Tue Oct 8 21:37:12 2024 -0400 Tweaks commit db00d93b686f4aae428e023d9c6a64894f0c4460 Author: Wilhelm Thieme Date: Tue Oct 8 11:20:12 2024 -0400 New open/close instructions commit 1fd45630bf7c1b3b371ae246cc32fd6c5bd05366 Merge: df7466d 447528b Author: Wilhelm Thieme Date: Tue Oct 8 11:01:03 2024 -0400 Merge branch 'wjthieme/utils-package' into wjthieme/ts-sdk # Conflicts: # yarn.lock commit 447528b170cd3265bae8bc3bc00716d5638e3013 Merge: aa32a8f 16661e2 Author: Wilhelm Thieme Date: Tue Oct 8 11:00:17 2024 -0400 Merge branch 'main' into wjthieme/utils-package # Conflicts: # docs/ts/package.json # yarn.lock commit df7466d65684c3092136bc2ca66ef0ac6c666707 Author: Wilhelm Thieme Date: Tue Oct 8 10:59:02 2024 -0400 Fetch positions and Transfer fees commit a4a967b7046ba5641dad2743e9d324cc461bb653 Author: Wilhelm Thieme Date: Mon Oct 7 08:34:20 2024 -0400 Add TODOs commit 845401950604a9cad9fd6a9cca99b0c2f68fc053 Merge: f66c061 aa32a8f Author: Wilhelm Thieme Date: Wed Oct 2 17:46:49 2024 -0400 Merge branch 'wjthieme/utils-package' into wjthieme/ts-sdk # Conflicts: # ts-sdk/client/package.json # yarn.lock commit aa32a8fa8e4bcfc0a2b30a5bf0ee15abb6e186bb Author: Wilhelm Thieme Date: Wed Oct 2 17:45:24 2024 -0400 Cargo lock commit 6ac1a3f345982ccf9e71776daea4076ff42bf1f9 Merge: 3c32ace 2c35e54 Author: Wilhelm Thieme Date: Wed Oct 2 17:45:03 2024 -0400 Merge branch 'main' into wjthieme/utils-package # Conflicts: # rust-sdk/client/Cargo.toml # yarn.lock commit f66c0619aa0673328934dd7d19e73c6a76e8c3b8 Author: Wilhelm Thieme Date: Wed Oct 2 17:42:23 2024 -0400 Build fix commit 4604375bed1258cb8698d6309370f801ea3233c0 Author: Wilhelm Thieme Date: Tue Sep 17 11:04:09 2024 +0800 Failing test commit 373ad973136dbee2005abf1fa1c1c8dcaccf8fda Merge: 919f0dd 3c32ace Author: Wilhelm Thieme Date: Tue Sep 17 09:54:29 2024 +0800 Merge branch 'wjthieme/utils-package' into wjthieme/ts-sdk # Conflicts: # ts-sdk/whirlpool/package.json # yarn.lock commit 3c32aceab195e55fb7d7240fe54e1ab76c9db7a1 Merge: 7424e40 18d5bcc Author: Wilhelm Thieme Date: Tue Sep 17 09:52:38 2024 +0800 Merge branch 'main' into wjthieme/utils-package # Conflicts: # docs/ts/package.json # yarn.lock commit 919f0dd938266433d6e699361605f6b627118a60 Author: Wilhelm Thieme Date: Mon Sep 9 18:06:26 2024 -0400 Fix tests commit 7424e40990adb38fa717b311762b027554800fc4 Author: Wilhelm Thieme Date: Fri Aug 30 22:31:55 2024 -0500 Format commit f61b31f702ae91b6fe03cf19c9039d4413123011 Author: Wilhelm Thieme Date: Fri Aug 30 22:31:32 2024 -0500 Format commit acaee2afe21861f8ed14ca1dbdd986043ff24853 Author: Wilhelm Thieme Date: Fri Aug 30 22:26:51 2024 -0500 Swap commit 4cd718a32f63456e881fdac0d2ebbe8aaf540d29 Merge: 31956ef 4d627c4 Author: Wilhelm Thieme Date: Fri Aug 30 22:13:05 2024 -0500 Merge branch 'wjthieme/utils-package' into wjthieme/ts-sdk commit 4d627c45a8541d3c5c19a6bfb71bb6ea59a8958e Author: Wilhelm Thieme Date: Fri Aug 30 22:12:57 2024 -0500 Fix test commit 31956ef75a7ac8c07a798f546fc48cef57290327 Merge: 25a2b87 0dbd9dd Author: Wilhelm Thieme Date: Fri Aug 30 22:10:54 2024 -0500 Merge branch 'wjthieme/utils-package' into wjthieme/ts-sdk commit 0dbd9dd07fd1c14171a8f5a86bccf33285d1cb4d Author: Wilhelm Thieme Date: Fri Aug 30 22:10:45 2024 -0500 More tick arrays commit a0834c19760991068b5d9b590123f19c02b98d7b Author: Wilhelm Thieme Date: Fri Aug 30 11:36:11 2024 -0500 Manifest and readme files commit 25a2b877520a2a4552122bafb4476665fb81ad71 Author: Wilhelm Thieme Date: Thu Aug 29 11:27:07 2024 -0500 Token 22 test case commit c5afd33a1b18a6afa4bce98f30ea7f969e71babd Author: Wilhelm Thieme Date: Thu Aug 29 11:21:04 2024 -0500 Typedoc commit 030ff1903e868665698e579fd20173b7e02dd7d9 Author: Wilhelm Thieme Date: Thu Aug 29 11:08:22 2024 -0500 Instruction assertions commit bba3da04d69d85af452dd915beca6de7f18f00e5 Author: Wilhelm Thieme Date: Thu Aug 29 09:22:11 2024 -0500 Tests for token account creation commit dde599bffcf97410d0906f9a7836e761c9e8dd19 Author: Wilhelm Thieme Date: Wed Aug 28 17:00:31 2024 -0500 Amend commit fc75f932c8b728eecd014171b8223a77be32b122 Author: Wilhelm Thieme Date: Wed Aug 28 16:59:59 2024 -0500 Sol wrapping and unwrapping commit f8c00d4b22eb3008f1c2a3e46a829fdd98278497 Author: Wilhelm Thieme Date: Wed Aug 28 11:16:54 2024 -0400 Mock rpc for testing ts whirlpool lib commit 82415e44fb943951e3e3297e41c2de25c6706a76 Merge: addf594 c2cfe57 Author: Wilhelm Thieme Date: Wed Aug 28 07:28:27 2024 -0400 Merge branch 'wjthieme/utils-package' into wjthieme/ts-sdk # Conflicts: # rust-sdk/core/src/quote/swap.rs commit c2cfe5771b82e933c52d35d03550d4abe149df7b Author: Wilhelm Thieme Date: Wed Aug 28 07:27:20 2024 -0400 Tweaks commit addf5946104714c8dd51a3835beb2f9480aede91 Author: Wilhelm Thieme Date: Tue Aug 27 11:30:13 2024 -0400 Types tests commit 5be25bd05cf84903635ee09dfa467d51e19325c2 Author: Wilhelm Thieme Date: Tue Aug 27 09:59:00 2024 -0400 Enum type commit f113c26502c23efbf73753084f90b05c6b5bde3b Author: Wilhelm Thieme Date: Mon Aug 26 17:09:01 2024 -0400 Ts core smoke test commit 14158b4b936fbcb7c3da98408e599d70fb2ba114 Author: Wilhelm Thieme Date: Fri Aug 23 14:49:50 2024 -0400 Decrease liq and harvest position commit d0a75e869c30ed7d722dc6243cf7a39d1c4e646d Author: Wilhelm Thieme Date: Fri Aug 23 13:06:50 2024 -0400 Format commit edf241d91e72ead5663763effb7332fdbe3baa7c Author: Wilhelm Thieme Date: Fri Aug 23 12:39:15 2024 -0400 Format commit 621424d1ba4369a9be6557014735cbff0942ce3a Author: Wilhelm Thieme Date: Fri Aug 23 12:37:10 2024 -0400 open position and increase liquidity commit fbf54d10a89cec8a0e2dbdc004eba502468c4df5 Author: Wilhelm Thieme Date: Fri Aug 23 08:48:19 2024 -0400 Format commit ef97db2d9717a03110fed5eb58c004ef9616793e Author: Wilhelm Thieme Date: Fri Aug 23 08:39:58 2024 -0400 PDA tests commit 78bea38f7268d1013c32b65f848709df45e849db Author: Sam Johnson Date: Fri Aug 23 00:19:45 2024 -0400 add support for arrays commit f4dabc05f73a7ca4c35a2dd27f18cd2aea494950 Author: Wilhelm Thieme Date: Thu Aug 22 17:47:33 2024 -0400 Create Pool commit 57b7613e2c6a8567e75841b996ea5316ad89e921 Author: Wilhelm Thieme Date: Thu Aug 22 15:49:29 2024 -0400 Scaffolding commit 4f637c65769b9f65fcfe4eaf469b642283988145 Author: Wilhelm Thieme Date: Thu Aug 22 13:00:51 2024 -0400 Fix failing tests commit 4ab7c35494f82cb82e7d344ddbfd6b768ba813fe Merge: a11aeff 261905d Author: Wilhelm Thieme Date: Thu Aug 22 12:03:55 2024 -0400 Merge branch 'main' into wjthieme/utils-package # Conflicts: # yarn.lock commit a11aeff51c0a191f3745bdc1b092cfd15fbc8179 Author: Wilhelm Thieme Date: Wed Aug 21 21:09:16 2024 -0400 Squash commit 92ed42621f7b931bef2078524048f177a21ef887 Author: Wilhelm Thieme Date: Wed Oct 9 09:04:28 2024 -0400 Squashed commit of the following: commit 447528b170cd3265bae8bc3bc00716d5638e3013 Merge: aa32a8f 16661e2 Author: Wilhelm Thieme Date: Tue Oct 8 11:00:17 2024 -0400 Merge branch 'main' into wjthieme/utils-package # Conflicts: # docs/ts/package.json # yarn.lock commit aa32a8fa8e4bcfc0a2b30a5bf0ee15abb6e186bb Author: Wilhelm Thieme Date: Wed Oct 2 17:45:24 2024 -0400 Cargo lock commit 6ac1a3f345982ccf9e71776daea4076ff42bf1f9 Merge: 3c32ace 2c35e54 Author: Wilhelm Thieme Date: Wed Oct 2 17:45:03 2024 -0400 Merge branch 'main' into wjthieme/utils-package # Conflicts: # rust-sdk/client/Cargo.toml # yarn.lock commit 3c32aceab195e55fb7d7240fe54e1ab76c9db7a1 Merge: 7424e40 18d5bcc Author: Wilhelm Thieme Date: Tue Sep 17 09:52:38 2024 +0800 Merge branch 'main' into wjthieme/utils-package # Conflicts: # docs/ts/package.json # yarn.lock commit 7424e40990adb38fa717b311762b027554800fc4 Author: Wilhelm Thieme Date: Fri Aug 30 22:31:55 2024 -0500 Format commit 4d627c45a8541d3c5c19a6bfb71bb6ea59a8958e Author: Wilhelm Thieme Date: Fri Aug 30 22:12:57 2024 -0500 Fix test commit 0dbd9dd07fd1c14171a8f5a86bccf33285d1cb4d Author: Wilhelm Thieme Date: Fri Aug 30 22:10:45 2024 -0500 More tick arrays commit a0834c19760991068b5d9b590123f19c02b98d7b Author: Wilhelm Thieme Date: Fri Aug 30 11:36:11 2024 -0500 Manifest and readme files commit c2cfe5771b82e933c52d35d03550d4abe149df7b Author: Wilhelm Thieme Date: Wed Aug 28 07:27:20 2024 -0400 Tweaks commit 4f637c65769b9f65fcfe4eaf469b642283988145 Author: Wilhelm Thieme Date: Thu Aug 22 13:00:51 2024 -0400 Fix failing tests commit 4ab7c35494f82cb82e7d344ddbfd6b768ba813fe Merge: a11aeff 261905d Author: Wilhelm Thieme Date: Thu Aug 22 12:03:55 2024 -0400 Merge branch 'main' into wjthieme/utils-package # Conflicts: # yarn.lock commit a11aeff51c0a191f3745bdc1b092cfd15fbc8179 Author: Wilhelm Thieme Date: Wed Aug 21 21:09:16 2024 -0400 Squash --- .github/actions/anchor/action.yml | 104 +- .github/workflows/checks.yml | 29 +- .github/workflows/docs.yml | 15 +- .github/workflows/publish.yml | 41 +- .husky/pre-commit | 2 +- Anchor.toml | 2 +- README.md | 10 +- docs/legacy/package.json | 1 + docs/ts/package.json | 1 + docs/whirlpool/docusaurus.config.js | 3 +- legacy-sdk/scripts/package.json | 1 - legacy-sdk/whirlpool/package.json | 2 + .../whirlpool/src/utils/public/price-math.ts | 4 +- .../close_bundled_position.test.ts | 2 +- ...ose_position_with_token_extensions.test.ts | 2 +- .../delete_position_bundle.test.ts | 2 +- .../bundled_position_management.test.ts | 2 +- .../integration/multi-ix/sparse_swap.test.ts | 10 +- .../integration/multi-ix/splash_pool.test.ts | 2 +- .../integration/open_bundled_position.test.ts | 2 +- .../tests/integration/open_position.test.ts | 2 +- .../open_position_with_metadata.test.ts | 2 +- ...pen_position_with_token_extensions.test.ts | 4 +- .../integration/set_reward_authority.test.ts | 2 +- ...est.ts => router-util-priceImpact.test.ts} | 0 ...t.ts => position-impl-collectFees.test.ts} | 8 +- ...s => position-impl-collectRewards.test.ts} | 8 +- .../whirlpools/swap/swap-edge-case.test.ts | 2 +- .../sdk/whirlpools/utils/fetcher-util.test.ts | 2 +- .../utils/token-extension-util.test.ts | 2 +- ...s => whirlpool-impl-closePosition.test.ts} | 6 +- ...collectFeesAndRewardsForPositions.test.ts} | 8 +- .../whirlpool/tests/utils/v2/token-2022.ts | 6 +- package.json | 8 +- programs/whirlpool/package.json | 4 +- rust-sdk/client/Cargo.lock | 31 + rust-sdk/client/Cargo.toml | 17 +- rust-sdk/client/package.json | 7 +- rust-sdk/client/src/core_types/mod.rs | 3 + rust-sdk/client/src/core_types/position.rs | 27 + rust-sdk/client/src/core_types/tick_array.rs | 24 + rust-sdk/client/src/core_types/whirlpool.rs | 28 + rust-sdk/client/src/lib.rs | 3 + rust-sdk/core/Cargo.lock | 492 ++ rust-sdk/core/Cargo.toml | 30 + rust-sdk/core/README.md | 1 + rust-sdk/core/package.json | 14 + rust-sdk/core/src/constants/bundle.rs | 8 + rust-sdk/core/src/constants/error.rs | 39 + rust-sdk/core/src/constants/mod.rs | 13 + rust-sdk/core/src/constants/pool.rs | 8 + rust-sdk/core/src/constants/swap.rs | 16 + rust-sdk/core/src/constants/tick.rs | 21 + rust-sdk/core/src/constants/token.rs | 1 + rust-sdk/core/src/lib.rs | 15 + rust-sdk/core/src/math/bundle.rs | 113 + rust-sdk/core/src/math/mod.rs | 17 + rust-sdk/core/src/math/position.rs | 191 + rust-sdk/core/src/math/price.rs | 170 + rust-sdk/core/src/math/tick.rs | 589 ++ rust-sdk/core/src/math/tick_array.rs | 257 + rust-sdk/core/src/math/token.rs | 608 ++ rust-sdk/core/src/quote/fees.rs | 210 + rust-sdk/core/src/quote/liquidity.rs | 1204 ++++ rust-sdk/core/src/quote/mod.rs | 9 + rust-sdk/core/src/quote/rewards.rs | 301 + rust-sdk/core/src/quote/swap.rs | 653 ++ rust-sdk/core/src/types/fees.rs | 11 + rust-sdk/core/src/types/liquidity.rs | 26 + rust-sdk/core/src/types/mod.rs | 27 + rust-sdk/core/src/types/pool.rs | 28 + rust-sdk/core/src/types/position.rs | 43 + rust-sdk/core/src/types/rewards.rs | 12 + rust-sdk/core/src/types/swap.rs | 24 + rust-sdk/core/src/types/tick.rs | 35 + rust-sdk/core/src/types/tick_array.rs | 122 + rust-sdk/core/src/types/token.rs | 24 + rust-sdk/core/src/types/u128.rs | 58 + rust-sdk/core/src/types/u64.rs | 11 + rust-sdk/macros/Cargo.lock | 47 + rust-sdk/macros/Cargo.toml | 18 + rust-sdk/macros/README.md | 1 + rust-sdk/macros/package.json | 11 + rust-sdk/macros/src/lib.rs | 30 + rust-sdk/macros/src/u64.rs | 11 + rust-sdk/macros/src/wasm_const.rs | 189 + rust-sdk/macros/src/wasm_enum.rs | 54 + rust-sdk/macros/src/wasm_fn.rs | 54 + rust-sdk/macros/src/wasm_struct.rs | 50 + rust-sdk/whirlpool/Cargo.lock | 32 + rust-sdk/whirlpool/Cargo.toml | 1 + rust-sdk/whirlpool/package.json | 4 +- rust-sdk/whirlpool/src/lib.rs | 1 + ts-sdk/client/package.json | 23 +- ts-sdk/client/src/index.ts | 1 + ts-sdk/client/src/pda/feeTier.ts | 21 + ts-sdk/client/src/pda/index.ts | 8 + ts-sdk/client/src/pda/oracle.ts | 12 + ts-sdk/client/src/pda/position.ts | 12 + ts-sdk/client/src/pda/positionBundle.ts | 26 + ts-sdk/client/src/pda/tickArray.ts | 17 + ts-sdk/client/src/pda/tokenBadge.ts | 17 + ts-sdk/client/src/pda/whirlpool.ts | 25 + .../src/pda/whirlpoolsConfigExtension.ts | 12 + ts-sdk/client/tests/gpa.test.ts | 31 +- ts-sdk/client/tests/pda.test.ts | 117 + ts-sdk/core/Cargo.lock | 310 + ts-sdk/core/Cargo.toml | 14 + ts-sdk/core/README.md | 1 + ts-sdk/core/package.json | 46 + ts-sdk/core/src/lib.rs | 1 + ts-sdk/core/tests/size.test.ts | 32 + ts-sdk/core/tests/smoke.test.ts | 184 + ts-sdk/core/tests/types.test.ts | 26 + ts-sdk/core/tsconfig.json | 7 + ts-sdk/lint/package.json | 2 +- ts-sdk/whirlpool/package.json | 28 +- ts-sdk/whirlpool/src/config.ts | 153 + ts-sdk/whirlpool/src/createPool.ts | 276 + ts-sdk/whirlpool/src/decreaseLiquidity.ts | 580 ++ ts-sdk/whirlpool/src/harvest.ts | 330 + ts-sdk/whirlpool/src/increaseLiquidity.ts | 593 ++ ts-sdk/whirlpool/src/index.ts | 10 +- ts-sdk/whirlpool/src/pool.ts | 255 + ts-sdk/whirlpool/src/position.ts | 162 + ts-sdk/whirlpool/src/swap.ts | 319 + ts-sdk/whirlpool/src/token.ts | 273 + ts-sdk/whirlpool/tests/assertInstruction.ts | 171 + ts-sdk/whirlpool/tests/config.test.ts | 82 + ts-sdk/whirlpool/tests/createPool.test.ts | 5 + .../whirlpool/tests/decreaseLiquidity.test.ts | 5 + ts-sdk/whirlpool/tests/e2e.test.ts | 5 + ts-sdk/whirlpool/tests/harvest.test.ts | 5 + .../whirlpool/tests/increaseLiquidity.test.ts | 5 + ts-sdk/whirlpool/tests/mockRpc.ts | 187 + ts-sdk/whirlpool/tests/pool.test.ts | 5 + ts-sdk/whirlpool/tests/position.test.ts | 5 + ts-sdk/whirlpool/tests/swap.test.ts | 5 + ts-sdk/whirlpool/tests/token.test.ts | 602 ++ yarn.lock | 5495 +++++++++-------- 140 files changed, 14233 insertions(+), 2613 deletions(-) rename legacy-sdk/whirlpool/tests/sdk/router/{router-util#priceImpact.test.ts => router-util-priceImpact.test.ts} (100%) rename legacy-sdk/whirlpool/tests/sdk/whirlpools/{position-impl#collectFees.test.ts => position-impl-collectFees.test.ts} (99%) rename legacy-sdk/whirlpool/tests/sdk/whirlpools/{position-impl#collectRewards.test.ts => position-impl-collectRewards.test.ts} (98%) rename legacy-sdk/whirlpool/tests/sdk/whirlpools/{whirlpool-impl#closePosition.test.ts => whirlpool-impl-closePosition.test.ts} (99%) rename legacy-sdk/whirlpool/tests/sdk/whirlpools/{whirlpool-impl#collectFeesAndRewardsForPositions.test.ts => whirlpool-impl-collectFeesAndRewardsForPositions.test.ts} (99%) create mode 100644 rust-sdk/client/src/core_types/mod.rs create mode 100644 rust-sdk/client/src/core_types/position.rs create mode 100644 rust-sdk/client/src/core_types/tick_array.rs create mode 100644 rust-sdk/client/src/core_types/whirlpool.rs create mode 100644 rust-sdk/core/Cargo.lock create mode 100644 rust-sdk/core/Cargo.toml create mode 100644 rust-sdk/core/README.md create mode 100644 rust-sdk/core/package.json create mode 100644 rust-sdk/core/src/constants/bundle.rs create mode 100644 rust-sdk/core/src/constants/error.rs create mode 100644 rust-sdk/core/src/constants/mod.rs create mode 100644 rust-sdk/core/src/constants/pool.rs create mode 100644 rust-sdk/core/src/constants/swap.rs create mode 100644 rust-sdk/core/src/constants/tick.rs create mode 100644 rust-sdk/core/src/constants/token.rs create mode 100644 rust-sdk/core/src/lib.rs create mode 100644 rust-sdk/core/src/math/bundle.rs create mode 100644 rust-sdk/core/src/math/mod.rs create mode 100644 rust-sdk/core/src/math/position.rs create mode 100644 rust-sdk/core/src/math/price.rs create mode 100644 rust-sdk/core/src/math/tick.rs create mode 100644 rust-sdk/core/src/math/tick_array.rs create mode 100644 rust-sdk/core/src/math/token.rs create mode 100644 rust-sdk/core/src/quote/fees.rs create mode 100644 rust-sdk/core/src/quote/liquidity.rs create mode 100644 rust-sdk/core/src/quote/mod.rs create mode 100644 rust-sdk/core/src/quote/rewards.rs create mode 100644 rust-sdk/core/src/quote/swap.rs create mode 100644 rust-sdk/core/src/types/fees.rs create mode 100644 rust-sdk/core/src/types/liquidity.rs create mode 100644 rust-sdk/core/src/types/mod.rs create mode 100644 rust-sdk/core/src/types/pool.rs create mode 100644 rust-sdk/core/src/types/position.rs create mode 100644 rust-sdk/core/src/types/rewards.rs create mode 100644 rust-sdk/core/src/types/swap.rs create mode 100644 rust-sdk/core/src/types/tick.rs create mode 100644 rust-sdk/core/src/types/tick_array.rs create mode 100644 rust-sdk/core/src/types/token.rs create mode 100644 rust-sdk/core/src/types/u128.rs create mode 100644 rust-sdk/core/src/types/u64.rs create mode 100644 rust-sdk/macros/Cargo.lock create mode 100644 rust-sdk/macros/Cargo.toml create mode 100644 rust-sdk/macros/README.md create mode 100644 rust-sdk/macros/package.json create mode 100644 rust-sdk/macros/src/lib.rs create mode 100644 rust-sdk/macros/src/u64.rs create mode 100644 rust-sdk/macros/src/wasm_const.rs create mode 100644 rust-sdk/macros/src/wasm_enum.rs create mode 100644 rust-sdk/macros/src/wasm_fn.rs create mode 100644 rust-sdk/macros/src/wasm_struct.rs create mode 100644 ts-sdk/client/src/pda/feeTier.ts create mode 100644 ts-sdk/client/src/pda/index.ts create mode 100644 ts-sdk/client/src/pda/oracle.ts create mode 100644 ts-sdk/client/src/pda/position.ts create mode 100644 ts-sdk/client/src/pda/positionBundle.ts create mode 100644 ts-sdk/client/src/pda/tickArray.ts create mode 100644 ts-sdk/client/src/pda/tokenBadge.ts create mode 100644 ts-sdk/client/src/pda/whirlpool.ts create mode 100644 ts-sdk/client/src/pda/whirlpoolsConfigExtension.ts create mode 100644 ts-sdk/client/tests/pda.test.ts create mode 100644 ts-sdk/core/Cargo.lock create mode 100644 ts-sdk/core/Cargo.toml create mode 100644 ts-sdk/core/README.md create mode 100644 ts-sdk/core/package.json create mode 100644 ts-sdk/core/src/lib.rs create mode 100644 ts-sdk/core/tests/size.test.ts create mode 100644 ts-sdk/core/tests/smoke.test.ts create mode 100644 ts-sdk/core/tests/types.test.ts create mode 100644 ts-sdk/core/tsconfig.json create mode 100644 ts-sdk/whirlpool/src/config.ts create mode 100644 ts-sdk/whirlpool/src/createPool.ts create mode 100644 ts-sdk/whirlpool/src/decreaseLiquidity.ts create mode 100644 ts-sdk/whirlpool/src/harvest.ts create mode 100644 ts-sdk/whirlpool/src/increaseLiquidity.ts create mode 100644 ts-sdk/whirlpool/src/pool.ts create mode 100644 ts-sdk/whirlpool/src/position.ts create mode 100644 ts-sdk/whirlpool/src/swap.ts create mode 100644 ts-sdk/whirlpool/src/token.ts create mode 100644 ts-sdk/whirlpool/tests/assertInstruction.ts create mode 100644 ts-sdk/whirlpool/tests/config.test.ts create mode 100644 ts-sdk/whirlpool/tests/createPool.test.ts create mode 100644 ts-sdk/whirlpool/tests/decreaseLiquidity.test.ts create mode 100644 ts-sdk/whirlpool/tests/e2e.test.ts create mode 100644 ts-sdk/whirlpool/tests/harvest.test.ts create mode 100644 ts-sdk/whirlpool/tests/increaseLiquidity.test.ts create mode 100644 ts-sdk/whirlpool/tests/mockRpc.ts create mode 100644 ts-sdk/whirlpool/tests/pool.test.ts create mode 100644 ts-sdk/whirlpool/tests/position.test.ts create mode 100644 ts-sdk/whirlpool/tests/swap.test.ts create mode 100644 ts-sdk/whirlpool/tests/token.test.ts diff --git a/.github/actions/anchor/action.yml b/.github/actions/anchor/action.yml index b34d179ed..e79bd174c 100644 --- a/.github/actions/anchor/action.yml +++ b/.github/actions/anchor/action.yml @@ -1,83 +1,69 @@ -name: 'Setup Anchor Development Environment' -description: 'Sets up the solana sdk using the specified version' +name: 'Setup Anchor' +description: 'Sets up an Anchor development environment.' branding: icon: anchor color: blue inputs: - anchor-version: - description: 'The version of anchor to use.' - required: false - default: 'v0.29.0' - rust-version: - description: 'The version of rust to use.' - required: false - default: '1.80' - solana-key: - description: 'The private key to use for the solana sdk.' - required: false solana-cluster: description: 'The cluster to use for the solana sdk.' required: false default: 'devnet' - run: - description: 'The command(s) to run.' + solana-key: + description: 'The private key to use for the solana sdk.' + required: false + rustc-version: + description: 'The version of rustc to use.' + default: 'v1.78.0' + node-version: + description: 'The version of node to use.' + default: 'v22.8.0' + solana-version: + description: 'The version of solana to use.' + default: 'v1.17.25' + anchor-version: + description: 'The version of anchor to use.' + default: 'v0.29.0' runs: using: "composite" steps: - - name: Shell Setup - run: | - touch run - chmod +x run - echo "#!/bin/bash" >> run - echo "set -xeo pipefail" >> run - echo "export RUST_LOG=" >> run - shell: bash - - name: Install Dependencies - run: | - echo "yarn" >> run - shell: bash - - name: Update rustc - run: | - echo "rustup install ${{ inputs.rust-version }}" >> run - echo "rustup default ${{ inputs.rust-version }}" >> run - shell: bash - - name: Configure Solana - run: | - echo "solana config set --url ${{ inputs.solana-cluster }}" >> run - shell: bash - - name: Configure Solana Key - if: ${{ !inputs.solana-key }} + - name: Setup rustc run: | - echo "solana-keygen new --no-bip39-passphrase" >> run + rust_version=${{ inputs.rustc-version }} + rustup toolchain install ${rust_version#v} + rustup default ${rust_version#v} + rustup component add rustfmt clippy shell: bash - - name: Configure Solana Key - if: ${{ inputs.solana-key }} + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node-version }} + - name: Install Solana CLI run: | - echo "echo \"${{ inputs.solana-key }}\" > ~/.config/solana/id.json" >> run + wget -qO- "https://release.anza.xyz/${{ inputs.solana-version }}/solana-release-x86_64-unknown-linux-gnu.tar.bz2" | tar -xvj + echo "$PWD/solana-release/bin" >> $GITHUB_PATH shell: bash - - name: Airdrop Solana - if: ${{ inputs.solana-key && inputs.solana-cluster == 'devnet' }} + - name: Install Anchor CLI run: | - echo "solana airdrop 1 || true" >> run + anchor_version=${{ inputs.anchor-version }} + npm install -g @coral-xyz/anchor-cli@${anchor_version#v} shell: bash - - name: Run Commands + - name: Configure Solana CLI run: | - echo "${{ inputs.run }}" >> run + solana config set --url ${{ inputs.solana-cluster }} + if [ -z "${{ inputs.solana-key }}" ]; then + solana-keygen new --no-bip39-passphrase + else + echo "${{ inputs.solana-key }}" > ~/.config/solana/id.json + fi + solana airdrop 1 || true shell: bash - - name: Log Commands + - name: Log Installed Tools run: | - echo "---" - cat run - echo "---" + echo "rustc: $(rustc --version)" + echo "node: $(node --version)" + echo "solana: $(solana --version)" + echo "anchor: $(anchor --version)" shell: bash - - name: Run Docker - run: | - docker run \ - --entrypoint '/workdir/run' \ - -v "$(pwd)":/workdir \ - backpackapp/build:${{ inputs.anchor-version }} - shell: bash - diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index c706469e1..8fee99971 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -2,7 +2,7 @@ name: Checks on: pull_request: - branches: [main] + branches: "*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -15,30 +15,33 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Build Packages + - name: Setup Anchor uses: ./.github/actions/anchor - with: - run: | - yarn build --output-style static + - name: Install dependencies + run: yarn install + - name: Build packages + run: yarn build --output-style static test: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Run Tests + - name: Setup Anchor uses: ./.github/actions/anchor - with: - run: | - yarn test --exclude legacy-sdk/whirlpool --output-style static + - name: Install dependencies + run: yarn install + - name: Run tests + run: yarn test --exclude legacy-sdk/whirlpool --output-style static lint: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Run Lint + - name: Setup Anchor uses: ./.github/actions/anchor - with: - run: | - yarn lint --output-style static + - name: Install dependencies + run: yarn install + - name: Run Lint + run: yarn lint --output-style static diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index fd48aa0cd..cb8cc4879 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -18,17 +18,18 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Setup Anchor + uses: ./.github/actions/anchor - name: Setup Github Pages uses: actions/configure-pages@v5 - - name: Build Docs - uses: ./.github/actions/anchor - with: - run: | - yarn build docs/whirlpool --output-style static - - name: Upload Artifact + - name: Install dependencies + run: yarn install + - name: Build docs + run: yarn build docs/whirlpool --output-style static + - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: ./docs/whirlpool/dist - - name: Deploy Artifact + - name: Deploy artifact id: deployment uses: actions/deploy-pages@v4 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 34c112168..15383ef97 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -19,18 +19,22 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Setup Anchor + uses: ./.github/actions/anchor - name: Set Version uses: ./.github/actions/version with: version: ${{ github.ref }} manifest-file: ts-sdk/${{ matrix.package }}/package.json - - name: Deploy npm - uses: ./.github/actions/anchor - with: - run: | - npm config set //registry.npmjs.org/:_authToken ${{ secrets.NPM_TOKEN }} && yarn - yarn build ts-sdk/${{ matrix.package }} --output-style static - cd ts-sdk/${{ matrix.package }} && npm publish --access public + - name: Setup npm + run: npm config set //registry.npmjs.org/:_authToken ${{ secrets.NPM_TOKEN }} + - name: Install dependencies + run: yarn install + - name: Build package + run: yarn build ts-sdk/${{ matrix.package }} --output-style static + - name: Publish package + working-directory: ts-sdk/${{ matrix.package }} + run: npm publish --access public cargo: strategy: @@ -44,18 +48,20 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Setup Anchor + uses: ./.github/actions/anchor - name: Set Version uses: ./.github/actions/version with: version: ${{ github.ref }} manifest-file: rust-sdk/${{ matrix.package }}/Cargo.toml - - name: Deploy cargo - uses: ./.github/actions/anchor - with: - run: | - export CARGO_REGISTRY_TOKEN=${{ secrets.CRATES_TOKEN }} - yarn build rust-sdk/${{ matrix.package }} --output-style static - cd rust-sdk/${{ matrix.package }} && cargo publish --allow-dirty + - name: Install dependencies + run: yarn install + - name: Build package + run: yarn build rust-sdk/${{ matrix.package }} --output-style static + - name: Publish package + working-directory: rust-sdk/${{ matrix.package }} + run: cargo publish --allow-dirty idl: runs-on: ubuntu-latest @@ -64,11 +70,10 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Build idl + - name: Setup Anchor uses: ./.github/actions/anchor - with: - run: | - anchor build + - name: Build idl + run: anchor build - name: Upload artifacts uses: actions/upload-artifact@v4 with: diff --git a/.husky/pre-commit b/.husky/pre-commit index 5a182ef10..1a2bd7ae1 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -yarn lint-staged +# yarn lint-staged diff --git a/Anchor.toml b/Anchor.toml index 116295309..4575a0159 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -9,7 +9,7 @@ cluster = "localnet" wallet = "~/.config/solana/id.json" [scripts] -test = "yarn ts-mocha --timeout 1000000 legacy-sdk/whirlpool/**/*.test.ts" +test = "yarn vitest run --test-timeout 1000000 --no-file-parallelism --globals legacy-sdk/whirlpool/tests" [test.validator] slots_per_epoch = "33" diff --git a/README.md b/README.md index 52e23c738..e40d4d342 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,11 @@ The program has been audited several times by different security firms. ***The new whirlpool SDKs are still in development and are not recommended for production use yet. Please see [Legacy](#legacy)*** -This repository contains several libraries that can be used to interact with the Whirlpools contract. For most purposes you can use the full library (`@orca-so/whirlpools` and `orca-whirlpools`). +This repository contains several libraries that can be used to interact with the Whirlpools contract. For most purposes you can use the full library (`@orca-so/whirlpools` and `orca_whirlpools`). For specific use-cases you can opt for integrating with lower level packages such as: -* `@orca-so/whirlpools-client` & `orca-whirlpools-client` - auto-generated client for the Whirlpools program that contains account, instruction and error parsing. -* `@orca-so/whirlpools-quoting` & `orca-whirlpools-quoting` - math lib used to calculate a quote for a given trade or liquidity action. -* `@orca-so/whirlpools-composite` & `orca-whirlpools-composite` - helper package for compositing instructions together for executing common actions. -* `@orca-so/whirlpools-utils` & `orca-whirlpools-utils` - utility and math functions used by other packages. +* `@orca-so/whirlpools-client` & `orca_whirlpools_client` - auto-generated client for the Whirlpools program that contains account, instruction and error parsing. +* `@orca-so/whirlpools-core` & `orca_whirlpools_core` - utility and math functions used by other packages. ### Legacy @@ -91,8 +89,6 @@ If you look closely, the commands just call individual commands specified in the If you want to stream the logs of a specific command you can add the `--output-style stream` flag to the command. This allows you to view the logs of the command as they are being produced which can be useful for longer running tasks like integration tests. ---- - # Support ### Questions diff --git a/docs/legacy/package.json b/docs/legacy/package.json index 3296730de..e1ca853b2 100644 --- a/docs/legacy/package.json +++ b/docs/legacy/package.json @@ -8,6 +8,7 @@ "clean": "rimraf dist" }, "devDependencies": { + "@orca-so/whirlpools": "*", "@orca-so/whirlpools-sdk": "*", "typedoc": "^0.26.10", "typescript": "^5.6.3" diff --git a/docs/ts/package.json b/docs/ts/package.json index 8dd6757fe..9ff6fd85d 100644 --- a/docs/ts/package.json +++ b/docs/ts/package.json @@ -9,6 +9,7 @@ }, "devDependencies": { "@orca-so/whirlpools": "*", + "@orca-so/whirlpools-sdk": "*", "typedoc": "^0.26.10", "typescript": "^5.6.3" } diff --git a/docs/whirlpool/docusaurus.config.js b/docs/whirlpool/docusaurus.config.js index e5ee40c0b..363eda938 100644 --- a/docs/whirlpool/docusaurus.config.js +++ b/docs/whirlpool/docusaurus.config.js @@ -32,7 +32,8 @@ export default { docs: { routeBasePath: "/", sidebarPath: "./sidebars.js", - editUrl: "https://github.com/orca-so/whirlpools/tree/main/docs/whirlpool", + editUrl: + "https://github.com/orca-so/whirlpools/tree/main/docs/whirlpool", }, theme: { customCss: "./static/index.css", diff --git a/legacy-sdk/scripts/package.json b/legacy-sdk/scripts/package.json index ec1efbab6..ab8bbb875 100644 --- a/legacy-sdk/scripts/package.json +++ b/legacy-sdk/scripts/package.json @@ -8,7 +8,6 @@ "@solana/web3.js": "^1.95.2" }, "devDependencies": { - "@types/mocha": "^10.0.9", "@types/mz": "^2.7.3", "mz": "^2.7.0", "typescript": "^5.6.3" diff --git a/legacy-sdk/whirlpool/package.json b/legacy-sdk/whirlpool/package.json index 7210b36c0..98372f3e5 100644 --- a/legacy-sdk/whirlpool/package.json +++ b/legacy-sdk/whirlpool/package.json @@ -21,6 +21,8 @@ "@orca-so/whirlpools-program": "*", "@solana/spl-token": "^0.4.8", "@solana/web3.js": "^1.90.0", + "@types/bn.js": "~5.1.6", + "@types/jest": "^29.5.13", "decimal.js": "^10.4.3", "typescript": "^5.6.3" }, diff --git a/legacy-sdk/whirlpool/src/utils/public/price-math.ts b/legacy-sdk/whirlpool/src/utils/public/price-math.ts index c1a290dba..b5d9adf31 100644 --- a/legacy-sdk/whirlpool/src/utils/public/price-math.ts +++ b/legacy-sdk/whirlpool/src/utils/public/price-math.ts @@ -208,11 +208,11 @@ export class PriceMath { .toDecimalPlaces(0); const lowerBoundSqrtPrice = BN.min( - BN.max(new BN(lowerBoundSqrtPriceDecimal.toString()), MIN_SQRT_PRICE_BN), + BN.max(new BN(lowerBoundSqrtPriceDecimal.toFixed(0)), MIN_SQRT_PRICE_BN), MAX_SQRT_PRICE_BN, ); const upperBoundSqrtPrice = BN.min( - BN.max(new BN(upperBoundSqrtPriceDecimal.toString()), MIN_SQRT_PRICE_BN), + BN.max(new BN(upperBoundSqrtPriceDecimal.toFixed(0)), MIN_SQRT_PRICE_BN), MAX_SQRT_PRICE_BN, ); diff --git a/legacy-sdk/whirlpool/tests/integration/close_bundled_position.test.ts b/legacy-sdk/whirlpool/tests/integration/close_bundled_position.test.ts index c5566d5b4..b8187549a 100644 --- a/legacy-sdk/whirlpool/tests/integration/close_bundled_position.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/close_bundled_position.test.ts @@ -47,7 +47,7 @@ describe("close_bundled_position", () => { let whirlpoolPda: PDA; const funderKeypair = anchor.web3.Keypair.generate(); - before(async () => { + beforeAll(async () => { poolInitInfo = (await initTestPool(ctx, TickSpacing.Standard)).poolInitInfo; whirlpoolPda = poolInitInfo.whirlpoolPda; await systemTransferTx( diff --git a/legacy-sdk/whirlpool/tests/integration/close_position_with_token_extensions.test.ts b/legacy-sdk/whirlpool/tests/integration/close_position_with_token_extensions.test.ts index f424ee4e9..c8a04197b 100644 --- a/legacy-sdk/whirlpool/tests/integration/close_position_with_token_extensions.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/close_position_with_token_extensions.test.ts @@ -44,7 +44,7 @@ describe("close_position_with_token_extensions", () => { let whirlpoolPda: PDA; const funderKeypair = anchor.web3.Keypair.generate(); - before(async () => { + beforeAll(async () => { poolInitInfo = (await initTestPool(ctx, TickSpacing.Standard)).poolInitInfo; whirlpoolPda = poolInitInfo.whirlpoolPda; await systemTransferTx( diff --git a/legacy-sdk/whirlpool/tests/integration/delete_position_bundle.test.ts b/legacy-sdk/whirlpool/tests/integration/delete_position_bundle.test.ts index fbca08bc2..7b130962d 100644 --- a/legacy-sdk/whirlpool/tests/integration/delete_position_bundle.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/delete_position_bundle.test.ts @@ -40,7 +40,7 @@ describe("delete_position_bundle", () => { let whirlpoolPda: PDA; const funderKeypair = anchor.web3.Keypair.generate(); - before(async () => { + beforeAll(async () => { poolInitInfo = (await initTestPool(ctx, TickSpacing.Standard)).poolInitInfo; whirlpoolPda = poolInitInfo.whirlpoolPda; await systemTransferTx( diff --git a/legacy-sdk/whirlpool/tests/integration/multi-ix/bundled_position_management.test.ts b/legacy-sdk/whirlpool/tests/integration/multi-ix/bundled_position_management.test.ts index 437c89709..9e0727fad 100644 --- a/legacy-sdk/whirlpool/tests/integration/multi-ix/bundled_position_management.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/multi-ix/bundled_position_management.test.ts @@ -54,7 +54,7 @@ describe("bundled position management tests", () => { const sleep = (second: number) => new Promise((resolve) => setTimeout(resolve, second * 1000)); - before(() => { + beforeAll(() => { anchor.setProvider(provider); const program = anchor.workspace.Whirlpool; const whirlpoolCtx = WhirlpoolContext.fromWorkspace(provider, program); diff --git a/legacy-sdk/whirlpool/tests/integration/multi-ix/sparse_swap.test.ts b/legacy-sdk/whirlpool/tests/integration/multi-ix/sparse_swap.test.ts index e256aedd1..7d41d0c4c 100644 --- a/legacy-sdk/whirlpool/tests/integration/multi-ix/sparse_swap.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/multi-ix/sparse_swap.test.ts @@ -55,7 +55,7 @@ describe("sparse swap tests", () => { let testCtx: SharedTestContext; - before(() => { + beforeAll(() => { anchor.setProvider(provider); const program = anchor.workspace.Whirlpool; const whirlpoolCtx = WhirlpoolContext.fromWorkspace(provider, program); @@ -1203,7 +1203,7 @@ describe("sparse swap tests", () => { } let referenceResult: { quote: SwapQuote; poolData: WhirlpoolData }; - before(async () => { + beforeAll(async () => { referenceResult = await runSwap(true, true, true, false); }); @@ -1366,7 +1366,7 @@ describe("sparse swap tests", () => { } let referenceResult: { quote: SwapQuote; poolData: WhirlpoolData }; - before(async () => { + beforeAll(async () => { referenceResult = await runSwap(true, true, true, false); }); @@ -1687,7 +1687,7 @@ describe("sparse swap tests", () => { quote1: SwapQuote; poolData1: WhirlpoolData; }; - before(async () => { + beforeAll(async () => { referenceResult = await runSwap(true, true, true, false); }); @@ -2022,7 +2022,7 @@ describe("sparse swap tests", () => { quote1: SwapQuote; poolData1: WhirlpoolData; }; - before(async () => { + beforeAll(async () => { referenceResult = await runSwap(true, true, true, false); }); diff --git a/legacy-sdk/whirlpool/tests/integration/multi-ix/splash_pool.test.ts b/legacy-sdk/whirlpool/tests/integration/multi-ix/splash_pool.test.ts index f00422786..c599d4228 100644 --- a/legacy-sdk/whirlpool/tests/integration/multi-ix/splash_pool.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/multi-ix/splash_pool.test.ts @@ -48,7 +48,7 @@ describe("splash pool tests", () => { let testCtx: SharedTestContext; - before(() => { + beforeAll(() => { anchor.setProvider(provider); const program = anchor.workspace.Whirlpool; const whirlpoolCtx = WhirlpoolContext.fromWorkspace(provider, program); diff --git a/legacy-sdk/whirlpool/tests/integration/open_bundled_position.test.ts b/legacy-sdk/whirlpool/tests/integration/open_bundled_position.test.ts index 0df191725..cf86b5237 100644 --- a/legacy-sdk/whirlpool/tests/integration/open_bundled_position.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/open_bundled_position.test.ts @@ -57,7 +57,7 @@ describe("open_bundled_position", () => { let fullRangeOnlyWhirlpoolPda: PDA; const funderKeypair = anchor.web3.Keypair.generate(); - before(async () => { + beforeAll(async () => { poolInitInfo = (await initTestPool(ctx, TickSpacing.Standard)).poolInitInfo; whirlpoolPda = poolInitInfo.whirlpoolPda; diff --git a/legacy-sdk/whirlpool/tests/integration/open_position.test.ts b/legacy-sdk/whirlpool/tests/integration/open_position.test.ts index 15a926ee0..d120d9180 100644 --- a/legacy-sdk/whirlpool/tests/integration/open_position.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/open_position.test.ts @@ -51,7 +51,7 @@ describe("open_position", () => { let fullRangeOnlyWhirlpoolPda: PDA; const funderKeypair = anchor.web3.Keypair.generate(); - before(async () => { + beforeAll(async () => { poolInitInfo = (await initTestPool(ctx, TickSpacing.Standard)).poolInitInfo; whirlpoolPda = poolInitInfo.whirlpoolPda; diff --git a/legacy-sdk/whirlpool/tests/integration/open_position_with_metadata.test.ts b/legacy-sdk/whirlpool/tests/integration/open_position_with_metadata.test.ts index e30360f6e..9599dd2ea 100644 --- a/legacy-sdk/whirlpool/tests/integration/open_position_with_metadata.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/open_position_with_metadata.test.ts @@ -62,7 +62,7 @@ describe("open_position_with_metadata", () => { let fullRangeOnlyWhirlpoolPda: PDA; const funderKeypair = anchor.web3.Keypair.generate(); - before(async () => { + beforeAll(async () => { poolInitInfo = (await initTestPool(ctx, TickSpacing.Standard)).poolInitInfo; whirlpoolPda = poolInitInfo.whirlpoolPda; diff --git a/legacy-sdk/whirlpool/tests/integration/open_position_with_token_extensions.test.ts b/legacy-sdk/whirlpool/tests/integration/open_position_with_token_extensions.test.ts index 5eacd46a1..b656833ef 100644 --- a/legacy-sdk/whirlpool/tests/integration/open_position_with_token_extensions.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/open_position_with_token_extensions.test.ts @@ -61,7 +61,7 @@ describe("open_position_with_token_extensions", () => { let whirlpoolPda: PDA; const funderKeypair = anchor.web3.Keypair.generate(); - before(async () => { + beforeAll(async () => { poolInitInfo = (await initTestPool(ctx, TickSpacing.Standard)).poolInitInfo; whirlpoolPda = poolInitInfo.whirlpoolPda; await systemTransferTx( @@ -411,7 +411,7 @@ describe("open_position_with_token_extensions", () => { let defaultParams: OpenPositionWithTokenExtensionsParams; let defaultMint: Keypair; - before(async () => { + beforeAll(async () => { const { params, mint } = await generateDefaultOpenPositionWithTokenExtensionsParams( ctx, whirlpoolPda.publicKey, diff --git a/legacy-sdk/whirlpool/tests/integration/set_reward_authority.test.ts b/legacy-sdk/whirlpool/tests/integration/set_reward_authority.test.ts index 9fd8b7c06..bff7484c1 100644 --- a/legacy-sdk/whirlpool/tests/integration/set_reward_authority.test.ts +++ b/legacy-sdk/whirlpool/tests/integration/set_reward_authority.test.ts @@ -136,7 +136,7 @@ describe("set_reward_authority", () => { }); function generateKeypairs(n: number): anchor.web3.Keypair[] { - const keypairs = []; + const keypairs: anchor.web3.Keypair[] = []; for (let i = 0; i < n; i++) { keypairs.push(anchor.web3.Keypair.generate()); } diff --git a/legacy-sdk/whirlpool/tests/sdk/router/router-util#priceImpact.test.ts b/legacy-sdk/whirlpool/tests/sdk/router/router-util-priceImpact.test.ts similarity index 100% rename from legacy-sdk/whirlpool/tests/sdk/router/router-util#priceImpact.test.ts rename to legacy-sdk/whirlpool/tests/sdk/router/router-util-priceImpact.test.ts diff --git a/legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl#collectFees.test.ts b/legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl-collectFees.test.ts similarity index 99% rename from legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl#collectFees.test.ts rename to legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl-collectFees.test.ts index 2637b1067..43cc392f9 100644 --- a/legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl#collectFees.test.ts +++ b/legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl-collectFees.test.ts @@ -35,7 +35,7 @@ describe("PositionImpl#collectFees()", () => { const tickSpacing = TickSpacing.Standard; const liquidityAmount = new BN(10_000_000); - before(() => { + beforeAll(() => { const provider = anchor.AnchorProvider.local( undefined, defaultConfirmOptions, @@ -145,7 +145,7 @@ describe("PositionImpl#collectFees()", () => { assert.ok(quote.feeOwedA.gtn(0) || quote.feeOwedB.gtn(0)); } - context("when the whirlpool is SPL-only", () => { + describe("when the whirlpool is SPL-only", () => { it("should collect fees", async () => { const fixture = await new WhirlpoolTestFixture(testCtx.whirlpoolCtx).init( { @@ -340,7 +340,7 @@ describe("PositionImpl#collectFees()", () => { }); }); - context("when the whirlpool is SOL-SPL", () => { + describe("when the whirlpool is SOL-SPL", () => { it("should collect fees", async () => { const fixture = await new WhirlpoolTestFixture(testCtx.whirlpoolCtx).init( { @@ -564,7 +564,7 @@ describe("PositionImpl#collectFees()", () => { assert.ok(quote.feeOwedA.gtn(0) || quote.feeOwedB.gtn(0)); } - context("when the whirlpool is SPL-only (TokenExtension)", () => { + describe("when the whirlpool is SPL-only (TokenExtension)", () => { it("should collect fees", async () => { const fixture = await new WhirlpoolTestFixtureV2( testCtx.whirlpoolCtx, diff --git a/legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl#collectRewards.test.ts b/legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl-collectRewards.test.ts similarity index 98% rename from legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl#collectRewards.test.ts rename to legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl-collectRewards.test.ts index 43b2c899d..aff6598cd 100644 --- a/legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl#collectRewards.test.ts +++ b/legacy-sdk/whirlpool/tests/sdk/whirlpools/position-impl-collectRewards.test.ts @@ -34,7 +34,7 @@ describe("PositionImpl#collectRewards()", () => { const tickSpacing = TickSpacing.Standard; const liquidityAmount = new BN(10_000_000); - before(() => { + beforeAll(() => { const provider = anchor.AnchorProvider.local( undefined, defaultConfirmOptions, @@ -52,7 +52,7 @@ describe("PositionImpl#collectRewards()", () => { }; }); - context("when the whirlpool is SPL-only", () => { + describe("when the whirlpool is SPL-only", () => { it("should collect rewards", async () => { const fixture = await new WhirlpoolTestFixture(testCtx.whirlpoolCtx).init( { @@ -245,7 +245,7 @@ describe("PositionImpl#collectRewards()", () => { }); }); - context("when the whirlpool is SOL-SPL", () => { + describe("when the whirlpool is SOL-SPL", () => { it("should collect rewards", async () => { const fixture = await new WhirlpoolTestFixture(testCtx.whirlpoolCtx).init( { @@ -338,7 +338,7 @@ describe("PositionImpl#collectRewards()", () => { }); }); - context("when the whirlpool is SPL-only (TokenExtension)", () => { + describe("when the whirlpool is SPL-only (TokenExtension)", () => { it("should collect rewards", async () => { const fixture = await new WhirlpoolTestFixtureV2( testCtx.whirlpoolCtx, diff --git a/legacy-sdk/whirlpool/tests/sdk/whirlpools/swap/swap-edge-case.test.ts b/legacy-sdk/whirlpool/tests/sdk/whirlpools/swap/swap-edge-case.test.ts index 41030c9eb..0d1151f4c 100644 --- a/legacy-sdk/whirlpool/tests/sdk/whirlpools/swap/swap-edge-case.test.ts +++ b/legacy-sdk/whirlpool/tests/sdk/whirlpools/swap/swap-edge-case.test.ts @@ -7,12 +7,12 @@ import { WhirlpoolContext, buildWhirlpoolClient, swapQuoteByInputToken, + swapQuoteByOutputToken } from "../../../../src"; import { IGNORE_CACHE } from "../../../../src/network/public/fetcher"; import { defaultConfirmOptions } from "../../../utils/const"; import { NATIVE_MINT } from "@solana/spl-token"; import { WhirlpoolTestFixture } from "../../../utils/fixture"; -import { swapQuoteByOutputToken } from "../../../../dist"; import { SystemInstruction } from "@solana/web3.js"; import { SwapUtils } from "../../../../dist/utils/public/swap-utils"; diff --git a/legacy-sdk/whirlpool/tests/sdk/whirlpools/utils/fetcher-util.test.ts b/legacy-sdk/whirlpool/tests/sdk/whirlpools/utils/fetcher-util.test.ts index e30171836..6d6ef1fea 100644 --- a/legacy-sdk/whirlpool/tests/sdk/whirlpools/utils/fetcher-util.test.ts +++ b/legacy-sdk/whirlpool/tests/sdk/whirlpools/utils/fetcher-util.test.ts @@ -31,7 +31,7 @@ describe("fetcher util tests", () => { const isolatedWallet = new NodeWallet(isolatedOwnerKeypair); const ctx = WhirlpoolContext.from(globalCtx.connection, isolatedWallet, globalCtx.program.programId); const fetcher = ctx.fetcher; - before(async () => { + beforeAll(async () => { await systemTransferTx( provider, isolatedOwnerKeypair.publicKey, diff --git a/legacy-sdk/whirlpool/tests/sdk/whirlpools/utils/token-extension-util.test.ts b/legacy-sdk/whirlpool/tests/sdk/whirlpools/utils/token-extension-util.test.ts index 504d39335..e24797c3c 100644 --- a/legacy-sdk/whirlpool/tests/sdk/whirlpools/utils/token-extension-util.test.ts +++ b/legacy-sdk/whirlpool/tests/sdk/whirlpools/utils/token-extension-util.test.ts @@ -35,7 +35,7 @@ describe("TokenExtensionUtil tests", () => { return true; } - before(async () => { + beforeAll(async () => { const vaultStartBalance = 1_000_000; const lowerTickIndex = -1280, upperTickIndex = 1280, diff --git a/legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl#closePosition.test.ts b/legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl-closePosition.test.ts similarity index 99% rename from legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl#closePosition.test.ts rename to legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl-closePosition.test.ts index 2072593d1..f71f0aa72 100644 --- a/legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl#closePosition.test.ts +++ b/legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl-closePosition.test.ts @@ -44,7 +44,7 @@ describe("WhirlpoolImpl#closePosition()", () => { const tickSpacing = TickSpacing.Standard; const liquidityAmount = new BN(10_000_000); - before(() => { + beforeAll(() => { const provider = anchor.AnchorProvider.local( undefined, defaultConfirmOptions, @@ -311,7 +311,7 @@ describe("WhirlpoolImpl#closePosition()", () => { } } - context("when the whirlpool is SPL-only", () => { + describe("when the whirlpool is SPL-only", () => { const tokenTraitVariations: { tokenTraitA: TokenTrait; tokenTraitB: TokenTrait; @@ -638,7 +638,7 @@ describe("WhirlpoolImpl#closePosition()", () => { }); }); - context("when the whirlpool is SOL-SPL", () => { + describe("when the whirlpool is SOL-SPL", () => { it("should close a position with liquidity, fees, and rewards", async () => { const fixture = await new WhirlpoolTestFixture(testCtx.whirlpoolCtx).init( { diff --git a/legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl#collectFeesAndRewardsForPositions.test.ts b/legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl-collectFeesAndRewardsForPositions.test.ts similarity index 99% rename from legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl#collectFeesAndRewardsForPositions.test.ts rename to legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl-collectFeesAndRewardsForPositions.test.ts index fc3fa5703..a77bef29c 100644 --- a/legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl#collectFeesAndRewardsForPositions.test.ts +++ b/legacy-sdk/whirlpool/tests/sdk/whirlpools/whirlpool-impl-collectFeesAndRewardsForPositions.test.ts @@ -57,7 +57,7 @@ describe("WhirlpoolImpl#collectFeesAndRewardsForPositions()", () => { const sleep = (second: number) => new Promise((resolve) => setTimeout(resolve, second * 1000)); - before(() => { + beforeAll(() => { const provider = anchor.AnchorProvider.local( undefined, defaultConfirmOptions, @@ -517,7 +517,7 @@ describe("WhirlpoolImpl#collectFeesAndRewardsForPositions()", () => { } } - context("when the whirlpool is SPL-only", () => { + describe("when the whirlpool is SPL-only", () => { it("should collect fees and rewards, create all ATAs", async () => { const tokenAIsNative = false; const ataExists = false; @@ -537,7 +537,7 @@ describe("WhirlpoolImpl#collectFeesAndRewardsForPositions()", () => { }); }); - context("when the whirlpool is SOL-SPL", () => { + describe("when the whirlpool is SOL-SPL", () => { it("should collect fees and rewards, create all ATAs", async () => { const tokenAIsNative = true; const ataExists = false; @@ -557,7 +557,7 @@ describe("WhirlpoolImpl#collectFeesAndRewardsForPositions()", () => { }); }); - context("when the whirlpool is TokenExtension-TokenExtension", () => { + describe("when the whirlpool is TokenExtension-TokenExtension", () => { async function accrueFeesV2(fixture: WhirlpoolTestFixtureV2) { const ctx = testCtx.whirlpoolCtx; const { diff --git a/legacy-sdk/whirlpool/tests/utils/v2/token-2022.ts b/legacy-sdk/whirlpool/tests/utils/v2/token-2022.ts index f8b0fd17e..ef5a1797a 100644 --- a/legacy-sdk/whirlpool/tests/utils/v2/token-2022.ts +++ b/legacy-sdk/whirlpool/tests/utils/v2/token-2022.ts @@ -361,8 +361,8 @@ async function createMintInstructions( const groupData: TokenGroup = { mint, updateAuthority: authority, - maxSize: 10, - size: 10, + maxSize: 10n, + size: 10n, }; const tokenGroupSize = packTokenGroup(groupData).length; @@ -386,7 +386,7 @@ async function createMintInstructions( const groupMemberData: TokenGroupMember = { mint: mint, group: mint, - memberNumber: 10, + memberNumber: 10n, }; const tokenGroupMemberSize = packTokenGroupMember(groupMemberData).length; diff --git a/package.json b/package.json index 66051ef34..e42b7c27a 100644 --- a/package.json +++ b/package.json @@ -13,17 +13,13 @@ "prepare": "husky install" }, "devDependencies": { - "@types/bn.js": "~5.1.6", - "@types/mocha": "^10.0.9", "@types/node": "^22.7.6", - "@types/sinon": "^17.0.3", "husky": "^9.1.6", "lint-staged": "^15.2.10", - "mocha": "^10.7.3", "nx": "^20.0.2", "rimraf": "^6.0.1", - "sinon": "^19.0.2", - "ts-mocha": "^10.0.0" + "tsup": "^8.3.0", + "vitest": "^2.1.3" }, "workspaces": [ "programs/*", diff --git a/programs/whirlpool/package.json b/programs/whirlpool/package.json index 466d11e20..346166e8c 100644 --- a/programs/whirlpool/package.json +++ b/programs/whirlpool/package.json @@ -5,8 +5,8 @@ "scripts": { "build": "anchor build -p whirlpool", "test": "cargo test -p whirlpool --lib", - "format": "cargo clippy -p whirlpool --fix --allow-dirty --allow-staged -- -D clippy::all && cargo fmt -p whirlpool", - "lint": "cargo clippy -p whirlpool -- -D clippy::all", + "format": "cargo clippy -p whirlpool --fix --allow-dirty --allow-staged && cargo fmt -p whirlpool", + "lint": "cargo clippy -p whirlpool", "clean": "anchor clean" } } diff --git a/rust-sdk/client/Cargo.lock b/rust-sdk/client/Cargo.lock index 0b6bcb464..7b613e4f2 100644 --- a/rust-sdk/client/Cargo.lock +++ b/rust-sdk/client/Cargo.lock @@ -837,6 +837,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + [[package]] name = "feature-probe" version = "0.1.1" @@ -1073,6 +1079,12 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libsecp256k1" version = "0.6.0" @@ -1238,12 +1250,31 @@ dependencies = [ "borsh 0.10.3", "num-derive", "num-traits", + "orca_whirlpools_core", "serde", "serde_with", "solana-program", "thiserror", ] +[[package]] +name = "orca_whirlpools_core" +version = "0.1.0" +dependencies = [ + "ethnum", + "libm", + "orca_whirlpools_macros", +] + +[[package]] +name = "orca_whirlpools_macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + [[package]] name = "parking_lot" version = "0.12.3" diff --git a/rust-sdk/client/Cargo.toml b/rust-sdk/client/Cargo.toml index a44ffe980..3900dac6f 100644 --- a/rust-sdk/client/Cargo.toml +++ b/rust-sdk/client/Cargo.toml @@ -12,17 +12,20 @@ authors = ["team@orca.so"] edition = "2021" [features] +default = ["core-types"] anchor = ["dep:anchor-lang"] anchor-idl-build = [] test-sbf = [] +core-types = ["dep:orca_whirlpools_core"] serde = ["dep:serde", "dep:serde_with"] [dependencies] -anchor-lang = { version = "^0.30.0", optional = true } -borsh = { version = "^0.10.3" } -num-derive = { version = "^0.4.2" } -num-traits = { version = "^0.2.19" } -solana-program = { version = "^1.18.21" } -thiserror = { version = "^1.0.64" } -serde = { version = "^1.0", features = ["derive"], optional = true } +anchor-lang = { version = "^0.30", optional = true } +borsh = { version = "^0.10" } +num-derive = { version = "^0.4" } +num-traits = { version = "^0.2" } +orca_whirlpools_core = { path = "../core", optional = true } +serde = { version = "^1", features = ["derive"], optional = true } serde_with = { version = "^3.10", optional = true } +solana-program = { version = "^1.18" } +thiserror = { version = "^1" } diff --git a/rust-sdk/client/package.json b/rust-sdk/client/package.json index 7ef8d36eb..0d13a9540 100644 --- a/rust-sdk/client/package.json +++ b/rust-sdk/client/package.json @@ -5,13 +5,14 @@ "scripts": { "build": "node ./kinobi.js && cargo build", "test": "cargo test --lib", - "format": "cargo clippy --fix --allow-dirty --allow-staged -- -D clippy::all && cargo fmt", - "lint": "cargo clippy -- -D clippy::all", + "format": "cargo clippy --fix --allow-dirty --allow-staged && cargo fmt", + "lint": "cargo clippy", "clean": "cargo clean" }, "devDependencies": { "@kinobi-so/nodes-from-anchor": "^0.22.0", "@kinobi-so/renderers-rust": "^0.22.0", - "@orca-so/whirlpools-program": "*" + "@orca-so/whirlpools-program": "*", + "@orca-so/whirlpools-rust-core": "*" } } diff --git a/rust-sdk/client/src/core_types/mod.rs b/rust-sdk/client/src/core_types/mod.rs new file mode 100644 index 000000000..a7b38f239 --- /dev/null +++ b/rust-sdk/client/src/core_types/mod.rs @@ -0,0 +1,3 @@ +mod position; +mod tick_array; +mod whirlpool; diff --git a/rust-sdk/client/src/core_types/position.rs b/rust-sdk/client/src/core_types/position.rs new file mode 100644 index 000000000..f23ed3e87 --- /dev/null +++ b/rust-sdk/client/src/core_types/position.rs @@ -0,0 +1,27 @@ +use orca_whirlpools_core::{PositionFacade, PositionRewardInfoFacade}; + +use crate::{accounts::Position, generated::types::PositionRewardInfo}; + +impl From for PositionFacade { + fn from(val: Position) -> Self { + PositionFacade { + liquidity: val.liquidity, + tick_lower_index: val.tick_lower_index, + tick_upper_index: val.tick_upper_index, + fee_growth_checkpoint_a: val.fee_growth_checkpoint_a, + fee_growth_checkpoint_b: val.fee_growth_checkpoint_b, + fee_owed_a: val.fee_owed_a, + fee_owed_b: val.fee_owed_b, + reward_infos: val.reward_infos.map(|info| info.into()), + } + } +} + +impl From for PositionRewardInfoFacade { + fn from(val: PositionRewardInfo) -> Self { + PositionRewardInfoFacade { + growth_inside_checkpoint: val.growth_inside_checkpoint, + amount_owed: val.amount_owed, + } + } +} diff --git a/rust-sdk/client/src/core_types/tick_array.rs b/rust-sdk/client/src/core_types/tick_array.rs new file mode 100644 index 000000000..7215f2f4b --- /dev/null +++ b/rust-sdk/client/src/core_types/tick_array.rs @@ -0,0 +1,24 @@ +use orca_whirlpools_core::{TickArrayFacade, TickFacade}; + +use crate::{accounts::TickArray, generated::types::Tick}; + +impl From for TickArrayFacade { + fn from(val: TickArray) -> Self { + TickArrayFacade { + start_tick_index: val.start_tick_index, + ticks: val.ticks.map(|tick| tick.into()), + } + } +} + +impl From for TickFacade { + fn from(val: Tick) -> Self { + TickFacade { + liquidity_net: val.liquidity_net, + initialized: val.initialized, + fee_growth_outside_a: val.fee_growth_outside_a, + fee_growth_outside_b: val.fee_growth_outside_b, + reward_growths_outside: val.reward_growths_outside, + } + } +} diff --git a/rust-sdk/client/src/core_types/whirlpool.rs b/rust-sdk/client/src/core_types/whirlpool.rs new file mode 100644 index 000000000..e60e6ba79 --- /dev/null +++ b/rust-sdk/client/src/core_types/whirlpool.rs @@ -0,0 +1,28 @@ +use orca_whirlpools_core::{WhirlpoolFacade, WhirlpoolRewardInfoFacade}; + +use crate::{accounts::Whirlpool, generated::types::WhirlpoolRewardInfo}; + +impl From for WhirlpoolFacade { + fn from(val: Whirlpool) -> Self { + WhirlpoolFacade { + tick_spacing: val.tick_spacing, + fee_rate: val.fee_rate, + liquidity: val.liquidity, + sqrt_price: val.sqrt_price, + tick_current_index: val.tick_current_index, + fee_growth_global_a: val.fee_growth_global_a, + fee_growth_global_b: val.fee_growth_global_b, + reward_last_updated_timestamp: val.reward_last_updated_timestamp, + reward_infos: val.reward_infos.map(|info| info.into()), + } + } +} + +impl From for WhirlpoolRewardInfoFacade { + fn from(val: WhirlpoolRewardInfo) -> Self { + WhirlpoolRewardInfoFacade { + emissions_per_second_x64: val.emissions_per_second_x64, + growth_global_x64: val.growth_global_x64, + } + } +} diff --git a/rust-sdk/client/src/lib.rs b/rust-sdk/client/src/lib.rs index 10aad6f9c..5773826da 100644 --- a/rust-sdk/client/src/lib.rs +++ b/rust-sdk/client/src/lib.rs @@ -1,4 +1,7 @@ mod generated; +#[cfg(feature = "core-types")] +mod core_types; + pub use generated::programs::WHIRLPOOL_ID as ID; pub use generated::*; diff --git a/rust-sdk/core/Cargo.lock b/rust-sdk/core/Cargo.lock new file mode 100644 index 000000000..9ecc95dc1 --- /dev/null +++ b/rust-sdk/core/Cargo.lock @@ -0,0 +1,492 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "dos-cp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea38e2b4c8238a6ab3939a92df9c6a4566ee1b61d6f854c876d293dd71c8fa68" +dependencies = [ + "either", + "exit-no-std", + "iter-identify_first_last", + "panicking", + "pc-ints", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "errno-no-std" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fdcf14936c837bfd4be0770bb6b9a0df31ddfb5d53a6e6f37d6f07ec4ca90cd" +dependencies = [ + "document-features", + "errno-sys", + "libc", + "widestring", + "winapi", +] + +[[package]] +name = "errno-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f7083207e75d4435df450dc6413612d97fe5a441477aba02484f9f7f77057e" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + +[[package]] +name = "exit-no-std" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd5f513f5e291767d1a48311655cd6980305945027c0d8ad31c1081aa7cb7a" +dependencies = [ + "libc", + "pc-ints", + "winapi", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "iter-identify_first_last" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91506f15038dff631f051ed27b43954375772a20d62785f0d8c7a830e1f765eb" +dependencies = [ + "document-features", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "orca_whirlpools_core" +version = "0.1.0" +dependencies = [ + "approx", + "ethnum", + "js-sys", + "libm", + "orca_whirlpools_macros", + "print-no-std", + "serde", + "serde-big-array", + "serde-wasm-bindgen 0.6.5", + "tsify", + "wasm-bindgen", +] + +[[package]] +name = "orca_whirlpools_macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "panicking" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21eb594cd667adf943bf4617e74ca71e2f4041f2fa630d5fc7be9314a1b480de" + +[[package]] +name = "pc-ints" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfa325ecd8dfc61925ef42dd711b5ea0bb9ef13e13056eefb9531828a18606e" +dependencies = [ + "memoffset", +] + +[[package]] +name = "print-no-std" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4617895c4a5787cff6720529173d06c1426925da4910638e66731557e847ba10" +dependencies = [ + "dos-cp", + "errno-no-std", + "iter-identify_first_last", + "libc", + "winapi", +] + +[[package]] +name = "proc-macro2" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.207" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.207" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde-wasm-bindgen 0.5.0", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/rust-sdk/core/Cargo.toml b/rust-sdk/core/Cargo.toml new file mode 100644 index 000000000..b8503fe4b --- /dev/null +++ b/rust-sdk/core/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "orca_whirlpools_core" +version = "0.1.0" +description = "Orca's core rust package." +documentation = "https://orca-so.github.io/whirlpools/" +homepage = "https://orca.so" +repository = "https://github.com/orca-so/whirlpools" +license = "Apache-2.0" +keywords = ["solana", "crypto", "defi", "dex", "amm"] +edition = "2021" + +[features] +default = ["floats"] +wasm = ["dep:wasm-bindgen", "dep:serde", "dep:serde-big-array", "dep:serde-wasm-bindgen", "dep:js-sys", "dep:tsify"] +floats = ["dep:libm"] + +[dependencies] +ethnum = { version = "^1.5" } +libm = { version = "^0.2", optional = true } +orca_whirlpools_macros = { path = "../macros" } +wasm-bindgen = { version = "^0.2", optional = true } +serde = { version = "^1", features = ["derive"], optional = true } +serde-big-array = { version = "^0.5", optional = true } +serde-wasm-bindgen = { version = "^0.6", optional = true } +js-sys = { version = "^0.3", optional = true } +tsify = { version = "^0.4", features = ["js"], optional = true } + +[dev-dependencies] +print-no-std = { version = "^0.1"} +approx = { version = "^0.3" } diff --git a/rust-sdk/core/README.md b/rust-sdk/core/README.md new file mode 100644 index 000000000..a679c3499 --- /dev/null +++ b/rust-sdk/core/README.md @@ -0,0 +1 @@ +# Orca Whirlpools Rust Core diff --git a/rust-sdk/core/package.json b/rust-sdk/core/package.json new file mode 100644 index 000000000..b0474a308 --- /dev/null +++ b/rust-sdk/core/package.json @@ -0,0 +1,14 @@ +{ + "name": "@orca-so/whirlpools-rust-core", + "version": "0.0.1", + "scripts": { + "build": "cargo build -p orca_whirlpools_core", + "test": "cargo test -p orca_whirlpools_core --lib", + "format": "cargo clippy --fix --allow-dirty --allow-staged && cargo fmt", + "lint": "cargo clippy", + "clean": "cargo clean -p orca_whirlpools_core" + }, + "devDependencies": { + "@orca-so/whirlpools-rust-macros": "*" + } +} diff --git a/rust-sdk/core/src/constants/bundle.rs b/rust-sdk/core/src/constants/bundle.rs new file mode 100644 index 000000000..a847ad56c --- /dev/null +++ b/rust-sdk/core/src/constants/bundle.rs @@ -0,0 +1,8 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +/// The maximum number of positions in a position bundle. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const POSITION_BUNDLE_SIZE: usize = 256; diff --git a/rust-sdk/core/src/constants/error.rs b/rust-sdk/core/src/constants/error.rs new file mode 100644 index 000000000..0c40a62ae --- /dev/null +++ b/rust-sdk/core/src/constants/error.rs @@ -0,0 +1,39 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +pub type ErrorCode = u16; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const TICK_ARRAY_NOT_EVENLY_SPACED: ErrorCode = 9000; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const TICK_INDEX_OUT_OF_BOUNDS: ErrorCode = 9001; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const INVALID_TICK_INDEX: ErrorCode = 9002; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const ARITHMETIC_OVERFLOW: ErrorCode = 9003; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const AMOUNT_EXCEEDS_MAX_U64: ErrorCode = 9004; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const SQRT_PRICE_OUT_OF_BOUNDS: ErrorCode = 9005; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const TICK_SEQUENCE_EMPTY: ErrorCode = 9006; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const SQRT_PRICE_LIMIT_OUT_OF_BOUNDS: ErrorCode = 9007; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const INVALID_SQRT_PRICE_LIMIT_DIRECTION: ErrorCode = 9008; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const ZERO_TRADABLE_AMOUNT: ErrorCode = 9009; + +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const INVALID_TIMESTAMP: ErrorCode = 9010; diff --git a/rust-sdk/core/src/constants/mod.rs b/rust-sdk/core/src/constants/mod.rs new file mode 100644 index 000000000..7db7d2a74 --- /dev/null +++ b/rust-sdk/core/src/constants/mod.rs @@ -0,0 +1,13 @@ +mod bundle; +mod error; +mod pool; +mod swap; +mod tick; +mod token; + +pub use bundle::*; +pub use error::*; +pub use pool::*; +pub use swap::*; +pub use tick::*; +pub use token::*; diff --git a/rust-sdk/core/src/constants/pool.rs b/rust-sdk/core/src/constants/pool.rs new file mode 100644 index 000000000..463190070 --- /dev/null +++ b/rust-sdk/core/src/constants/pool.rs @@ -0,0 +1,8 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +/// The number of reward tokens in a pool. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const NUM_REWARDS: usize = 3; diff --git a/rust-sdk/core/src/constants/swap.rs b/rust-sdk/core/src/constants/swap.rs new file mode 100644 index 000000000..2727a9662 --- /dev/null +++ b/rust-sdk/core/src/constants/swap.rs @@ -0,0 +1,16 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +/// The denominator of the fee rate value. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const FEE_RATE_DENOMINATOR: u32 = 1_000_000; + +// TODO: WASM export (which doesn't work with u128 yet) + +/// The minimum sqrt price for a whirlpool. +pub const MIN_SQRT_PRICE: u128 = 4295048016; + +/// The maximum sqrt price for a whirlpool. +pub const MAX_SQRT_PRICE: u128 = 79226673515401279992447579055; diff --git a/rust-sdk/core/src/constants/tick.rs b/rust-sdk/core/src/constants/tick.rs new file mode 100644 index 000000000..d2ae57074 --- /dev/null +++ b/rust-sdk/core/src/constants/tick.rs @@ -0,0 +1,21 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +/// The number of ticks in a tick array. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const TICK_ARRAY_SIZE: usize = 88; + +/// Pools with tick spacing above this threshold are considered full range only. +/// This means the program rejects any non-full range positions in these pools. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const FULL_RANGE_ONLY_TICK_SPACING_THRESHOLD: u16 = 32768; // 2^15 + +/// The minimum tick index. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const MIN_TICK_INDEX: i32 = -443636; + +/// The maximum tick index. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub const MAX_TICK_INDEX: i32 = 443636; diff --git a/rust-sdk/core/src/constants/token.rs b/rust-sdk/core/src/constants/token.rs new file mode 100644 index 000000000..2c1df5a1b --- /dev/null +++ b/rust-sdk/core/src/constants/token.rs @@ -0,0 +1 @@ +pub const BPS_DENOMINATOR: u16 = 10000; diff --git a/rust-sdk/core/src/lib.rs b/rust-sdk/core/src/lib.rs new file mode 100644 index 000000000..4eb174f1e --- /dev/null +++ b/rust-sdk/core/src/lib.rs @@ -0,0 +1,15 @@ +// FIXME: disable std for non-test builds to decrease wasm binary size. +// There is currently something in tsify that prevents this: +// https://github.com/madonoharu/tsify/issues/56 +// #![cfg_attr(not(test), no_std)] +#![allow(clippy::useless_conversion)] + +mod constants; +mod math; +mod quote; +mod types; + +pub use constants::*; +pub use math::*; +pub use quote::*; +pub use types::*; diff --git a/rust-sdk/core/src/math/bundle.rs b/rust-sdk/core/src/math/bundle.rs new file mode 100644 index 000000000..bf114a42e --- /dev/null +++ b/rust-sdk/core/src/math/bundle.rs @@ -0,0 +1,113 @@ +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use ethnum::U256; + +use crate::POSITION_BUNDLE_SIZE; + +const POSITION_BUNDLE_BYTES: usize = POSITION_BUNDLE_SIZE / 8; + +/// Get the first unoccupied position in a bundle +/// +/// # Arguments +/// * `bundle` - The bundle to check +/// +/// # Returns +/// * `u32` - The first unoccupied position (None if full) +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn first_unoccupied_position_in_bundle(bitmap: &[u8]) -> Option { + let value = bitmap_to_u256(bitmap); + for i in 0..POSITION_BUNDLE_SIZE { + if value & (U256::ONE << i) == 0 { + return Some(i as u32); + } + } + None +} + +/// Check whether a position bundle is full +/// A position bundle can contain 256 positions +/// +/// # Arguments +/// * `bundle` - The bundle to check +/// +/// # Returns +/// * `bool` - Whether the bundle is full +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn is_position_bundle_full(bitmap: &[u8]) -> bool { + let value = bitmap_to_u256(bitmap); + value == U256::MAX +} + +/// Check whether a position bundle is empty +/// +/// # Arguments +/// * `bundle` - The bundle to check +/// +/// # Returns +/// * `bool` - Whether the bundle is empty +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn is_position_bundle_empty(bitmap: &[u8]) -> bool { + let value = bitmap_to_u256(bitmap); + value == U256::MIN +} + +// Private functions + +#[allow(clippy::needless_range_loop)] +fn bitmap_to_u256(bitmap: &[u8]) -> U256 { + let mut u256 = ::from(0u32); + for i in 0..POSITION_BUNDLE_BYTES { + let byte = bitmap[i]; + u256 += ::from(byte) << (i * 8); + } + u256 +} + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use super::*; + + #[test] + fn test_first_unoccupied_position_in_bundle() { + let bundle: [u8; POSITION_BUNDLE_BYTES] = [0; POSITION_BUNDLE_BYTES]; + assert_eq!(first_unoccupied_position_in_bundle(&bundle), Some(0)); + + let mut low_bundle: [u8; POSITION_BUNDLE_BYTES] = [0; POSITION_BUNDLE_BYTES]; + low_bundle[0] = 0b11101111; + assert_eq!(first_unoccupied_position_in_bundle(&low_bundle), Some(4)); + + let mut high_bundle: [u8; POSITION_BUNDLE_BYTES] = [255; POSITION_BUNDLE_BYTES]; + high_bundle[10] = 0b10111111; + assert_eq!(first_unoccupied_position_in_bundle(&high_bundle), Some(86)); + + let full_bundle: [u8; POSITION_BUNDLE_BYTES] = [255; POSITION_BUNDLE_BYTES]; + assert_eq!(first_unoccupied_position_in_bundle(&full_bundle), None); + } + + #[test] + fn test_is_position_bundle_full() { + let bundle: [u8; POSITION_BUNDLE_BYTES] = [0; POSITION_BUNDLE_BYTES]; + assert!(!is_position_bundle_full(&bundle)); + + let bundle: [u8; POSITION_BUNDLE_BYTES] = [255; POSITION_BUNDLE_BYTES]; + assert!(is_position_bundle_full(&bundle)); + + let mut bundle: [u8; POSITION_BUNDLE_BYTES] = [0; POSITION_BUNDLE_BYTES]; + bundle[0] = 0b11111111; + assert!(!is_position_bundle_full(&bundle)); + } + + #[test] + fn test_is_position_bundle_empty() { + let bundle: [u8; POSITION_BUNDLE_BYTES] = [0; POSITION_BUNDLE_BYTES]; + assert!(is_position_bundle_empty(&bundle)); + + let bundle: [u8; POSITION_BUNDLE_BYTES] = [255; POSITION_BUNDLE_BYTES]; + assert!(!is_position_bundle_empty(&bundle)); + + let mut bundle: [u8; POSITION_BUNDLE_BYTES] = [0; POSITION_BUNDLE_BYTES]; + bundle[0] = 0b111111; + assert!(!is_position_bundle_empty(&bundle)); + } +} diff --git a/rust-sdk/core/src/math/mod.rs b/rust-sdk/core/src/math/mod.rs new file mode 100644 index 000000000..cf2a832d5 --- /dev/null +++ b/rust-sdk/core/src/math/mod.rs @@ -0,0 +1,17 @@ +mod bundle; +mod position; +mod tick; +mod tick_array; +mod token; + +#[cfg(feature = "floats")] +mod price; + +pub use bundle::*; +pub use position::*; +pub use tick::*; +pub use tick_array::*; +pub use token::*; + +#[cfg(feature = "floats")] +pub use price::*; diff --git a/rust-sdk/core/src/math/position.rs b/rust-sdk/core/src/math/position.rs new file mode 100644 index 000000000..21255c349 --- /dev/null +++ b/rust-sdk/core/src/math/position.rs @@ -0,0 +1,191 @@ +use crate::{PositionRatio, PositionStatus, BPS_DENOMINATOR, U128}; + +use ethnum::U256; +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use super::{order_tick_indexes, tick_index_to_sqrt_price}; + +/// Check if a position is in range. +/// When a position is in range it is earning fees and rewards +/// +/// # Parameters +/// - `sqrt_price` - A u128 integer representing the sqrt price of the pool +/// - `tick_index_1` - A i32 integer representing the first tick index of the position +/// - `tick_index_2` - A i32 integer representing the second tick index of the position +/// +/// # Returns +/// - A boolean value indicating if the position is in range +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn is_position_in_range(sqrt_price: U128, tick_index_1: i32, tick_index_2: i32) -> bool { + position_status(sqrt_price.into(), tick_index_1, tick_index_2) == PositionStatus::PriceInRange +} + +/// Calculate the status of a position +/// The status can be one of three values: +/// - InRange: The position is in range +/// - BelowRange: The position is below the range +/// - AboveRange: The position is above the range +/// +/// # Parameters +/// - `sqrt_price` - A u128 integer representing the sqrt price of the pool +/// - `tick_index_1` - A i32 integer representing the first tick index of the position +/// - `tick_index_2` - A i32 integer representing the second tick index of the position +/// +/// # Returns +/// - A PositionStatus enum value indicating the status of the position +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn position_status( + current_sqrt_price: U128, + tick_index_1: i32, + tick_index_2: i32, +) -> PositionStatus { + let current_sqrt_price: u128 = current_sqrt_price.into(); + let tick_range = order_tick_indexes(tick_index_1, tick_index_2); + let sqrt_price_lower: u128 = tick_index_to_sqrt_price(tick_range.tick_lower_index).into(); + let sqrt_price_upper: u128 = tick_index_to_sqrt_price(tick_range.tick_upper_index).into(); + + if tick_index_1 == tick_index_2 { + PositionStatus::Invalid + } else if current_sqrt_price <= sqrt_price_lower { + PositionStatus::PriceBelowRange + } else if current_sqrt_price >= sqrt_price_upper { + PositionStatus::PriceAboveRange + } else { + PositionStatus::PriceInRange + } +} + +/// Calculate the token_a / token_b ratio of a (ficticious) position +/// +/// # Parameters +/// - `sqrt_price` - A u128 integer representing the sqrt price of the pool +/// - `tick_index_1` - A i32 integer representing the first tick index of the position +/// - `tick_index_2` - A i32 integer representing the second tick index of the position +/// +/// # Returns +/// - A PositionRatio struct containing the ratio of token_a and token_b +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn position_ratio( + current_sqrt_price: U128, + tick_index_1: i32, + tick_index_2: i32, +) -> PositionRatio { + let current_sqrt_price: u128 = current_sqrt_price.into(); + let position_status = position_status(current_sqrt_price.into(), tick_index_1, tick_index_2); + match position_status { + PositionStatus::Invalid => PositionRatio { + ratio_a: 0, + ratio_b: 0, + }, + PositionStatus::PriceBelowRange => PositionRatio { + ratio_a: 10000, + ratio_b: 0, + }, + PositionStatus::PriceAboveRange => PositionRatio { + ratio_a: 0, + ratio_b: 10000, + }, + PositionStatus::PriceInRange => { + let tick_range = order_tick_indexes(tick_index_1, tick_index_2); + let lower_sqrt_price: u128 = + tick_index_to_sqrt_price(tick_range.tick_lower_index).into(); + let upper_sqrt_price: u128 = + tick_index_to_sqrt_price(tick_range.tick_upper_index).into(); + + let l: U256 = ::from(1u16) << 128; + let p = ::from(current_sqrt_price) * ::from(current_sqrt_price); + + let deposit_a_1: U256 = (l << 64) / current_sqrt_price; + let deposit_a_2: U256 = (l << 64) / upper_sqrt_price; + let deposit_a: U256 = ((deposit_a_1 - deposit_a_2) * p) >> 128; + + let deposit_b_1 = current_sqrt_price - lower_sqrt_price; + let deposit_b = (l * deposit_b_1) >> 64; + + let total_deposit = deposit_a + deposit_b; + + let denominator = ::from(BPS_DENOMINATOR); + let ratio_a: U256 = (deposit_a * denominator) / total_deposit; + let ratio_b: U256 = denominator - ratio_a; + + PositionRatio { + ratio_a: ratio_a.as_u16(), + ratio_b: ratio_b.as_u16(), + } + } + } +} + +#[cfg(all(test, not(feature = "wasm")))] +mod test { + use super::*; + + #[test] + fn test_is_position_in_range() { + assert!(is_position_in_range(18446744073709551616, -5, 5)); + assert!(!is_position_in_range(18446744073709551616, 0, 5)); + assert!(!is_position_in_range(18446744073709551616, -5, 0)); + assert!(!is_position_in_range(18446744073709551616, -5, -1)); + assert!(!is_position_in_range(18446744073709551616, 1, 5)); + } + + #[test] + fn test_position_status() { + assert_eq!( + position_status(18354745142194483560, -100, 100), + PositionStatus::PriceBelowRange + ); + assert_eq!( + position_status(18354745142194483561, -100, 100), + PositionStatus::PriceBelowRange + ); + assert_eq!( + position_status(18354745142194483562, -100, 100), + PositionStatus::PriceInRange + ); + assert_eq!( + position_status(18446744073709551616, -100, 100), + PositionStatus::PriceInRange + ); + assert_eq!( + position_status(18539204128674405811, -100, 100), + PositionStatus::PriceInRange + ); + assert_eq!( + position_status(18539204128674405812, -100, 100), + PositionStatus::PriceAboveRange + ); + assert_eq!( + position_status(18539204128674405813, -100, 100), + PositionStatus::PriceAboveRange + ); + assert_eq!( + position_status(18446744073709551616, 100, 100), + PositionStatus::Invalid + ); + } + + #[test] + fn test_position_ratio() { + let ratio_1 = position_ratio(18354745142194483561, -100, 100); + assert_eq!(ratio_1.ratio_a, 10000); + assert_eq!(ratio_1.ratio_b, 0); + + let ratio_2 = position_ratio(18446744073709551616, -100, 100); + assert_eq!(ratio_2.ratio_a, 4999); + assert_eq!(ratio_2.ratio_b, 5001); + + let ratio_3 = position_ratio(18539204128674405812, -100, 100); + assert_eq!(ratio_3.ratio_a, 0); + assert_eq!(ratio_3.ratio_b, 10000); + + let ratio_4 = position_ratio(18446744073709551616, 0, 0); + assert_eq!(ratio_4.ratio_a, 0); + assert_eq!(ratio_4.ratio_b, 0); + + let ratio_5 = position_ratio(7267764841821948241, -21136, -17240); + assert_eq!(ratio_5.ratio_a, 3630); + assert_eq!(ratio_5.ratio_b, 6370); + } +} diff --git a/rust-sdk/core/src/math/price.rs b/rust-sdk/core/src/math/price.rs new file mode 100644 index 000000000..bd45c084d --- /dev/null +++ b/rust-sdk/core/src/math/price.rs @@ -0,0 +1,170 @@ +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use libm::{floor, pow, sqrt}; + +use crate::U128; + +use super::{invert_tick_index, sqrt_price_to_tick_index, tick_index_to_sqrt_price}; + +const Q64_RESOLUTION: f64 = 18446744073709551616.0; + +/// Convert a price into a sqrt priceX64 +/// IMPORTANT: floating point operations can reduce the precision of the result. +/// Make sure to do these operations last and not to use the result for further calculations. +/// +/// # Parameters +/// * `price` - The price to convert +/// * `decimals_a` - The number of decimals of the base token +/// * `decimals_b` - The number of decimals of the quote token +/// +/// # Returns +/// * `u128` - The sqrt priceX64 +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn price_to_sqrt_price(price: f64, decimals_a: u8, decimals_b: u8) -> U128 { + let power = pow(10f64, decimals_a as f64 - decimals_b as f64); + (floor(sqrt(price / power) * Q64_RESOLUTION) as u128).into() +} + +/// Convert a sqrt priceX64 into a tick index +/// IMPORTANT: floating point operations can reduce the precision of the result. +/// Make sure to do these operations last and not to use the result for further calculations. +/// +/// # Parameters +/// * `sqrt_price` - The sqrt priceX64 to convert +/// * `decimals_a` - The number of decimals of the base token +/// * `decimals_b` - The number of decimals of the quote token +/// +/// # Returns +/// * `f64` - The decimal price +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn sqrt_price_to_price(sqrt_price: U128, decimals_a: u8, decimals_b: u8) -> f64 { + let power = pow(10f64, decimals_a as f64 - decimals_b as f64); + let sqrt_price: u128 = sqrt_price.into(); + let sqrt_price_u128 = sqrt_price as f64; + pow(sqrt_price_u128 / Q64_RESOLUTION, 2.0) * power +} + +/// Invert a price +/// IMPORTANT: floating point operations can reduce the precision of the result. +/// Make sure to do these operations last and not to use the result for further calculations. +/// +/// # Parameters +/// * `price` - The price to invert +/// * `decimals_a` - The number of decimals of the base token +/// * `decimals_b` - The number of decimals of the quote token +/// +/// # Returns +/// * `f64` - The inverted price +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn invert_price(price: f64, decimals_a: u8, decimals_b: u8) -> f64 { + let tick_index = price_to_tick_index(price, decimals_a, decimals_b); + let inverted_tick_index = invert_tick_index(tick_index); + tick_index_to_price(inverted_tick_index, decimals_a, decimals_b) +} + +/// Convert a tick index into a price +/// IMPORTANT: floating point operations can reduce the precision of the result. +/// Make sure to do these operations last and not to use the result for further calculations. +/// +/// # Parameters +/// * `tick_index` - The tick index to convert +/// * `decimals_a` - The number of decimals of the base token +/// * `decimals_b` - The number of decimals of the quote token +/// +/// # Returns +/// * `f64` - The decimal price +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn tick_index_to_price(tick_index: i32, decimals_a: u8, decimals_b: u8) -> f64 { + let sqrt_price = tick_index_to_sqrt_price(tick_index); + sqrt_price_to_price(sqrt_price, decimals_a, decimals_b) +} + +/// Convert a price into a tick index +/// IMPORTANT: floating point operations can reduce the precision of the result. +/// Make sure to do these operations last and not to use the result for further calculations. +/// +/// # Parameters +/// * `price` - The price to convert +/// * `decimals_a` - The number of decimals of the base token +/// * `decimals_b` - The number of decimals of the quote token +/// +/// # Returns +/// * `i32` - The tick index +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn price_to_tick_index(price: f64, decimals_a: u8, decimals_b: u8) -> i32 { + let sqrt_price = price_to_sqrt_price(price, decimals_a, decimals_b); + sqrt_price_to_tick_index(sqrt_price) +} + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use approx::assert_relative_eq; + + use super::*; + + #[test] + fn test_price_to_sqrt_price() { + assert_eq!(price_to_sqrt_price(0.00999999, 8, 6), 184467348503352096); + assert_eq!(price_to_sqrt_price(100.0, 6, 6), 184467440737095516160); + assert_eq!(price_to_sqrt_price(100.0111, 6, 8), 1844776783959692673024); + } + + #[test] + fn test_sqrt_price_to_price() { + assert_relative_eq!(sqrt_price_to_price(184467348503352096, 8, 6), 0.00999999); + assert_relative_eq!(sqrt_price_to_price(184467440737095516160, 6, 6), 100.0); + assert_relative_eq!(sqrt_price_to_price(1844776783959692673024, 6, 8), 100.0111); + } + + #[test] + fn test_invert_price() { + assert_relative_eq!( + invert_price(0.00999999, 8, 6), + 1000099.11863, + epsilon = 1e-5 + ); + assert_relative_eq!(invert_price(100.0, 6, 6), 0.01, epsilon = 1e-5); + assert_relative_eq!(invert_price(100.0111, 6, 8), 9.99e-7, epsilon = 1e-5); + } + + #[test] + fn test_tick_index_to_price() { + assert_relative_eq!(tick_index_to_price(-92111, 8, 6), 0.009998, epsilon = 1e-5); + assert_relative_eq!(tick_index_to_price(0, 6, 6), 1.0); + assert_relative_eq!(tick_index_to_price(92108, 6, 8), 99.999912, epsilon = 1e-5); + } + + #[test] + fn test_price_to_tick_index() { + assert_eq!(price_to_tick_index(0.009998, 8, 6), -92111); + assert_eq!(price_to_tick_index(1.0, 6, 6), 0); + assert_eq!(price_to_tick_index(99.999912, 6, 8), 92108); + } + + #[test] + fn test_sol_usdc() { + let sqrt_price = 6918418495991757039u128; // 140.661 USDC/SOL + let decimals_a = 9u8; // SOL + let decimals_b = 6u8; // USDC + let price = sqrt_price_to_price(sqrt_price, decimals_a, decimals_b); + assert_eq!(price, 140.66116595692344); + let sqrt_price_back = price_to_sqrt_price(price, decimals_a, decimals_b); + let diff = (sqrt_price_back as i128) - (sqrt_price as i128); + let diff_rate = (diff as f64) / (sqrt_price as f64) * 100.0; + assert_relative_eq!(diff_rate, 0.0, epsilon = 1e-10); + } + + #[test] + fn test_bonk_usdc() { + let sqrt_price = 265989152599097743u128; // 0.00002 USDC/BONK + let decimals_a = 5u8; // BONK + let decimals_b = 6u8; // USDC + let price = sqrt_price_to_price(sqrt_price, decimals_a, decimals_b); + assert_eq!(price, 2.0791623715496336e-5); + let sqrt_price_back = price_to_sqrt_price(price, decimals_a, decimals_b); + let diff = (sqrt_price_back as i128) - (sqrt_price as i128); + let diff_rate = (diff as f64) / (sqrt_price as f64) * 100.0; + assert_relative_eq!(diff_rate, 0.0, epsilon = 1e-10); + } +} diff --git a/rust-sdk/core/src/math/tick.rs b/rust-sdk/core/src/math/tick.rs new file mode 100644 index 000000000..f1a4a85e8 --- /dev/null +++ b/rust-sdk/core/src/math/tick.rs @@ -0,0 +1,589 @@ +use ethnum::U256; + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use crate::{ + TickRange, FULL_RANGE_ONLY_TICK_SPACING_THRESHOLD, MAX_TICK_INDEX, MIN_TICK_INDEX, + TICK_ARRAY_SIZE, U128, +}; + +const LOG_B_2_X32: i128 = 59543866431248i128; +const BIT_PRECISION: u32 = 14; +const LOG_B_P_ERR_MARGIN_LOWER_X64: i128 = 184467440737095516i128; // 0.01 +const LOG_B_P_ERR_MARGIN_UPPER_X64: i128 = 15793534762490258745i128; // 2^-precision / log_2_b + 0.01 + +/// Get the first tick index in the tick array that contains the specified tick index. +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick integer +/// - `tick_spacing` - A i32 integer representing the tick spacing +/// +/// # Returns +/// - A i32 integer representing the first tick index in the tick array +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn get_tick_array_start_tick_index(tick_index: i32, tick_spacing: u16) -> i32 { + let tick_spacing_i32 = tick_spacing as i32; + let tick_array_size_i32 = TICK_ARRAY_SIZE as i32; + let real_index = tick_index / tick_spacing_i32 / tick_array_size_i32; + real_index * tick_spacing_i32 * tick_array_size_i32 +} + +/// Derive the sqrt-price from a tick index. The precision of this method is only guarranted +/// if tick is within the bounds of {max, min} tick-index. +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick integer +/// +/// # Returns +/// - `Ok`: A u128 Q32.64 representing the sqrt_price +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn tick_index_to_sqrt_price(tick_index: i32) -> U128 { + if tick_index >= 0 { + get_sqrt_price_positive_tick(tick_index).into() + } else { + get_sqrt_price_negative_tick(tick_index).into() + } +} + +/// Derive the tick index from a sqrt price. The precision of this method is only guarranted +/// if tick is within the bounds of {max, min} tick-index. +/// +/// # Parameters +/// - `sqrt_price` - A u128 integer representing the sqrt price +/// +/// # Returns +/// - `Ok`: A i32 integer representing the tick integer +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn sqrt_price_to_tick_index(sqrt_price: U128) -> i32 { + let sqrt_price_x64: u128 = sqrt_price.into(); + // Determine log_b(sqrt_ratio). First by calculating integer portion (msb) + let msb: u32 = 128 - sqrt_price_x64.leading_zeros() - 1; + let log2p_integer_x32 = (msb as i128 - 64) << 32; + + // get fractional value (r/2^msb), msb always > 128 + // We begin the iteration from bit 63 (0.5 in Q64.64) + let mut bit: i128 = 0x8000_0000_0000_0000i128; + let mut precision = 0; + let mut log2p_fraction_x64 = 0; + + // Log2 iterative approximation for the fractional part + // Go through each 2^(j) bit where j < 64 in a Q64.64 number + // Append current bit value to fraction result if r^2 Q2.126 is more than 2 + let mut r = if msb >= 64 { + sqrt_price_x64 >> (msb - 63) + } else { + sqrt_price_x64 << (63 - msb) + }; + + while bit > 0 && precision < BIT_PRECISION { + r *= r; + let is_r_more_than_two = r >> 127_u32; + r >>= 63 + is_r_more_than_two; + log2p_fraction_x64 += bit * is_r_more_than_two as i128; + bit >>= 1; + precision += 1; + } + + let log2p_fraction_x32 = log2p_fraction_x64 >> 32; + let log2p_x32 = log2p_integer_x32 + log2p_fraction_x32; + + // Transform from base 2 to base b + let logbp_x64 = log2p_x32 * LOG_B_2_X32; + + // Derive tick_low & high estimate. Adjust with the possibility of under-estimating by 2^precision_bits/log_2(b) + 0.01 error margin. + let tick_low: i32 = ((logbp_x64 - LOG_B_P_ERR_MARGIN_LOWER_X64) >> 64) as i32; + let tick_high: i32 = ((logbp_x64 + LOG_B_P_ERR_MARGIN_UPPER_X64) >> 64) as i32; + + if tick_low == tick_high { + tick_low + } else { + // If our estimation for tick_high returns a lower sqrt_price than the input + // then the actual tick_high has to be higher than than tick_high. + // Otherwise, the actual value is between tick_low & tick_high, so a floor value + // (tick_low) is returned + let actual_tick_high_sqrt_price_x64: u128 = tick_index_to_sqrt_price(tick_high).into(); + if actual_tick_high_sqrt_price_x64 <= sqrt_price_x64 { + tick_high + } else { + tick_low + } + } +} + +/// Get the initializable tick index. +/// If the tick index is already initializable, it is returned as is. +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick integer +/// - `tick_spacing` - A i32 integer representing the tick spacing +/// - `round_up` - A boolean value indicating if the supplied tick index should be rounded up. None will round to the nearest. +/// +/// # Returns +/// - A i32 integer representing the previous initializable tick index +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn get_initializable_tick_index( + tick_index: i32, + tick_spacing: u16, + round_up: Option, +) -> i32 { + let tick_spacing_i32 = tick_spacing as i32; + let remainder = tick_index.rem_euclid(tick_spacing_i32); + let result = tick_index.div_euclid(tick_spacing_i32) * tick_spacing_i32; + + let should_round_up = if let Some(round_up) = round_up { + round_up && remainder > 0 + } else { + remainder >= tick_spacing_i32 / 2 + }; + + if should_round_up { + result + tick_spacing_i32 + } else { + result + } +} + +/// Get the previous initializable tick index. +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick integer +/// - `tick_spacing` - A i32 integer representing the tick spacing +/// +/// # Returns +/// - A i32 integer representing the previous initializable tick index +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn get_prev_initializable_tick_index(tick_index: i32, tick_spacing: u16) -> i32 { + let tick_spacing_i32 = tick_spacing as i32; + let remainder = tick_index.rem_euclid(tick_spacing_i32); + if remainder == 0 { + tick_index - tick_spacing_i32 + } else { + tick_index - remainder + } +} + +/// Get the next initializable tick index. +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick integer +/// - `tick_spacing` - A i32 integer representing the tick spacing +/// +/// # Returns +/// - A i32 integer representing the next initializable tick index +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn get_next_initializable_tick_index(tick_index: i32, tick_spacing: u16) -> i32 { + let tick_spacing_i32 = tick_spacing as i32; + let remainder = tick_index.rem_euclid(tick_spacing_i32); + tick_index - remainder + tick_spacing_i32 +} + +/// Check if a tick is in-bounds. +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick integer +/// +/// # Returns +/// - A boolean value indicating if the tick is in-bounds +#[cfg_attr(feature = "wasm", wasm_expose)] +#[allow(clippy::manual_range_contains)] +pub fn is_tick_index_in_bounds(tick_index: i32) -> bool { + tick_index <= MAX_TICK_INDEX && tick_index >= MIN_TICK_INDEX +} + +/// Check if a tick is initializable. +/// A tick is initializable if it is divisible by the tick spacing. +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick integer +/// - `tick_spacing` - A i32 integer representing the tick spacing +/// +/// # Returns +/// - A boolean value indicating if the tick is initializable +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn is_tick_initializable(tick_index: i32, tick_spacing: u16) -> bool { + let tick_spacing_i32 = tick_spacing as i32; + tick_index % tick_spacing_i32 == 0 +} + +/// Get the tick index for the inverse of the price that this tick represents. +/// Eg: Consider tick i where Pb/Pa = 1.0001 ^ i +/// inverse of this, i.e. Pa/Pb = 1 / (1.0001 ^ i) = 1.0001^-i +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick integer +/// +/// # Returns +/// - A i32 integer representing the tick index for the inverse of the price +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn invert_tick_index(tick_index: i32) -> i32 { + -tick_index +} + +/// Get the sqrt price for the inverse of the price that this tick represents. +/// Because converting to a tick index and then back to a sqrt price is lossy, +/// this function is clamped to the nearest tick index. +/// +/// # Parameters +/// - `sqrt_price` - A u128 integer representing the sqrt price +/// +/// # Returns +/// - A u128 integer representing the sqrt price for the inverse of the price +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn invert_sqrt_price(sqrt_price: U128) -> U128 { + let tick_index = sqrt_price_to_tick_index(sqrt_price); + let inverted_tick_index = invert_tick_index(tick_index); + tick_index_to_sqrt_price(inverted_tick_index) +} + +/// Get the minimum and maximum tick index that can be initialized. +/// +/// # Parameters +/// - `tick_spacing` - A i32 integer representing the tick spacing +/// +/// # Returns +/// - A TickRange struct containing the lower and upper tick index +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn get_full_range_tick_indexes(tick_spacing: u16) -> TickRange { + let tick_spacing_i32 = tick_spacing as i32; + let min_tick_index = (MIN_TICK_INDEX / tick_spacing_i32) * tick_spacing_i32; + let max_tick_index = (MAX_TICK_INDEX / tick_spacing_i32) * tick_spacing_i32; + TickRange { + tick_lower_index: min_tick_index, + tick_upper_index: max_tick_index, + } +} + +/// Order tick indexes in ascending order. +/// If the lower tick index is greater than the upper tick index, the indexes are swapped. +/// This is useful for ensuring that the lower tick index is always less than the upper tick index. +/// +/// # Parameters +/// - `tick_index_1` - A i32 integer representing the first tick index +/// - `tick_index_2` - A i32 integer representing the second tick index +/// +/// # Returns +/// - A TickRange struct containing the lower and upper tick index +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn order_tick_indexes(tick_index_1: i32, tick_index_2: i32) -> TickRange { + if tick_index_1 < tick_index_2 { + TickRange { + tick_lower_index: tick_index_1, + tick_upper_index: tick_index_2, + } + } else { + TickRange { + tick_lower_index: tick_index_2, + tick_upper_index: tick_index_1, + } + } +} + +/// Check if a whirlpool is a full-range only pool. +/// +/// # Parameters +/// - `tick_spacing` - A u16 integer representing the tick spacing +/// +/// # Returns +/// - A boolean value indicating if the whirlpool is a full-range only pool +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn is_full_range_only(tick_spacing: u16) -> bool { + tick_spacing >= FULL_RANGE_ONLY_TICK_SPACING_THRESHOLD +} + +/// Get the index of a tick in a tick array. +/// +/// # Parameters +/// - `tick_index` - A i32 integer representing the tick index +/// - `tick_array_start_index` - A i32 integer representing the start tick index of the tick array +/// - `tick_spacing` - A u16 integer representing the tick spacing +/// +/// # Returns +/// - A i32 integer representing the tick index in the tick array +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn get_tick_index_in_array( + tick_index: i32, + tick_array_start_index: i32, + tick_spacing: u16, +) -> i32 { + (tick_index - tick_array_start_index) / tick_spacing as i32 +} + +// Private functions + +fn mul_shift_96(n0: u128, n1: u128) -> u128 { + let mul: U256 = (::from(n0) * ::from(n1)) >> 96; + mul.as_u128() +} + +fn get_sqrt_price_positive_tick(tick: i32) -> u128 { + let mut ratio: u128 = if tick & 1 != 0 { + 79232123823359799118286999567 + } else { + 79228162514264337593543950336 + }; + + if tick & 2 != 0 { + ratio = mul_shift_96(ratio, 79236085330515764027303304731); + } + if tick & 4 != 0 { + ratio = mul_shift_96(ratio, 79244008939048815603706035061); + } + if tick & 8 != 0 { + ratio = mul_shift_96(ratio, 79259858533276714757314932305); + } + if tick & 16 != 0 { + ratio = mul_shift_96(ratio, 79291567232598584799939703904); + } + if tick & 32 != 0 { + ratio = mul_shift_96(ratio, 79355022692464371645785046466); + } + if tick & 64 != 0 { + ratio = mul_shift_96(ratio, 79482085999252804386437311141); + } + if tick & 128 != 0 { + ratio = mul_shift_96(ratio, 79736823300114093921829183326); + } + if tick & 256 != 0 { + ratio = mul_shift_96(ratio, 80248749790819932309965073892); + } + if tick & 512 != 0 { + ratio = mul_shift_96(ratio, 81282483887344747381513967011); + } + if tick & 1024 != 0 { + ratio = mul_shift_96(ratio, 83390072131320151908154831281); + } + if tick & 2048 != 0 { + ratio = mul_shift_96(ratio, 87770609709833776024991924138); + } + if tick & 4096 != 0 { + ratio = mul_shift_96(ratio, 97234110755111693312479820773); + } + if tick & 8192 != 0 { + ratio = mul_shift_96(ratio, 119332217159966728226237229890); + } + if tick & 16384 != 0 { + ratio = mul_shift_96(ratio, 179736315981702064433883588727); + } + if tick & 32768 != 0 { + ratio = mul_shift_96(ratio, 407748233172238350107850275304); + } + if tick & 65536 != 0 { + ratio = mul_shift_96(ratio, 2098478828474011932436660412517); + } + if tick & 131072 != 0 { + ratio = mul_shift_96(ratio, 55581415166113811149459800483533); + } + if tick & 262144 != 0 { + ratio = mul_shift_96(ratio, 38992368544603139932233054999993551); + } + + ratio >> 32 +} + +fn get_sqrt_price_negative_tick(tick: i32) -> u128 { + let abs_tick = tick.abs(); + + let mut ratio: u128 = if abs_tick & 1 != 0 { + 18445821805675392311 + } else { + 18446744073709551616 + }; + + if abs_tick & 2 != 0 { + ratio = (ratio * 18444899583751176498) >> 64 + } + if abs_tick & 4 != 0 { + ratio = (ratio * 18443055278223354162) >> 64 + } + if abs_tick & 8 != 0 { + ratio = (ratio * 18439367220385604838) >> 64 + } + if abs_tick & 16 != 0 { + ratio = (ratio * 18431993317065449817) >> 64 + } + if abs_tick & 32 != 0 { + ratio = (ratio * 18417254355718160513) >> 64 + } + if abs_tick & 64 != 0 { + ratio = (ratio * 18387811781193591352) >> 64 + } + if abs_tick & 128 != 0 { + ratio = (ratio * 18329067761203520168) >> 64 + } + if abs_tick & 256 != 0 { + ratio = (ratio * 18212142134806087854) >> 64 + } + if abs_tick & 512 != 0 { + ratio = (ratio * 17980523815641551639) >> 64 + } + if abs_tick & 1024 != 0 { + ratio = (ratio * 17526086738831147013) >> 64 + } + if abs_tick & 2048 != 0 { + ratio = (ratio * 16651378430235024244) >> 64 + } + if abs_tick & 4096 != 0 { + ratio = (ratio * 15030750278693429944) >> 64 + } + if abs_tick & 8192 != 0 { + ratio = (ratio * 12247334978882834399) >> 64 + } + if abs_tick & 16384 != 0 { + ratio = (ratio * 8131365268884726200) >> 64 + } + if abs_tick & 32768 != 0 { + ratio = (ratio * 3584323654723342297) >> 64 + } + if abs_tick & 65536 != 0 { + ratio = (ratio * 696457651847595233) >> 64 + } + if abs_tick & 131072 != 0 { + ratio = (ratio * 26294789957452057) >> 64 + } + if abs_tick & 262144 != 0 { + ratio = (ratio * 37481735321082) >> 64 + } + + ratio +} + +// Tests + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use super::*; + use crate::{MAX_SQRT_PRICE, MIN_SQRT_PRICE}; + + #[test] + fn test_get_tick_array_start_tick_index() { + assert_eq!(get_tick_array_start_tick_index(100, 10), 0); + assert_eq!(get_tick_array_start_tick_index(1000, 10), 880); + assert_eq!(get_tick_array_start_tick_index(0, 10), 0); + } + + #[test] + fn test_tick_index_to_sqrt_price() { + assert_eq!(tick_index_to_sqrt_price(MAX_TICK_INDEX), MAX_SQRT_PRICE); + assert_eq!(tick_index_to_sqrt_price(100), 18539204128674405812); + assert_eq!(tick_index_to_sqrt_price(1), 18447666387855959850); + assert_eq!(tick_index_to_sqrt_price(0), 18446744073709551616); + assert_eq!(tick_index_to_sqrt_price(-1), 18445821805675392311); + assert_eq!(tick_index_to_sqrt_price(-100), 18354745142194483561); + assert_eq!(tick_index_to_sqrt_price(MIN_TICK_INDEX), MIN_SQRT_PRICE); + } + + #[test] + fn test_sqrt_price_to_tick_index() { + assert_eq!(sqrt_price_to_tick_index(MAX_SQRT_PRICE), MAX_TICK_INDEX); + assert_eq!(sqrt_price_to_tick_index(18539204128674405812), 100); + assert_eq!(sqrt_price_to_tick_index(18447666387855959850), 1); + assert_eq!(sqrt_price_to_tick_index(18446744073709551616), 0); + assert_eq!(sqrt_price_to_tick_index(18445821805675392311), -1); + assert_eq!(sqrt_price_to_tick_index(18354745142194483561), -100); + assert_eq!(sqrt_price_to_tick_index(MIN_SQRT_PRICE), MIN_TICK_INDEX); + } + + #[test] + fn test_get_initializable_tick_index() { + assert_eq!(get_initializable_tick_index(-100, 10, Some(true)), -100); + assert_eq!(get_initializable_tick_index(-100, 10, Some(false)), -100); + assert_eq!(get_initializable_tick_index(-100, 10, None), -100); + + assert_eq!(get_initializable_tick_index(-101, 10, Some(true)), -100); + assert_eq!(get_initializable_tick_index(-101, 10, Some(false)), -110); + assert_eq!(get_initializable_tick_index(-101, 10, None), -100); + + assert_eq!(get_initializable_tick_index(-105, 10, Some(true)), -100); + assert_eq!(get_initializable_tick_index(-105, 10, Some(false)), -110); + assert_eq!(get_initializable_tick_index(-105, 10, None), -100); + + assert_eq!(get_initializable_tick_index(-109, 10, Some(true)), -100); + assert_eq!(get_initializable_tick_index(-109, 10, Some(false)), -110); + assert_eq!(get_initializable_tick_index(-109, 10, None), -110); + + assert_eq!(get_initializable_tick_index(-100, 10, Some(true)), -100); + assert_eq!(get_initializable_tick_index(-100, 10, Some(false)), -100); + assert_eq!(get_initializable_tick_index(-100, 10, None), -100); + + assert_eq!(get_initializable_tick_index(101, 10, Some(true)), 110); + assert_eq!(get_initializable_tick_index(101, 10, Some(false)), 100); + assert_eq!(get_initializable_tick_index(101, 10, None), 100); + + assert_eq!(get_initializable_tick_index(105, 10, Some(true)), 110); + assert_eq!(get_initializable_tick_index(105, 10, Some(false)), 100); + assert_eq!(get_initializable_tick_index(105, 10, None), 110); + + assert_eq!(get_initializable_tick_index(109, 10, Some(true)), 110); + assert_eq!(get_initializable_tick_index(109, 10, Some(false)), 100); + assert_eq!(get_initializable_tick_index(109, 10, None), 110); + } + + #[test] + fn test_get_prev_initializable_tick_index() { + assert_eq!(get_prev_initializable_tick_index(10, 10), 0); + assert_eq!(get_prev_initializable_tick_index(5, 10), 0); + assert_eq!(get_prev_initializable_tick_index(0, 10), -10); + assert_eq!(get_prev_initializable_tick_index(-5, 10), -10); + assert_eq!(get_prev_initializable_tick_index(-10, 10), -20); + } + + #[test] + fn test_get_next_initializable_tick_index() { + assert_eq!(get_next_initializable_tick_index(10, 10), 20); + assert_eq!(get_next_initializable_tick_index(5, 10), 10); + assert_eq!(get_next_initializable_tick_index(0, 10), 10); + assert_eq!(get_next_initializable_tick_index(-5, 10), 0); + assert_eq!(get_next_initializable_tick_index(-10, 10), 0); + } + + #[test] + fn test_is_tick_index_in_bounds() { + assert!(is_tick_index_in_bounds(MAX_TICK_INDEX)); + assert!(is_tick_index_in_bounds(MIN_TICK_INDEX)); + assert!(!is_tick_index_in_bounds(MAX_TICK_INDEX + 1)); + assert!(!is_tick_index_in_bounds(MIN_TICK_INDEX - 1)); + } + + #[test] + fn test_is_tick_initializable() { + assert!(is_tick_initializable(100, 10)); + assert!(!is_tick_initializable(105, 10)); + } + + #[test] + fn test_invert_tick_index() { + assert_eq!(invert_tick_index(100), -100); + assert_eq!(invert_tick_index(-100), 100); + } + + #[test] + fn test_get_full_range_tick_indexes() { + let range = get_full_range_tick_indexes(10); + assert_eq!(range.tick_lower_index, (MIN_TICK_INDEX / 10) * 10); + assert_eq!(range.tick_upper_index, (MAX_TICK_INDEX / 10) * 10); + } + + #[test] + fn test_order_tick_indexes() { + let range_1 = order_tick_indexes(100, 200); + assert_eq!(range_1.tick_lower_index, 100); + assert_eq!(range_1.tick_upper_index, 200); + + let range_2 = order_tick_indexes(200, 100); + assert_eq!(range_2.tick_lower_index, 100); + assert_eq!(range_2.tick_upper_index, 200); + + let range_3 = order_tick_indexes(100, 100); + assert_eq!(range_3.tick_lower_index, 100); + assert_eq!(range_3.tick_upper_index, 100); + } + + #[test] + fn test_is_full_range_only() { + assert!(is_full_range_only(FULL_RANGE_ONLY_TICK_SPACING_THRESHOLD)); + assert!(!is_full_range_only( + FULL_RANGE_ONLY_TICK_SPACING_THRESHOLD - 1 + )); + } +} diff --git a/rust-sdk/core/src/math/tick_array.rs b/rust-sdk/core/src/math/tick_array.rs new file mode 100644 index 000000000..994cb9cbc --- /dev/null +++ b/rust-sdk/core/src/math/tick_array.rs @@ -0,0 +1,257 @@ +use crate::{ + ErrorCode, TickArrayFacade, TickFacade, INVALID_TICK_INDEX, MAX_TICK_INDEX, MIN_TICK_INDEX, + TICK_ARRAY_NOT_EVENLY_SPACED, TICK_ARRAY_SIZE, TICK_INDEX_OUT_OF_BOUNDS, TICK_SEQUENCE_EMPTY, +}; + +use super::{ + get_initializable_tick_index, get_next_initializable_tick_index, + get_prev_initializable_tick_index, +}; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TickArraySequence { + tick_arrays: [Option; SIZE], + tick_spacing: u16, +} + +impl TickArraySequence { + pub fn new( + tick_arrays: [Option; SIZE], + tick_spacing: u16, + ) -> Result { + let mut tick_arrays = tick_arrays; + tick_arrays.sort_by_key(start_tick_index); + + if tick_arrays.is_empty() || tick_arrays[0].is_none() { + return Err(TICK_SEQUENCE_EMPTY); + } + + let required_tick_array_spacing = TICK_ARRAY_SIZE as i32 * tick_spacing as i32; + for i in 0..tick_arrays.len() - 1 { + let current_start_tick_index = start_tick_index(&tick_arrays[i]); + let next_start_tick_index = start_tick_index(&tick_arrays[i + 1]); + if next_start_tick_index - current_start_tick_index != required_tick_array_spacing + && next_start_tick_index != ::MAX + { + return Err(TICK_ARRAY_NOT_EVENLY_SPACED); + } + } + + Ok(Self { + tick_arrays, + tick_spacing, + }) + } + + pub fn start_index(&self) -> i32 { + start_tick_index(&self.tick_arrays[0]).max(MIN_TICK_INDEX) + } + + pub fn end_index(&self) -> i32 { + let mut last_valid_start_index = self.start_index(); + for i in 0..self.tick_arrays.len() { + if start_tick_index(&self.tick_arrays[i]) != ::MAX { + last_valid_start_index = start_tick_index(&self.tick_arrays[i]); + } + } + let end_index = last_valid_start_index + TICK_ARRAY_SIZE as i32 * self.tick_spacing as i32; + end_index.min(MAX_TICK_INDEX) + } + + pub fn tick(&self, tick_index: i32) -> Result<&TickFacade, ErrorCode> { + if (tick_index < self.start_index()) || (tick_index >= self.end_index()) { + return Err(TICK_INDEX_OUT_OF_BOUNDS); + } + if (tick_index % self.tick_spacing as i32) != 0 { + return Err(INVALID_TICK_INDEX); + } + let tick_array_index = ((tick_index - self.start_index()) + / (TICK_ARRAY_SIZE as i32 * self.tick_spacing as i32)) + as usize; + let tick_array_start_index = start_tick_index(&self.tick_arrays[tick_array_index]); + let tick_array_ticks = ticks(&self.tick_arrays[tick_array_index]); + let index_in_array = (tick_index - tick_array_start_index) / self.tick_spacing as i32; + Ok(&tick_array_ticks[index_in_array as usize]) + } + + pub fn next_initialized_tick(&self, tick_index: i32) -> Result<(&TickFacade, i32), ErrorCode> { + let mut next_index = tick_index; + loop { + next_index = get_next_initializable_tick_index(next_index, self.tick_spacing); + let tick = self.tick(next_index)?; + if tick.initialized { + return Ok((tick, next_index)); + } + } + } + + pub fn prev_initialized_tick(&self, tick_index: i32) -> Result<(&TickFacade, i32), ErrorCode> { + let mut prev_index = + get_initializable_tick_index(tick_index, self.tick_spacing, Some(false)); + loop { + let tick = self.tick(prev_index)?; + if tick.initialized { + return Ok((tick, prev_index)); + } + prev_index = get_prev_initializable_tick_index(prev_index, self.tick_spacing); + } + } +} + +// internal functions + +fn start_tick_index(tick_array: &Option) -> i32 { + if let Some(tick_array) = tick_array { + tick_array.start_tick_index + } else { + ::MAX + } +} + +fn ticks(tick_array: &Option) -> &[TickFacade] { + if let Some(tick_array) = tick_array { + &tick_array.ticks + } else { + &[] + } +} + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use super::*; + + fn test_sequence() -> TickArraySequence<5> { + let ticks: [TickFacade; TICK_ARRAY_SIZE] = (0..TICK_ARRAY_SIZE) + .map(|x| TickFacade { + initialized: x & 1 == 1, + liquidity_net: x as i128, + ..TickFacade::default() + }) + .collect::>() + .try_into() + .unwrap(); + let one = TickArrayFacade { + start_tick_index: TICK_ARRAY_SIZE as i32 * -16, + ticks, + }; + let two = TickArrayFacade { + start_tick_index: 0, + ticks, + }; + let three = TickArrayFacade { + start_tick_index: TICK_ARRAY_SIZE as i32 * 16, + ticks, + }; + TickArraySequence::new([Some(one), Some(two), Some(three), None, None], 16).unwrap() + } + + #[test] + fn test_tick_array_start_index() { + let sequence = test_sequence(); + assert_eq!(sequence.start_index(), -1408); + } + + #[test] + fn test_tick_array_end_index() { + let sequence = test_sequence(); + assert_eq!(sequence.end_index(), 2816); + } + + #[test] + fn test_get_tick() { + let sequence = test_sequence(); + assert_eq!(sequence.tick(-1408).unwrap().liquidity_net, 0); + assert_eq!(sequence.tick(-16).unwrap().liquidity_net, 87); + assert_eq!(sequence.tick(0).unwrap().liquidity_net, 0); + assert_eq!(sequence.tick(16).unwrap().liquidity_net, 1); + assert_eq!(sequence.tick(1408).unwrap().liquidity_net, 0); + assert_eq!(sequence.tick(1424).unwrap().liquidity_net, 1); + } + + #[test] + fn test_get_tick_errors() { + let sequence = test_sequence(); + + let out_out_bounds_lower = sequence.tick(-1409); + assert!(matches!( + out_out_bounds_lower, + Err(TICK_INDEX_OUT_OF_BOUNDS) + )); + + let out_of_bounds_upper = sequence.tick(2817); + assert!(matches!(out_of_bounds_upper, Err(TICK_INDEX_OUT_OF_BOUNDS))); + + let invalid_tick_index = sequence.tick(1); + assert!(matches!(invalid_tick_index, Err(INVALID_TICK_INDEX))); + + let invalid_negative_tick_index = sequence.tick(-1); + assert!(matches!( + invalid_negative_tick_index, + Err(INVALID_TICK_INDEX) + )); + } + + #[test] + fn test_get_next_initializable_tick_index() { + let sequence = test_sequence(); + let (tick, index) = sequence.next_initialized_tick(0).unwrap(); + assert_eq!(index, 16); + assert_eq!(tick.liquidity_net, 1); + } + + #[test] + fn test_get_next_initializable_tick_index_off_spacing() { + let sequence = test_sequence(); + let (tick, index) = sequence.next_initialized_tick(-17).unwrap(); + assert_eq!(index, -16); + assert_eq!(tick.liquidity_net, 87); + } + + #[test] + fn test_get_next_initializable_tick_cross_array() { + let sequence = test_sequence(); + let (tick, index) = sequence.next_initialized_tick(1392).unwrap(); + assert_eq!(index, 1424); + assert_eq!(tick.liquidity_net, 1); + } + + #[test] + fn test_get_next_initializable_tick_skip_uninitialized() { + let sequence = test_sequence(); + let (tick, index) = sequence.next_initialized_tick(-1).unwrap(); + assert_eq!(index, 16); + assert_eq!(tick.liquidity_net, 1); + } + + #[test] + fn test_get_prev_initializable_tick_index() { + let sequence = test_sequence(); + let (tick, index) = sequence.prev_initialized_tick(32).unwrap(); + assert_eq!(index, 16); + assert_eq!(tick.liquidity_net, 1); + } + + #[test] + fn test_get_prev_initializable_tick_index_off_spacing() { + let sequence = test_sequence(); + let (tick, index) = sequence.prev_initialized_tick(-1).unwrap(); + assert_eq!(index, -16); + assert_eq!(tick.liquidity_net, 87); + } + + #[test] + fn test_get_prev_initializable_tick_skip_uninitialized() { + let sequence = test_sequence(); + let (tick, index) = sequence.prev_initialized_tick(33).unwrap(); + assert_eq!(index, 16); + assert_eq!(tick.liquidity_net, 1); + } + + #[test] + fn test_get_prev_initializable_tick_cross_array() { + let sequence = test_sequence(); + let (tick, index) = sequence.prev_initialized_tick(1408).unwrap(); + assert_eq!(index, 1392); + assert_eq!(tick.liquidity_net, 87); + } +} diff --git a/rust-sdk/core/src/math/token.rs b/rust-sdk/core/src/math/token.rs new file mode 100644 index 000000000..2da2087f7 --- /dev/null +++ b/rust-sdk/core/src/math/token.rs @@ -0,0 +1,608 @@ +use crate::{ + ErrorCode, TransferFee, AMOUNT_EXCEEDS_MAX_U64, ARITHMETIC_OVERFLOW, BPS_DENOMINATOR, + FEE_RATE_DENOMINATOR, MAX_SQRT_PRICE, MIN_SQRT_PRICE, SQRT_PRICE_OUT_OF_BOUNDS, U128, +}; + +use ethnum::U256; +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +/// Calculate the amount A delta between two sqrt_prices +/// +/// # Parameters +/// - `current_sqrt_price`: The current square root price +/// - `target_sqrt_price`: The target square root price +/// - `current_liquidity`: The current liquidity +/// - `round_up`: Whether to round up or not +/// +/// # Returns +/// - `u64`: The amount delta +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_get_amount_delta_a( + current_sqrt_price: U128, + target_sqrt_price: U128, + current_liquidity: U128, + round_up: bool, +) -> Result { + let (sqrt_price_lower, sqrt_price_upper) = + order_prices(current_sqrt_price.into(), target_sqrt_price.into()); + let sqrt_price_diff = sqrt_price_upper - sqrt_price_lower; + let numerator: U256 = ::from(current_liquidity) + .checked_mul(sqrt_price_diff.into()) + .ok_or(ARITHMETIC_OVERFLOW)? + .checked_shl(64) + .ok_or(ARITHMETIC_OVERFLOW)?; + + let denominator: U256 = ::from(sqrt_price_lower) + .checked_mul(sqrt_price_upper.into()) + .ok_or(ARITHMETIC_OVERFLOW)?; + + let quotient = numerator / denominator; + let remainder = numerator % denominator; + + let result = if round_up && remainder != 0 { + quotient + 1 + } else { + quotient + }; + + result.try_into().map_err(|_| AMOUNT_EXCEEDS_MAX_U64) +} + +/// Calculate the amount B delta between two sqrt_prices +/// +/// # Parameters +/// - `current_sqrt_price`: The current square root price +/// - `target_sqrt_price`: The target square root price +/// - `current_liquidity`: The current liquidity +/// - `round_up`: Whether to round up or not +/// +/// # Returns +/// - `u64`: The amount delta +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_get_amount_delta_b( + current_sqrt_price: U128, + target_sqrt_price: U128, + current_liquidity: U128, + round_up: bool, +) -> Result { + let (sqrt_price_lower, sqrt_price_upper) = + order_prices(current_sqrt_price.into(), target_sqrt_price.into()); + let sqrt_price_diff = sqrt_price_upper - sqrt_price_lower; + + let product: U256 = ::from(current_liquidity) + .checked_mul(sqrt_price_diff.into()) + .ok_or(ARITHMETIC_OVERFLOW)?; + let quotient: U256 = product >> 64; + + let should_round = round_up && product & ::from(u64::MAX) > 0; + + let result = if should_round { quotient + 1 } else { quotient }; + + result.try_into().map_err(|_| AMOUNT_EXCEEDS_MAX_U64) +} + +/// Calculate the next square root price +/// +/// # Parameters +/// - `current_sqrt_price`: The current square root price +/// - `current_liquidity`: The current liquidity +/// - `amount`: The amount +/// - `specified_input`: Whether the input is specified +/// +/// # Returns +/// - `u128`: The next square root price +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_get_next_sqrt_price_from_a( + current_sqrt_price: U128, + current_liquidity: U128, + amount: u64, + specified_input: bool, +) -> Result { + if amount == 0 { + return Ok(current_sqrt_price); + } + let current_sqrt_price: u128 = current_sqrt_price.into(); + let current_liquidity: u128 = current_liquidity.into(); + + let p = ::from(current_sqrt_price).saturating_mul(amount.into()); + let numerator = ::from(current_liquidity) + .checked_mul(current_sqrt_price.into()) + .ok_or(ARITHMETIC_OVERFLOW)? + .checked_shl(64) + .ok_or(ARITHMETIC_OVERFLOW)?; + + let current_liquidity_shifted = ::from(current_liquidity) + .checked_shl(64) + .ok_or(ARITHMETIC_OVERFLOW)?; + let denominator = if specified_input { + current_liquidity_shifted + p + } else { + current_liquidity_shifted - p + }; + + let quotient: U256 = numerator / denominator; + let remainder: U256 = numerator % denominator; + + let result = if remainder != 0 { + quotient + 1 + } else { + quotient + }; + + if !(MIN_SQRT_PRICE..=MAX_SQRT_PRICE).contains(&result) { + return Err(SQRT_PRICE_OUT_OF_BOUNDS); + } + + result + .try_into() + .map(|x: u128| x.into()) + .map_err(|_| AMOUNT_EXCEEDS_MAX_U64) +} + +/// Calculate the next square root price +/// +/// # Parameters +/// - `current_sqrt_price`: The current square root price +/// - `current_liquidity`: The current liquidity +/// - `amount`: The amount +/// - `specified_input`: Whether the input is specified +/// +/// # Returns +/// - `u128`: The next square root price +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_get_next_sqrt_price_from_b( + current_sqrt_price: U128, + current_liquidity: U128, + amount: u64, + specified_input: bool, +) -> Result { + if amount == 0 { + return Ok(current_sqrt_price); + } + let current_sqrt_price = ::from(current_sqrt_price); + let current_liquidity = ::from(current_liquidity); + let amount_shifted = ::from(amount) + .checked_shl(64) + .ok_or(ARITHMETIC_OVERFLOW)?; + + let quotient: U256 = amount_shifted / current_liquidity; + let remainder: U256 = amount_shifted % current_liquidity; + + let delta = if !specified_input && remainder != 0 { + quotient + 1 + } else { + quotient + }; + + let result = if specified_input { + current_sqrt_price + delta + } else { + current_sqrt_price - delta + }; + + if !(MIN_SQRT_PRICE..=MAX_SQRT_PRICE).contains(&result) { + return Err(SQRT_PRICE_OUT_OF_BOUNDS); + } + + Ok(result.as_u128().into()) +} + +/// Apply a transfer fee to an amount +/// e.g. You send 10000 amount with 100 fee rate. The fee amount will be 100. +/// So the amount after fee will be 9900. +/// +/// # Parameters +/// - `amount`: The amount to apply the fee to +/// - `transfer_fee`: The transfer fee to apply +/// +/// # Returns +/// - `u64`: The amount after the fee has been applied +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_apply_transfer_fee(amount: u64, transfer_fee: TransferFee) -> Result { + try_adjust_amount( + amount, + transfer_fee.fee_bps.into(), + BPS_DENOMINATOR.into(), + transfer_fee.max_fee.into(), + false, + ) +} + +/// Reverse the application of a transfer fee to an amount +/// e.g. You received 9900 amount with 100 fee rate. The fee amount will be 100. +/// So the amount before fee will be 10000. +/// +/// # Parameters +/// - `amount`: The amount to reverse the fee from +/// - `transfer_fee`: The transfer fee to reverse +/// +/// # Returns +/// - `u64`: The amount before the fee has been applied +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_reverse_apply_transfer_fee( + amount: u64, + transfer_fee: TransferFee, +) -> Result { + try_reverse_adjust_amount( + amount, + transfer_fee.fee_bps.into(), + BPS_DENOMINATOR.into(), + transfer_fee.max_fee.into(), + false, + ) +} + +/// Get the maximum amount with a slippage tolerance +/// e.g. Your estimated amount you send is 10000 with 100 slippage tolerance. The max you send will be 10100. +/// +/// # Parameters +/// - `amount`: The amount to apply the fee to +/// - `slippage_tolerance_bps`: The slippage tolerance in bps +/// +/// # Returns +/// - `u64`: The maximum amount +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_get_max_amount_with_slippage_tolerance( + amount: u64, + slippage_tolerance_bps: u16, +) -> Result { + try_adjust_amount( + amount, + slippage_tolerance_bps.into(), + BPS_DENOMINATOR.into(), + u128::MAX, + true, + ) +} + +/// Get the minimum amount with a slippage tolerance +/// e.g. Your estimated amount you receive is 10000 with 100 slippage tolerance. The min amount you receive will be 9900. +/// +/// # Parameters +/// - `amount`: The amount to apply the fee to +/// - `slippage_tolerance_bps`: The slippage tolerance in bps +/// +/// # Returns +/// - `u64`: The minimum amount +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_get_min_amount_with_slippage_tolerance( + amount: u64, + slippage_tolerance_bps: u16, +) -> Result { + try_adjust_amount( + amount, + slippage_tolerance_bps.into(), + BPS_DENOMINATOR.into(), + u128::MAX, + false, + ) +} + +/// Apply a swap fee to an amount +/// e.g. You send 10000 amount with 10000 fee rate. The fee amount will be 100. +/// So the amount after fee will be 9900. +/// +/// # Parameters +/// - `amount`: The amount to apply the fee to +/// - `fee_rate`: The fee rate to apply denominated in 1e6 +/// +/// # Returns +/// - `u64`: The amount after the fee has been applied +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_apply_swap_fee(amount: u64, fee_rate: u16) -> Result { + try_adjust_amount( + amount, + fee_rate.into(), + FEE_RATE_DENOMINATOR.into(), + u128::MAX, + false, + ) +} + +/// Reverse the application of a swap fee to an amount +/// e.g. You received 9900 amount with 10000 fee rate. The fee amount will be 100. +/// So the amount before fee will be 10000. +/// +/// # Parameters +/// - `amount`: The amount to reverse the fee from +/// - `fee_rate`: The fee rate to reverse denominated in 1e6 +/// +/// # Returns +/// - `u64`: The amount before the fee has been applied +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn try_reverse_apply_swap_fee(amount: u64, fee_rate: u16) -> Result { + try_reverse_adjust_amount( + amount, + fee_rate.into(), + FEE_RATE_DENOMINATOR.into(), + u128::MAX, + false, + ) +} + +// Private functions + +fn try_adjust_amount( + amount: u64, + adjust_numerator: u128, + adjust_denominator: u128, + adjust_max: u128, + adjust_up: bool, +) -> Result { + if amount == 0 { + return Ok(0); + } + + if adjust_numerator == 0 { + return Ok(amount); + } + + let amount: u128 = amount.into(); + + let product = if adjust_up { + adjust_denominator + adjust_numerator + } else { + adjust_denominator - adjust_numerator + }; + + let numerator = amount.checked_mul(product).ok_or(ARITHMETIC_OVERFLOW)?; + let denominator = adjust_denominator; + let quotient = numerator / denominator; + let remainder = numerator % denominator; + + let mut result: u128 = if adjust_up && remainder != 0 { + quotient + 1 + } else { + quotient + }; + + let fee_amount = if adjust_up { + result - amount + } else { + amount - result + }; + + if fee_amount >= adjust_max { + if adjust_up { + result = amount + adjust_max + } else { + result = amount - adjust_max + } + } + + result.try_into().map_err(|_| AMOUNT_EXCEEDS_MAX_U64) +} + +fn try_reverse_adjust_amount( + amount: u64, + adjust_numerator: u128, + adjust_denominator: u128, + adjust_max: u128, + adjust_up: bool, +) -> Result { + if amount == 0 { + return Ok(0); + } + + if adjust_numerator == 0 { + return Ok(amount); + } + + let amount: u128 = amount.into(); + + let numerator = amount + .checked_mul(adjust_denominator) + .ok_or(ARITHMETIC_OVERFLOW)?; + let denominator = if adjust_up { + adjust_denominator + adjust_numerator + } else { + adjust_denominator - adjust_numerator + }; + + let quotient = numerator / denominator; + let remainder = numerator % denominator; + + let mut result = if !adjust_up && remainder != 0 { + quotient + 1 + } else { + quotient + }; + + let fee_amount = if adjust_up { + amount - result + } else { + result - amount + }; + + if fee_amount >= adjust_max { + if adjust_up { + result = amount - adjust_max + } else { + result = amount + adjust_max + } + } + + result.try_into().map_err(|_| AMOUNT_EXCEEDS_MAX_U64) +} + +fn order_prices(a: u128, b: u128) -> (u128, u128) { + if a < b { + (a, b) + } else { + (b, a) + } +} + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use super::*; + + #[test] + fn test_get_amount_delta_a() { + assert_eq!( + try_get_amount_delta_a(4 << 64, 2 << 64, 4, true).unwrap(), + 1 + ); + assert_eq!( + try_get_amount_delta_a(4 << 64, 2 << 64, 4, false).unwrap(), + 1 + ); + + assert_eq!( + try_get_amount_delta_a(4 << 64, 4 << 64, 4, true).unwrap(), + 0 + ); + assert_eq!( + try_get_amount_delta_a(4 << 64, 4 << 64, 4, false).unwrap(), + 0 + ); + } + + #[test] + fn test_get_amount_delta_b() { + assert_eq!( + try_get_amount_delta_b(4 << 64, 2 << 64, 4, true).unwrap(), + 8 + ); + assert_eq!( + try_get_amount_delta_b(4 << 64, 2 << 64, 4, false).unwrap(), + 8 + ); + + assert_eq!( + try_get_amount_delta_b(4 << 64, 4 << 64, 4, true).unwrap(), + 0 + ); + assert_eq!( + try_get_amount_delta_b(4 << 64, 4 << 64, 4, false).unwrap(), + 0 + ); + } + + #[test] + fn test_get_next_sqrt_price_from_a() { + assert_eq!( + try_get_next_sqrt_price_from_a(4 << 64, 4, 1, true).unwrap(), + 2 << 64 + ); + assert_eq!( + try_get_next_sqrt_price_from_a(2 << 64, 4, 1, false).unwrap(), + 4 << 64 + ); + + assert_eq!( + try_get_next_sqrt_price_from_a(4 << 64, 4, 0, true).unwrap(), + 4 << 64 + ); + assert_eq!( + try_get_next_sqrt_price_from_a(4 << 64, 4, 0, false).unwrap(), + 4 << 64 + ); + } + + #[test] + fn test_get_next_sqrt_price_from_b() { + assert_eq!( + try_get_next_sqrt_price_from_b(2 << 64, 4, 8, true).unwrap(), + 4 << 64 + ); + assert_eq!( + try_get_next_sqrt_price_from_b(4 << 64, 4, 8, false).unwrap(), + 2 << 64 + ); + + assert_eq!( + try_get_next_sqrt_price_from_b(4 << 64, 4, 0, true).unwrap(), + 4 << 64 + ); + assert_eq!( + try_get_next_sqrt_price_from_b(4 << 64, 4, 0, false).unwrap(), + 4 << 64 + ); + } + + #[test] + fn test_apply_transfer_fee() { + assert_eq!( + try_apply_transfer_fee(10000, TransferFee::new(100)).unwrap(), + 9900 + ); + assert_eq!( + try_apply_transfer_fee(10000, TransferFee::new(1000)).unwrap(), + 9000 + ); + } + + #[test] + fn test_apply_transfer_fee_with_max() { + assert_eq!( + try_apply_transfer_fee(10000, TransferFee::new_with_max(100, 500)).unwrap(), + 9900 + ); + assert_eq!( + try_apply_transfer_fee(10000, TransferFee::new_with_max(1000, 500)).unwrap(), + 9500 + ); + } + + #[test] + fn test_reverse_apply_transfer_fee() { + assert_eq!( + try_reverse_apply_transfer_fee(9900, TransferFee::new(100)).unwrap(), + 10000 + ); + assert_eq!( + try_reverse_apply_transfer_fee(9000, TransferFee::new(1000)).unwrap(), + 10000 + ); + } + + #[test] + fn test_reverse_apply_transfer_fee_with_max() { + assert_eq!( + try_reverse_apply_transfer_fee(9900, TransferFee::new_with_max(100, 500)).unwrap(), + 10000 + ); + assert_eq!( + try_reverse_apply_transfer_fee(9500, TransferFee::new_with_max(1000, 500)).unwrap(), + 10000 + ); + } + + #[test] + fn test_get_max_amount_with_slippage_tolerance() { + assert_eq!( + try_get_max_amount_with_slippage_tolerance(10000, 100).unwrap(), + 10100 + ); + assert_eq!( + try_get_max_amount_with_slippage_tolerance(10000, 1000).unwrap(), + 11000 + ); + } + + #[test] + fn test_get_min_amount_with_slippage_tolerance() { + assert_eq!( + try_get_min_amount_with_slippage_tolerance(10000, 100).unwrap(), + 9900 + ); + assert_eq!( + try_get_min_amount_with_slippage_tolerance(10000, 1000).unwrap(), + 9000 + ); + } + + #[test] + fn test_apply_swap_fee() { + assert_eq!(try_apply_swap_fee(10000, 1000).unwrap(), 9990); + assert_eq!(try_apply_swap_fee(10000, 10000).unwrap(), 9900); + } + + #[test] + fn test_reverse_apply_swap_fee() { + assert_eq!(try_reverse_apply_swap_fee(9990, 1000).unwrap(), 10000); + assert_eq!(try_reverse_apply_swap_fee(9900, 10000).unwrap(), 10000); + } +} diff --git a/rust-sdk/core/src/quote/fees.rs b/rust-sdk/core/src/quote/fees.rs new file mode 100644 index 000000000..0bae1d45a --- /dev/null +++ b/rust-sdk/core/src/quote/fees.rs @@ -0,0 +1,210 @@ +use ethnum::U256; + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use crate::{ + try_apply_transfer_fee, CollectFeesQuote, ErrorCode, PositionFacade, TickFacade, TransferFee, + WhirlpoolFacade, AMOUNT_EXCEEDS_MAX_U64, ARITHMETIC_OVERFLOW, +}; + +/// Calculate fees owed for a position +/// +/// # Paramters +/// - `whirlpool`: The whirlpool state +/// - `position`: The position state +/// - `tick_lower`: The lower tick state +/// - `tick_upper`: The upper tick state +/// - `transfer_fee_a`: The transfer fee for token A +/// - `transfer_fee_b`: The transfer fee for token B +/// +/// # Returns +/// - `CollectFeesQuote`: The fees owed for token A and token B +#[allow(clippy::too_many_arguments)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn collect_fees_quote( + whirlpool: WhirlpoolFacade, + position: PositionFacade, + tick_lower: TickFacade, + tick_upper: TickFacade, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let mut fee_growth_below_a: u128 = tick_lower.fee_growth_outside_a; + let mut fee_growth_above_a: u128 = tick_upper.fee_growth_outside_a; + let mut fee_growth_below_b: u128 = tick_lower.fee_growth_outside_b; + let mut fee_growth_above_b: u128 = tick_upper.fee_growth_outside_b; + + if whirlpool.tick_current_index < position.tick_lower_index { + fee_growth_below_a = whirlpool.fee_growth_global_a - fee_growth_below_a; + fee_growth_below_b = whirlpool.fee_growth_global_b - fee_growth_below_b; + } + + if whirlpool.tick_current_index >= position.tick_upper_index { + fee_growth_above_a = whirlpool.fee_growth_global_a - fee_growth_above_a; + fee_growth_above_b = whirlpool.fee_growth_global_b - fee_growth_above_b; + } + + let fee_growth_inside_a = + whirlpool.fee_growth_global_a - fee_growth_below_a - fee_growth_above_a; + + let fee_growth_inside_b = + whirlpool.fee_growth_global_b - fee_growth_below_b - fee_growth_above_b; + + let fee_owed_delta_a: U256 = + ::from(fee_growth_inside_a - position.fee_growth_checkpoint_a) + .checked_mul(position.liquidity.into()) + .ok_or(ARITHMETIC_OVERFLOW)? + >> 64; + + let fee_owed_delta_b: U256 = + ::from(fee_growth_inside_b - position.fee_growth_checkpoint_b) + .checked_mul(position.liquidity.into()) + .ok_or(ARITHMETIC_OVERFLOW)? + >> 64; + + let fee_owed_delta_a: u64 = fee_owed_delta_a + .try_into() + .map_err(|_| AMOUNT_EXCEEDS_MAX_U64)?; + let fee_owed_delta_b: u64 = fee_owed_delta_b + .try_into() + .map_err(|_| AMOUNT_EXCEEDS_MAX_U64)?; + + let withdrawable_fee_a = position.fee_owed_a + fee_owed_delta_a; + let withdrawable_fee_b = position.fee_owed_b + fee_owed_delta_b; + + let fee_owed_a = + try_apply_transfer_fee(withdrawable_fee_a, transfer_fee_a.unwrap_or_default())?; + let fee_owed_b = + try_apply_transfer_fee(withdrawable_fee_b, transfer_fee_b.unwrap_or_default())?; + + Ok(CollectFeesQuote { + fee_owed_a, + fee_owed_b, + }) +} + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use super::*; + + fn test_whirlpool(tick_index: i32) -> WhirlpoolFacade { + WhirlpoolFacade { + tick_current_index: tick_index, + fee_growth_global_a: 800, + fee_growth_global_b: 1000, + ..WhirlpoolFacade::default() + } + } + + fn test_position() -> PositionFacade { + PositionFacade { + liquidity: 10000000000000000000, + tick_lower_index: 5, + tick_upper_index: 10, + fee_growth_checkpoint_a: 0, + fee_owed_a: 400, + fee_growth_checkpoint_b: 0, + fee_owed_b: 600, + ..PositionFacade::default() + } + } + + fn test_tick() -> TickFacade { + TickFacade { + fee_growth_outside_a: 50, + fee_growth_outside_b: 20, + ..TickFacade::default() + } + } + + #[test] + fn test_collect_out_of_range_lower() { + let result = collect_fees_quote( + test_whirlpool(0), + test_position(), + test_tick(), + test_tick(), + None, + None, + ) + .unwrap(); + assert_eq!(result.fee_owed_a, 400); + assert_eq!(result.fee_owed_b, 600); + } + + #[test] + fn test_in_range() { + let result = collect_fees_quote( + test_whirlpool(7), + test_position(), + test_tick(), + test_tick(), + None, + None, + ) + .unwrap(); + assert_eq!(result.fee_owed_a, 779); + assert_eq!(result.fee_owed_b, 1120); + } + + #[test] + fn test_collect_out_of_range_upper() { + let result = collect_fees_quote( + test_whirlpool(15), + test_position(), + test_tick(), + test_tick(), + None, + None, + ) + .unwrap(); + assert_eq!(result.fee_owed_a, 400); + assert_eq!(result.fee_owed_b, 600); + } + + #[test] + fn test_collect_on_range_lower() { + let result = collect_fees_quote( + test_whirlpool(5), + test_position(), + test_tick(), + test_tick(), + None, + None, + ) + .unwrap(); + assert_eq!(result.fee_owed_a, 779); + assert_eq!(result.fee_owed_b, 1120); + } + + #[test] + fn test_collect_on_upper() { + let result = collect_fees_quote( + test_whirlpool(10), + test_position(), + test_tick(), + test_tick(), + None, + None, + ) + .unwrap(); + assert_eq!(result.fee_owed_a, 400); + assert_eq!(result.fee_owed_b, 600); + } + + #[test] + fn test_collect_transfer_fee() { + let result = collect_fees_quote( + test_whirlpool(7), + test_position(), + test_tick(), + test_tick(), + Some(TransferFee::new(2000)), + Some(TransferFee::new(5000)), + ) + .unwrap(); + assert_eq!(result.fee_owed_a, 623); + assert_eq!(result.fee_owed_b, 560); + } +} diff --git a/rust-sdk/core/src/quote/liquidity.rs b/rust-sdk/core/src/quote/liquidity.rs new file mode 100644 index 000000000..0f16fd1d8 --- /dev/null +++ b/rust-sdk/core/src/quote/liquidity.rs @@ -0,0 +1,1204 @@ +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use ethnum::U256; + +use crate::{ + order_tick_indexes, position_status, tick_index_to_sqrt_price, try_apply_transfer_fee, + try_get_max_amount_with_slippage_tolerance, try_get_min_amount_with_slippage_tolerance, + try_reverse_apply_transfer_fee, DecreaseLiquidityQuote, ErrorCode, IncreaseLiquidityQuote, + PositionStatus, TransferFee, AMOUNT_EXCEEDS_MAX_U64, ARITHMETIC_OVERFLOW, U128, +}; + +/// Calculate the quote for decreasing liquidity +/// +/// # Parameters +/// - `liquidity_delta` - The amount of liquidity to decrease +/// - `slippage_tolerance` - The slippage tolerance in bps +/// - `current_sqrt_price` - The current sqrt price of the pool +/// - `tick_index_1` - The first tick index of the position +/// - `tick_index_2` - The second tick index of the position +/// - `transfer_fee_a` - The transfer fee for token A in bps +/// - `transfer_fee_b` - The transfer fee for token B in bps +/// +/// # Returns +/// - A DecreaseLiquidityQuote struct containing the estimated token amounts +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn decrease_liquidity_quote( + liquidity_delta: U128, + slippage_tolerance_bps: u16, + current_sqrt_price: U128, + tick_index_1: i32, + tick_index_2: i32, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let liquidity_delta: u128 = liquidity_delta.into(); + if liquidity_delta == 0 { + return Ok(DecreaseLiquidityQuote::default()); + } + + let tick_range = order_tick_indexes(tick_index_1, tick_index_2); + let current_sqrt_price: u128 = current_sqrt_price.into(); + + let (token_est_before_fees_a, token_est_before_fees_b) = + try_get_token_estimates_from_liquidity( + liquidity_delta, + current_sqrt_price, + tick_range.tick_lower_index, + tick_range.tick_upper_index, + )?; + + let token_min_before_slippage_a = + try_apply_transfer_fee(token_est_before_fees_a, transfer_fee_a.unwrap_or_default())?; + let token_min_before_slippage_b = + try_apply_transfer_fee(token_est_before_fees_b, transfer_fee_b.unwrap_or_default())?; + + let token_est_a = + try_apply_transfer_fee(token_est_before_fees_a, transfer_fee_a.unwrap_or_default())?; + let token_est_b = + try_apply_transfer_fee(token_est_before_fees_b, transfer_fee_b.unwrap_or_default())?; + + let token_min_a = try_get_min_amount_with_slippage_tolerance( + token_min_before_slippage_a, + slippage_tolerance_bps, + )?; + let token_min_b = try_get_min_amount_with_slippage_tolerance( + token_min_before_slippage_b, + slippage_tolerance_bps, + )?; + + Ok(DecreaseLiquidityQuote { + liquidity_delta, + token_est_a, + token_est_b, + token_min_a, + token_min_b, + }) +} + +/// Calculate the quote for decreasing liquidity given a token a amount +/// +/// # Parameters +/// - `token_amount_a` - The amount of token a to decrease +/// - `slippage_tolerance` - The slippage tolerance in bps +/// - `current_sqrt_price` - The current sqrt price of the pool +/// - `tick_index_1` - The first tick index of the position +/// - `tick_index_2` - The second tick index of the position +/// - `transfer_fee_a` - The transfer fee for token A in bps +/// - `transfer_fee_b` - The transfer fee for token B in bps +/// +/// # Returns +/// - A DecreaseLiquidityQuote struct containing the estimated token amounts +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn decrease_liquidity_quote_a( + token_amount_a: u64, + slippage_tolerance_bps: u16, + current_sqrt_price: U128, + tick_index_1: i32, + tick_index_2: i32, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let tick_range = order_tick_indexes(tick_index_1, tick_index_2); + let token_delta_a = + try_reverse_apply_transfer_fee(token_amount_a, transfer_fee_a.unwrap_or_default())?; + + if token_delta_a == 0 { + return Ok(DecreaseLiquidityQuote::default()); + } + + let current_sqrt_price: u128 = current_sqrt_price.into(); + let sqrt_price_lower: u128 = tick_index_to_sqrt_price(tick_range.tick_lower_index).into(); + let sqrt_price_upper: u128 = tick_index_to_sqrt_price(tick_range.tick_upper_index).into(); + + let position_status = position_status( + current_sqrt_price.into(), + tick_range.tick_lower_index, + tick_range.tick_upper_index, + ); + + let liquidity: u128 = match position_status { + PositionStatus::PriceBelowRange => { + try_get_liquidity_from_a(token_delta_a, sqrt_price_lower, sqrt_price_upper)? + } + PositionStatus::Invalid | PositionStatus::PriceAboveRange => 0, + PositionStatus::PriceInRange => { + try_get_liquidity_from_a(token_delta_a, current_sqrt_price, sqrt_price_upper)? + } + }; + + decrease_liquidity_quote( + liquidity.into(), + slippage_tolerance_bps, + current_sqrt_price.into(), + tick_index_1, + tick_index_2, + transfer_fee_a, + transfer_fee_b, + ) +} + +/// Calculate the quote for decreasing liquidity given a token b amount +/// +/// # Parameters +/// - `token_amount_b` - The amount of token b to decrease +/// - `slippage_tolerance` - The slippage tolerance in bps +/// - `current_sqrt_price` - The current sqrt price of the pool +/// - `tick_index_1` - The first tick index of the position +/// - `tick_index_2` - The second tick index of the position +/// - `transfer_fee_a` - The transfer fee for token A in bps +/// - `transfer_fee_b` - The transfer fee for token B in bps +/// +/// # Returns +/// - A DecreaseLiquidityQuote struct containing the estimated token amounts +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn decrease_liquidity_quote_b( + token_amount_b: u64, + slippage_tolerance_bps: u16, + current_sqrt_price: U128, + tick_index_1: i32, + tick_index_2: i32, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let tick_range = order_tick_indexes(tick_index_1, tick_index_2); + let token_delta_b = + try_reverse_apply_transfer_fee(token_amount_b, transfer_fee_b.unwrap_or_default())?; + + if token_delta_b == 0 { + return Ok(DecreaseLiquidityQuote::default()); + } + + let current_sqrt_price: u128 = current_sqrt_price.into(); + let sqrt_price_lower: u128 = tick_index_to_sqrt_price(tick_range.tick_lower_index).into(); + let sqrt_price_upper: u128 = tick_index_to_sqrt_price(tick_range.tick_upper_index).into(); + + let position_status = position_status( + current_sqrt_price.into(), + tick_range.tick_lower_index, + tick_range.tick_upper_index, + ); + + let liquidity: u128 = match position_status { + PositionStatus::Invalid | PositionStatus::PriceBelowRange => 0, + PositionStatus::PriceAboveRange => { + try_get_liquidity_from_b(token_delta_b, sqrt_price_lower, sqrt_price_upper)? + } + PositionStatus::PriceInRange => { + try_get_liquidity_from_b(token_delta_b, sqrt_price_lower, current_sqrt_price)? + } + }; + + decrease_liquidity_quote( + liquidity.into(), + slippage_tolerance_bps, + current_sqrt_price.into(), + tick_index_1, + tick_index_2, + transfer_fee_a, + transfer_fee_b, + ) +} + +/// Calculate the quote for increasing liquidity +/// +/// # Parameters +/// - `liquidity_delta` - The amount of liquidity to increase +/// - `slippage_tolerance` - The slippage tolerance in bps +/// - `current_sqrt_price` - The current sqrt price of the pool +/// - `tick_index_1` - The first tick index of the position +/// - `tick_index_2` - The second tick index of the position +/// - `transfer_fee_a` - The transfer fee for token A in bps +/// - `transfer_fee_b` - The transfer fee for token B in bps +/// +/// # Returns +/// - An IncreaseLiquidityQuote struct containing the estimated token amounts +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn increase_liquidity_quote( + liquidity_delta: U128, + slippage_tolerance_bps: u16, + current_sqrt_price: U128, + tick_index_1: i32, + tick_index_2: i32, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let liquidity_delta: u128 = liquidity_delta.into(); + if liquidity_delta == 0 { + return Ok(IncreaseLiquidityQuote::default()); + } + + let current_sqrt_price: u128 = current_sqrt_price.into(); + let tick_range = order_tick_indexes(tick_index_1, tick_index_2); + + let (token_est_before_fees_a, token_est_before_fees_b) = + try_get_token_estimates_from_liquidity( + liquidity_delta, + current_sqrt_price, + tick_range.tick_lower_index, + tick_range.tick_upper_index, + )?; + + let token_max_before_slippage_a = try_reverse_apply_transfer_fee( + token_est_before_fees_a, + transfer_fee_a.unwrap_or_default(), + )?; + let token_max_before_slippage_b = try_reverse_apply_transfer_fee( + token_est_before_fees_b, + transfer_fee_b.unwrap_or_default(), + )?; + + let token_est_a = try_reverse_apply_transfer_fee( + token_est_before_fees_a, + transfer_fee_a.unwrap_or_default(), + )?; + let token_est_b = try_reverse_apply_transfer_fee( + token_est_before_fees_b, + transfer_fee_b.unwrap_or_default(), + )?; + + let token_max_a = try_get_max_amount_with_slippage_tolerance( + token_max_before_slippage_a, + slippage_tolerance_bps, + )?; + let token_max_b = try_get_max_amount_with_slippage_tolerance( + token_max_before_slippage_b, + slippage_tolerance_bps, + )?; + + Ok(IncreaseLiquidityQuote { + liquidity_delta, + token_est_a, + token_est_b, + token_max_a, + token_max_b, + }) +} + +/// Calculate the quote for increasing liquidity given a token a amount +/// +/// # Parameters +/// - `token_amount_a` - The amount of token a to increase +/// - `slippage_tolerance` - The slippage tolerance in bps +/// - `current_sqrt_price` - The current sqrt price of the pool +/// - `tick_index_1` - The first tick index of the position +/// - `tick_index_2` - The second tick index of the position +/// - `transfer_fee_a` - The transfer fee for token A in bps +/// - `transfer_fee_b` - The transfer fee for token B in bps +/// +/// # Returns +/// - An IncreaseLiquidityQuote struct containing the estimated token amounts +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn increase_liquidity_quote_a( + token_amount_a: u64, + slippage_tolerance_bps: u16, + current_sqrt_price: U128, + tick_index_1: i32, + tick_index_2: i32, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let tick_range = order_tick_indexes(tick_index_1, tick_index_2); + let token_delta_a = try_apply_transfer_fee(token_amount_a, transfer_fee_a.unwrap_or_default())?; + + if token_delta_a == 0 { + return Ok(IncreaseLiquidityQuote::default()); + } + + let current_sqrt_price: u128 = current_sqrt_price.into(); + let sqrt_price_lower: u128 = tick_index_to_sqrt_price(tick_range.tick_lower_index).into(); + let sqrt_price_upper: u128 = tick_index_to_sqrt_price(tick_range.tick_upper_index).into(); + + let position_status = position_status(current_sqrt_price.into(), tick_index_1, tick_index_2); + + let liquidity: u128 = match position_status { + PositionStatus::PriceBelowRange => { + try_get_liquidity_from_a(token_delta_a, sqrt_price_lower, sqrt_price_upper)? + } + PositionStatus::Invalid | PositionStatus::PriceAboveRange => 0, + PositionStatus::PriceInRange => { + try_get_liquidity_from_a(token_delta_a, current_sqrt_price, sqrt_price_upper)? + } + }; + + increase_liquidity_quote( + liquidity.into(), + slippage_tolerance_bps, + current_sqrt_price.into(), + tick_index_1, + tick_index_2, + transfer_fee_a, + transfer_fee_b, + ) +} + +/// Calculate the quote for increasing liquidity given a token b amount +/// +/// # Parameters +/// - `token_amount_b` - The amount of token b to increase +/// - `slippage_tolerance` - The slippage tolerance in bps +/// - `current_sqrt_price` - The current sqrt price of the pool +/// - `tick_index_1` - The first tick index of the position +/// - `tick_index_2` - The second tick index of the position +/// - `transfer_fee_a` - The transfer fee for token A in bps +/// - `transfer_fee_b` - The transfer fee for token B in bps +/// +/// # Returns +/// - An IncreaseLiquidityQuote struct containing the estimated token amounts +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn increase_liquidity_quote_b( + token_amount_b: u64, + slippage_tolerance_bps: u16, + current_sqrt_price: U128, + tick_index_1: i32, + tick_index_2: i32, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let tick_range = order_tick_indexes(tick_index_1, tick_index_2); + let token_delta_b = try_apply_transfer_fee(token_amount_b, transfer_fee_b.unwrap_or_default())?; + + if token_delta_b == 0 { + return Ok(IncreaseLiquidityQuote::default()); + } + + let current_sqrt_price: u128 = current_sqrt_price.into(); + let sqrt_price_lower: u128 = tick_index_to_sqrt_price(tick_range.tick_lower_index).into(); + let sqrt_price_upper: u128 = tick_index_to_sqrt_price(tick_range.tick_upper_index).into(); + + let position_status = position_status(current_sqrt_price.into(), tick_index_1, tick_index_2); + + let liquidity: u128 = match position_status { + PositionStatus::Invalid | PositionStatus::PriceBelowRange => 0, + PositionStatus::PriceAboveRange => { + try_get_liquidity_from_b(token_delta_b, sqrt_price_lower, sqrt_price_upper)? + } + PositionStatus::PriceInRange => { + try_get_liquidity_from_b(token_delta_b, sqrt_price_lower, current_sqrt_price)? + } + }; + + increase_liquidity_quote( + liquidity.into(), + slippage_tolerance_bps, + current_sqrt_price.into(), + tick_index_1, + tick_index_2, + transfer_fee_a, + transfer_fee_b, + ) +} + +// Private functions + +fn try_get_liquidity_from_a( + token_delta_a: u64, + sqrt_price_lower: u128, + sqrt_price_upper: u128, +) -> Result { + let sqrt_price_diff = sqrt_price_upper - sqrt_price_lower; + let mul: U256 = ::from(token_delta_a) + .checked_mul(sqrt_price_lower.into()) + .ok_or(ARITHMETIC_OVERFLOW)? + .checked_mul(sqrt_price_upper.into()) + .ok_or(ARITHMETIC_OVERFLOW)?; + let result: U256 = (mul / sqrt_price_diff) >> 64; + result.try_into().map_err(|_| AMOUNT_EXCEEDS_MAX_U64) +} + +fn try_get_token_a_from_liquidity( + liquidity_delta: u128, + sqrt_price_lower: u128, + sqrt_price_upper: u128, + round_up: bool, +) -> Result { + let sqrt_price_diff = sqrt_price_upper - sqrt_price_lower; + let numerator: U256 = ::from(liquidity_delta) + .saturating_mul(sqrt_price_diff.into()) + .checked_shl(64) + .ok_or(ARITHMETIC_OVERFLOW)?; + let denominator = sqrt_price_upper.saturating_mul(sqrt_price_lower); + let quotient = numerator / denominator; + let remainder = numerator % denominator; + if round_up && remainder != 0 { + (quotient + 1) + .try_into() + .map_err(|_| AMOUNT_EXCEEDS_MAX_U64) + } else { + quotient.try_into().map_err(|_| AMOUNT_EXCEEDS_MAX_U64) + } +} + +fn try_get_liquidity_from_b( + token_delta_b: u64, + sqrt_price_lower: u128, + sqrt_price_upper: u128, +) -> Result { + let numerator: U256 = ::from(token_delta_b) + .checked_shl(64) + .ok_or(ARITHMETIC_OVERFLOW)?; + let sqrt_price_diff = sqrt_price_upper - sqrt_price_lower; + numerator + .saturating_div(sqrt_price_diff.into()) + .try_into() + .map_err(|_| AMOUNT_EXCEEDS_MAX_U64) +} + +fn try_get_token_b_from_liquidity( + liquidity_delta: u128, + sqrt_price_lower: u128, + sqrt_price_upper: u128, + round_up: bool, +) -> Result { + let sqrt_price_diff = sqrt_price_upper - sqrt_price_lower; + let mul: U256 = ::from(liquidity_delta) + .checked_mul(sqrt_price_diff.into()) + .ok_or(ARITHMETIC_OVERFLOW)?; + let result: U256 = mul >> 64; + if round_up && mul & ::from(u64::MAX) > 0 { + (result + 1).try_into().map_err(|_| AMOUNT_EXCEEDS_MAX_U64) + } else { + result.try_into().map_err(|_| AMOUNT_EXCEEDS_MAX_U64) + } +} + +fn try_get_token_estimates_from_liquidity( + liquidity_delta: u128, + current_sqrt_price: u128, + tick_lower_index: i32, + tick_upper_index: i32, +) -> Result<(u64, u64), ErrorCode> { + if liquidity_delta == 0 { + return Ok((0, 0)); + } + + let sqrt_price_lower = tick_index_to_sqrt_price(tick_lower_index).into(); + let sqrt_price_upper = tick_index_to_sqrt_price(tick_upper_index).into(); + + let position_status = position_status( + current_sqrt_price.into(), + tick_lower_index, + tick_upper_index, + ); + + match position_status { + PositionStatus::PriceBelowRange => { + let token_a = try_get_token_a_from_liquidity( + liquidity_delta, + sqrt_price_lower, + sqrt_price_upper, + true, + )?; + Ok((token_a, 0)) + } + PositionStatus::PriceInRange => { + let token_a = try_get_token_a_from_liquidity( + liquidity_delta, + sqrt_price_lower, + current_sqrt_price, + false, + )?; + let token_b = try_get_token_b_from_liquidity( + liquidity_delta, + current_sqrt_price, + sqrt_price_upper, + false, + )?; + Ok((token_a, token_b)) + } + PositionStatus::PriceAboveRange => { + let token_b = try_get_token_b_from_liquidity( + liquidity_delta, + sqrt_price_lower, + sqrt_price_upper, + true, + )?; + Ok((0, token_b)) + } + PositionStatus::Invalid => Ok((0, 0)), + } +} + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use super::*; + + #[test] + fn test_decrease_liquidity_quote() { + // Below range + let result = + decrease_liquidity_quote(1000000, 100, 18354745142194483561, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 1000); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 990); + assert_eq!(result.token_min_b, 0); + + // in range + let result = + decrease_liquidity_quote(1000000, 100, 18446744073709551616, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 500); + assert_eq!(result.token_est_b, 500); + assert_eq!(result.token_min_a, 495); + assert_eq!(result.token_min_b, 495); + + // Above range + let result = + decrease_liquidity_quote(1000000, 100, 18539204128674405812, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 1000); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 990); + + // zero liquidity + let result = + decrease_liquidity_quote(0, 100, 18446744073709551616, -10, 10, None, None).unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + } + + #[test] + fn test_decrease_liquidity_quote_a() { + // Below range + let result = + decrease_liquidity_quote_a(1000, 100, 18354745142194483561, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000049); + assert_eq!(result.token_est_a, 1000); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 990); + assert_eq!(result.token_min_b, 0); + + // in range + let result = + decrease_liquidity_quote_a(500, 100, 18446744073709551616, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000300); + assert_eq!(result.token_est_a, 500); + assert_eq!(result.token_est_b, 500); + assert_eq!(result.token_min_a, 495); + assert_eq!(result.token_min_b, 495); + + // Above range + let result = + decrease_liquidity_quote_a(1000, 100, 18539204128674405812, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + + // zero liquidity + let result = + decrease_liquidity_quote_a(0, 100, 18446744073709551616, -10, 10, None, None).unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + } + + #[test] + fn test_decrease_liquidity_quote_b() { + // Below range + let result = + decrease_liquidity_quote_b(1000, 100, 18354745142194483561, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + + // in range + let result = + decrease_liquidity_quote_b(500, 100, 18446744073709551616, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000300); + assert_eq!(result.token_est_a, 500); + assert_eq!(result.token_est_b, 500); + assert_eq!(result.token_min_a, 495); + assert_eq!(result.token_min_b, 495); + + // Above range + let result = + decrease_liquidity_quote_b(1000, 100, 18539204128674405812, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000049); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 1000); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 990); + + // zero liquidity + let result = + decrease_liquidity_quote_b(0, 100, 18446744073709551616, -10, 10, None, None).unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + } + + #[test] + fn test_increase_liquidity_quote() { + // Below range + let result = + increase_liquidity_quote(1000000, 100, 18354745142194483561, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 1000); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 1010); + assert_eq!(result.token_max_b, 0); + + // in range + let result = + increase_liquidity_quote(1000000, 100, 18446744073709551616, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 500); + assert_eq!(result.token_est_b, 500); + assert_eq!(result.token_max_a, 505); + assert_eq!(result.token_max_b, 505); + + // Above range + let result = + increase_liquidity_quote(1000000, 100, 18539204128674405812, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 1000); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 1010); + + // zero liquidity + let result = + increase_liquidity_quote(0, 100, 18446744073709551616, -10, 10, None, None).unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + } + + #[test] + fn test_increase_liquidity_quote_a() { + // Below range + let result = + increase_liquidity_quote_a(1000, 100, 18354745142194483561, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000049); + assert_eq!(result.token_est_a, 1000); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 1010); + assert_eq!(result.token_max_b, 0); + + // in range + let result = + increase_liquidity_quote_a(500, 100, 18446744073709551616, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000300); + assert_eq!(result.token_est_a, 500); + assert_eq!(result.token_est_b, 500); + assert_eq!(result.token_max_a, 505); + assert_eq!(result.token_max_b, 505); + + // Above range + let result = + increase_liquidity_quote_a(1000, 100, 18539204128674405812, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + + // zero liquidity + let result = + increase_liquidity_quote_a(0, 100, 18446744073709551616, -10, 10, None, None).unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + } + + #[test] + fn test_increase_liquidity_quote_b() { + // Below range + let result = + increase_liquidity_quote_b(1000, 100, 18354745142194483561, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + + // in range + let result = + increase_liquidity_quote_b(500, 100, 18446744073709551616, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000300); + assert_eq!(result.token_est_a, 500); + assert_eq!(result.token_est_b, 500); + assert_eq!(result.token_max_a, 505); + assert_eq!(result.token_max_b, 505); + + // Above range + let result = + increase_liquidity_quote_b(1000, 100, 18539204128674405812, -10, 10, None, None) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000049); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 1000); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 1010); + + // zero liquidity + let result = + increase_liquidity_quote_b(0, 100, 18446744073709551616, -10, 10, None, None).unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + } + + #[test] + fn test_decrease_liquidity_quote_with_fee() { + // Below range + let result = decrease_liquidity_quote( + 1000000, + 100, + 18354745142194483561, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 800); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 792); + assert_eq!(result.token_min_b, 0); + + // in range + let result = decrease_liquidity_quote( + 1000000, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 400); + assert_eq!(result.token_est_b, 450); + assert_eq!(result.token_min_a, 396); + assert_eq!(result.token_min_b, 445); + + // Above range + let result = decrease_liquidity_quote( + 1000000, + 100, + 18539204128674405812, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 900); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 891); + + // zero liquidity + let result = decrease_liquidity_quote( + 0, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + } + + #[test] + fn test_decrease_liquidity_quote_a_with_fee() { + // Below range + let result = decrease_liquidity_quote_a( + 1000, + 100, + 18354745142194483561, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1250062); + assert_eq!(result.token_est_a, 1000); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 990); + assert_eq!(result.token_min_b, 0); + + // in range + let result = decrease_liquidity_quote_a( + 500, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1250375); + assert_eq!(result.token_est_a, 500); + assert_eq!(result.token_est_b, 562); + assert_eq!(result.token_min_a, 495); + assert_eq!(result.token_min_b, 556); + + // Above range + let result = decrease_liquidity_quote_a( + 1000, + 100, + 18539204128674405812, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + + // zero liquidity + let result = decrease_liquidity_quote_a( + 0, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + } + + #[test] + fn test_decrease_liquidity_quote_b_with_fee() { + // Below range + let result = decrease_liquidity_quote_b( + 1000, + 100, + 18354745142194483561, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + + // in range + let result = decrease_liquidity_quote_b( + 500, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1112333); + assert_eq!(result.token_est_a, 444); + assert_eq!(result.token_est_b, 500); + assert_eq!(result.token_min_a, 439); + assert_eq!(result.token_min_b, 495); + + // Above range + let result = decrease_liquidity_quote_b( + 1000, + 100, + 18539204128674405812, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1112055); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 1000); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 990); + + // zero liquidity + let result = decrease_liquidity_quote_b( + 0, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_min_a, 0); + assert_eq!(result.token_min_b, 0); + } + + #[test] + fn test_increase_liquidity_quote_with_fee() { + // Below range + let result = increase_liquidity_quote( + 1000000, + 100, + 18354745142194483561, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 1250); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 1263); + assert_eq!(result.token_max_b, 0); + + // in range + let result = increase_liquidity_quote( + 1000000, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 625); + assert_eq!(result.token_est_b, 556); + assert_eq!(result.token_max_a, 632); + assert_eq!(result.token_max_b, 562); + + // Above range + let result = increase_liquidity_quote( + 1000000, + 100, + 18539204128674405812, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 1000000); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 1112); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 1124); + + // zero liquidity + let result = increase_liquidity_quote( + 0, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + } + + #[test] + fn test_increase_liquidity_quote_a_with_fee() { + // Below range + let result = increase_liquidity_quote_a( + 1000, + 100, + 18354745142194483561, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 800039); + assert_eq!(result.token_est_a, 1000); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 1010); + assert_eq!(result.token_max_b, 0); + + // in range + let result = increase_liquidity_quote_a( + 500, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 800240); + assert_eq!(result.token_est_a, 500); + assert_eq!(result.token_est_b, 445); + assert_eq!(result.token_max_a, 505); + assert_eq!(result.token_max_b, 450); + + // Above range + let result = increase_liquidity_quote_a( + 1000, + 100, + 18539204128674405812, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + + // zero liquidity + let result = increase_liquidity_quote_a( + 0, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + } + + #[test] + fn test_increase_liquidity_quote_b_with_fee() { + // Below range + let result = increase_liquidity_quote_b( + 1000, + 100, + 18354745142194483561, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + + // in range + let result = increase_liquidity_quote_b( + 500, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 900270); + assert_eq!(result.token_est_a, 563); + assert_eq!(result.token_est_b, 500); + assert_eq!(result.token_max_a, 569); + assert_eq!(result.token_max_b, 505); + + // Above range + let result = increase_liquidity_quote_b( + 1000, + 100, + 18539204128674405812, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 900044); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 1000); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 1010); + + // zero liquidity + let result = increase_liquidity_quote_b( + 0, + 100, + 18446744073709551616, + -10, + 10, + Some(TransferFee::new(2000)), + Some(TransferFee::new(1000)), + ) + .unwrap(); + assert_eq!(result.liquidity_delta, 0); + assert_eq!(result.token_est_a, 0); + assert_eq!(result.token_est_b, 0); + assert_eq!(result.token_max_a, 0); + assert_eq!(result.token_max_b, 0); + } +} diff --git a/rust-sdk/core/src/quote/mod.rs b/rust-sdk/core/src/quote/mod.rs new file mode 100644 index 000000000..825594d31 --- /dev/null +++ b/rust-sdk/core/src/quote/mod.rs @@ -0,0 +1,9 @@ +mod fees; +mod liquidity; +mod rewards; +mod swap; + +pub use fees::*; +pub use liquidity::*; +pub use rewards::*; +pub use swap::*; diff --git a/rust-sdk/core/src/quote/rewards.rs b/rust-sdk/core/src/quote/rewards.rs new file mode 100644 index 000000000..e3466b48d --- /dev/null +++ b/rust-sdk/core/src/quote/rewards.rs @@ -0,0 +1,301 @@ +use ethnum::U256; + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use crate::{ + try_apply_transfer_fee, CollectRewardsQuote, ErrorCode, PositionFacade, TickFacade, + TransferFee, WhirlpoolFacade, AMOUNT_EXCEEDS_MAX_U64, ARITHMETIC_OVERFLOW, +}; + +/// Calculate rewards owed for a position +/// +/// # Paramters +/// - `whirlpool`: The whirlpool state +/// - `position`: The position state +/// - `tick_lower`: The lower tick state +/// - `tick_upper`: The upper tick state +/// - `current_timestamp`: The current timestamp +/// - `transfer_fee_1`: The transfer fee for token 1 +/// - `transfer_fee_2`: The transfer fee for token 2 +/// - `transfer_fee_3`: The transfer fee for token 3 +/// +/// # Returns +/// - `CollectRewardsQuote`: The rewards owed for the 3 reward tokens. +#[allow(clippy::too_many_arguments)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn collect_rewards_quote( + whirlpool: WhirlpoolFacade, + position: PositionFacade, + tick_lower: TickFacade, + tick_upper: TickFacade, + current_timestamp: u64, + transfer_fee_1: Option, + transfer_fee_2: Option, + transfer_fee_3: Option, +) -> Result { + let timestamp_delta = current_timestamp - whirlpool.reward_last_updated_timestamp; + + let mut reward_growth_1: u128 = whirlpool.reward_infos[0].growth_global_x64; + let mut reward_growth_2: u128 = whirlpool.reward_infos[1].growth_global_x64; + let mut reward_growth_3: u128 = whirlpool.reward_infos[2].growth_global_x64; + + if whirlpool.liquidity != 0 { + let reward_growth_delta_1 = whirlpool.reward_infos[0] + .emissions_per_second_x64 + .checked_mul(timestamp_delta as u128) + .ok_or(ARITHMETIC_OVERFLOW)? + / whirlpool.liquidity; + reward_growth_1 += ::try_from(reward_growth_delta_1).unwrap(); + + let reward_growth_delta_2 = whirlpool.reward_infos[1] + .emissions_per_second_x64 + .checked_mul(timestamp_delta as u128) + .ok_or(ARITHMETIC_OVERFLOW)? + / whirlpool.liquidity; + reward_growth_2 += ::try_from(reward_growth_delta_2).unwrap(); + + let reward_growth_delta_3 = whirlpool.reward_infos[2] + .emissions_per_second_x64 + .checked_mul(timestamp_delta as u128) + .ok_or(ARITHMETIC_OVERFLOW)? + / whirlpool.liquidity; + reward_growth_3 += ::try_from(reward_growth_delta_3).unwrap(); + } + + let mut reward_growth_below_1: u128 = tick_lower.reward_growths_outside[0]; + let mut reward_growth_below_2: u128 = tick_lower.reward_growths_outside[1]; + let mut reward_growth_below_3: u128 = tick_lower.reward_growths_outside[2]; + + let mut reward_growth_above_1: u128 = tick_upper.reward_growths_outside[0]; + let mut reward_growth_above_2: u128 = tick_upper.reward_growths_outside[1]; + let mut reward_growth_above_3: u128 = tick_upper.reward_growths_outside[2]; + + if whirlpool.tick_current_index < position.tick_lower_index { + reward_growth_below_1 = reward_growth_1 - reward_growth_below_1; + reward_growth_below_2 = reward_growth_2 - reward_growth_below_2; + reward_growth_below_3 = reward_growth_3 - reward_growth_below_3; + } + + if whirlpool.tick_current_index >= position.tick_upper_index { + reward_growth_above_1 = reward_growth_1 - reward_growth_above_1; + reward_growth_above_2 = reward_growth_2 - reward_growth_above_2; + reward_growth_above_3 = reward_growth_3 - reward_growth_above_3; + } + + let reward_growth_inside_1 = reward_growth_1 - reward_growth_below_1 - reward_growth_above_1; + + let reward_growth_inside_2 = reward_growth_2 - reward_growth_below_2 - reward_growth_above_2; + + let reward_growth_inside_3 = reward_growth_3 - reward_growth_below_3 - reward_growth_above_3; + + let reward_growth_delta_1: U256 = + ::from(reward_growth_inside_1 - position.reward_infos[0].growth_inside_checkpoint) + .checked_mul(position.liquidity.into()) + .ok_or(ARITHMETIC_OVERFLOW)?; + + let reward_growth_delta_2: U256 = + ::from(reward_growth_inside_2 - position.reward_infos[1].growth_inside_checkpoint) + .checked_mul(position.liquidity.into()) + .ok_or(ARITHMETIC_OVERFLOW)?; + + let reward_growth_delta_3: U256 = + ::from(reward_growth_inside_3 - position.reward_infos[2].growth_inside_checkpoint) + .checked_mul(position.liquidity.into()) + .ok_or(ARITHMETIC_OVERFLOW)?; + + let reward_growth_delta_1: u64 = reward_growth_delta_1 + .try_into() + .map_err(|_| AMOUNT_EXCEEDS_MAX_U64)?; + let reward_growth_delta_2: u64 = reward_growth_delta_2 + .try_into() + .map_err(|_| AMOUNT_EXCEEDS_MAX_U64)?; + let reward_growth_delta_3: u64 = reward_growth_delta_3 + .try_into() + .map_err(|_| AMOUNT_EXCEEDS_MAX_U64)?; + + let withdrawable_reward_1 = position.reward_infos[0].amount_owed + reward_growth_delta_1; + let withdrawable_reward_2 = position.reward_infos[1].amount_owed + reward_growth_delta_2; + let withdrawable_reward_3 = position.reward_infos[2].amount_owed + reward_growth_delta_3; + + let reward_owed_1 = + try_apply_transfer_fee(withdrawable_reward_1, transfer_fee_1.unwrap_or_default())?; + let reward_owed_2 = + try_apply_transfer_fee(withdrawable_reward_2, transfer_fee_2.unwrap_or_default())?; + let reward_owed_3 = + try_apply_transfer_fee(withdrawable_reward_3, transfer_fee_3.unwrap_or_default())?; + + Ok(CollectRewardsQuote { + reward_owed_1, + reward_owed_2, + reward_owed_3, + }) +} + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use crate::{PositionRewardInfoFacade, WhirlpoolRewardInfoFacade}; + + use super::*; + + fn test_whirlpool(tick_current_index: i32) -> WhirlpoolFacade { + WhirlpoolFacade { + tick_current_index, + reward_last_updated_timestamp: 0, + reward_infos: [ + WhirlpoolRewardInfoFacade { + growth_global_x64: 500, + emissions_per_second_x64: 1, + }, + WhirlpoolRewardInfoFacade { + growth_global_x64: 600, + emissions_per_second_x64: 2, + }, + WhirlpoolRewardInfoFacade { + growth_global_x64: 700, + emissions_per_second_x64: 3, + }, + ], + liquidity: 50, + ..WhirlpoolFacade::default() + } + } + + fn test_position() -> PositionFacade { + PositionFacade { + liquidity: 50, + tick_lower_index: 5, + tick_upper_index: 10, + reward_infos: [ + PositionRewardInfoFacade { + growth_inside_checkpoint: 0, + amount_owed: 100, + }, + PositionRewardInfoFacade { + growth_inside_checkpoint: 0, + amount_owed: 200, + }, + PositionRewardInfoFacade { + growth_inside_checkpoint: 0, + amount_owed: 300, + }, + ], + ..PositionFacade::default() + } + } + + fn test_tick() -> TickFacade { + TickFacade { + reward_growths_outside: [10, 20, 30], + ..TickFacade::default() + } + } + + #[test] + fn test_collect_rewards_below_range() { + let quote = collect_rewards_quote( + test_whirlpool(0), + test_position(), + test_tick(), + test_tick(), + 10, + None, + None, + None, + ) + .unwrap(); + assert_eq!(quote.reward_owed_1, 100); + assert_eq!(quote.reward_owed_2, 200); + assert_eq!(quote.reward_owed_3, 300); + } + + #[test] + fn test_collect_rewards_in_range() { + let quote = collect_rewards_quote( + test_whirlpool(7), + test_position(), + test_tick(), + test_tick(), + 10, + None, + None, + None, + ) + .unwrap(); + assert_eq!(quote.reward_owed_1, 24100); + assert_eq!(quote.reward_owed_2, 28200); + assert_eq!(quote.reward_owed_3, 32300); + } + + #[test] + fn test_collect_rewards_above_range() { + let quote = collect_rewards_quote( + test_whirlpool(15), + test_position(), + test_tick(), + test_tick(), + 10, + None, + None, + None, + ) + .unwrap(); + assert_eq!(quote.reward_owed_1, 100); + assert_eq!(quote.reward_owed_2, 200); + assert_eq!(quote.reward_owed_3, 300); + } + + #[test] + fn test_collect_rewards_on_range_lower() { + let quote = collect_rewards_quote( + test_whirlpool(5), + test_position(), + test_tick(), + test_tick(), + 10, + None, + None, + None, + ) + .unwrap(); + assert_eq!(quote.reward_owed_1, 24100); + assert_eq!(quote.reward_owed_2, 28200); + assert_eq!(quote.reward_owed_3, 32300); + } + + #[test] + fn test_collect_rewards_on_range_upper() { + let quote = collect_rewards_quote( + test_whirlpool(10), + test_position(), + test_tick(), + test_tick(), + 10, + None, + None, + None, + ) + .unwrap(); + assert_eq!(quote.reward_owed_1, 100); + assert_eq!(quote.reward_owed_2, 200); + assert_eq!(quote.reward_owed_3, 300); + } + + #[test] + fn test_transfer_fee() { + let quote = collect_rewards_quote( + test_whirlpool(7), + test_position(), + test_tick(), + test_tick(), + 10, + Some(TransferFee::new(1000)), + Some(TransferFee::new(2000)), + Some(TransferFee::new(3000)), + ) + .unwrap(); + assert_eq!(quote.reward_owed_1, 21690); + assert_eq!(quote.reward_owed_2, 22560); + assert_eq!(quote.reward_owed_3, 22610); + } +} diff --git a/rust-sdk/core/src/quote/swap.rs b/rust-sdk/core/src/quote/swap.rs new file mode 100644 index 000000000..3dc5eaac1 --- /dev/null +++ b/rust-sdk/core/src/quote/swap.rs @@ -0,0 +1,653 @@ +use crate::{ + sqrt_price_to_tick_index, tick_index_to_sqrt_price, try_apply_swap_fee, try_apply_transfer_fee, + try_get_amount_delta_a, try_get_amount_delta_b, try_get_max_amount_with_slippage_tolerance, + try_get_min_amount_with_slippage_tolerance, try_get_next_sqrt_price_from_a, + try_get_next_sqrt_price_from_b, try_reverse_apply_swap_fee, try_reverse_apply_transfer_fee, + ErrorCode, ExactInSwapQuote, ExactOutSwapQuote, TickArraySequence, TickArrays, TickFacade, + TransferFee, WhirlpoolFacade, ARITHMETIC_OVERFLOW, INVALID_SQRT_PRICE_LIMIT_DIRECTION, + MAX_SQRT_PRICE, MIN_SQRT_PRICE, SQRT_PRICE_LIMIT_OUT_OF_BOUNDS, ZERO_TRADABLE_AMOUNT, +}; + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +/// Computes the exact input or output amount for a swap transaction. +/// +/// # Arguments +/// - `token_in`: The input token amount. +/// - `specified_token_a`: If `true`, the input token is token A. Otherwise, it is token B. +/// - `slippage_tolerance`: The slippage tolerance in basis points. +/// - `whirlpool`: The whirlpool state. +/// - `tick_arrays`: The tick arrays needed for the swap. +/// - `transfer_fee_a`: The transfer fee for token A. +/// - `transfer_fee_b`: The transfer fee for token B. +/// +/// # Returns +/// The exact input or output amount for the swap transaction. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn swap_quote_by_input_token( + token_in: u64, + specified_token_a: bool, + slippage_tolerance_bps: u16, + whirlpool: WhirlpoolFacade, + tick_arrays: TickArrays, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let (transfer_fee_in, transfer_fee_out) = if specified_token_a { + (transfer_fee_a, transfer_fee_b) + } else { + (transfer_fee_b, transfer_fee_a) + }; + let token_in_after_fee = + try_apply_transfer_fee(token_in.into(), transfer_fee_in.unwrap_or_default())?; + + let tick_sequence = TickArraySequence::new(tick_arrays.into(), whirlpool.tick_spacing)?; + + let swap_result = compute_swap( + token_in_after_fee.into(), + 0, + whirlpool, + tick_sequence, + specified_token_a, + true, + 0, + )?; + + let (token_in_after_fees, token_est_out_before_fee) = if specified_token_a { + (swap_result.token_a, swap_result.token_b) + } else { + (swap_result.token_b, swap_result.token_a) + }; + + let token_in = + try_reverse_apply_transfer_fee(token_in_after_fees, transfer_fee_in.unwrap_or_default())?; + + let token_est_out = try_apply_transfer_fee( + token_est_out_before_fee, + transfer_fee_out.unwrap_or_default(), + )?; + + let token_min_out = + try_get_min_amount_with_slippage_tolerance(token_est_out, slippage_tolerance_bps)?; + + Ok(ExactInSwapQuote { + token_in, + token_est_out, + token_min_out, + trade_fee: swap_result.trade_fee, + }) +} + +/// Computes the exact input or output amount for a swap transaction. +/// +/// # Arguments +/// - `token_out`: The output token amount. +/// - `specified_token_a`: If `true`, the output token is token A. Otherwise, it is token B. +/// - `slippage_tolerance`: The slippage tolerance in basis points. +/// - `whirlpool`: The whirlpool state. +/// - `tick_arrays`: The tick arrays needed for the swap. +/// - `transfer_fee_a`: The transfer fee for token A. +/// - `transfer_fee_b`: The transfer fee for token B. +/// +/// # Returns +/// The exact input or output amount for the swap transaction. +#[cfg_attr(feature = "wasm", wasm_expose)] +pub fn swap_quote_by_output_token( + token_out: u64, + specified_token_a: bool, + slippage_tolerance_bps: u16, + whirlpool: WhirlpoolFacade, + tick_arrays: TickArrays, + transfer_fee_a: Option, + transfer_fee_b: Option, +) -> Result { + let (transfer_fee_in, transfer_fee_out) = if specified_token_a { + (transfer_fee_b, transfer_fee_a) + } else { + (transfer_fee_a, transfer_fee_b) + }; + let token_out_before_fee = + try_reverse_apply_transfer_fee(token_out, transfer_fee_out.unwrap_or_default())?; + + let tick_sequence = TickArraySequence::new(tick_arrays.into(), whirlpool.tick_spacing)?; + + let swap_result = compute_swap( + token_out_before_fee.into(), + 0, + whirlpool, + tick_sequence, + !specified_token_a, + false, + 0, + )?; + + let (token_out_before_fee, token_est_in_after_fee) = if specified_token_a { + (swap_result.token_a, swap_result.token_b) + } else { + (swap_result.token_b, swap_result.token_a) + }; + + let token_out = + try_apply_transfer_fee(token_out_before_fee, transfer_fee_out.unwrap_or_default())?; + + let token_est_in = try_reverse_apply_transfer_fee( + token_est_in_after_fee, + transfer_fee_in.unwrap_or_default(), + )?; + + let token_max_in = + try_get_max_amount_with_slippage_tolerance(token_est_in, slippage_tolerance_bps)?; + + Ok(ExactOutSwapQuote { + token_out, + token_est_in, + token_max_in, + trade_fee: swap_result.trade_fee, + }) +} + +// Private functions + +struct SwapResult { + token_a: u64, + token_b: u64, + trade_fee: u64, +} + +fn compute_swap( + token_amount: u64, + sqrt_price_limit: u128, + whirlpool: WhirlpoolFacade, + tick_sequence: TickArraySequence, + a_to_b: bool, + specified_input: bool, + _timestamp: u64, // currently ignored but needed for full swap logic +) -> Result { + let sqrt_price_limit = if sqrt_price_limit == 0 { + if a_to_b { + MIN_SQRT_PRICE + } else { + MAX_SQRT_PRICE + } + } else { + sqrt_price_limit + }; + + if !(MIN_SQRT_PRICE..=MAX_SQRT_PRICE).contains(&sqrt_price_limit) { + return Err(SQRT_PRICE_LIMIT_OUT_OF_BOUNDS); + } + + if a_to_b && sqrt_price_limit > whirlpool.sqrt_price + || !a_to_b && sqrt_price_limit < whirlpool.sqrt_price + { + return Err(INVALID_SQRT_PRICE_LIMIT_DIRECTION); + } + + if token_amount == 0 { + return Err(ZERO_TRADABLE_AMOUNT); + } + + let mut amount_remaining = token_amount; + let mut amount_calculated = 0u64; + let mut current_sqrt_price = whirlpool.sqrt_price; + let mut current_tick_index = whirlpool.tick_current_index; + let mut current_liquidity = whirlpool.liquidity; + let mut trade_fee = 0u64; + + while amount_remaining > 0 && sqrt_price_limit != current_sqrt_price { + let (next_tick, next_tick_index) = if a_to_b { + tick_sequence.prev_initialized_tick(current_tick_index)? + } else { + tick_sequence.next_initialized_tick(current_tick_index)? + }; + let next_tick_sqrt_price: u128 = tick_index_to_sqrt_price(next_tick_index.into()).into(); + let target_sqrt_price = if a_to_b { + next_tick_sqrt_price.max(sqrt_price_limit) + } else { + next_tick_sqrt_price.min(sqrt_price_limit) + }; + + let step_quote = compute_swap_step( + amount_remaining, + whirlpool.fee_rate, + current_liquidity, + current_sqrt_price, + target_sqrt_price, + a_to_b, + specified_input, + )?; + + trade_fee += step_quote.fee_amount; + + if specified_input { + amount_remaining = amount_remaining + .checked_sub(step_quote.amount_in) + .ok_or(ARITHMETIC_OVERFLOW)? + .checked_sub(step_quote.fee_amount) + .ok_or(ARITHMETIC_OVERFLOW)?; + amount_calculated = amount_calculated + .checked_add(step_quote.amount_out) + .ok_or(ARITHMETIC_OVERFLOW)?; + } else { + amount_remaining = amount_remaining + .checked_sub(step_quote.amount_out) + .ok_or(ARITHMETIC_OVERFLOW)?; + amount_calculated = amount_calculated + .checked_add(step_quote.amount_in) + .ok_or(ARITHMETIC_OVERFLOW)? + .checked_add(step_quote.fee_amount) + .ok_or(ARITHMETIC_OVERFLOW)?; + } + + if step_quote.next_sqrt_price == next_tick_sqrt_price { + current_liquidity = get_next_liquidity(current_liquidity, next_tick, a_to_b); + current_tick_index = if a_to_b { + next_tick_index - 1 + } else { + next_tick_index + } + } else { + current_tick_index = sqrt_price_to_tick_index(step_quote.next_sqrt_price.into()).into(); + } + + current_sqrt_price = step_quote.next_sqrt_price; + } + + let swapped_amount = token_amount - amount_remaining; + + let token_a = if a_to_b == specified_input { + swapped_amount + } else { + amount_calculated + }; + let token_b = if a_to_b == specified_input { + amount_calculated + } else { + swapped_amount + }; + + Ok(SwapResult { + token_a, + token_b, + trade_fee, + }) +} + +fn get_next_liquidity(current_liquidity: u128, next_tick: &TickFacade, a_to_b: bool) -> u128 { + let liquidity_net = next_tick.liquidity_net; + let liquidity_net_unsigned = liquidity_net.unsigned_abs(); + if a_to_b { + if liquidity_net < 0 { + current_liquidity + liquidity_net_unsigned + } else { + current_liquidity - liquidity_net_unsigned + } + } else if liquidity_net < 0 { + current_liquidity - liquidity_net_unsigned + } else { + current_liquidity + liquidity_net_unsigned + } +} + +struct SwapStepQuote { + amount_in: u64, + amount_out: u64, + next_sqrt_price: u128, + fee_amount: u64, +} + +fn compute_swap_step( + amount_remaining: u64, + fee_rate: u16, + current_liquidity: u128, + current_sqrt_price: u128, + target_sqrt_price: u128, + a_to_b: bool, + specified_input: bool, +) -> Result { + let initial_amount_fixed_delta = try_get_amount_fixed_delta( + current_sqrt_price, + target_sqrt_price, + current_liquidity, + a_to_b, + specified_input, + ); + + let amount_calculated = if specified_input { + try_apply_swap_fee(amount_remaining.into(), fee_rate)? + } else { + amount_remaining + }; + + let next_sqrt_price = + if initial_amount_fixed_delta.is_ok() && initial_amount_fixed_delta? <= amount_calculated { + target_sqrt_price + } else { + try_get_next_sqrt_price( + current_sqrt_price, + current_liquidity, + amount_calculated, + a_to_b, + specified_input, + )? + }; + + let is_max_swap = next_sqrt_price == target_sqrt_price; + + let amount_unfixed_delta = try_get_amount_unfixed_delta( + current_sqrt_price, + next_sqrt_price, + current_liquidity, + a_to_b, + specified_input, + )?; + + // If the swap is not at the max, we need to readjust the amount of the fixed token we are using + let amount_fixed_delta = if !is_max_swap || initial_amount_fixed_delta.is_err() { + try_get_amount_fixed_delta( + current_sqrt_price, + next_sqrt_price, + current_liquidity, + a_to_b, + specified_input, + )? + } else { + initial_amount_fixed_delta? + }; + + let (amount_in, mut amount_out) = if specified_input { + (amount_fixed_delta, amount_unfixed_delta) + } else { + (amount_unfixed_delta, amount_fixed_delta) + }; + + // Cap output amount if using output + if !specified_input && amount_out > amount_remaining { + amount_out = amount_remaining; + } + + let fee_amount = if specified_input && !is_max_swap { + amount_remaining - amount_in + } else { + let pre_fee_amount = try_reverse_apply_swap_fee(amount_in.into(), fee_rate)?; + pre_fee_amount - amount_in + }; + + Ok(SwapStepQuote { + amount_in, + amount_out, + next_sqrt_price, + fee_amount, + }) +} + +fn try_get_amount_fixed_delta( + current_sqrt_price: u128, + target_sqrt_price: u128, + current_liquidity: u128, + a_to_b: bool, + specified_input: bool, +) -> Result { + if a_to_b == specified_input { + try_get_amount_delta_a( + current_sqrt_price.into(), + target_sqrt_price.into(), + current_liquidity.into(), + specified_input, + ) + } else { + try_get_amount_delta_b( + current_sqrt_price.into(), + target_sqrt_price.into(), + current_liquidity.into(), + specified_input, + ) + } +} + +fn try_get_amount_unfixed_delta( + current_sqrt_price: u128, + target_sqrt_price: u128, + current_liquidity: u128, + a_to_b: bool, + specified_input: bool, +) -> Result { + if specified_input == a_to_b { + try_get_amount_delta_b( + current_sqrt_price.into(), + target_sqrt_price.into(), + current_liquidity.into(), + !specified_input, + ) + } else { + try_get_amount_delta_a( + current_sqrt_price.into(), + target_sqrt_price.into(), + current_liquidity.into(), + !specified_input, + ) + } +} + +fn try_get_next_sqrt_price( + current_sqrt_price: u128, + current_liquidity: u128, + amount_calculated: u64, + a_to_b: bool, + specified_input: bool, +) -> Result { + if specified_input == a_to_b { + try_get_next_sqrt_price_from_a( + current_sqrt_price.into(), + current_liquidity.into(), + amount_calculated.into(), + specified_input, + ) + .map(|x| x.into()) + } else { + try_get_next_sqrt_price_from_b( + current_sqrt_price.into(), + current_liquidity.into(), + amount_calculated.into(), + specified_input, + ) + .map(|x| x.into()) + } +} + +#[cfg(all(test, not(feature = "wasm")))] +mod tests { + use crate::{TickArrayFacade, TICK_ARRAY_SIZE}; + + use super::*; + + fn test_whirlpool(sqrt_price: u128, sufficient_liq: bool) -> WhirlpoolFacade { + let tick_current_index = sqrt_price_to_tick_index(sqrt_price); + let liquidity = if sufficient_liq { 100000000 } else { 265000 }; + WhirlpoolFacade { + tick_current_index, + fee_rate: 3000, + liquidity, + sqrt_price, + tick_spacing: 2, + ..WhirlpoolFacade::default() + } + } + + fn test_tick(positive: bool) -> TickFacade { + let liquidity_net = if positive { 1000 } else { -1000 }; + TickFacade { + initialized: true, + liquidity_net, + ..TickFacade::default() + } + } + + fn test_tick_array(start_tick_index: i32) -> TickArrayFacade { + let positive_liq_net = start_tick_index < 0; + TickArrayFacade { + start_tick_index, + ticks: [test_tick(positive_liq_net); TICK_ARRAY_SIZE], + } + } + + fn test_tick_arrays() -> TickArrays { + [ + test_tick_array(0), + test_tick_array(176), + test_tick_array(352), + test_tick_array(-176), + test_tick_array(-352), + ] + .into() + } + + #[test] + fn test_exact_in_a_to_b_simple() { + let result = swap_quote_by_input_token( + 1000, + true, + 1000, + test_whirlpool(1 << 64, true), + test_tick_arrays(), + None, + None, + ) + .unwrap(); + assert_eq!(result.token_in, 1000); + assert_eq!(result.token_est_out, 996); + assert_eq!(result.token_min_out, 896); + assert_eq!(result.trade_fee, 3); + } + + #[test] + fn test_exact_in_a_to_b() { + let result = swap_quote_by_input_token( + 1000, + true, + 1000, + test_whirlpool(1 << 64, false), + test_tick_arrays(), + None, + None, + ) + .unwrap(); + assert_eq!(result.token_in, 1000); + assert_eq!(result.token_est_out, 920); + assert_eq!(result.token_min_out, 828); + assert_eq!(result.trade_fee, 38); + } + + #[test] + fn test_exact_in_b_to_a_simple() { + let result = swap_quote_by_input_token( + 1000, + false, + 1000, + test_whirlpool(1 << 64, true), + test_tick_arrays(), + None, + None, + ) + .unwrap(); + assert_eq!(result.token_in, 1000); + assert_eq!(result.token_est_out, 996); + assert_eq!(result.token_min_out, 896); + assert_eq!(result.trade_fee, 3); + } + + #[test] + fn test_exact_in_b_to_a() { + let result = swap_quote_by_input_token( + 1000, + false, + 1000, + test_whirlpool(1 << 64, false), + test_tick_arrays(), + None, + None, + ) + .unwrap(); + assert_eq!(result.token_in, 1000); + assert_eq!(result.token_est_out, 918); + assert_eq!(result.token_min_out, 826); + assert_eq!(result.trade_fee, 39); + } + + #[test] + fn test_exact_out_a_to_b_simple() { + let result = swap_quote_by_output_token( + 1000, + false, + 1000, + test_whirlpool(1 << 64, true), + test_tick_arrays(), + None, + None, + ) + .unwrap(); + assert_eq!(result.token_out, 1000); + assert_eq!(result.token_est_in, 1005); + assert_eq!(result.token_max_in, 1106); + assert_eq!(result.trade_fee, 4); + } + + #[test] + fn test_exact_out_a_to_b() { + let result = swap_quote_by_output_token( + 1000, + false, + 1000, + test_whirlpool(1 << 64, false), + test_tick_arrays(), + None, + None, + ) + .unwrap(); + assert_eq!(result.token_out, 1000); + assert_eq!(result.token_est_in, 1088); + assert_eq!(result.token_max_in, 1197); + assert_eq!(result.trade_fee, 42); + } + + #[test] + fn test_exact_out_b_to_a_simple() { + let result = swap_quote_by_output_token( + 1000, + true, + 1000, + test_whirlpool(1 << 64, true), + test_tick_arrays(), + None, + None, + ) + .unwrap(); + assert_eq!(result.token_out, 1000); + assert_eq!(result.token_est_in, 1005); + assert_eq!(result.token_max_in, 1106); + assert_eq!(result.trade_fee, 4); + } + + #[test] + fn test_exact_out_b_to_a() { + let result = swap_quote_by_output_token( + 1000, + true, + 1000, + test_whirlpool(1 << 64, false), + test_tick_arrays(), + None, + None, + ) + .unwrap(); + assert_eq!(result.token_out, 1000); + assert_eq!(result.token_est_in, 1088); + assert_eq!(result.token_max_in, 1197); + assert_eq!(result.trade_fee, 42); + } + + // TODO: add more complex tests that + // * only fill partially + // * transfer fee +} diff --git a/rust-sdk/core/src/types/fees.rs b/rust-sdk/core/src/types/fees.rs new file mode 100644 index 000000000..1af340c6d --- /dev/null +++ b/rust-sdk/core/src/types/fees.rs @@ -0,0 +1,11 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct CollectFeesQuote { + pub fee_owed_a: u64, + pub fee_owed_b: u64, +} diff --git a/rust-sdk/core/src/types/liquidity.rs b/rust-sdk/core/src/types/liquidity.rs new file mode 100644 index 000000000..6466e642e --- /dev/null +++ b/rust-sdk/core/src/types/liquidity.rs @@ -0,0 +1,26 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] + +pub struct DecreaseLiquidityQuote { + pub liquidity_delta: u128, + pub token_est_a: u64, + pub token_est_b: u64, + pub token_min_a: u64, + pub token_min_b: u64, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] + +pub struct IncreaseLiquidityQuote { + pub liquidity_delta: u128, + pub token_est_a: u64, + pub token_est_b: u64, + pub token_max_a: u64, + pub token_max_b: u64, +} diff --git a/rust-sdk/core/src/types/mod.rs b/rust-sdk/core/src/types/mod.rs new file mode 100644 index 000000000..a7da41608 --- /dev/null +++ b/rust-sdk/core/src/types/mod.rs @@ -0,0 +1,27 @@ +mod fees; +mod liquidity; +mod pool; +mod position; +mod rewards; +mod swap; +mod tick; +mod tick_array; +mod token; +mod u128; + +#[cfg(feature = "wasm")] +mod u64; + +pub use fees::*; +pub use liquidity::*; +pub use pool::*; +pub use position::*; +pub use rewards::*; +pub use swap::*; +pub use tick::*; +pub use tick_array::*; +pub use token::*; +pub use u128::*; + +#[cfg(feature = "wasm")] +pub use u64::*; diff --git a/rust-sdk/core/src/types/pool.rs b/rust-sdk/core/src/types/pool.rs new file mode 100644 index 000000000..10864b76d --- /dev/null +++ b/rust-sdk/core/src/types/pool.rs @@ -0,0 +1,28 @@ +#![allow(non_snake_case)] + +use crate::NUM_REWARDS; + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct WhirlpoolFacade { + pub tick_spacing: u16, + pub fee_rate: u16, + pub liquidity: u128, + pub sqrt_price: u128, + pub tick_current_index: i32, + pub fee_growth_global_a: u128, + pub fee_growth_global_b: u128, + pub reward_last_updated_timestamp: u64, + #[cfg_attr(feature = "wasm", tsify(type = "WhirlpoolRewardInfoFacade[]"))] + pub reward_infos: [WhirlpoolRewardInfoFacade; NUM_REWARDS], +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct WhirlpoolRewardInfoFacade { + pub emissions_per_second_x64: u128, + pub growth_global_x64: u128, +} diff --git a/rust-sdk/core/src/types/position.rs b/rust-sdk/core/src/types/position.rs new file mode 100644 index 000000000..2add731c4 --- /dev/null +++ b/rust-sdk/core/src/types/position.rs @@ -0,0 +1,43 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use crate::NUM_REWARDS; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct PositionRatio { + pub ratio_a: u16, + pub ratio_b: u16, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub enum PositionStatus { + PriceInRange, + PriceBelowRange, + PriceAboveRange, + Invalid, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct PositionFacade { + pub liquidity: u128, + pub tick_lower_index: i32, + pub tick_upper_index: i32, + pub fee_growth_checkpoint_a: u128, + pub fee_owed_a: u64, + pub fee_growth_checkpoint_b: u128, + pub fee_owed_b: u64, + #[cfg_attr(feature = "wasm", tsify(type = "PositionRewardInfoFacade[]"))] + pub reward_infos: [PositionRewardInfoFacade; NUM_REWARDS], +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct PositionRewardInfoFacade { + pub growth_inside_checkpoint: u128, + pub amount_owed: u64, +} diff --git a/rust-sdk/core/src/types/rewards.rs b/rust-sdk/core/src/types/rewards.rs new file mode 100644 index 000000000..38b00ee34 --- /dev/null +++ b/rust-sdk/core/src/types/rewards.rs @@ -0,0 +1,12 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct CollectRewardsQuote { + pub reward_owed_1: u64, + pub reward_owed_2: u64, + pub reward_owed_3: u64, +} diff --git a/rust-sdk/core/src/types/swap.rs b/rust-sdk/core/src/types/swap.rs new file mode 100644 index 000000000..b1d716d7b --- /dev/null +++ b/rust-sdk/core/src/types/swap.rs @@ -0,0 +1,24 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] + +pub struct ExactInSwapQuote { + pub token_in: u64, + pub token_est_out: u64, + pub token_min_out: u64, + pub trade_fee: u64, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] + +pub struct ExactOutSwapQuote { + pub token_out: u64, + pub token_est_in: u64, + pub token_max_in: u64, + pub trade_fee: u64, +} diff --git a/rust-sdk/core/src/types/tick.rs b/rust-sdk/core/src/types/tick.rs new file mode 100644 index 000000000..a5a6a5d78 --- /dev/null +++ b/rust-sdk/core/src/types/tick.rs @@ -0,0 +1,35 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use serde_big_array::BigArray; + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +use crate::TICK_ARRAY_SIZE; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct TickRange { + pub tick_lower_index: i32, + pub tick_upper_index: i32, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct TickFacade { + pub initialized: bool, + pub liquidity_net: i128, + pub fee_growth_outside_a: u128, + pub fee_growth_outside_b: u128, + #[cfg_attr(feature = "wasm", tsify(type = "bigint[]"))] + pub reward_growths_outside: [u128; 3], +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct TickArrayFacade { + pub start_tick_index: i32, + #[cfg_attr(feature = "wasm", serde(with = "BigArray"))] + pub ticks: [TickFacade; TICK_ARRAY_SIZE], +} diff --git a/rust-sdk/core/src/types/tick_array.rs b/rust-sdk/core/src/types/tick_array.rs new file mode 100644 index 000000000..c988b5e35 --- /dev/null +++ b/rust-sdk/core/src/types/tick_array.rs @@ -0,0 +1,122 @@ +use crate::types::TickArrayFacade; + +#[cfg(not(feature = "wasm"))] +pub struct TickArrays([Option; 6]); + +#[cfg(feature = "wasm")] +use core::fmt::{Debug, Formatter, Result as FmtResult}; + +#[cfg(feature = "wasm")] +use js_sys::Array; + +#[cfg(feature = "wasm")] +use wasm_bindgen::prelude::*; + +#[cfg(feature = "wasm")] +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(typescript_type = "TickArrayFacade[]")] + pub type TickArrays; +} + +#[cfg(feature = "wasm")] +impl Debug for TickArrays { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "{:?}", JsValue::from(self)) + } +} + +#[cfg(feature = "wasm")] +impl From for [Option; 6] { + fn from(val: TickArrays) -> Self { + let val = JsValue::from(val); + if !val.is_array() { + return [None, None, None, None, None, None]; + } + let array: Array = val.unchecked_into(); + let mut result = [None, None, None, None, None, None]; + for (i, item) in array.iter().enumerate() { + if let Ok(item) = serde_wasm_bindgen::from_value(item) { + result[i] = Some(item); + } + } + result + } +} + +#[cfg(not(feature = "wasm"))] +impl From for [Option; 6] { + fn from(val: TickArrays) -> Self { + val.0 + } +} + +#[cfg(not(feature = "wasm"))] +impl From for TickArrays { + fn from(val: TickArrayFacade) -> Self { + TickArrays([Some(val), None, None, None, None, None]) + } +} + +#[cfg(not(feature = "wasm"))] +impl From<[TickArrayFacade; 1]> for TickArrays { + fn from(val: [TickArrayFacade; 1]) -> Self { + TickArrays([Some(val[0]), None, None, None, None, None]) + } +} + +#[cfg(not(feature = "wasm"))] +impl From<[TickArrayFacade; 2]> for TickArrays { + fn from(val: [TickArrayFacade; 2]) -> Self { + TickArrays([Some(val[0]), Some(val[1]), None, None, None, None]) + } +} + +#[cfg(not(feature = "wasm"))] +impl From<[TickArrayFacade; 3]> for TickArrays { + fn from(val: [TickArrayFacade; 3]) -> Self { + TickArrays([Some(val[0]), Some(val[1]), Some(val[2]), None, None, None]) + } +} + +#[cfg(not(feature = "wasm"))] +impl From<[TickArrayFacade; 4]> for TickArrays { + fn from(val: [TickArrayFacade; 4]) -> Self { + TickArrays([ + Some(val[0]), + Some(val[1]), + Some(val[2]), + Some(val[3]), + None, + None, + ]) + } +} + +#[cfg(not(feature = "wasm"))] +impl From<[TickArrayFacade; 5]> for TickArrays { + fn from(val: [TickArrayFacade; 5]) -> Self { + TickArrays([ + Some(val[0]), + Some(val[1]), + Some(val[2]), + Some(val[3]), + Some(val[4]), + None, + ]) + } +} + +#[cfg(not(feature = "wasm"))] +impl From<[TickArrayFacade; 6]> for TickArrays { + fn from(val: [TickArrayFacade; 6]) -> Self { + TickArrays([ + Some(val[0]), + Some(val[1]), + Some(val[2]), + Some(val[3]), + Some(val[4]), + Some(val[5]), + ]) + } +} diff --git a/rust-sdk/core/src/types/token.rs b/rust-sdk/core/src/types/token.rs new file mode 100644 index 000000000..543923bb6 --- /dev/null +++ b/rust-sdk/core/src/types/token.rs @@ -0,0 +1,24 @@ +#![allow(non_snake_case)] + +#[cfg(feature = "wasm")] +use orca_whirlpools_macros::wasm_expose; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "wasm", wasm_expose)] +pub struct TransferFee { + pub fee_bps: u16, + pub max_fee: u64, +} + +impl TransferFee { + pub fn new(fee_bps: u16) -> Self { + Self { + fee_bps, + max_fee: u64::MAX, + } + } + + pub fn new_with_max(fee_bps: u16, max_fee: u64) -> Self { + Self { fee_bps, max_fee } + } +} diff --git a/rust-sdk/core/src/types/u128.rs b/rust-sdk/core/src/types/u128.rs new file mode 100644 index 000000000..32cda1e74 --- /dev/null +++ b/rust-sdk/core/src/types/u128.rs @@ -0,0 +1,58 @@ +// While `wasm_expose` doesn't automatically convert rust `u128` to js `bigint`, we have +// to proxy it through an opaque type that we define here. This is a workaround until +// `wasm_bindgen` supports `u128` abi conversion natively. + +#[cfg(not(feature = "wasm"))] +pub type U128 = u128; + +#[cfg(feature = "wasm")] +use core::fmt::{Debug, Formatter, Result}; + +#[cfg(feature = "wasm")] +use ethnum::U256; + +#[cfg(feature = "wasm")] +use wasm_bindgen::prelude::*; + +#[cfg(feature = "wasm")] +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(typescript_type = "bigint")] + pub type U128; +} + +#[cfg(feature = "wasm")] +impl Debug for U128 { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + write!(f, "{:?}", JsValue::from(self)) + } +} + +#[cfg(feature = "wasm")] +impl From for u128 { + fn from(value: U128) -> u128 { + JsValue::from(value).try_into().unwrap_or(0) + } +} + +#[cfg(feature = "wasm")] +impl From for U256 { + fn from(value: U128) -> U256 { + let u_128: u128 = value.into(); + ::from(u_128) + } +} + +#[cfg(feature = "wasm")] +impl From for U128 { + fn from(value: u128) -> U128 { + JsValue::from(value).unchecked_into() + } +} + +#[cfg(feature = "wasm")] +impl PartialEq for U128 { + fn eq(&self, other: &u128) -> bool { + self == &(*other).into() + } +} diff --git a/rust-sdk/core/src/types/u64.rs b/rust-sdk/core/src/types/u64.rs new file mode 100644 index 000000000..c58f33a92 --- /dev/null +++ b/rust-sdk/core/src/types/u64.rs @@ -0,0 +1,11 @@ +use serde::Serializer; + +// Serialize a u64 as a u128. This is so that we can use u64 value in rust +// but serialize as a bigint in wasm. + +pub fn u64_serialize(value: &u64, serializer: S) -> Result +where + S: Serializer, +{ + serializer.serialize_u128(*value as u128) +} diff --git a/rust-sdk/macros/Cargo.lock b/rust-sdk/macros/Cargo.lock new file mode 100644 index 000000000..43e546f04 --- /dev/null +++ b/rust-sdk/macros/Cargo.lock @@ -0,0 +1,47 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "orca_whirlpools_macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/rust-sdk/macros/Cargo.toml b/rust-sdk/macros/Cargo.toml new file mode 100644 index 000000000..9b2a49a8d --- /dev/null +++ b/rust-sdk/macros/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "orca_whirlpools_macros" +version = "0.1.0" +description = "Orca's rust wasm macros package." +documentation = "https://orca-so.github.io/whirlpools/" +homepage = "https://orca.so" +repository = "https://github.com/orca-so/whirlpools" +license = "Apache-2.0" +keywords = ["solana", "crypto", "defi", "dex", "amm"] +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "^2", features = ["full"] } +quote = { version = "^1" } +proc-macro2 = { version = "^1" } diff --git a/rust-sdk/macros/README.md b/rust-sdk/macros/README.md new file mode 100644 index 000000000..b213f3605 --- /dev/null +++ b/rust-sdk/macros/README.md @@ -0,0 +1 @@ +# Orca Whirlpools Rust Macros diff --git a/rust-sdk/macros/package.json b/rust-sdk/macros/package.json new file mode 100644 index 000000000..bc73d837b --- /dev/null +++ b/rust-sdk/macros/package.json @@ -0,0 +1,11 @@ +{ + "name": "@orca-so/whirlpools-rust-macros", + "version": "0.0.1", + "scripts": { + "build": "cargo build", + "test": "cargo test --lib", + "format": "cargo clippy --fix --allow-dirty --allow-staged && cargo fmt", + "lint": "cargo clippy", + "clean": "cargo clean" + } +} diff --git a/rust-sdk/macros/src/lib.rs b/rust-sdk/macros/src/lib.rs new file mode 100644 index 000000000..f95dd8976 --- /dev/null +++ b/rust-sdk/macros/src/lib.rs @@ -0,0 +1,30 @@ +mod wasm_const; +mod wasm_enum; +mod wasm_fn; +mod wasm_struct; + +use proc_macro::TokenStream; +use syn::{parse::Nothing, parse2, Item, Result}; + +#[proc_macro_attribute] +pub fn wasm_expose(attr: TokenStream, item: TokenStream) -> TokenStream { + match wasm_expose_impl(attr, item) { + Ok(expanded) => expanded, + Err(err) => err.to_compile_error().into(), + } +} + +fn wasm_expose_impl(attr: TokenStream, item: TokenStream) -> Result { + let attr: Nothing = parse2(attr.into())?; + let item: Item = parse2(item.into())?; + + let result = match item { + Item::Struct(s) => crate::wasm_struct::wasm_struct_impl(s, attr), + Item::Enum(e) => crate::wasm_enum::wasm_enum_impl(e, attr), + Item::Const(c) => crate::wasm_const::wasm_const_impl(c, attr), + Item::Fn(f) => crate::wasm_fn::wasm_fn_impl(f, attr), + _ => Err(syn::Error::new_spanned(item, "Unexpected item")), + }; + + result.map(|ts| ts.into()) +} diff --git a/rust-sdk/macros/src/u64.rs b/rust-sdk/macros/src/u64.rs new file mode 100644 index 000000000..c58f33a92 --- /dev/null +++ b/rust-sdk/macros/src/u64.rs @@ -0,0 +1,11 @@ +use serde::Serializer; + +// Serialize a u64 as a u128. This is so that we can use u64 value in rust +// but serialize as a bigint in wasm. + +pub fn u64_serialize(value: &u64, serializer: S) -> Result +where + S: Serializer, +{ + serializer.serialize_u128(*value as u128) +} diff --git a/rust-sdk/macros/src/wasm_const.rs b/rust-sdk/macros/src/wasm_const.rs new file mode 100644 index 000000000..6164f0ed1 --- /dev/null +++ b/rust-sdk/macros/src/wasm_const.rs @@ -0,0 +1,189 @@ +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; +use syn::{parse::Nothing, Expr, ExprUnary, ItemConst, Lit, Result, UnOp}; + +// FIXME: also add the rustdoc comment to the generated ts constant + +pub fn wasm_const_impl(item: ItemConst, _attr: Nothing) -> Result { + let const_name = format_ident!("_{}", item.ident); + let const_type = &item.ty; + + let const_value = match &*item.expr { + Expr::Lit(syn::ExprLit { lit, .. }) => match lit { + Lit::Int(value) => Ok(quote! { #value }), + Lit::Float(value) => Ok(quote! { #value }), + Lit::Bool(value) => Ok(quote! { #value }), + Lit::Str(value) => Ok(quote! { #value }), + _ => { + return Err(syn::Error::new_spanned( + &item.expr, + "Unsupported literal type", + )) + } + }, + Expr::Array(array) => { + let elements: Result> = array + .elems + .iter() + .map(|elem| match elem { + Expr::Lit(syn::ExprLit { lit, .. }) => match lit { + Lit::Int(value) => Ok(quote! { #value }), + Lit::Float(value) => Ok(quote! { #value }), + Lit::Bool(value) => Ok(quote! { #value }), + Lit::Str(value) => Ok(quote! { #value }), + _ => Err(syn::Error::new_spanned( + elem, + "Unsupported array element type", + )), + }, + _ => Err(syn::Error::new_spanned( + elem, + "Expected a literal type in array", + )), + }) + .collect(); + + elements.map(|elems| quote! { [#(#elems),*] }) + } + Expr::Unary(ExprUnary { + op: UnOp::Neg(_), + expr, + .. + }) => match &**expr { + Expr::Lit(syn::ExprLit { lit, .. }) => match lit { + Lit::Int(value) => Ok(quote! { -#value }), + Lit::Float(value) => Ok(quote! { -#value }), + _ => { + return Err(syn::Error::new_spanned( + &item.expr, + "Unsupported literal type", + )) + } + }, + _ => { + return Err(syn::Error::new_spanned( + &item.expr, + "Expected a literal after unary operator", + )) + } + }, + _ => { + return Err(syn::Error::new_spanned( + &item.expr, + "Expected a literal or array", + )) + } + }?; + + let expanded = quote! { + #[::wasm_bindgen::prelude::wasm_bindgen(skip_jsdoc)] + pub fn #const_name() -> #const_type { + #const_value + } + #item + }; + + Ok(expanded) +} + +#[cfg(test)] +pub mod tests { + use super::*; + use syn::parse_quote; + + #[test] + fn test_usize() { + let item: ItemConst = parse_quote! { + #[existing_attr] + pub const TICK_ARRAY_SIZE_TS: usize = 88; + }; + let attr = Nothing {}; + let result = wasm_const_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (skip_jsdoc)] pub fn _TICK_ARRAY_SIZE_TS () -> usize { 88 } # [existing_attr] pub const TICK_ARRAY_SIZE_TS : usize = 88 ;"); + } + + #[test] + fn test_float() { + let item: ItemConst = parse_quote! { + #[existing_attr] + pub const PI_TS: f64 = 3.14; + }; + let attr = Nothing {}; + let result = wasm_const_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (skip_jsdoc)] pub fn _PI_TS () -> f64 { 3.14 } # [existing_attr] pub const PI_TS : f64 = 3.14 ;"); + } + + #[test] + fn test_negative_int() { + let item: ItemConst = parse_quote! { + #[existing_attr] + pub const NEG_INT_TS: i32 = -42; + }; + let attr = Nothing {}; + let result = wasm_const_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (skip_jsdoc)] pub fn _NEG_INT_TS () -> i32 { - 42 } # [existing_attr] pub const NEG_INT_TS : i32 = - 42 ;"); + } + + #[test] + fn test_negative_float() { + let item: ItemConst = parse_quote! { + #[existing_attr] + pub const NEG_FLOAT_TS: f64 = -3.14; + }; + let attr = Nothing {}; + let result = wasm_const_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (skip_jsdoc)] pub fn _NEG_FLOAT_TS () -> f64 { - 3.14 } # [existing_attr] pub const NEG_FLOAT_TS : f64 = - 3.14 ;"); + } + + #[test] + fn test_bool() { + let item: ItemConst = parse_quote! { + #[existing_attr] + pub const IS_ENABLED_TS: bool = true; + }; + let attr = Nothing {}; + let result = wasm_const_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (skip_jsdoc)] pub fn _IS_ENABLED_TS () -> bool { true } # [existing_attr] pub const IS_ENABLED_TS : bool = true ;"); + } + + #[test] + fn test_string() { + let item: ItemConst = parse_quote! { + #[existing_attr] + pub const NAME_TS: &str = "example"; + }; + let attr = Nothing {}; + let result = wasm_const_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (skip_jsdoc)] pub fn _NAME_TS () -> & str { \"example\" } # [existing_attr] pub const NAME_TS : & str = \"example\" ;"); + } + + #[test] + fn test_int_array() { + let item: ItemConst = parse_quote! { + #[existing_attr] + pub const NUMBERS: [i32; 3] = [1, 2, 3]; + }; + let attr = Nothing {}; + let result = wasm_const_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (skip_jsdoc)] pub fn _NUMBERS () -> [i32 ; 3] { [1 , 2 , 3] } # [existing_attr] pub const NUMBERS : [i32 ; 3] = [1 , 2 , 3] ;"); + } + + #[test] + fn test_bool_array() { + let item: ItemConst = parse_quote! { + #[existing_attr] + pub const BOOLS: [bool; 2] = [true, false]; + }; + let attr = Nothing {}; + let result = wasm_const_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (skip_jsdoc)] pub fn _BOOLS () -> [bool ; 2] { [true , false] } # [existing_attr] pub const BOOLS : [bool ; 2] = [true , false] ;"); + } +} diff --git a/rust-sdk/macros/src/wasm_enum.rs b/rust-sdk/macros/src/wasm_enum.rs new file mode 100644 index 000000000..5fada75e6 --- /dev/null +++ b/rust-sdk/macros/src/wasm_enum.rs @@ -0,0 +1,54 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::{parse::Nothing, parse_quote, Fields, ItemEnum, Result, Type}; + +pub fn wasm_enum_impl(item: ItemEnum, _attr: Nothing) -> Result { + let mut item = item; + + // Add attributes to u64 fields + for variant in &mut item.variants { + if let Fields::Named(fields) = &mut variant.fields { + for field in &mut fields.named { + if let Type::Path(type_path) = &field.ty { + if type_path.path.is_ident("u64") { + field + .attrs + .push(parse_quote!(#[serde(serialize_with = "crate::u64_serialize")])); + field.attrs.push(parse_quote!(#[tsify(type = "bigint")])); + } + } + } + } + } + + let expanded = quote! { + #[derive(::serde::Serialize, ::serde::Deserialize, ::tsify::Tsify)] + #[serde(rename_all = "camelCase")] + #[tsify(from_wasm_abi, into_wasm_abi)] + #item + }; + + Ok(expanded) +} + +#[cfg(test)] +mod tests { + use super::*; + use syn::parse_quote; + + #[test] + fn test_enum() { + let item: ItemEnum = parse_quote! { + #[existing_attr] + pub enum TestEnum { + A(u64, u128), + B { a: u64, #[existing_attr] b: u128 }, + C + } + }; + let attr = Nothing {}; + let result = wasm_enum_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [derive (:: serde :: Serialize , :: serde :: Deserialize , :: tsify :: Tsify)] # [serde (rename_all = \"camelCase\")] # [tsify (from_wasm_abi , into_wasm_abi)] # [existing_attr] pub enum TestEnum { A (u64 , u128) , B { # [serde (serialize_with = \"crate::u64_serialize\")] # [tsify (type = \"bigint\")] a : u64 , # [existing_attr] b : u128 } , C }"); + } +} diff --git a/rust-sdk/macros/src/wasm_fn.rs b/rust-sdk/macros/src/wasm_fn.rs new file mode 100644 index 000000000..f8a732b4d --- /dev/null +++ b/rust-sdk/macros/src/wasm_fn.rs @@ -0,0 +1,54 @@ +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; +use syn::{parse::Nothing, Ident, ItemFn, Result}; + +pub fn wasm_fn_impl(item: ItemFn, _attr: Nothing) -> Result { + let js_name = to_js_name(item.clone().sig.ident); + + let expanded = quote! { + #[::wasm_bindgen::prelude::wasm_bindgen(js_name = #js_name, skip_jsdoc)] + #item + }; + + Ok(expanded) +} + +fn to_js_name(ident: Ident) -> Ident { + let mut js_name = String::new(); + let mut capitalize_next = false; + + for (i, c) in ident.to_string().chars().enumerate() { + if i == 0 { + js_name.push(c.to_lowercase().next().unwrap()); + } else if c == '_' { + capitalize_next = true; + } else if capitalize_next { + js_name.push(c.to_uppercase().next().unwrap()); + capitalize_next = false; + } else { + js_name.push(c); + } + } + + format_ident!("{}", js_name) +} + +#[cfg(test)] +mod tests { + use super::*; + use syn::parse_quote; + + #[test] + fn test_fn() { + let item = parse_quote! { + #[existing_attr] + pub fn foo_foo_bar(a: u64, b: u128) -> u64 { + 42 + } + }; + let attr = Nothing {}; + let result = wasm_fn_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [:: wasm_bindgen :: prelude :: wasm_bindgen (js_name = fooFooBar , skip_jsdoc)] # [existing_attr] pub fn foo_foo_bar (a : u64 , b : u128) -> u64 { 42 }"); + } +} diff --git a/rust-sdk/macros/src/wasm_struct.rs b/rust-sdk/macros/src/wasm_struct.rs new file mode 100644 index 000000000..53b07e619 --- /dev/null +++ b/rust-sdk/macros/src/wasm_struct.rs @@ -0,0 +1,50 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::{parse::Nothing, parse_quote, ItemStruct, Result, Type}; + +pub fn wasm_struct_impl(item: ItemStruct, _attr: Nothing) -> Result { + let mut item = item; + + // Add attributes to u64 fields + for field in &mut item.fields { + if let Type::Path(type_path) = &field.ty { + if type_path.path.is_ident("u64") { + field + .attrs + .push(parse_quote!(#[serde(serialize_with = "crate::u64_serialize")])); + field.attrs.push(parse_quote!(#[tsify(type = "bigint")])); + } + } + } + + let expanded = quote! { + #[derive(::serde::Serialize, ::serde::Deserialize, ::tsify::Tsify)] + #[serde(rename_all = "camelCase")] + #[tsify(from_wasm_abi, into_wasm_abi)] + #item + }; + + Ok(expanded) +} + +#[cfg(test)] +mod tests { + use super::*; + use syn::parse_quote; + + #[test] + fn test_correct() { + let item: ItemStruct = parse_quote! { + #[existing_attr] + pub struct TestStruct { + #[existing_attr] + pub foo: u64, + pub bar: u128 + } + }; + let attr = Nothing {}; + let result = wasm_struct_impl(item, attr); + let output = result.unwrap().to_string(); + assert_eq!(output, "# [derive (:: serde :: Serialize , :: serde :: Deserialize , :: tsify :: Tsify)] # [serde (rename_all = \"camelCase\")] # [tsify (from_wasm_abi , into_wasm_abi)] # [existing_attr] pub struct TestStruct { # [existing_attr] # [serde (serialize_with = \"crate::u64_serialize\")] # [tsify (type = \"bigint\")] pub foo : u64 , pub bar : u128 }"); + } +} diff --git a/rust-sdk/whirlpool/Cargo.lock b/rust-sdk/whirlpool/Cargo.lock index 70940dd9d..11a8d4aab 100644 --- a/rust-sdk/whirlpool/Cargo.lock +++ b/rust-sdk/whirlpool/Cargo.lock @@ -565,6 +565,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + [[package]] name = "feature-probe" version = "0.1.1" @@ -733,6 +739,12 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libsecp256k1" version = "0.6.0" @@ -889,6 +901,7 @@ name = "orca_whirlpools" version = "0.1.0" dependencies = [ "orca_whirlpools_client", + "orca_whirlpools_core", ] [[package]] @@ -898,10 +911,29 @@ dependencies = [ "borsh 0.10.3", "num-derive", "num-traits", + "orca_whirlpools_core", "solana-program", "thiserror", ] +[[package]] +name = "orca_whirlpools_core" +version = "0.1.0" +dependencies = [ + "ethnum", + "libm", + "orca_whirlpools_macros", +] + +[[package]] +name = "orca_whirlpools_macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + [[package]] name = "parking_lot" version = "0.12.3" diff --git a/rust-sdk/whirlpool/Cargo.toml b/rust-sdk/whirlpool/Cargo.toml index 0fb7f0c2f..062c5c2a9 100644 --- a/rust-sdk/whirlpool/Cargo.toml +++ b/rust-sdk/whirlpool/Cargo.toml @@ -10,4 +10,5 @@ keywords = ["solana", "crypto", "defi", "dex", "amm"] edition = "2021" [dependencies] +orca_whirlpools_core = { path = "../core" } orca_whirlpools_client = { path = "../client" } diff --git a/rust-sdk/whirlpool/package.json b/rust-sdk/whirlpool/package.json index 9a220fa67..e082de90d 100644 --- a/rust-sdk/whirlpool/package.json +++ b/rust-sdk/whirlpool/package.json @@ -4,8 +4,8 @@ "scripts": { "build": "cargo build", "test": "cargo test --lib", - "format": "cargo clippy --fix --allow-dirty --allow-staged -- -D clippy::all && cargo fmt", - "lint": "cargo clippy -- -D clippy::all", + "format": "cargo clippy --fix --allow-dirty --allow-staged && cargo fmt", + "lint": "cargo clippy", "clean": "cargo clean" }, "devDependencies": { diff --git a/rust-sdk/whirlpool/src/lib.rs b/rust-sdk/whirlpool/src/lib.rs index 130f136ab..b97c07886 100644 --- a/rust-sdk/whirlpool/src/lib.rs +++ b/rust-sdk/whirlpool/src/lib.rs @@ -1 +1,2 @@ pub use orca_whirlpools_client::*; +pub use orca_whirlpools_core::*; diff --git a/ts-sdk/client/package.json b/ts-sdk/client/package.json index 9b42fbebd..cf2aa9f20 100644 --- a/ts-sdk/client/package.json +++ b/ts-sdk/client/package.json @@ -2,27 +2,38 @@ "name": "@orca-so/whirlpools-client", "version": "0.0.1", "description": "Typescript client to interact with Orca's on-chain Whirlpool program.", - "main": "./dist/index.js", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.js", "types": "./dist/index.d.ts", + "exports": { + "import": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "require": { + "types": "./dist/index.d.cts", + "require": "./dist/index.cjs" + } + }, "sideEffects": false, - "type": "module", "files": [ "dist", "README.md" ], "scripts": { - "build": "node ./kinobi.js && tsc", - "test": "ts-mocha ./tests/**/*.test.ts", + "build": "node ./kinobi.js && tsup src/index.ts --format cjs,esm --dts --sourcemap", + "test": "vitest run tests", "clean": "rimraf dist src/generated" }, "peerDependencies": { - "@solana/web3.js": "^2.0.0-preview.4" + "@solana/web3.js": "^2.0.0-rc.1" }, "devDependencies": { "@kinobi-so/nodes-from-anchor": "^0.22.0", "@kinobi-so/renderers-js": "^0.22.0", "@orca-so/whirlpools-program": "*", - "@solana/web3.js": "^2.0.0-preview.4", + "@solana/web3.js": "^2.0.0-rc.1", "kinobi": "^0.22.0", "typescript": "^5.6.3" }, diff --git a/ts-sdk/client/src/index.ts b/ts-sdk/client/src/index.ts index 4e84cbc07..f22ef6bbd 100644 --- a/ts-sdk/client/src/index.ts +++ b/ts-sdk/client/src/index.ts @@ -2,3 +2,4 @@ Object.assign(global, { __DEV__: process.env.NODE_ENV === "development" }); export * from "./generated"; export * from "./gpa"; +export * from "./pda"; diff --git a/ts-sdk/client/src/pda/feeTier.ts b/ts-sdk/client/src/pda/feeTier.ts new file mode 100644 index 000000000..e3c14096a --- /dev/null +++ b/ts-sdk/client/src/pda/feeTier.ts @@ -0,0 +1,21 @@ +import type { Address, ProgramDerivedAddress } from "@solana/web3.js"; +import { + getAddressEncoder, + getProgramDerivedAddress, + getU16Encoder, +} from "@solana/web3.js"; +import { WHIRLPOOL_PROGRAM_ADDRESS } from "../generated/programs/whirlpool"; + +export async function getFeeTierAddress( + whirlpoolsConfig: Address, + tickSpacing: number, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: [ + "fee_tier", + getAddressEncoder().encode(whirlpoolsConfig), + getU16Encoder().encode(tickSpacing), + ], + }); +} diff --git a/ts-sdk/client/src/pda/index.ts b/ts-sdk/client/src/pda/index.ts new file mode 100644 index 000000000..7ef690a4b --- /dev/null +++ b/ts-sdk/client/src/pda/index.ts @@ -0,0 +1,8 @@ +export * from "./feeTier"; +export * from "./oracle"; +export * from "./position"; +export * from "./positionBundle"; +export * from "./tickArray"; +export * from "./tokenBadge"; +export * from "./whirlpool"; +export * from "./whirlpoolsConfigExtension"; diff --git a/ts-sdk/client/src/pda/oracle.ts b/ts-sdk/client/src/pda/oracle.ts new file mode 100644 index 000000000..3e314b958 --- /dev/null +++ b/ts-sdk/client/src/pda/oracle.ts @@ -0,0 +1,12 @@ +import type { Address, ProgramDerivedAddress } from "@solana/web3.js"; +import { getAddressEncoder, getProgramDerivedAddress } from "@solana/web3.js"; +import { WHIRLPOOL_PROGRAM_ADDRESS } from "../generated/programs/whirlpool"; + +export async function getOracleAddress( + whirlpool: Address, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: ["oracle", getAddressEncoder().encode(whirlpool)], + }); +} diff --git a/ts-sdk/client/src/pda/position.ts b/ts-sdk/client/src/pda/position.ts new file mode 100644 index 000000000..01abe9eff --- /dev/null +++ b/ts-sdk/client/src/pda/position.ts @@ -0,0 +1,12 @@ +import type { Address, ProgramDerivedAddress } from "@solana/web3.js"; +import { getAddressEncoder, getProgramDerivedAddress } from "@solana/web3.js"; +import { WHIRLPOOL_PROGRAM_ADDRESS } from "../generated/programs/whirlpool"; + +export async function getPositionAddress( + positionMint: Address, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: ["position", getAddressEncoder().encode(positionMint)], + }); +} diff --git a/ts-sdk/client/src/pda/positionBundle.ts b/ts-sdk/client/src/pda/positionBundle.ts new file mode 100644 index 000000000..7f12d295e --- /dev/null +++ b/ts-sdk/client/src/pda/positionBundle.ts @@ -0,0 +1,26 @@ +import type { Address, ProgramDerivedAddress } from "@solana/web3.js"; +import { getAddressEncoder, getProgramDerivedAddress } from "@solana/web3.js"; +import { WHIRLPOOL_PROGRAM_ADDRESS } from "../generated/programs/whirlpool"; + +export async function getPositionBundleAddress( + positionBundleMint: Address, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: ["position_bundle", getAddressEncoder().encode(positionBundleMint)], + }); +} + +export async function getBundledPositionAddress( + positionBundleAddress: Address, + bundleIndex: number, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: [ + "bundled_position", + getAddressEncoder().encode(positionBundleAddress), + Buffer.from(bundleIndex.toString()), + ], + }); +} diff --git a/ts-sdk/client/src/pda/tickArray.ts b/ts-sdk/client/src/pda/tickArray.ts new file mode 100644 index 000000000..2c7b8add8 --- /dev/null +++ b/ts-sdk/client/src/pda/tickArray.ts @@ -0,0 +1,17 @@ +import type { Address, ProgramDerivedAddress } from "@solana/web3.js"; +import { getAddressEncoder, getProgramDerivedAddress } from "@solana/web3.js"; +import { WHIRLPOOL_PROGRAM_ADDRESS } from "../generated/programs/whirlpool"; + +export async function getTickArrayAddress( + whirlpool: Address, + startTickIndex: number, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: [ + "tick_array", + getAddressEncoder().encode(whirlpool), + `${startTickIndex}`, + ], + }); +} diff --git a/ts-sdk/client/src/pda/tokenBadge.ts b/ts-sdk/client/src/pda/tokenBadge.ts new file mode 100644 index 000000000..22d1c4206 --- /dev/null +++ b/ts-sdk/client/src/pda/tokenBadge.ts @@ -0,0 +1,17 @@ +import type { Address, ProgramDerivedAddress } from "@solana/web3.js"; +import { getAddressEncoder, getProgramDerivedAddress } from "@solana/web3.js"; +import { WHIRLPOOL_PROGRAM_ADDRESS } from "../generated/programs/whirlpool"; + +export async function getTokenBadgeAddress( + whirlpoolsConfig: Address, + tokenMint: Address, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: [ + "token_badge", + getAddressEncoder().encode(whirlpoolsConfig), + getAddressEncoder().encode(tokenMint), + ], + }); +} diff --git a/ts-sdk/client/src/pda/whirlpool.ts b/ts-sdk/client/src/pda/whirlpool.ts new file mode 100644 index 000000000..74c6bb18e --- /dev/null +++ b/ts-sdk/client/src/pda/whirlpool.ts @@ -0,0 +1,25 @@ +import type { Address, ProgramDerivedAddress } from "@solana/web3.js"; +import { + getAddressEncoder, + getProgramDerivedAddress, + getU16Encoder, +} from "@solana/web3.js"; +import { WHIRLPOOL_PROGRAM_ADDRESS } from "../generated/programs/whirlpool"; + +export async function getWhirlpoolAddress( + whirlpoolsConfig: Address, + tokenMintA: Address, + tokenMintB: Address, + tickSpacing: number, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: [ + "whirlpool", + getAddressEncoder().encode(whirlpoolsConfig), + getAddressEncoder().encode(tokenMintA), + getAddressEncoder().encode(tokenMintB), + getU16Encoder().encode(tickSpacing), + ], + }); +} diff --git a/ts-sdk/client/src/pda/whirlpoolsConfigExtension.ts b/ts-sdk/client/src/pda/whirlpoolsConfigExtension.ts new file mode 100644 index 000000000..430809463 --- /dev/null +++ b/ts-sdk/client/src/pda/whirlpoolsConfigExtension.ts @@ -0,0 +1,12 @@ +import type { Address, ProgramDerivedAddress } from "@solana/web3.js"; +import { getAddressEncoder, getProgramDerivedAddress } from "@solana/web3.js"; +import { WHIRLPOOL_PROGRAM_ADDRESS } from "../generated/programs/whirlpool"; + +export async function getWhirlpoolsConfigExtensionAddress( + configAddress: Address, +): Promise { + return await getProgramDerivedAddress({ + programAddress: WHIRLPOOL_PROGRAM_ADDRESS, + seeds: ["config_extension", getAddressEncoder().encode(configAddress)], + }); +} diff --git a/ts-sdk/client/tests/gpa.test.ts b/ts-sdk/client/tests/gpa.test.ts index bbcd85e4e..e661a3374 100644 --- a/ts-sdk/client/tests/gpa.test.ts +++ b/ts-sdk/client/tests/gpa.test.ts @@ -1,4 +1,4 @@ -import { describe, it } from "mocha"; +import { describe, it, beforeEach, afterEach, vi } from "vitest"; import assert from "assert"; import type { FeeTierArgs } from "../src/generated/accounts/feeTier"; import { getFeeTierEncoder } from "../src/generated/accounts/feeTier"; @@ -85,38 +85,31 @@ import { whirlpoolsConfigExtensionConfigTokenBadgeAuthorityFilter, whirlpoolsConfigExtensionWhirlpoolsConfigFilter, } from "../src/gpa/whirlpoolsConfigExtension"; -import type { SinonStub } from "sinon"; -import { stub } from "sinon"; -import * as gpa from "../src/gpa/utils"; +import { fetchDecodedProgramAccounts } from "../src/gpa/utils"; describe("get program account memcmp filters", () => { const mockRpc = createSolanaRpcFromTransport( createDefaultRpcTransport({ url: "" }), ); - let addresses: Address[] = []; - let gpaMock: SinonStub; - - before(() => { - const decoder = getAddressDecoder(); - addresses = [...Array(25).keys()].map((i) => { - const bytes = Array.from({ length: 32 }, () => i); - return decoder.decode(new Uint8Array(bytes)); - }); + const addresses: Address[] = [...Array(25).keys()].map((i) => { + const bytes = Array.from({ length: 32 }, () => i); + return getAddressDecoder().decode(new Uint8Array(bytes)); }); beforeEach(() => { - gpaMock = stub(gpa, "fetchDecodedProgramAccounts").returns( - Promise.resolve([]), - ); + vi.mock("../src/gpa/utils", () => ({ + fetchDecodedProgramAccounts: vi.fn().mockResolvedValue([]), + })); }); afterEach(() => { - gpaMock.restore(); + vi.restoreAllMocks(); }); function assertFilters(data: ReadonlyUint8Array) { - const filters = gpaMock.getCall(0) - .args[2] as GetProgramAccountsMemcmpFilter[]; + const mockFetch = vi.mocked(fetchDecodedProgramAccounts); + const filters = mockFetch.mock + .calls[0][2] as GetProgramAccountsMemcmpFilter[]; for (const filter of filters) { const offset = Number(filter.memcmp.offset); const actual = getBase58Encoder().encode(filter.memcmp.bytes); diff --git a/ts-sdk/client/tests/pda.test.ts b/ts-sdk/client/tests/pda.test.ts new file mode 100644 index 000000000..f100664d0 --- /dev/null +++ b/ts-sdk/client/tests/pda.test.ts @@ -0,0 +1,117 @@ +import { address } from "@solana/web3.js"; +import assert from "assert"; +import { getFeeTierAddress } from "../src/pda/feeTier"; +import { getOracleAddress } from "../src/pda/oracle"; +import { getPositionAddress } from "../src/pda/position"; +import { + getBundledPositionAddress, + getPositionBundleAddress, +} from "../src/pda/positionBundle"; +import { getTickArrayAddress } from "../src/pda/tickArray"; +import { getTokenBadgeAddress } from "../src/pda/tokenBadge"; +import { getWhirlpoolAddress } from "../src/pda/whirlpool"; +import { getWhirlpoolsConfigExtensionAddress } from "../src/pda/whirlpoolsConfigExtension"; +import { describe, it } from "vitest"; + +const TEST_WHIRLPOOLS_CONFIG_ADDRESS = address( + "2LecshUwdy9xi7meFgHtFJQNSKk4KdTrcpvaB56dP2NQ", +); +const TEST_POSITION_MINT_ADDRESS = address( + "6sf6fSK6tTubFA2LMCeTzt4c6DeNVyA6WpDDgtWs7a5p", +); +const TEST_WHIRLPOOL_ADDRESS = address( + "2kJmUjxWBwL2NGPBV2PiA5hWtmLCqcKY6reQgkrPtaeS", +); +const TEST_TOKEN_MINT_ADDRESS = address( + "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo", +); +const TEST_NATIVE_MINT_ADDRESS = address( + "So11111111111111111111111111111111111111112", +); + +describe("derive program accounts", () => { + it("FeeTier", async () => { + const address = await getFeeTierAddress(TEST_WHIRLPOOLS_CONFIG_ADDRESS, 1); + assert.strictEqual( + address[0], + "62dSkn5ktwY1PoKPNMArZA4bZsvyemuknWUnnQ2ATTuN", + ); + }); + + it("Oracle", async () => { + const address = await getOracleAddress(TEST_WHIRLPOOL_ADDRESS); + assert.strictEqual( + address[0], + "821SHenpVGYY7BCXUzNhs8Xi4grG557fqRw4wzgaPQcS", + ); + }); + + it("Position", async () => { + const address = await getPositionAddress(TEST_POSITION_MINT_ADDRESS); + assert.strictEqual( + address[0], + "2EtH4ZZStW8Ffh2CbbW4baekdtWgPLcBXfYQ6FRmMVsq", + ); + }); + + it("PositionBundle", async () => { + const address = await getPositionBundleAddress(TEST_POSITION_MINT_ADDRESS); + assert.strictEqual( + address[0], + "At1QvbnANV6imkdNkfB4h1XsY4jbTzPAmScgjLCnM7jy", + ); + }); + + it("BundledPosition", async () => { + const address = await getBundledPositionAddress( + TEST_POSITION_MINT_ADDRESS, + 0, + ); + assert.strictEqual( + address[0], + "9Zj8oWYVQdBCtqMn9Z3YyGo8o7hVXLEUZ5x5no5ykVm6", + ); + }); + + it("TickArray", async () => { + const address = await getTickArrayAddress(TEST_WHIRLPOOL_ADDRESS, -2894848); + assert.strictEqual( + address[0], + "7me8W7puQ5tNA15r7ocNX9tFQD9pwtzFDTSdHMMSmDRt", + ); + }); + + it("TokenBadge", async () => { + const address = await getTokenBadgeAddress( + TEST_WHIRLPOOLS_CONFIG_ADDRESS, + TEST_TOKEN_MINT_ADDRESS, + ); + assert.strictEqual( + address[0], + "HX5iftnCxhtu11ys3ZuWbvUqo7cyPYaVNZBrLL67Hrbm", + ); + }); + + it("Whirlpool", async () => { + const address = await getWhirlpoolAddress( + TEST_WHIRLPOOLS_CONFIG_ADDRESS, + TEST_NATIVE_MINT_ADDRESS, + TEST_TOKEN_MINT_ADDRESS, + 2, + ); + assert.strictEqual( + address[0], + "JDQ9GDphXV5ENDrAQtRFvT98m3JwsVJJk8BYHoX8uTAg", + ); + }); + + it("WhilrpoolsConfigExtension", async () => { + const address = await getWhirlpoolsConfigExtensionAddress( + TEST_WHIRLPOOLS_CONFIG_ADDRESS, + ); + assert.strictEqual( + address[0], + "777H5H3Tp9U11uRVRzFwM8BinfiakbaLT8vQpeuhvEiH", + ); + }); +}); diff --git a/ts-sdk/core/Cargo.lock b/ts-sdk/core/Cargo.lock new file mode 100644 index 000000000..7ce02bf2b --- /dev/null +++ b/ts-sdk/core/Cargo.lock @@ -0,0 +1,310 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "orca_whirlpools_core" +version = "0.1.0" +dependencies = [ + "ethnum", + "js-sys", + "libm", + "orca_whirlpools_macros", + "serde", + "serde-big-array", + "serde-wasm-bindgen 0.6.5", + "tsify", + "wasm-bindgen", +] + +[[package]] +name = "orca_whirlpools_core_js_bindings" +version = "0.1.0" +dependencies = [ + "orca_whirlpools_core", +] + +[[package]] +name = "orca_whirlpools_macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.207" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.207" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde-wasm-bindgen 0.5.0", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] diff --git a/ts-sdk/core/Cargo.toml b/ts-sdk/core/Cargo.toml new file mode 100644 index 000000000..25516cd94 --- /dev/null +++ b/ts-sdk/core/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "orca_whirlpools_core_js_bindings" +version = "0.1.0" +publish = false +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +orca_whirlpools_core = { path = "../../rust-sdk/core", features = ["wasm", "floats"] } + +[profile.release] +opt-level = "s" diff --git a/ts-sdk/core/README.md b/ts-sdk/core/README.md new file mode 100644 index 000000000..ecdd4a3f8 --- /dev/null +++ b/ts-sdk/core/README.md @@ -0,0 +1 @@ +# Orca Whirlpools Typescript Core diff --git a/ts-sdk/core/package.json b/ts-sdk/core/package.json new file mode 100644 index 000000000..00005d280 --- /dev/null +++ b/ts-sdk/core/package.json @@ -0,0 +1,46 @@ +{ + "name": "@orca-so/whirlpools-core", + "description": "Orca's core typescript package.", + "version": "0.0.1", + "main": "./dist/nodejs/orca_whirlpools_core_js_bindings.js", + "types": "./dist/nodejs/orca_whirlpools_core_js_bindings.d.ts", + "browser": "./dist/web/orca_whirlpools_core_js_bindings.js", + "type": "module", + "sideEffects": [ + "./dist/web/snippets/*" + ], + "files": [ + "./dist/*/orca_whirlpools_core_js_bindings_bg.wasm", + "./dist/*/orca_whirlpools_core_js_bindings.js", + "./dist/*/orca_whirlpools_core_js_bindings.d.ts", + "README.md" + ], + "scripts": { + "build": "wasm-pack build --out-dir ./dist/web --target web && wasm-pack build --out-dir ./dist/nodejs --target nodejs", + "test": "tsc --noEmit && vitest run tests", + "clean": "cargo clean && rimraf dist" + }, + "devDependencies": { + "@orca-so/whirlpools-client": "*", + "@orca-so/whirlpools-rust-core": "*", + "typescript": "^5.6.3", + "wasm-pack": "^0.13.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/orca-so/whirlpools.git" + }, + "license": "Apache-2.0", + "keywords": [ + "solana", + "crypto", + "defi", + "dex", + "amm" + ], + "author": "team@orca.so", + "bugs": { + "url": "https://github.com/orca-so/whirlpools/issues" + }, + "homepage": "https://orca.so" +} diff --git a/ts-sdk/core/src/lib.rs b/ts-sdk/core/src/lib.rs new file mode 100644 index 000000000..289154dc5 --- /dev/null +++ b/ts-sdk/core/src/lib.rs @@ -0,0 +1 @@ +pub use orca_whirlpools_core::*; diff --git a/ts-sdk/core/tests/size.test.ts b/ts-sdk/core/tests/size.test.ts new file mode 100644 index 000000000..254fcdd7e --- /dev/null +++ b/ts-sdk/core/tests/size.test.ts @@ -0,0 +1,32 @@ +import { execSync } from "child_process"; +import { describe, it } from "vitest"; + +// FIXME: Renable this test when we remove stdlib from the wasm binary. + +const WASM_SIZE_LIMIT = 25000; // 25KB + +describe("WASM bundle size", () => { + it.skip("NodeJS", () => { + const output = execSync( + "gzip -c dist/nodejs/orca_whirlpools_core_js_bindings_bg.wasm | wc -c", + ).toString(); + const size = parseInt(output); + if (size > WASM_SIZE_LIMIT) { + throw new Error( + `Bundle size ${size} exceeds limit of ${WASM_SIZE_LIMIT}`, + ); + } + }); + + it.skip("Web", () => { + const output = execSync( + "gzip -c dist/web/orca_whirlpools_core_js_bindings_bg.wasm | wc -c", + ).toString(); + const size = parseInt(output); + if (size > WASM_SIZE_LIMIT) { + throw new Error( + `Bundle size ${size} exceeds limit of ${WASM_SIZE_LIMIT}`, + ); + } + }); +}); diff --git a/ts-sdk/core/tests/smoke.test.ts b/ts-sdk/core/tests/smoke.test.ts new file mode 100644 index 000000000..f3eb72e48 --- /dev/null +++ b/ts-sdk/core/tests/smoke.test.ts @@ -0,0 +1,184 @@ +import { describe, it } from "vitest"; +import type { + PositionFacade, + TickArrayFacade, + TickFacade, + WhirlpoolFacade, +} from "../dist/nodejs/orca_whirlpools_core_js_bindings"; +import { + collectFeesQuote, + collectRewardsQuote, + decreaseLiquidityQuote, + increaseLiquidityQuote, + swapQuoteByInputToken, + swapQuoteByOutputToken, +} from "../dist/nodejs/orca_whirlpools_core_js_bindings"; +import assert from "assert"; + +// Assumption: if a complex test cases produces the same result as the rust test, +// then the WASM bundle is working correctly and we don't need to test every single +// function in the WASM bundle. + +function testWhirlpool(): WhirlpoolFacade { + return { + tickCurrentIndex: 0, + feeGrowthGlobalA: 800n, + feeGrowthGlobalB: 1000n, + feeRate: 3000, + liquidity: 265000n, + sqrtPrice: 1n << 64n, + tickSpacing: 2, + rewardLastUpdatedTimestamp: 0n, + rewardInfos: [ + { + growthGlobalX64: 500n, + emissionsPerSecondX64: 1n, + }, + { + growthGlobalX64: 600n, + emissionsPerSecondX64: 2n, + }, + { + growthGlobalX64: 700n, + emissionsPerSecondX64: 3n, + }, + ], + }; +} + +function testTick(positive: boolean = true): TickFacade { + const liquidityNet = positive ? 1000n : -1000n; + return { + initialized: true, + liquidityNet, + feeGrowthOutsideA: 50n, + feeGrowthOutsideB: 20n, + rewardGrowthsOutside: [10n, 20n, 30n], + }; +} + +function testTickArray(startTickIndex: number): TickArrayFacade { + return { + startTickIndex, + ticks: Array.from({ length: 88 }, () => testTick(startTickIndex < 0)), + }; +} + +function testPosition(): PositionFacade { + return { + liquidity: 50n, + tickLowerIndex: -5, + tickUpperIndex: 5, + feeGrowthCheckpointA: 0n, + feeOwedA: 400n, + feeGrowthCheckpointB: 0n, + feeOwedB: 600n, + rewardInfos: [ + { + growthInsideCheckpoint: 0n, + amountOwed: 100n, + }, + { + growthInsideCheckpoint: 0n, + amountOwed: 200n, + }, + { + growthInsideCheckpoint: 0n, + amountOwed: 300n, + }, + ], + }; +} + +describe("WASM bundle smoke test", () => { + it("SwapIn", async () => { + const result = swapQuoteByInputToken(1000n, false, 1000, testWhirlpool(), [ + testTickArray(0), + testTickArray(176), + testTickArray(352), + testTickArray(-176), + testTickArray(-352), + ]); + assert.strictEqual(result.tokenIn, 1000n); + assert.strictEqual(result.tokenEstOut, 918n); + assert.strictEqual(result.tokenMinOut, 826n); + assert.strictEqual(result.tradeFee, 39n); + }); + + it("SwapOut", async () => { + const result = swapQuoteByOutputToken(1000n, true, 1000, testWhirlpool(), [ + testTickArray(0), + testTickArray(176), + testTickArray(352), + testTickArray(-176), + testTickArray(-352), + ]); + assert.strictEqual(result.tokenOut, 1000n); + assert.strictEqual(result.tokenEstIn, 1088n); + assert.strictEqual(result.tokenMaxIn, 1197n); + assert.strictEqual(result.tradeFee, 42n); + }); + + it("IncreaseLiquidity", async () => { + const result = increaseLiquidityQuote( + 1000000n, + 100, + 18446744073709551616n, + -10, + 10, + { feeBps: 2000, maxFee: 100000n }, + { feeBps: 1000, maxFee: 100000n }, + ); + assert.strictEqual(result.liquidityDelta, 1000000n); + assert.strictEqual(result.tokenEstA, 625n); + assert.strictEqual(result.tokenEstB, 556n); + assert.strictEqual(result.tokenMaxA, 632n); + assert.strictEqual(result.tokenMaxB, 562n); + }); + + it("DecreaseLiquidity", async () => { + const result = decreaseLiquidityQuote( + 1000000n, + 100, + 18446744073709551616n, + -10, + 10, + { feeBps: 2000, maxFee: 100000n }, + { feeBps: 1000, maxFee: 100000n }, + ); + assert.strictEqual(result.liquidityDelta, 1000000n); + assert.strictEqual(result.tokenEstA, 400n); + assert.strictEqual(result.tokenEstB, 450n); + assert.strictEqual(result.tokenMinA, 396n); + assert.strictEqual(result.tokenMinB, 445n); + }); + + it("CollectFeesQuote", async () => { + const result = collectFeesQuote( + testWhirlpool(), + testPosition(), + testTick(), + testTick(), + { feeBps: 2000, maxFee: 100000n }, + { feeBps: 5000, maxFee: 100000n }, + ); + assert.strictEqual(result.feeOwedA, 320n); + assert.strictEqual(result.feeOwedB, 300n); + }); + + it("CollectRewardsQuote", async () => { + const result = collectRewardsQuote( + testWhirlpool(), + testPosition(), + testTick(), + testTick(), + 10n, + { feeBps: 1000, maxFee: 100000n }, + { feeBps: 2000, maxFee: 100000n }, + { feeBps: 3000, maxFee: 100000n }, + ); + assert.strictEqual(result.rewardOwed1, 21690n); + assert.strictEqual(result.rewardOwed2, 22560n); + assert.strictEqual(result.rewardOwed3, 22610n); + }); +}); diff --git a/ts-sdk/core/tests/types.test.ts b/ts-sdk/core/tests/types.test.ts new file mode 100644 index 000000000..d74e25898 --- /dev/null +++ b/ts-sdk/core/tests/types.test.ts @@ -0,0 +1,26 @@ +import { describe, it } from "vitest"; +import type { Position, TickArray, Whirlpool } from "../../client/src"; +import type { + PositionFacade, + TickArrayFacade, + WhirlpoolFacade, +} from "../dist/nodejs/orca_whirlpools_core_js_bindings"; + +// Since these tests are only for type checking, nothing actually happens at runtime. + +describe("WASM exported types match Kinobi types", () => { + it("Whirlpool", () => { + const fauxWhirlpool = {} as Whirlpool; + fauxWhirlpool satisfies WhirlpoolFacade; + }); + + it("Position", () => { + const fauxPosition = {} as Position; + fauxPosition satisfies PositionFacade; + }); + + it("TickArray", () => { + const fauxTickArray = {} as TickArray; + fauxTickArray satisfies TickArrayFacade; + }); +}); diff --git a/ts-sdk/core/tsconfig.json b/ts-sdk/core/tsconfig.json new file mode 100644 index 000000000..761618ba9 --- /dev/null +++ b/ts-sdk/core/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist" + }, + "include": ["./tests/**/*.ts"] +} diff --git a/ts-sdk/lint/package.json b/ts-sdk/lint/package.json index 75a7e746b..8026ea0a2 100644 --- a/ts-sdk/lint/package.json +++ b/ts-sdk/lint/package.json @@ -3,7 +3,7 @@ "private": true, "type": "module", "scripts": { - "format": "cd ../.. && eslint -c ts-sdk/lint/eslint.config.js --fix && prettier './**/*.{js,jsx,ts,tsx,json}' --write", + "format": "cd ../.. && prettier './**/*.{js,jsx,ts,tsx,json}' --write && eslint -c ts-sdk/lint/eslint.config.js --fix", "lint": "cd ../.. && eslint -c ts-sdk/lint/eslint.config.js" }, "devDependencies": { diff --git a/ts-sdk/whirlpool/package.json b/ts-sdk/whirlpool/package.json index 7fbb11ffe..7e15441c5 100644 --- a/ts-sdk/whirlpool/package.json +++ b/ts-sdk/whirlpool/package.json @@ -2,21 +2,43 @@ "name": "@orca-so/whirlpools", "version": "0.0.1", "description": "Orca's high-level typescript sdk to interact with Orca's on-chain Whirlpool program.", - "main": "./dist/index.js", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.js", "types": "./dist/index.d.ts", + "exports": { + "import": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "require": { + "types": "./dist/index.d.cts", + "require": "./dist/index.cjs" + } + }, "sideEffects": false, "files": [ "dist", "README.md" ], "scripts": { - "build": "tsc", + "build": "tsup src/index.ts --format cjs,esm --dts --sourcemap", + "test": "vitest run tests", "clean": "rimraf dist" }, "dependencies": { - "@orca-so/whirlpools-client": "*" + "@orca-so/whirlpools-client": "*", + "@orca-so/whirlpools-core": "*", + "@solana-program/memo": "^0.5.0", + "@solana-program/system": "^0.5.0", + "@solana-program/token": "^0.2.1", + "@solana-program/token-2022": "^0.1.0" + }, + "peerDependencies": { + "@solana/web3.js": "^2.0.0-rc.1" }, "devDependencies": { + "@solana/web3.js": "^2.0.0-rc.1", "typescript": "^5.6.3" }, "repository": { diff --git a/ts-sdk/whirlpool/src/config.ts b/ts-sdk/whirlpool/src/config.ts new file mode 100644 index 000000000..a2bea8edf --- /dev/null +++ b/ts-sdk/whirlpool/src/config.ts @@ -0,0 +1,153 @@ +import { getWhirlpoolsConfigExtensionAddress } from "@orca-so/whirlpools-client"; +import type { Address, TransactionPartialSigner } from "@solana/web3.js"; +import { address, createNoopSigner } from "@solana/web3.js"; + +/** + * The default (null) address. + */ +export const DEFAULT_ADDRESS = address("11111111111111111111111111111111"); + +/** + * The default WhirlpoolsConfig address. + */ +export const DEFAULT_WHIRLPOOLS_CONFIG_ADDRESS = address( + "2LecshUwdy9xi7meFgHtFJQNSKk4KdTrcpvaB56dP2NQ", +); + +/** + * The default WhirlpoolsConfigExtension address. + */ +export const DEFAULT_WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS = address( + "777H5H3Tp9U11uRVRzFwM8BinfiakbaLT8vQpeuhvEiH", +); + +/** + * The WhirlpoolsConfig address. + */ +export let WHIRLPOOLS_CONFIG_ADDRESS: Address = + DEFAULT_WHIRLPOOLS_CONFIG_ADDRESS; + +/** + * The WhirlpoolsConfigExtension address. + */ +export let WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS: Address = + DEFAULT_WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS; + +/** + * Updates the WhirlpoolsConfig and WhirlpoolsConfigExtension addresses. + * + * @param {Address} whirlpoolsConfigAddress - A WhirlpoolsConfig address. + * @returns {Promise} - Resolves when the addresses have been updated. + */ +export async function setWhirlpoolsConfig( + whirlpoolsConfigAddress: Address, +): Promise { + WHIRLPOOLS_CONFIG_ADDRESS = whirlpoolsConfigAddress; + WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS = + await getWhirlpoolsConfigExtensionAddress(whirlpoolsConfigAddress).then( + (x) => x[0], + ); +} + +/** + * The tick spacing for the Splash pools. + */ +export const SPLASH_POOL_TICK_SPACING = 32896; + +/** + * The default funder for transactions. No explicit funder specified. + */ +export const DEFAULT_FUNDER: TransactionPartialSigner = + createNoopSigner(DEFAULT_ADDRESS); + +/** + * The currently selected funder for transactions. + */ +export let FUNDER: TransactionPartialSigner = DEFAULT_FUNDER; + +/** + * Sets the default funder for transactions. + * + * @param {TransactionPartialSigner | Address | null} funder - The funder to be set as default, either as an address or a transaction signer. + */ +export function setDefaultFunder( + funder: TransactionPartialSigner | Address | null, +): void { + if (typeof funder === "string") { + FUNDER = createNoopSigner(funder); + } else { + FUNDER = funder ?? createNoopSigner(DEFAULT_ADDRESS); + } +} + +/** + * The default slippage tolerance, expressed in basis points. Value of 100 is equivalent to 1%. + */ +export const DEFAULT_SLIPPAGE_TOLERANCE_BPS = 100; + +/** + * The currently selected slippage tolerance, expressed in basis points. Value of 100 is equivalent to 1%. + */ +export let SLIPPAGE_TOLERANCE_BPS = DEFAULT_SLIPPAGE_TOLERANCE_BPS; + +/** + * Sets the default slippage tolerance for transactions. + * + * @param {number} slippageToleranceBps - The slippage tolerance, expressed basis points. Value of 100 is equivalent to 1%. + */ +export function setDefaultSlippageToleranceBps( + slippageToleranceBps: number, +): void { + SLIPPAGE_TOLERANCE_BPS = Math.floor(slippageToleranceBps); +} + +/** + * Defines the strategy for handling SOL wrapping in a transaction. + * + * - **Keypair**: + * Creates an auxiliary token account using a keypair. Optionally adds funds to the account. Closes it at the end of the transaction. + * + * - **Seed**: + * Functions similarly to Keypair, but uses a seed account instead. + * + * - **ATA**: + * Creates an associated token account (ATA) for `NATIVE_MINT` if necessary. Optionally adds funds to the ATA. Closes it at the end of the transaction if it was newly created. + * + * - **None**: + * Uses or creates the ATA without performing any SOL wrapping or unwrapping. + */ +export type SolWrappingStrategy = "keypair" | "seed" | "ata" | "none"; + +/** + * The default sol wrapping strategy. + */ +export const DEFAULT_SOL_WRAPPING_STRATEGY: SolWrappingStrategy = "keypair"; + +/** + * The currently selected sol wrapping strategy. + */ +export let SOL_WRAPPING_STRATEGY: SolWrappingStrategy = + DEFAULT_SOL_WRAPPING_STRATEGY; + +/** + * Sets the sol wrapping strategy. + * + * @param {SolWrappingStrategy} strategy - The sol wrapping strategy. + */ +export function setSolWrappingStrategy(strategy: SolWrappingStrategy): void { + SOL_WRAPPING_STRATEGY = strategy; +} + +/** + * Resets the configuration to its default state. + * + * @returns {Promise} - Resolves when the configuration has been reset. + */ +export function resetConfiguration() { + WHIRLPOOLS_CONFIG_ADDRESS = DEFAULT_WHIRLPOOLS_CONFIG_ADDRESS; + WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS = + DEFAULT_WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS; + FUNDER = DEFAULT_FUNDER; + SLIPPAGE_TOLERANCE_BPS = DEFAULT_SLIPPAGE_TOLERANCE_BPS; + SOL_WRAPPING_STRATEGY = DEFAULT_SOL_WRAPPING_STRATEGY; +} diff --git a/ts-sdk/whirlpool/src/createPool.ts b/ts-sdk/whirlpool/src/createPool.ts new file mode 100644 index 000000000..132fc724a --- /dev/null +++ b/ts-sdk/whirlpool/src/createPool.ts @@ -0,0 +1,276 @@ +import { + getFeeTierAddress, + getInitializePoolV2Instruction, + getInitializeTickArrayInstruction, + getTickArrayAddress, + getTickArraySize, + getTokenBadgeAddress, + getWhirlpoolAddress, + getWhirlpoolSize, +} from "@orca-so/whirlpools-client"; +import type { + Address, + GetMinimumBalanceForRentExemptionApi, + GetMultipleAccountsApi, + IInstruction, + LamportsUnsafeBeyond2Pow53Minus1, + Rpc, + TransactionPartialSigner, +} from "@solana/web3.js"; +import { generateKeyPairSigner } from "@solana/web3.js"; +import { + DEFAULT_ADDRESS, + FUNDER, + SPLASH_POOL_TICK_SPACING, + WHIRLPOOLS_CONFIG_ADDRESS, +} from "./config"; +import { + getFullRangeTickIndexes, + getTickArrayStartTickIndex, + priceToSqrtPrice, + sqrtPriceToTickIndex, +} from "@orca-so/whirlpools-core"; +import { fetchAllMint, getTokenSize } from "@solana-program/token"; +import assert from "assert"; + +/** + * Represents the instructions and metadata for creating a pool. + */ +export type CreatePoolInstructions = { + /** The list of instructions needed to create the pool. */ + instructions: IInstruction[]; + + /** The estimated rent exemption cost for initializing the pool, in lamports. */ + estInitializationCost: LamportsUnsafeBeyond2Pow53Minus1; + + /** The address of the newly created pool. */ + poolAddress: Address; +}; + +/** + * Creates the necessary instructions to initialize a Splash Pool on Orca Whirlpools. + * + * @param {SolanaRpc} rpc - A Solana RPC client for communicating with the blockchain. + * @param {Address} tokenMintA - The first token mint address to include in the pool. + * @param {Address} tokenMintB - The second token mint address to include in the pool. + * @param {number} [initialPrice=1] - The initial price of token 1 in terms of token 2. + * @param {TransactionPartialSigner} [funder=FUNDER] - The account that will fund the initialization process. + * + * @returns {Promise} A promise that resolves to an object containing the pool creation instructions, the estimated initialization cost, and the pool address. + * + * @example + * import { createSplashPoolInstructions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const tokenMintOne = "TOKEN_MINT_ADDRESS_1"; + * const tokenMintTwo = "TOKEN_MINT_ADDRESS_2"; + * const initialPrice = 0.01; + * + * const { poolAddress, instructions, initializationCost } = await createSplashPoolInstructions( + * devnetRpc, + * tokenMintOne, + * tokenMintTwo, + * initialPrice, + * wallet + * ); + */ +export function createSplashPoolInstructions( + rpc: Rpc, + tokenMintA: Address, + tokenMintB: Address, + initialPrice: number = 1, + funder: TransactionPartialSigner = FUNDER, +): Promise { + return createConcentratedLiquidityPoolInstructions( + rpc, + tokenMintA, + tokenMintB, + SPLASH_POOL_TICK_SPACING, + initialPrice, + funder, + ); +} + +/** + * Creates the necessary instructions to initialize a Concentrated Liquidity Pool (CLMM) on Orca Whirlpools. + * + * @param {SolanaRpc} rpc - A Solana RPC client for communicating with the blockchain. + * @param {Address} tokenMintA - The first token mint address to include in the pool. + * @param {Address} tokenMintB - The second token mint address to include in the pool. + * @param {number} tickSpacing - The spacing between price ticks for the pool. + * @param {number} [initialPrice=1] - The initial price of token 1 in terms of token 2. + * @param {TransactionPartialSigner} [funder=FUNDER] - The account that will fund the initialization process. + * + * @returns {Promise} A promise that resolves to an object containing the pool creation instructions, the estimated initialization cost, and the pool address. + * + * @example + * import { createConcentratedLiquidityPool } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const tokenMintOne = "TOKEN_MINT_ADDRESS_1"; + * const tokenMintTwo = "TOKEN_MINT_ADDRESS_2"; + * const tickSpacing = 64; + * const initialPrice = 0.01; + * + * const { poolAddress, instructions, initializationCost } = await createConcentratedLiquidityPool( + * devnetRpc, + * tokenMintOne, + * tokenMintTwo, + * tickSpacing, + * initialPrice, + * wallet + * ); + */ +export async function createConcentratedLiquidityPoolInstructions( + rpc: Rpc, + tokenMintA: Address, + tokenMintB: Address, + tickSpacing: number, + initialPrice: number = 1, + funder: TransactionPartialSigner = FUNDER, +): Promise { + assert( + funder.address !== DEFAULT_ADDRESS, + "Either supply a funder or set the default funder", + ); + assert( + Buffer.from(tokenMintA) < Buffer.from(tokenMintB), + "Token order needs to be flipped to match the canonical ordering (i.e. sorted on the byte repr. of the mint pubkeys)", + ); + const instructions: IInstruction[] = []; + let stateSpace = 0; + + // Since TE mint data is an extension of T mint data, we can use the same fetch function + const [mintA, mintB] = await fetchAllMint(rpc, [tokenMintA, tokenMintB]); + const decimalsA = mintA.data.decimals; + const decimalsB = mintB.data.decimals; + const tokenProgramA = mintA.programAddress; + const tokenProgramB = mintB.programAddress; + + const initialSqrtPrice = priceToSqrtPrice(initialPrice, decimalsA, decimalsB); + + const [ + poolAddress, + feeTier, + tokenBadgeA, + tokenBadgeB, + tokenVaultA, + tokenVaultB, + ] = await Promise.all([ + getWhirlpoolAddress( + WHIRLPOOLS_CONFIG_ADDRESS, + tokenMintA, + tokenMintB, + tickSpacing, + ).then((x) => x[0]), + getFeeTierAddress(WHIRLPOOLS_CONFIG_ADDRESS, tickSpacing).then((x) => x[0]), + getTokenBadgeAddress(WHIRLPOOLS_CONFIG_ADDRESS, tokenMintA).then( + (x) => x[0], + ), + getTokenBadgeAddress(WHIRLPOOLS_CONFIG_ADDRESS, tokenMintB).then( + (x) => x[0], + ), + generateKeyPairSigner(), + generateKeyPairSigner(), + ]); + + instructions.push( + getInitializePoolV2Instruction({ + whirlpoolsConfig: WHIRLPOOLS_CONFIG_ADDRESS, + tokenMintA, + tokenMintB, + tokenBadgeA, + tokenBadgeB, + funder, + whirlpool: poolAddress, + tokenVaultA, + tokenVaultB, + tokenProgramA, + tokenProgramB, + feeTier, + tickSpacing, + initialSqrtPrice, + }), + ); + + stateSpace += getTokenSize() * 2; + stateSpace += getWhirlpoolSize(); + + const fullRange = getFullRangeTickIndexes(tickSpacing); + const lowerTickIndex = getTickArrayStartTickIndex( + fullRange.tickLowerIndex, + tickSpacing, + ); + const upperTickIndex = getTickArrayStartTickIndex( + fullRange.tickUpperIndex, + tickSpacing, + ); + const initialTickIndex = sqrtPriceToTickIndex(initialSqrtPrice); + const currentTickIndex = getTickArrayStartTickIndex( + initialTickIndex, + tickSpacing, + ); + + const [ + lowerTickArrayAddress, + upperTickArrayAddress, + currentTickArrayAddress, + ] = await Promise.all([ + getTickArrayAddress(poolAddress, lowerTickIndex).then((x) => x[0]), + getTickArrayAddress(poolAddress, upperTickIndex).then((x) => x[0]), + getTickArrayAddress(poolAddress, currentTickIndex).then((x) => x[0]), + ]); + + instructions.push( + getInitializeTickArrayInstruction({ + whirlpool: poolAddress, + funder, + tickArray: lowerTickArrayAddress, + startTickIndex: lowerTickIndex, + }), + ); + + instructions.push( + getInitializeTickArrayInstruction({ + whirlpool: poolAddress, + funder, + tickArray: upperTickArrayAddress, + startTickIndex: upperTickIndex, + }), + ); + + stateSpace += getTickArraySize() * 2; + + if ( + currentTickIndex !== lowerTickIndex && + currentTickIndex !== upperTickIndex + ) { + instructions.push( + getInitializeTickArrayInstruction({ + whirlpool: poolAddress, + funder, + tickArray: currentTickArrayAddress, + startTickIndex: currentTickIndex, + }), + ); + stateSpace += getTickArraySize(); + } + + const nonRefundableRent = await rpc + .getMinimumBalanceForRentExemption(BigInt(stateSpace)) + .send(); + + return { + instructions, + poolAddress, + estInitializationCost: nonRefundableRent, + }; +} diff --git a/ts-sdk/whirlpool/src/decreaseLiquidity.ts b/ts-sdk/whirlpool/src/decreaseLiquidity.ts new file mode 100644 index 000000000..1e3d8d670 --- /dev/null +++ b/ts-sdk/whirlpool/src/decreaseLiquidity.ts @@ -0,0 +1,580 @@ +import type { Whirlpool } from "@orca-so/whirlpools-client"; +import { + fetchAllTickArray, + fetchPosition, + fetchWhirlpool, + getClosePositionInstruction, + getClosePositionWithTokenExtensionsInstruction, + getCollectFeesV2Instruction, + getCollectRewardV2Instruction, + getDecreaseLiquidityV2Instruction, + getPositionAddress, + getTickArrayAddress, +} from "@orca-so/whirlpools-client"; +import type { + CollectFeesQuote, + CollectRewardsQuote, + DecreaseLiquidityQuote, + TickRange, + TransferFee, +} from "@orca-so/whirlpools-core"; +import { + _MAX_TICK_INDEX, + _MIN_TICK_INDEX, + getTickArrayStartTickIndex, + decreaseLiquidityQuote, + decreaseLiquidityQuoteA, + decreaseLiquidityQuoteB, + collectFeesQuote, + collectRewardsQuote, + getTickIndexInArray, +} from "@orca-so/whirlpools-core"; +import type { + Address, + GetAccountInfoApi, + GetMinimumBalanceForRentExemptionApi, + GetMultipleAccountsApi, + IInstruction, + Rpc, + TransactionPartialSigner, +} from "@solana/web3.js"; +import { DEFAULT_ADDRESS, FUNDER, SLIPPAGE_TOLERANCE_BPS } from "./config"; +import { + findAssociatedTokenPda, + TOKEN_PROGRAM_ADDRESS, +} from "@solana-program/token"; +import { + getCurrentTransferFee, + prepareTokenAccountsInstructions, +} from "./token"; +import { + fetchAllMint, + fetchAllMaybeMint, + TOKEN_2022_PROGRAM_ADDRESS, +} from "@solana-program/token-2022"; +import { MEMO_PROGRAM_ADDRESS } from "@solana-program/memo"; +import assert from "assert"; + +// TODO: allow specify number as well as bigint +// TODO: transfer hook + +/** + * Represents the parameters for decreasing liquidity. + * You must choose only one of the properties (`liquidity`, `tokenA`, or `tokenB`). + * The SDK will compute the other two based on the input provided. + */ +export type DecreaseLiquidityQuoteParam = + | { + /** The amount of liquidity to decrease.*/ + liquidity: bigint; + } + | { + /** The amount of Token A to withdraw.*/ + tokenA: bigint; + } + | { + /** The amount of Token B to withdraw.*/ + tokenB: bigint; + }; + +/** + * Represents the instructions and quote for decreasing liquidity in a position. + */ +export type DecreaseLiquidityInstructions = { + /** The quote details for decreasing liquidity, including the liquidity delta, estimated tokens, and minimum token amounts based on slippage tolerance. */ + quote: DecreaseLiquidityQuote; + + /** The list of instructions required to decrease liquidity. */ + instructions: IInstruction[]; +}; + +function getDecreaseLiquidityQuote( + param: DecreaseLiquidityQuoteParam, + pool: Whirlpool, + tickRange: TickRange, + slippageToleranceBps: number, + transferFeeA: TransferFee | undefined, + transferFeeB: TransferFee | undefined, +): DecreaseLiquidityQuote { + if ("liquidity" in param) { + return decreaseLiquidityQuote( + param.liquidity, + slippageToleranceBps, + pool.sqrtPrice, + tickRange.tickLowerIndex, + tickRange.tickUpperIndex, + transferFeeA, + transferFeeB, + ); + } else if ("tokenA" in param) { + return decreaseLiquidityQuoteA( + param.tokenA, + slippageToleranceBps, + pool.sqrtPrice, + tickRange.tickLowerIndex, + tickRange.tickUpperIndex, + transferFeeA, + transferFeeB, + ); + } else { + return decreaseLiquidityQuoteB( + param.tokenB, + slippageToleranceBps, + pool.sqrtPrice, + tickRange.tickLowerIndex, + tickRange.tickUpperIndex, + transferFeeA, + transferFeeB, + ); + } +} + +/** + * Generates instructions to decrease liquidity from an existing position in an Orca Whirlpool. + * + * @param {SolanaRpc} rpc - A Solana RPC client for fetching necessary accounts and pool data. + * @param {Address} positionMintAddress - The mint address of the NFT that represents ownership of the position from which liquidity will be removed. + * @param {DecreaseLiquidityQuoteParam} param - Defines the liquidity removal method (liquidity, tokenA, or tokenB). + * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The acceptable slippage tolerance in basis points. + * @param {TransactionPartialSigner} [authority=FUNDER] - The account authorizing the liquidity removal. + * + * @returns {Promise} A promise resolving to an object containing the decrease liquidity quote and instructions. + * + * @example + * import { decreaseLiquidityInstructions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const positionMint = "POSITION_MINT"; + * + * const param = { liquidity: 500_000n }; + * + * const { quote, instructions } = await decreaseLiquidityInstructions( + * devnetRpc, + * positionMint, + * param, + * 100, + * wallet + * ); + */ +export async function decreaseLiquidityInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi + >, + positionMintAddress: Address, + param: DecreaseLiquidityQuoteParam, + slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS, + authority: TransactionPartialSigner = FUNDER, +): Promise { + assert( + authority.address !== DEFAULT_ADDRESS, + "Either supply the authority or set the default funder", + ); + + const positionAddress = await getPositionAddress(positionMintAddress); + const position = await fetchPosition(rpc, positionAddress[0]); + const whirlpool = await fetchWhirlpool(rpc, position.data.whirlpool); + + const currentEpoch = await rpc.getEpochInfo().send(); + const [mintA, mintB, positionMint] = await fetchAllMint(rpc, [ + whirlpool.data.tokenMintA, + whirlpool.data.tokenMintB, + positionMintAddress, + ]); + const transferFeeA = getCurrentTransferFee(mintA.data, currentEpoch.epoch); + const transferFeeB = getCurrentTransferFee(mintB.data, currentEpoch.epoch); + + const quote = getDecreaseLiquidityQuote( + param, + whirlpool.data, + position.data, + slippageToleranceBps, + transferFeeA, + transferFeeB, + ); + const instructions: IInstruction[] = []; + + const lowerTickArrayStartIndex = getTickArrayStartTickIndex( + position.data.tickLowerIndex, + whirlpool.data.tickSpacing, + ); + const upperTickArrayStartIndex = getTickArrayStartTickIndex( + position.data.tickUpperIndex, + whirlpool.data.tickSpacing, + ); + + const [positionTokenAccount, tickArrayLower, tickArrayUpper] = + await Promise.all([ + findAssociatedTokenPda({ + owner: authority.address, + mint: positionMintAddress, + tokenProgram: positionMint.programAddress, + }).then((x) => x[0]), + getTickArrayAddress(whirlpool.address, lowerTickArrayStartIndex).then( + (x) => x[0], + ), + getTickArrayAddress(whirlpool.address, upperTickArrayStartIndex).then( + (x) => x[0], + ), + ]); + + const { createInstructions, cleanupInstructions, tokenAccountAddresses } = + await prepareTokenAccountsInstructions(rpc, authority, [ + whirlpool.data.tokenMintA, + whirlpool.data.tokenMintB, + ]); + + instructions.push(...createInstructions); + + instructions.push( + getDecreaseLiquidityV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: position.address, + positionTokenAccount, + tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA], + tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB], + tokenVaultA: whirlpool.data.tokenVaultA, + tokenVaultB: whirlpool.data.tokenVaultB, + tokenMintA: whirlpool.data.tokenMintA, + tokenMintB: whirlpool.data.tokenMintB, + tokenProgramA: mintA.programAddress, + tokenProgramB: mintB.programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + tickArrayLower, + tickArrayUpper, + liquidityAmount: quote.liquidityDelta, + tokenMinA: quote.tokenMinA, + tokenMinB: quote.tokenMinB, + remainingAccountsInfo: null, + }), + ); + + instructions.push(...cleanupInstructions); + + return { quote, instructions }; +} + +/** + * Represents the instructions and quotes for closing a liquidity position in an Orca Whirlpool. + * Extends `DecreaseLiquidityInstructions` and adds additional fee and reward details. + */ +export type ClosePositionInstructions = DecreaseLiquidityInstructions & { + /** The fees collected from the position, including the amounts for token A (`fee_owed_a`) and token B (`fee_owed_b`). */ + feesQuote: CollectFeesQuote; + + /** The rewards collected from the position, including up to three reward tokens (`reward_owed_1`, `reward_owed_2`, and `reward_owed_3`). */ + rewardsQuote: CollectRewardsQuote; +}; + +/** + * Generates instructions to close a liquidity position in an Orca Whirlpool. This includes collecting all fees, + * rewards, removing any remaining liquidity, and closing the position. + * + * @param {SolanaRpc} rpc - A Solana RPC client for fetching accounts and pool data. + * @param {Address} positionMintAddress - The mint address of the NFT that represents ownership of the position to be closed. + * @param {DecreaseLiquidityQuoteParam} param - The parameters for removing liquidity (liquidity, tokenA, or tokenB). + * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The acceptable slippage tolerance in basis points. + * @param {TransactionPartialSigner} [authority=FUNDER] - The account authorizing the transaction. + * + * @returns {Promise} A promise resolving to an object containing instructions, fees quote, rewards quote, and the liquidity quote for the closed position. + * + * @example + * import { closePositionInstructions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const positionMint = "POSITION_MINT"; + * + * const param = { liquidity: 500_000n }; + * + * const { instructions, quote, feesQuote, rewardsQuote } = await closePositionInstructions( + * devnetRpc, + * positionMint, + * param, + * 100, + * wallet + * ); + */ +export async function closePositionInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi + >, + positionMintAddress: Address, + param: DecreaseLiquidityQuoteParam, + slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS, + authority: TransactionPartialSigner = FUNDER, +): Promise { + assert( + authority.address !== DEFAULT_ADDRESS, + "Either supply an authority or set the default funder", + ); + + const positionAddress = await getPositionAddress(positionMintAddress); + const position = await fetchPosition(rpc, positionAddress[0]); + const whirlpool = await fetchWhirlpool(rpc, position.data.whirlpool); + + const currentEpoch = await rpc.getEpochInfo().send(); + const [mintA, mintB, positionMint, ...rewardMints] = await fetchAllMaybeMint( + rpc, + [ + whirlpool.data.tokenMintA, + whirlpool.data.tokenMintB, + positionMintAddress, + ...whirlpool.data.rewardInfos.map((x) => x.mint), + ], + ); + + assert(mintA.exists, "Token A not found"); + assert(mintB.exists, "Token B not found"); + assert(positionMint.exists, "Position mint not found"); + + const transferFeeA = getCurrentTransferFee(mintA.data, currentEpoch.epoch); + const transferFeeB = getCurrentTransferFee(mintB.data, currentEpoch.epoch); + + const quote = getDecreaseLiquidityQuote( + param, + whirlpool.data, + position.data, + slippageToleranceBps, + transferFeeA, + transferFeeB, + ); + + const lowerTickArrayStartIndex = getTickArrayStartTickIndex( + position.data.tickLowerIndex, + whirlpool.data.tickSpacing, + ); + const upperTickArrayStartIndex = getTickArrayStartTickIndex( + position.data.tickUpperIndex, + whirlpool.data.tickSpacing, + ); + + const [positionTokenAccount, lowerTickArrayAddress, upperTickArrayAddress] = + await Promise.all([ + findAssociatedTokenPda({ + owner: authority.address, + mint: positionMintAddress, + tokenProgram: positionMint.programAddress, + }).then((x) => x[0]), + getTickArrayAddress(whirlpool.address, lowerTickArrayStartIndex).then( + (x) => x[0], + ), + getTickArrayAddress(whirlpool.address, upperTickArrayStartIndex).then( + (x) => x[0], + ), + ]); + + const [lowerTickArray, upperTickArray] = await fetchAllTickArray(rpc, [ + lowerTickArrayAddress, + upperTickArrayAddress, + ]); + + const lowerTick = + lowerTickArray.data.ticks[ + getTickIndexInArray( + position.data.tickLowerIndex, + lowerTickArrayStartIndex, + whirlpool.data.tickSpacing, + ) + ]; + const upperTick = + upperTickArray.data.ticks[ + getTickIndexInArray( + position.data.tickUpperIndex, + upperTickArrayStartIndex, + whirlpool.data.tickSpacing, + ) + ]; + + const feesQuote = collectFeesQuote( + whirlpool.data, + position.data, + lowerTick, + upperTick, + ); + const currentUnixTimestamp = BigInt(Math.floor(Date.now() / 1000)); + const rewardsQuote = collectRewardsQuote( + whirlpool.data, + position.data, + lowerTick, + upperTick, + currentUnixTimestamp, + ); + + const requiredMints: Address[] = []; + if (quote.liquidityDelta > 0n || feesQuote.feeOwedA > 0n) { + requiredMints.push(whirlpool.data.tokenMintA); + } + if (quote.liquidityDelta > 0n || feesQuote.feeOwedB > 0n) { + requiredMints.push(whirlpool.data.tokenMintB); + } + if (rewardsQuote.rewardOwed1 > 0n) { + requiredMints.push(whirlpool.data.rewardInfos[0].mint); + } + if (rewardsQuote.rewardOwed2 > 0n) { + requiredMints.push(whirlpool.data.rewardInfos[1].mint); + } + if (rewardsQuote.rewardOwed3 > 0n) { + requiredMints.push(whirlpool.data.rewardInfos[2].mint); + } + + // FIXME: this creates the accounts even if they are not actually needed + // (no rewards, fees, to decrease liquidity, etc.) + const { createInstructions, cleanupInstructions, tokenAccountAddresses } = + await prepareTokenAccountsInstructions(rpc, authority, requiredMints); + + const instructions: IInstruction[] = []; + instructions.push(...createInstructions); + + if (quote.liquidityDelta > 0n) { + instructions.push( + getDecreaseLiquidityV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA], + tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB], + tokenVaultA: whirlpool.data.tokenVaultA, + tokenVaultB: whirlpool.data.tokenVaultB, + tickArrayLower: lowerTickArrayAddress, + tickArrayUpper: upperTickArrayAddress, + liquidityAmount: quote.liquidityDelta, + tokenMinA: quote.tokenMinA, + tokenMinB: quote.tokenMinB, + tokenMintA: whirlpool.data.tokenMintA, + tokenMintB: whirlpool.data.tokenMintB, + tokenProgramA: mintA.programAddress, + tokenProgramB: mintB.programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + if (feesQuote.feeOwedA > 0n || feesQuote.feeOwedB > 0n) { + instructions.push( + getCollectFeesV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA], + tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB], + tokenVaultA: whirlpool.data.tokenVaultA, + tokenVaultB: whirlpool.data.tokenVaultB, + tokenMintA: whirlpool.data.tokenMintA, + tokenMintB: whirlpool.data.tokenMintB, + tokenProgramA: mintA.programAddress, + tokenProgramB: mintB.programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + if (rewardsQuote.rewardOwed1 > 0n) { + assert(rewardMints[0].exists, "Reward mint 0 not found"); + instructions.push( + getCollectRewardV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + rewardOwnerAccount: tokenAccountAddresses[rewardMints[0].address], + rewardVault: whirlpool.data.rewardInfos[0].vault, + rewardIndex: 0, + rewardMint: rewardMints[0].address, + rewardTokenProgram: rewardMints[0].programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + if (rewardsQuote.rewardOwed2 > 0n) { + assert(rewardMints[1].exists, "Reward mint 1 not found"); + instructions.push( + getCollectRewardV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + rewardOwnerAccount: tokenAccountAddresses[rewardMints[1].address], + rewardVault: whirlpool.data.rewardInfos[1].vault, + rewardIndex: 1, + rewardMint: rewardMints[1].address, + rewardTokenProgram: rewardMints[1].programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + if (rewardsQuote.rewardOwed3 > 0n) { + assert(rewardMints[2].exists, "Reward mint 2 not found"); + instructions.push( + getCollectRewardV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + rewardOwnerAccount: tokenAccountAddresses[rewardMints[2].address], + rewardVault: whirlpool.data.rewardInfos[2].vault, + rewardIndex: 2, + rewardMint: rewardMints[2].address, + rewardTokenProgram: rewardMints[2].programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + switch (positionMint.programAddress) { + case TOKEN_PROGRAM_ADDRESS: + instructions.push( + getClosePositionInstruction({ + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + positionMint: positionMintAddress, + receiver: authority.address, + }), + ); + break; + case TOKEN_2022_PROGRAM_ADDRESS: + instructions.push( + getClosePositionWithTokenExtensionsInstruction({ + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + positionMint: positionMintAddress, + receiver: authority.address, + token2022Program: TOKEN_2022_PROGRAM_ADDRESS, + }), + ); + break; + default: + throw new Error("Invalid token program"); + } + + instructions.push(...cleanupInstructions); + + return { + instructions, + quote, + feesQuote, + rewardsQuote, + }; +} diff --git a/ts-sdk/whirlpool/src/harvest.ts b/ts-sdk/whirlpool/src/harvest.ts new file mode 100644 index 000000000..88763e330 --- /dev/null +++ b/ts-sdk/whirlpool/src/harvest.ts @@ -0,0 +1,330 @@ +import type { + CollectFeesQuote, + CollectRewardsQuote, +} from "@orca-so/whirlpools-core"; +import { + collectFeesQuote, + collectRewardsQuote, + getTickArrayStartTickIndex, + getTickIndexInArray, +} from "@orca-so/whirlpools-core"; +import type { + Rpc, + GetAccountInfoApi, + Address, + IInstruction, + TransactionPartialSigner, + GetMultipleAccountsApi, + GetMinimumBalanceForRentExemptionApi, + GetEpochInfoApi, +} from "@solana/web3.js"; +import { DEFAULT_ADDRESS, FUNDER } from "./config"; +import type { Whirlpool } from "@orca-so/whirlpools-client"; +import { + fetchAllTickArray, + fetchPosition, + fetchWhirlpool, + getCollectFeesV2Instruction, + getCollectRewardV2Instruction, + getPositionAddress, + getTickArrayAddress, + getUpdateFeesAndRewardsInstruction, +} from "@orca-so/whirlpools-client"; +import { findAssociatedTokenPda } from "@solana-program/token"; +import { + getCurrentTransferFee, + prepareTokenAccountsInstructions, +} from "./token"; +import { fetchAllMaybeMint } from "@solana-program/token-2022"; +import { MEMO_PROGRAM_ADDRESS } from "@solana-program/memo"; +import assert from "assert"; + +// TODO: Transfer hook + +/** + * Represents the instructions and quotes for harvesting a position. + */ +export type HarvestPositionInstructions = { + /** A breakdown of the fees owed to the position owner, detailing the amounts for token A (`fee_owed_a`) and token B (`fee_owed_b`). */ + feesQuote: CollectFeesQuote; + + /** A breakdown of the rewards owed, detailing up to three reward tokens (`reward_owed_1`, `reward_owed_2`, and `reward_owed_3`). */ + rewardsQuote: CollectRewardsQuote; + + /** A list of instructions required to harvest the position. */ + instructions: IInstruction[]; +}; + +async function getTransferFeeConfigs( + rpc: Rpc, + whirlpool: Whirlpool, +) { + const currentEpoch = await rpc.getEpochInfo().send(); + const mintAddresses = [ + whirlpool.tokenMintA, + whirlpool.tokenMintB, + whirlpool.rewardInfos[0].mint, + whirlpool.rewardInfos[1].mint, + whirlpool.rewardInfos[2].mint, + ]; + + const mints = await fetchAllMaybeMint(rpc, mintAddresses); + const [tokenA, tokenB, reward1, reward2, reward3] = mints.map((x) => + x.exists ? getCurrentTransferFee(x.data, currentEpoch.epoch) : undefined, + ); + return { + tokenA, + tokenB, + reward1, + reward2, + reward3, + }; +} + +/** + * This function creates a set of instructions that collect any accumulated fees and rewards from a position. + * The liquidity remains in place, and the position stays open. + * + * @param {SolanaRpc} rpc + * A Solana RPC client used to interact with the blockchain. + * @param {Address} positionMintAddress + * The position mint address you want to harvest fees and rewards from. + * @param {TransactionPartialSigner} [authority=FUNDER] + * The account that authorizes the transaction. Defaults to a predefined funder. + * + * @returns {Promise} + * A promise that resolves to an object containing the instructions, fees, and rewards quotes. + * @example + * import { harvestPositionInstructions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const positionMint = "POSITION_MINT"; + * + * const { feesQuote, rewardsQuote, instructions } = await harvestPositionInstructions( + * devnetRpc, + * positionMint, + * wallet + * ); + */ +export async function harvestPositionInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi & + GetEpochInfoApi + >, + positionMintAddress: Address, + authority: TransactionPartialSigner = FUNDER, +): Promise { + assert( + authority.address !== DEFAULT_ADDRESS, + "Either supply an authority or set the default funder", + ); + + const positionAddress = await getPositionAddress(positionMintAddress); + const position = await fetchPosition(rpc, positionAddress[0]); + const whirlpool = await fetchWhirlpool(rpc, position.data.whirlpool); + const [mintA, mintB, positionMint, ...rewardMints] = await fetchAllMaybeMint( + rpc, + [ + whirlpool.data.tokenMintA, + whirlpool.data.tokenMintB, + positionMintAddress, + ...whirlpool.data.rewardInfos.map((x) => x.mint), + ], + ); + + assert(mintA.exists, "Token A not found"); + assert(mintB.exists, "Token B not found"); + assert(positionMint.exists, "Position mint not found"); + + const lowerTickArrayStartIndex = getTickArrayStartTickIndex( + position.data.tickLowerIndex, + whirlpool.data.tickSpacing, + ); + const upperTickArrayStartIndex = getTickArrayStartTickIndex( + position.data.tickUpperIndex, + whirlpool.data.tickSpacing, + ); + + const [positionTokenAccount, lowerTickArrayAddress, upperTickArrayAddress] = + await Promise.all([ + findAssociatedTokenPda({ + owner: authority.address, + mint: positionMintAddress, + tokenProgram: positionMint.programAddress, + }).then((x) => x[0]), + getTickArrayAddress(whirlpool.address, lowerTickArrayStartIndex).then( + (x) => x[0], + ), + getTickArrayAddress(whirlpool.address, upperTickArrayStartIndex).then( + (x) => x[0], + ), + ]); + + const [lowerTickArray, upperTickArray] = await fetchAllTickArray(rpc, [ + lowerTickArrayAddress, + upperTickArrayAddress, + ]); + + const lowerTick = + lowerTickArray.data.ticks[ + getTickIndexInArray( + position.data.tickLowerIndex, + lowerTickArrayStartIndex, + whirlpool.data.tickSpacing, + ) + ]; + const upperTick = + upperTickArray.data.ticks[ + getTickIndexInArray( + position.data.tickUpperIndex, + upperTickArrayStartIndex, + whirlpool.data.tickSpacing, + ) + ]; + + const transferFees = await getTransferFeeConfigs(rpc, whirlpool.data); + + const feesQuote = collectFeesQuote( + whirlpool.data, + position.data, + lowerTick, + upperTick, + transferFees.tokenA, + transferFees.tokenB, + ); + const currentUnixTimestamp = BigInt(Math.floor(Date.now() / 1000)); + const rewardsQuote = collectRewardsQuote( + whirlpool.data, + position.data, + lowerTick, + upperTick, + currentUnixTimestamp, + transferFees.reward1, + transferFees.reward2, + transferFees.reward3, + ); + + const requiredMints: Address[] = []; + if (feesQuote.feeOwedA > 0n) { + requiredMints.push(whirlpool.data.tokenMintA); + } + if (feesQuote.feeOwedB > 0n) { + requiredMints.push(whirlpool.data.tokenMintB); + } + if (rewardsQuote.rewardOwed1 > 0n) { + requiredMints.push(whirlpool.data.rewardInfos[0].mint); + } + if (rewardsQuote.rewardOwed2 > 0n) { + requiredMints.push(whirlpool.data.rewardInfos[1].mint); + } + if (rewardsQuote.rewardOwed3 > 0n) { + requiredMints.push(whirlpool.data.rewardInfos[2].mint); + } + + const { createInstructions, cleanupInstructions, tokenAccountAddresses } = + await prepareTokenAccountsInstructions(rpc, authority, requiredMints); + + const instructions: IInstruction[] = []; + instructions.push(...createInstructions); + + if (feesQuote.feeOwedA > 0n || feesQuote.feeOwedB > 0n) { + instructions.push( + getCollectFeesV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA], + tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB], + tokenVaultA: whirlpool.data.tokenVaultA, + tokenVaultB: whirlpool.data.tokenVaultB, + tokenMintA: whirlpool.data.tokenMintA, + tokenMintB: whirlpool.data.tokenMintB, + tokenProgramA: mintA.programAddress, + tokenProgramB: mintB.programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + if (rewardsQuote.rewardOwed1 > 0) { + assert(rewardMints[0].exists, "Reward mint 0 not found"); + instructions.push( + getCollectRewardV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + rewardOwnerAccount: tokenAccountAddresses[rewardMints[0].address], + rewardVault: whirlpool.data.rewardInfos[0].vault, + rewardIndex: 0, + rewardMint: rewardMints[0].address, + rewardTokenProgram: rewardMints[0].programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + if (rewardsQuote.rewardOwed2 > 0) { + assert(rewardMints[1].exists, "Reward mint 1 not found"); + instructions.push( + getCollectRewardV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + rewardOwnerAccount: tokenAccountAddresses[rewardMints[1].address], + rewardVault: whirlpool.data.rewardInfos[1].vault, + rewardIndex: 1, + rewardMint: rewardMints[1].address, + rewardTokenProgram: rewardMints[1].programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + if (rewardsQuote.rewardOwed3 > 0) { + assert(rewardMints[2].exists, "Reward mint 2 not found"); + instructions.push( + getCollectRewardV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: positionAddress[0], + positionTokenAccount, + rewardOwnerAccount: tokenAccountAddresses[rewardMints[2].address], + rewardVault: whirlpool.data.rewardInfos[2].vault, + rewardIndex: 2, + rewardMint: rewardMints[2].address, + rewardTokenProgram: rewardMints[2].programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + } + + instructions.push( + getUpdateFeesAndRewardsInstruction({ + whirlpool: whirlpool.address, + position: positionAddress[0], + tickArrayLower: lowerTickArrayAddress, + tickArrayUpper: upperTickArrayAddress, + }), + ); + + instructions.push(...cleanupInstructions); + + return { + feesQuote, + rewardsQuote, + instructions, + }; +} diff --git a/ts-sdk/whirlpool/src/increaseLiquidity.ts b/ts-sdk/whirlpool/src/increaseLiquidity.ts new file mode 100644 index 000000000..9557153d8 --- /dev/null +++ b/ts-sdk/whirlpool/src/increaseLiquidity.ts @@ -0,0 +1,593 @@ +import type { Whirlpool } from "@orca-so/whirlpools-client"; +import { + fetchAllMaybeTickArray, + fetchPosition, + fetchWhirlpool, + getIncreaseLiquidityV2Instruction, + getInitializeTickArrayInstruction, + getOpenPositionWithTokenExtensionsInstruction, + getPositionAddress, + getTickArrayAddress, + getTickArraySize, +} from "@orca-so/whirlpools-client"; +import type { + IncreaseLiquidityQuote, + TickRange, + TransferFee, +} from "@orca-so/whirlpools-core"; +import { + _MAX_TICK_INDEX, + _MIN_TICK_INDEX, + getFullRangeTickIndexes, + getTickArrayStartTickIndex, + increaseLiquidityQuote, + increaseLiquidityQuoteA, + increaseLiquidityQuoteB, + priceToTickIndex, + getInitializableTickIndex, + orderTickIndexes, +} from "@orca-so/whirlpools-core"; +import type { + Account, + Address, + GetAccountInfoApi, + GetMinimumBalanceForRentExemptionApi, + GetMultipleAccountsApi, + IInstruction, + LamportsUnsafeBeyond2Pow53Minus1, + Rpc, + TransactionPartialSigner, +} from "@solana/web3.js"; +import { generateKeyPairSigner, lamports } from "@solana/web3.js"; +import { + DEFAULT_ADDRESS, + FUNDER, + SLIPPAGE_TOLERANCE_BPS, + SPLASH_POOL_TICK_SPACING, +} from "./config"; +import { + ASSOCIATED_TOKEN_PROGRAM_ADDRESS, + findAssociatedTokenPda, + getMintSize, +} from "@solana-program/token"; +import { + getCurrentTransferFee, + prepareTokenAccountsInstructions, +} from "./token"; +import type { Mint } from "@solana-program/token-2022"; +import { + fetchAllMint, + TOKEN_2022_PROGRAM_ADDRESS, +} from "@solana-program/token-2022"; +import { MEMO_PROGRAM_ADDRESS } from "@solana-program/memo"; +import assert from "assert"; + +// TODO: allow specify number as well as bigint +// TODO: transfer hook + +/** + * Represents the parameters for increasing liquidity. + * You must choose only one of the properties (`liquidity`, `tokenA`, or `tokenB`). + * The SDK will compute the other two based on the input provided. + */ +export type IncreaseLiquidityQuoteParam = + | { + /** The amount of liquidity to increase. */ + liquidity: bigint; + } + | { + /** The amount of Token A to add. */ + tokenA: bigint; + } + | { + /** The amount of Token B to add. */ + tokenB: bigint; + }; + +/** + * Represents the instructions and quote for increasing liquidity in a position. + */ +export type IncreaseLiquidityInstructions = { + /** The quote object with details about the increase in liquidity, including the liquidity delta, estimated tokens, and maximum token amounts based on slippage tolerance. */ + quote: IncreaseLiquidityQuote; + + /** The initialization cost for liquidity in lamports. */ + initializationCost: LamportsUnsafeBeyond2Pow53Minus1; + + /** List of Solana transaction instructions to execute. */ + instructions: IInstruction[]; +}; + +function getIncreaseLiquidityQuote( + param: IncreaseLiquidityQuoteParam, + pool: Whirlpool, + tickRange: TickRange, + slippageToleranceBps: number, + transferFeeA: TransferFee | undefined, + transferFeeB: TransferFee | undefined, +): IncreaseLiquidityQuote { + if ("liquidity" in param) { + return increaseLiquidityQuote( + param.liquidity, + slippageToleranceBps, + pool.sqrtPrice, + tickRange.tickLowerIndex, + tickRange.tickUpperIndex, + transferFeeA, + transferFeeB, + ); + } else if ("tokenA" in param) { + return increaseLiquidityQuoteA( + param.tokenA, + slippageToleranceBps, + pool.sqrtPrice, + tickRange.tickLowerIndex, + tickRange.tickUpperIndex, + transferFeeA, + transferFeeB, + ); + } else { + return increaseLiquidityQuoteB( + param.tokenB, + slippageToleranceBps, + pool.sqrtPrice, + tickRange.tickLowerIndex, + tickRange.tickUpperIndex, + transferFeeA, + transferFeeB, + ); + } +} + +/** + * Generates instructions to increase liquidity for an existing position. + * + * @param {SolanaRpc} rpc - The Solana RPC client. + * @param {Address} positionMintAddress - The mint address of the NFT that represents the position. + * @param {IncreaseLiquidityQuoteParam} param - The parameters for adding liquidity. Can specify liquidity, Token A, or Token B amounts. + * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The maximum acceptable slippage, in basis points (BPS). + * @param {TransactionPartialSigner} [authority=FUNDER] - The account that authorizes the transaction. + * @returns {Promise} - Instructions and quote for increasing liquidity. + * + * @example + * import { increaseLiquidityInstructions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const positionMint = "POSITION_MINT"; + * + * const param = { tokenA: 1_000_000n }; + * + * const { quote, instructions, initializationCost } = await increaseLiquidityInstructions( + * devnetRpc, + * positionMint, + * param, + * 100, + * wallet + * ); + */ +export async function increaseLiquidityInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi + >, + positionMintAddress: Address, + param: IncreaseLiquidityQuoteParam, + slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS, + authority: TransactionPartialSigner = FUNDER, +): Promise { + assert( + authority.address !== DEFAULT_ADDRESS, + "Either supply the authority or set the default funder", + ); + + const positionAddress = await getPositionAddress(positionMintAddress); + const position = await fetchPosition(rpc, positionAddress[0]); + const whirlpool = await fetchWhirlpool(rpc, position.data.whirlpool); + + const currentEpoch = await rpc.getEpochInfo().send(); + const [mintA, mintB, positionMint] = await fetchAllMint(rpc, [ + whirlpool.data.tokenMintA, + whirlpool.data.tokenMintB, + positionMintAddress, + ]); + const transferFeeA = getCurrentTransferFee(mintA.data, currentEpoch.epoch); + const transferFeeB = getCurrentTransferFee(mintB.data, currentEpoch.epoch); + + const quote = getIncreaseLiquidityQuote( + param, + whirlpool.data, + position.data, + slippageToleranceBps, + transferFeeA, + transferFeeB, + ); + const instructions: IInstruction[] = []; + + const lowerTickArrayStartIndex = getTickArrayStartTickIndex( + position.data.tickLowerIndex, + whirlpool.data.tickSpacing, + ); + const upperTickArrayStartIndex = getTickArrayStartTickIndex( + position.data.tickUpperIndex, + whirlpool.data.tickSpacing, + ); + + const [positionTokenAccount, tickArrayLower, tickArrayUpper] = + await Promise.all([ + findAssociatedTokenPda({ + owner: authority.address, + mint: positionMintAddress, + tokenProgram: positionMint.programAddress, + }).then((x) => x[0]), + getTickArrayAddress(whirlpool.address, lowerTickArrayStartIndex).then( + (x) => x[0], + ), + getTickArrayAddress(whirlpool.address, upperTickArrayStartIndex).then( + (x) => x[0], + ), + ]); + + const { createInstructions, cleanupInstructions, tokenAccountAddresses } = + await prepareTokenAccountsInstructions(rpc, authority, { + [whirlpool.data.tokenMintA]: quote.tokenMaxA, + [whirlpool.data.tokenMintB]: quote.tokenMaxB, + }); + + instructions.push(...createInstructions); + + // Since position exists tick arrays must also already exist + + instructions.push( + getIncreaseLiquidityV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: authority, + position: position.address, + positionTokenAccount, + tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA], + tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB], + tokenVaultA: whirlpool.data.tokenVaultA, + tokenVaultB: whirlpool.data.tokenVaultB, + tokenMintA: whirlpool.data.tokenMintA, + tokenMintB: whirlpool.data.tokenMintB, + tokenProgramA: mintA.programAddress, + tokenProgramB: mintB.programAddress, + tickArrayLower, + tickArrayUpper, + liquidityAmount: quote.liquidityDelta, + tokenMaxA: quote.tokenMaxA, + tokenMaxB: quote.tokenMaxB, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + + instructions.push(...cleanupInstructions); + + return { quote, instructions, initializationCost: lamports(0n) }; +} + +async function internalOpenPositionInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi + >, + whirlpool: Account, + param: IncreaseLiquidityQuoteParam, + lowerTickIndex: number, + upperTickIndex: number, + mintA: Account, + mintB: Account, + slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS, + funder: TransactionPartialSigner = FUNDER, +): Promise { + assert( + funder.address !== DEFAULT_ADDRESS, + "Either supply a funder or set the default funder", + ); + const instructions: IInstruction[] = []; + let stateSpace = 0; + + const initializableLowerTickIndex = getInitializableTickIndex( + lowerTickIndex, + whirlpool.data.tickSpacing, + false, + ); + const initializableUpperTickIndex = getInitializableTickIndex( + upperTickIndex, + whirlpool.data.tickSpacing, + true, + ); + const tickRange = orderTickIndexes( + initializableLowerTickIndex, + initializableUpperTickIndex, + ); + + const currentEpoch = await rpc.getEpochInfo().send(); + const transferFeeA = getCurrentTransferFee(mintA.data, currentEpoch.epoch); + const transferFeeB = getCurrentTransferFee(mintB.data, currentEpoch.epoch); + + const quote = getIncreaseLiquidityQuote( + param, + whirlpool.data, + tickRange, + slippageToleranceBps, + transferFeeA, + transferFeeB, + ); + + const positionMint = await generateKeyPairSigner(); + + const lowerTickArrayIndex = getTickArrayStartTickIndex( + tickRange.tickLowerIndex, + whirlpool.data.tickSpacing, + ); + const upperTickArrayIndex = getTickArrayStartTickIndex( + tickRange.tickUpperIndex, + whirlpool.data.tickSpacing, + ); + + const [ + positionAddress, + positionTokenAccount, + lowerTickArrayAddress, + upperTickArrayAddress, + ] = await Promise.all([ + getPositionAddress(positionMint.address), + findAssociatedTokenPda({ + owner: funder.address, + mint: positionMint.address, + tokenProgram: TOKEN_2022_PROGRAM_ADDRESS, + }).then((x) => x[0]), + getTickArrayAddress(whirlpool.address, lowerTickArrayIndex).then( + (x) => x[0], + ), + getTickArrayAddress(whirlpool.address, upperTickArrayIndex).then( + (x) => x[0], + ), + ]); + + const { createInstructions, cleanupInstructions, tokenAccountAddresses } = + await prepareTokenAccountsInstructions(rpc, funder, { + [whirlpool.data.tokenMintA]: quote.tokenMaxA, + [whirlpool.data.tokenMintB]: quote.tokenMaxB, + }); + + instructions.push(...createInstructions); + + const [lowerTickArray, upperTickArray] = await fetchAllMaybeTickArray(rpc, [ + lowerTickArrayAddress, + upperTickArrayAddress, + ]); + + if (!lowerTickArray.exists) { + instructions.push( + getInitializeTickArrayInstruction({ + whirlpool: whirlpool.address, + funder, + tickArray: lowerTickArrayAddress, + startTickIndex: lowerTickIndex, + }), + ); + stateSpace += getTickArraySize(); + } + + if (!upperTickArray.exists && lowerTickArrayIndex !== upperTickArrayIndex) { + instructions.push( + getInitializeTickArrayInstruction({ + whirlpool: whirlpool.address, + funder, + tickArray: upperTickArrayAddress, + startTickIndex: upperTickIndex, + }), + ); + stateSpace += getTickArraySize(); + } + + instructions.push( + getOpenPositionWithTokenExtensionsInstruction({ + funder, + owner: funder.address, + position: positionAddress[0], + positionMint, + positionTokenAccount, + whirlpool: whirlpool.address, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS, + tickLowerIndex: tickRange.tickLowerIndex, + tickUpperIndex: tickRange.tickUpperIndex, + token2022Program: TOKEN_2022_PROGRAM_ADDRESS, + metadataUpdateAuth: positionAddress[0], + withTokenMetadataExtension: true, + }), + ); + stateSpace += getMintSize(); + + instructions.push( + getIncreaseLiquidityV2Instruction({ + whirlpool: whirlpool.address, + positionAuthority: funder, + position: positionAddress[0], + positionTokenAccount, + tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA], + tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB], + tokenVaultA: whirlpool.data.tokenVaultA, + tokenVaultB: whirlpool.data.tokenVaultB, + tokenMintA: whirlpool.data.tokenMintA, + tokenMintB: whirlpool.data.tokenMintB, + tokenProgramA: mintA.programAddress, + tokenProgramB: mintB.programAddress, + tickArrayLower: lowerTickArrayAddress, + tickArrayUpper: upperTickArrayAddress, + liquidityAmount: quote.liquidityDelta, + tokenMaxA: quote.tokenMaxA, + tokenMaxB: quote.tokenMaxB, + memoProgram: MEMO_PROGRAM_ADDRESS, + remainingAccountsInfo: null, + }), + ); + + instructions.push(...cleanupInstructions); + + const nonRefundableRent = await rpc + .getMinimumBalanceForRentExemption(BigInt(stateSpace)) + .send(); + const initializationCost = lamports(nonRefundableRent + 15616720n); // Rent + protocol fee for metaplex + + return { + instructions, + quote, + initializationCost, + }; +} + +/** + * Opens a full-range position for a pool, typically used for Splash Pools or other full-range liquidity provisioning. + * + * @param {SolanaRpc} rpc - The Solana RPC client. + * @param {Address} poolAddress - The address of the liquidity pool. + * @param {IncreaseLiquidityQuoteParam} param - The parameters for adding liquidity, where one of `liquidity`, `tokenA`, or `tokenB` must be specified. The SDK will compute the others. + * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The maximum acceptable slippage, in basis points (BPS). + * @param {TransactionPartialSigner} [funder=FUNDER] - The account funding the transaction. + * @returns {Promise} - Instructions and quote for opening a full-range position. + * + * @example + * import { openFullRangePositionInstructions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const poolAddress = "POOL_ADDRESS"; + * + * const param = { tokenA: 1_000_000n }; + * + * const { quote, instructions, initializationCost } = await openFullRangePositionInstructions( + * devnetRpc, + * poolAddress, + * param, + * 100, + * wallet + * ); + */ +export async function openFullRangePositionInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi + >, + poolAddress: Address, + param: IncreaseLiquidityQuoteParam, + slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS, + funder: TransactionPartialSigner = FUNDER, +): Promise { + const whirlpool = await fetchWhirlpool(rpc, poolAddress); + const tickRange = getFullRangeTickIndexes(whirlpool.data.tickSpacing); + const [mintA, mintB] = await fetchAllMint(rpc, [ + whirlpool.data.tokenMintA, + whirlpool.data.tokenMintB, + ]); + return internalOpenPositionInstructions( + rpc, + whirlpool, + param, + tickRange.tickLowerIndex, + tickRange.tickUpperIndex, + mintA, + mintB, + slippageToleranceBps, + funder, + ); +} + +/** + * Opens a new position in a concentrated liquidity pool within a specific price range. + * This function allows you to provide liquidity for the specified range of prices and adjust liquidity parameters accordingly. + * + * **Note:** This function cannot be used with Splash Pools. + * + * @param {SolanaRpc} rpc - A Solana RPC client used to interact with the blockchain. + * @param {Address} poolAddress - The address of the liquidity pool where the position will be opened. + * @param {IncreaseLiquidityQuoteParam} param - The parameters for increasing liquidity, where you must choose one (`liquidity`, `tokenA`, or `tokenB`). The SDK will compute the other two. + * @param {number} lowerPrice - The lower bound of the price range for the position. + * @param {number} upperPrice - The upper bound of the price range for the position. + * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The slippage tolerance for adding liquidity, in basis points (BPS). + * @param {TransactionPartialSigner} [funder=FUNDER] - The account funding the transaction. + * + * @returns {Promise} A promise that resolves to an object containing liquidity information and the list of instructions needed to open the position. + * + * @example + * import { openPositionInstructions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const poolAddress = "POOL_ADDRESS"; + * + * const param = { tokenA: 1_000_000n }; + * const lowerPrice = 0.00005; + * const upperPrice = 0.00015; + * + * const { quote, instructions, initializationCost } = await openPositionInstructions( + * devnetRpc, + * poolAddress, + * param, + * lowerPrice, + * upperPrice, + * 100, + * wallet + * ); + */ +export async function openPositionInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi + >, + poolAddress: Address, + param: IncreaseLiquidityQuoteParam, + lowerPrice: number, + upperPrice: number, + slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS, + funder: TransactionPartialSigner = FUNDER, +): Promise { + const whirlpool = await fetchWhirlpool(rpc, poolAddress); + assert( + whirlpool.data.tickSpacing !== SPLASH_POOL_TICK_SPACING, + "Splash pools only support full range positions", + ); + const [mintA, mintB] = await fetchAllMint(rpc, [ + whirlpool.data.tokenMintA, + whirlpool.data.tokenMintB, + ]); + const decimalsA = mintA.data.decimals; + const decimalsB = mintB.data.decimals; + const lowerTickIndex = priceToTickIndex(lowerPrice, decimalsA, decimalsB); + const lowerInitializableTickIndex = getInitializableTickIndex( + lowerTickIndex, + whirlpool.data.tickSpacing, + ); + const upperTickIndex = priceToTickIndex(upperPrice, decimalsA, decimalsB); + const upperInitializableTickIndex = getInitializableTickIndex( + upperTickIndex, + whirlpool.data.tickSpacing, + ); + return internalOpenPositionInstructions( + rpc, + whirlpool, + param, + lowerInitializableTickIndex, + upperInitializableTickIndex, + mintA, + mintB, + slippageToleranceBps, + funder, + ); +} diff --git a/ts-sdk/whirlpool/src/index.ts b/ts-sdk/whirlpool/src/index.ts index 171c874f1..72a9d8b6d 100644 --- a/ts-sdk/whirlpool/src/index.ts +++ b/ts-sdk/whirlpool/src/index.ts @@ -1 +1,9 @@ -export * from "@orca-so/whirlpools-client"; +export * from "./config"; +export * from "./createPool"; +export * from "./decreaseLiquidity"; +export * from "./harvest"; +export * from "./increaseLiquidity"; +export * from "./pool"; +export * from "./position"; +export * from "./swap"; +export * from "./token"; diff --git a/ts-sdk/whirlpool/src/pool.ts b/ts-sdk/whirlpool/src/pool.ts new file mode 100644 index 000000000..28b774de4 --- /dev/null +++ b/ts-sdk/whirlpool/src/pool.ts @@ -0,0 +1,255 @@ +import type { Whirlpool } from "@orca-so/whirlpools-client"; +import { + getFeeTierAddress, + getWhirlpoolAddress, + fetchWhirlpoolsConfig, + fetchFeeTier, + fetchMaybeWhirlpool, + fetchAllMaybeWhirlpool, + fetchAllFeeTierWithFilter, + feeTierWhirlpoolsConfigFilter, +} from "@orca-so/whirlpools-client"; +import type { + Rpc, + GetAccountInfoApi, + GetMultipleAccountsApi, + Address, + GetProgramAccountsApi, +} from "@solana/web3.js"; +import { SPLASH_POOL_TICK_SPACING, WHIRLPOOLS_CONFIG_ADDRESS } from "./config"; + +/** + * Type representing a pool that is not yet initialized. + */ +export type InitializablePool = { + /** Indicates the pool is not initialized. */ + initialized: false; +} & Pick< + Whirlpool, + | "whirlpoolsConfig" + | "tickSpacing" + | "feeRate" + | "protocolFeeRate" + | "tokenMintA" + | "tokenMintB" +>; + +/** + * Type representing a pool that has been initialized. + * Extends the `Whirlpool` type, inheriting all its properties. + */ +export type InitializedPool = { + /** Indicates the pool is initialized. */ + initialized: true; +} & Whirlpool; + +/** + * Combined type representing both initialized and uninitialized pools. + */ +export type PoolInfo = (InitializablePool | InitializedPool) & { + /** The address of the pool. */ + address: Address; +}; + +/** + * Fetches the details of a specific Splash Pool. + * + * @param {SolanaRpc} rpc - The Solana RPC client. + * @param {Address} tokenMintOne - The first token mint address in the pool. + * @param {Address} tokenMintTwo - The second token mint address in the pool. + * @returns {Promise} - A promise that resolves to the pool information, which includes whether the pool is initialized or not. + * + * @example + * import { fetchSplashPool } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const tokenMintOne = "TOKEN_MINT_ONE"; + * const tokenMintTwo = "TOKEN_MINT_TWO"; + * + * const poolInfo = await fetchSplashPool( + * devnetRpc, + * tokenMintOne, + * tokenMintTwo + * ); + */ +export async function fetchSplashPool( + rpc: Rpc, + tokenMintOne: Address, + tokenMintTwo: Address, +): Promise { + return fetchConcentratedLiquidityPool( + rpc, + tokenMintOne, + tokenMintTwo, + SPLASH_POOL_TICK_SPACING, + ); +} + +/** + * Fetches the details of a specific Concentrated Liquidity Pool. + * + * @param {SolanaRpc} rpc - The Solana RPC client. + * @param {Address} tokenMintOne - The first token mint address in the pool. + * @param {Address} tokenMintTwo - The second token mint address in the pool. + * @param {number} tickSpacing - The tick spacing of the pool. + * @returns {Promise} - A promise that resolves to the pool information, which includes whether the pool is initialized or not. + * + * @example + * import { fetchPool } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const tokenMintOne = "TOKEN_MINT_ONE"; + * const tokenMintTwo = "TOKEN_MINT_TWO"; + * const tickSpacing = 64; + * + * const poolInfo = await fetchPool( + * devnetRpc, + * tokenMintOne, + * tokenMintTwo, + * tickSpacing + * ); + */ +export async function fetchConcentratedLiquidityPool( + rpc: Rpc, + tokenMintOne: Address, + tokenMintTwo: Address, + tickSpacing: number, +): Promise { + const [tokenMintA, tokenMintB] = + Buffer.from(tokenMintOne) < Buffer.from(tokenMintTwo) + ? [tokenMintOne, tokenMintTwo] + : [tokenMintTwo, tokenMintOne]; + const feeTierAddress = await getFeeTierAddress( + WHIRLPOOLS_CONFIG_ADDRESS, + tickSpacing, + ).then((x) => x[0]); + const poolAddress = await getWhirlpoolAddress( + WHIRLPOOLS_CONFIG_ADDRESS, + tokenMintA, + tokenMintB, + tickSpacing, + ).then((x) => x[0]); + + // TODO: this is multiple rpc calls. Can we do it in one? + const [configAccount, feeTierAccount, poolAccount] = await Promise.all([ + fetchWhirlpoolsConfig(rpc, WHIRLPOOLS_CONFIG_ADDRESS), + fetchFeeTier(rpc, feeTierAddress), + fetchMaybeWhirlpool(rpc, poolAddress), + ]); + + if (poolAccount.exists) { + return { + initialized: true, + address: poolAddress, + ...poolAccount.data, + }; + } else { + return { + initialized: false, + address: poolAddress, + whirlpoolsConfig: WHIRLPOOLS_CONFIG_ADDRESS, + tickSpacing, + feeRate: feeTierAccount.data.defaultFeeRate, + protocolFeeRate: configAccount.data.defaultProtocolFeeRate, + tokenMintA: tokenMintA, + tokenMintB: tokenMintB, + }; + } +} + +/** + * Fetches all possible liquidity pools between two token mints in Orca Whirlpools. + * If a pool does not exist, it creates a placeholder account for the uninitialized pool with default data + * + * @param {SolanaRpc} rpc - The Solana RPC client. + * @param {Address} tokenMintOne - The first token mint address in the pool. + * @param {Address} tokenMintTwo - The second token mint address in the pool. + * @returns {Promise} - A promise that resolves to an array of pool information for each pool between the two tokens. + * + * @example + * import { fetchWhirlpools } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const tokenMintOne = "TOKEN_MINT_ONE"; + * const tokenMintTwo = "TOKEN_MINT_TWO"; + * + * const pools = await fetchWhirlpools( + * devnetRpc, + * tokenMintOne, + * tokenMintTwo + * ); + */ +export async function fetchWhirlpools( + rpc: Rpc, + tokenMintOne: Address, + tokenMintTwo: Address, +): Promise { + const [tokenMintA, tokenMintB] = + Buffer.from(tokenMintOne) < Buffer.from(tokenMintTwo) + ? [tokenMintOne, tokenMintTwo] + : [tokenMintTwo, tokenMintOne]; + + const feeTierAccounts = await fetchAllFeeTierWithFilter( + rpc, + feeTierWhirlpoolsConfigFilter(WHIRLPOOLS_CONFIG_ADDRESS), + ); + + const supportedTickSpacings = feeTierAccounts.map((x) => x.data.tickSpacing); + + const poolAddresses = await Promise.all( + supportedTickSpacings.map((x) => + getWhirlpoolAddress( + WHIRLPOOLS_CONFIG_ADDRESS, + tokenMintA, + tokenMintB, + x, + ).then((x) => x[0]), + ), + ); + + // TODO: this is multiple rpc calls. Can we do it in one? + const [configAccount, poolAccounts] = await Promise.all([ + fetchWhirlpoolsConfig(rpc, WHIRLPOOLS_CONFIG_ADDRESS), + fetchAllMaybeWhirlpool(rpc, poolAddresses), + ]); + + const pools: PoolInfo[] = []; + for (let i = 0; i < supportedTickSpacings.length; i++) { + const tickSpacing = supportedTickSpacings[i]; + const feeTierAccount = feeTierAccounts[i]; + const poolAccount = poolAccounts[i]; + const poolAddress = poolAddresses[i]; + + if (poolAccount.exists) { + pools.push({ + initialized: true, + address: poolAddress, + ...poolAccount.data, + }); + } else { + pools.push({ + initialized: false, + address: poolAddress, + whirlpoolsConfig: WHIRLPOOLS_CONFIG_ADDRESS, + tickSpacing, + feeRate: feeTierAccount.data.defaultFeeRate, + protocolFeeRate: configAccount.data.defaultProtocolFeeRate, + tokenMintA, + tokenMintB, + }); + } + } + return pools; +} diff --git a/ts-sdk/whirlpool/src/position.ts b/ts-sdk/whirlpool/src/position.ts new file mode 100644 index 000000000..9dca6f19f --- /dev/null +++ b/ts-sdk/whirlpool/src/position.ts @@ -0,0 +1,162 @@ +import type { Position, PositionBundle } from "@orca-so/whirlpools-client"; +import { + fetchAllMaybePosition, + fetchAllMaybePositionBundle, + fetchAllPosition, + getBundledPositionAddress, + getPositionAddress, + getPositionBundleAddress, +} from "@orca-so/whirlpools-client"; +import { getTokenDecoder, TOKEN_PROGRAM_ADDRESS } from "@solana-program/token"; +import { TOKEN_2022_PROGRAM_ADDRESS } from "@solana-program/token-2022"; +import type { + Account, + Address, + GetMultipleAccountsApi, + GetTokenAccountsByOwnerApi, + Rpc, +} from "@solana/web3.js"; +import { getBase58Encoder } from "@solana/web3.js"; + +/** + * Represents a Position Bundle account including its associated positions. + */ +export type HydratedPositionBundle = Account & { + positions: Account[]; +}; + +/** + * Represents either a Position or Position Bundle account. + */ +export type PositionOrBundle = Account | HydratedPositionBundle; + +/** + * Represents a decoded Position or Position Bundle account. + * Includes the token program address associated with the position. + */ +export type PositionData = PositionOrBundle & { + /** The token program associated with the position (either TOKEN_PROGRAM_ADDRESS or TOKEN_2022_PROGRAM_ADDRESS). */ + tokenProgram: Address; +}; + +function getPositionInBundleAddresses( + positionBundles: PositionBundle, +): Promise
[] { + const buffer = Buffer.from(positionBundles.positionBitmap); + const positions: Promise
[] = []; + for (let i = 0; i < 256; i++) { + const byteIndex = Math.floor(i / 8); + const bitIndex = i % 8; + if (buffer[byteIndex] & (1 << bitIndex)) { + positions.push( + getBundledPositionAddress(positionBundles.positionBundleMint, i).then( + (x) => x[0], + ), + ); + } + } + return positions; +} + +/** + * Fetches all positions owned by a given wallet in the Orca Whirlpools. + * It looks for token accounts owned by the wallet using both the TOKEN_PROGRAM_ADDRESS and TOKEN_2022_PROGRAM_ADDRESS. + * For token accounts holding exactly 1 token (indicating a position or bundle), it fetches the corresponding position addresses, + * decodes the accounts, and returns an array of position or bundle data. + * + * @param {SolanaRpc} rpc - The Solana RPC client used to fetch token accounts and multiple accounts. + * @param {Address} owner - The wallet address whose positions you want to fetch. + * @returns {Promise} - A promise that resolves to an array of decoded position data for the given owner. + * + * @example + * import { fetchPositions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const positions = await fetchPositions(devnetRpc, wallet.address); + */ +export async function fetchPositions( + rpc: Rpc, + owner: Address, +): Promise { + const [tokenAccounts, token2022Accounts] = await Promise.all([ + rpc + .getTokenAccountsByOwner(owner, { programId: TOKEN_PROGRAM_ADDRESS }) + .send(), + rpc + .getTokenAccountsByOwner(owner, { programId: TOKEN_2022_PROGRAM_ADDRESS }) + .send(), + ]); + + const encoder = getBase58Encoder(); + const decoder = getTokenDecoder(); + + const potentialTokens = [...tokenAccounts.value, ...token2022Accounts.value] + .map((x) => ({ + ...decoder.decode(encoder.encode(x.account.data)), + owner: x.account.owner, + })) + .filter((x) => x.amount === 1n); + + const positionAddresses = await Promise.all( + potentialTokens.map((x) => getPositionAddress(x.mint).then((x) => x[0])), + ); + + const positionBundleAddresses = await Promise.all( + potentialTokens.map((x) => + getPositionBundleAddress(x.mint).then((x) => x[0]), + ), + ); + + // FIXME: need to batch if more than 100 position bundles? + const [positions, positionBundles] = await Promise.all([ + fetchAllMaybePosition(rpc, positionAddresses), + fetchAllMaybePositionBundle(rpc, positionBundleAddresses), + ]); + + const bundledPositionAddresses = await Promise.all( + positionBundles + .filter((x) => x.exists) + .flatMap((x) => getPositionInBundleAddresses(x.data)), + ); + + const bundledPositions = await fetchAllPosition( + rpc, + bundledPositionAddresses, + ); + const bundledPositionMap = bundledPositions.reduce((acc, x) => { + const current = acc.get(x.data.positionMint) ?? []; + return acc.set(x.data.positionMint, [...current, x]); + }, new Map[]>()); + + const positionsOrBundles: PositionData[] = []; + + for (let i = 0; i < potentialTokens.length; i++) { + const position = positions[i]; + const positionBundle = positionBundles[i]; + const token = potentialTokens[i]; + + if (position.exists) { + positionsOrBundles.push({ + ...position, + tokenProgram: token.owner, + }); + } + + // FIXME: Should this fetch positions inside the bundle? + if (positionBundle.exists) { + const positions = + bundledPositionMap.get(positionBundle.data.positionBundleMint) ?? []; + positionsOrBundles.push({ + ...positionBundle, + positions, + tokenProgram: token.owner, + }); + } + } + + return positionsOrBundles; +} diff --git a/ts-sdk/whirlpool/src/swap.ts b/ts-sdk/whirlpool/src/swap.ts new file mode 100644 index 000000000..4fdb3d08a --- /dev/null +++ b/ts-sdk/whirlpool/src/swap.ts @@ -0,0 +1,319 @@ +import type { + Account, + Address, + GetAccountInfoApi, + GetMinimumBalanceForRentExemptionApi, + GetMultipleAccountsApi, + IInstruction, + Rpc, + TransactionPartialSigner, +} from "@solana/web3.js"; +import { AccountRole, lamports } from "@solana/web3.js"; +import { FUNDER, SLIPPAGE_TOLERANCE_BPS } from "./config"; +import type { + ExactInSwapQuote, + ExactOutSwapQuote, + TickArrayFacade, + TransferFee, +} from "@orca-so/whirlpools-core"; +import { + _TICK_ARRAY_SIZE, + getTickArrayStartTickIndex, + swapQuoteByInputToken, + swapQuoteByOutputToken, +} from "@orca-so/whirlpools-core"; +import type { Whirlpool } from "@orca-so/whirlpools-client"; +import { + AccountsType, + fetchAllMaybeTickArray, + fetchWhirlpool, + getOracleAddress, + getSwapV2Instruction, + getTickArrayAddress, +} from "@orca-so/whirlpools-client"; +import { + getCurrentTransferFee, + prepareTokenAccountsInstructions, +} from "./token"; +import { MEMO_PROGRAM_ADDRESS } from "@solana-program/memo"; +import { fetchAllMint } from "@solana-program/token-2022"; + +// TODO: allow specify number as well as bigint +// TODO: transfer hook + +/** + * Parameters for an exact input swap. + */ +export type ExactInParams = { + /** The exact amount of input tokens to be swapped. */ + inputAmount: bigint; +}; + +/** + * Parameters for an exact output swap. + */ +export type ExactOutParams = { + /** The exact amount of output tokens to be received from the swap. */ + outputAmount: bigint; +}; + +/** + * Swap parameters, either for an exact input or exact output swap. + */ +export type SwapParams = (ExactInParams | ExactOutParams) & { + /** The mint address of the token being swapped. */ + mint: Address; +}; + +/** + * Swap quote that corresponds to the type of swap being executed (either input or output swap). + * + * @template T - The type of swap (input or output). + */ +export type SwapQuote = T extends ExactInParams + ? ExactInSwapQuote + : ExactOutSwapQuote; + +/** + * Instructions and quote for executing a swap. + * + * @template T - The type of swap (input or output). + */ +export type SwapInstructions = { + /** The list of instructions needed to perform the swap. */ + instructions: IInstruction[]; + + /** The swap quote, which includes information about the amounts involved in the swap. */ + quote: SwapQuote; +}; + +function createUninitializedTickArray( + address: Address, + startTickIndex: number, + programAddress: Address, +): Account { + return { + address, + data: { + startTickIndex, + ticks: Array(_TICK_ARRAY_SIZE()).fill({ + initialized: false, + liquidityNet: 0n, + feeGrowthOutsideA: 0n, + feeGrowthOutsideB: 0n, + rewardGrowthsOutside: [0n, 0n, 0n], + }), + }, + executable: false, + lamports: lamports(0n), + programAddress, + }; +} + +async function fetchTickArrayOrDefault( + rpc: Rpc, + whirlpool: Account, +): Promise[]> { + const tickArrayStartIndex = getTickArrayStartTickIndex( + whirlpool.data.tickCurrentIndex, + whirlpool.data.tickSpacing, + ); + const offset = whirlpool.data.tickSpacing * _TICK_ARRAY_SIZE(); + + const tickArrayIndexes = [ + tickArrayStartIndex, + tickArrayStartIndex + offset, + tickArrayStartIndex + offset * 2, + tickArrayStartIndex - offset, + tickArrayStartIndex - offset * 2, + ]; + + const tickArrayAddresses = await Promise.all( + tickArrayIndexes.map((startIndex) => + getTickArrayAddress(whirlpool.address, startIndex).then((x) => x[0]), + ), + ); + + const maybeTickArrays = await fetchAllMaybeTickArray(rpc, tickArrayAddresses); + + const tickArrays: Account[] = []; + + for (let i = 0; i < maybeTickArrays.length; i++) { + const maybeTickArray = maybeTickArrays[i]; + if (maybeTickArray.exists) { + tickArrays.push(maybeTickArray); + } else { + tickArrays.push( + createUninitializedTickArray( + tickArrayAddresses[i], + tickArrayIndexes[i], + whirlpool.programAddress, + ), + ); + } + } + + return tickArrays; +} + +function getSwapQuote( + params: T, + whirlpool: Whirlpool, + transferFeeA: TransferFee | undefined, + transferFeeB: TransferFee | undefined, + tickArrays: TickArrayFacade[], + specifiedTokenA: boolean, + slippageToleranceBps: number, +): SwapQuote { + if ("inputAmount" in params) { + return swapQuoteByInputToken( + params.inputAmount, + specifiedTokenA, + slippageToleranceBps, + whirlpool, + tickArrays, + transferFeeA, + transferFeeB, + ) as SwapQuote; + } + + return swapQuoteByOutputToken( + params.outputAmount, + specifiedTokenA, + slippageToleranceBps, + whirlpool, + tickArrays, + transferFeeA, + transferFeeB, + ) as SwapQuote; +} + +/** + * Generates the instructions necessary to execute a token swap in an Orca Whirlpool. + * It handles both exact input and exact output swaps, fetching the required accounts, tick arrays, and determining the swap quote. + * + * @template T - The type of swap (exact input or output). + * @param {SolanaRpc} rpc - The Solana RPC client. + * @param {T} params - The swap parameters, specifying either the input or output amount and the mint address of the token being swapped. + * @param {Address} poolAddress - The address of the Whirlpool against which the swap will be made. + * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The maximum acceptable slippage tolerance for the swap, in basis points (BPS). + * @param {TransactionPartialSigner} [signer=FUNDER] - The wallet or signer executing the swap. + * @returns {Promise>} - A promise that resolves to an object containing the swap instructions and the swap quote. + * + * @example + * import { swapInstructions } from '@orca-so/whirlpools'; + * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/web3.js'; + * + * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com')); + * const wallet = await generateKeyPairSigner(); + * await devnetRpc.requestAirdrop(wallet.address, lamports(1000000000n)).send(); + * + * const poolAddress = "POOL_ADDRESS"; + * const mintAddress = "TOKEN_MINT"; + * const inputAmount = 1_000_000n; + * + * const { instructions, quote } = await swapInstructions( + * devnetRpc, + * { inputAmount, mint: mintAddress }, + * poolAddress, + * 100, + * wallet + * ); + */ +export async function swapInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi + >, + params: T, + poolAddress: Address, + slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS, + signer: TransactionPartialSigner = FUNDER, +): Promise> { + const whirlpool = await fetchWhirlpool(rpc, poolAddress); + const [tokenA, tokenB] = await fetchAllMint(rpc, [ + whirlpool.data.tokenMintA, + whirlpool.data.tokenMintB, + ]); + const specifiedTokenA = params.mint === whirlpool.data.tokenMintA; + const specifiedInput = "inputAmount" in params; + + const tickArrays = await fetchTickArrayOrDefault(rpc, whirlpool); + + const oracleAddress = await getOracleAddress(whirlpool.address).then( + (x) => x[0], + ); + + const currentEpoch = await rpc.getEpochInfo().send(); + const transferFeeA = getCurrentTransferFee(tokenA.data, currentEpoch.epoch); + const transferFeeB = getCurrentTransferFee(tokenB.data, currentEpoch.epoch); + + const quote = getSwapQuote( + params, + whirlpool.data, + transferFeeA, + transferFeeB, + tickArrays.map((x) => x.data), + specifiedTokenA, + slippageToleranceBps, + ); + const maxInAmount = "tokenIn" in quote ? quote.tokenIn : quote.tokenMaxIn; + const tokenAIsInput = specifiedTokenA === specifiedInput; + + const { createInstructions, cleanupInstructions, tokenAccountAddresses } = + await prepareTokenAccountsInstructions(rpc, signer, { + [whirlpool.data.tokenMintA]: tokenAIsInput ? maxInAmount : 0n, + [whirlpool.data.tokenMintB]: tokenAIsInput ? 0n : maxInAmount, + }); + + const instructions: IInstruction[] = []; + + instructions.push(...createInstructions); + + const specifiedAmount = + "inputAmount" in params ? params.inputAmount : params.outputAmount; + const otherAmountThreshold = + "tokenMaxIn" in quote ? quote.tokenMaxIn : quote.tokenMinOut; + + const swapInstruction = getSwapV2Instruction({ + tokenProgramA: tokenA.programAddress, + tokenProgramB: tokenB.programAddress, + memoProgram: MEMO_PROGRAM_ADDRESS, + tokenAuthority: signer, + whirlpool: whirlpool.address, + tokenMintA: whirlpool.data.tokenMintA, + tokenMintB: whirlpool.data.tokenMintB, + tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA], + tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB], + tokenVaultA: whirlpool.data.tokenVaultA, + tokenVaultB: whirlpool.data.tokenVaultB, + tickArray0: tickArrays[0].address, + tickArray1: tickArrays[1].address, + tickArray2: tickArrays[2].address, + amount: specifiedAmount, + otherAmountThreshold, + sqrtPriceLimit: 0, + amountSpecifiedIsInput: specifiedInput, + aToB: specifiedTokenA, + oracle: oracleAddress, + remainingAccountsInfo: { + slices: [ + { accountsType: AccountsType.SupplementalTickArrays, length: 2 }, + ], + }, + }); + + swapInstruction.accounts.push( + { address: tickArrays[3].address, role: AccountRole.WRITABLE }, + { address: tickArrays[4].address, role: AccountRole.WRITABLE }, + ); + + instructions.push(swapInstruction); + instructions.push(...cleanupInstructions); + + return { + quote, + instructions, + }; +} diff --git a/ts-sdk/whirlpool/src/token.ts b/ts-sdk/whirlpool/src/token.ts new file mode 100644 index 000000000..a9110c143 --- /dev/null +++ b/ts-sdk/whirlpool/src/token.ts @@ -0,0 +1,273 @@ +import { + fetchAllMaybeToken, + fetchAllMint, + findAssociatedTokenPda, + getCloseAccountInstruction, + getCreateAssociatedTokenInstruction, + getInitializeAccount3Instruction, + getSyncNativeInstruction, + getTokenSize, + TOKEN_PROGRAM_ADDRESS, +} from "@solana-program/token"; +import type { + Address, + GetAccountInfoApi, + GetMinimumBalanceForRentExemptionApi, + GetMultipleAccountsApi, + IInstruction, + Rpc, + TransactionSigner, +} from "@solana/web3.js"; +import { + address, + generateKeyPairSigner, + getAddressDecoder, + getAddressEncoder, +} from "@solana/web3.js"; +import { SOL_WRAPPING_STRATEGY } from "./config"; +import { + getCreateAccountInstruction, + getCreateAccountWithSeedInstruction, + getTransferSolInstruction, +} from "@solana-program/system"; +import type { Mint } from "@solana-program/token-2022"; +import type { TransferFee } from "@orca-so/whirlpools-core"; + +/** The public key for the native mint (SOL) */ +export const NATIVE_MINT = address( + "So11111111111111111111111111111111111111112", +); + +/** + * Represents the instructions and associated addresses for preparing token accounts during a transaction. + */ +type TokenAccountInstructions = { + /** A list of instructions required to create the necessary token accounts. */ + createInstructions: IInstruction[]; + + /** A list of instructions to clean up (e.g., close) token accounts after the transaction is complete. */ + cleanupInstructions: IInstruction[]; + + /** A mapping of mint addresses to their respective token account addresses. */ + tokenAccountAddresses: Record; +}; + +function mintFilter(x: Address) { + if (SOL_WRAPPING_STRATEGY === "none" || SOL_WRAPPING_STRATEGY === "ata") { + return true; + } + return x != NATIVE_MINT; +} + +/** + * + * Prepare token acounts required for a transaction. This will create + * ATAs for the supplied mints. + * + * The NATIVE_MINT is a special case where this function will optionally wrap/unwrap + * SOL based on the SOL_WRAPPING_STRATEGY. + * + * @param rpc + * @param owner the owner to create token accounts for + * @param spec the mints (and amounts) required in the token accounts + * @returns Instructions and addresses for the required token accounts + */ +export async function prepareTokenAccountsInstructions( + rpc: Rpc< + GetAccountInfoApi & + GetMultipleAccountsApi & + GetMinimumBalanceForRentExemptionApi + >, + owner: TransactionSigner, + spec: Address[] | Record, +): Promise { + const mintAddresses = Array.isArray(spec) + ? spec + : (Object.keys(spec) as Address[]); + const solMintIndex = mintAddresses.indexOf(NATIVE_MINT); + const hasSolMint = solMintIndex !== -1; + const mints = await fetchAllMint(rpc, mintAddresses.filter(mintFilter)); + const tokenAddresses = await Promise.all( + mints.map((mint) => + findAssociatedTokenPda({ + owner: owner.address, + mint: mint.address, + tokenProgram: mint.programAddress, + }).then((x) => x[0]), + ), + ); + const tokenAccounts = await fetchAllMaybeToken(rpc, tokenAddresses); + const tokenAccountAddresses: Record = {}; + + const createInstructions: IInstruction[] = []; + const cleanupInstructions: IInstruction[] = []; + + for (let i = 0; i < mints.length; i++) { + const mint = mints[i]; + const tokenAccount = tokenAccounts[i]; + tokenAccountAddresses[mint.address] = tokenAccount.address; + if (tokenAccount.exists) { + continue; + } + createInstructions.push( + getCreateAssociatedTokenInstruction({ + payer: owner, + owner: owner.address, + ata: tokenAccount.address, + mint: mint.address, + tokenProgram: mint.programAddress, + }), + ); + } + + if (hasSolMint && SOL_WRAPPING_STRATEGY === "keypair") { + const keypair = await generateKeyPairSigner(); + const space = getTokenSize(); + const lamports = await rpc + .getMinimumBalanceForRentExemption(BigInt(space)) + .send(); + createInstructions.push( + getCreateAccountInstruction({ + payer: owner, + newAccount: keypair, + lamports, + space, + programAddress: TOKEN_PROGRAM_ADDRESS, + }), + getInitializeAccount3Instruction({ + account: keypair.address, + mint: NATIVE_MINT, + owner: owner.address, + }), + ); + cleanupInstructions.push( + getCloseAccountInstruction({ + account: keypair.address, + owner, + destination: owner.address, + }), + ); + tokenAccountAddresses[NATIVE_MINT] = keypair.address; + } + + if (hasSolMint && SOL_WRAPPING_STRATEGY === "seed") { + const space = getTokenSize(); + const amount = await rpc + .getMinimumBalanceForRentExemption(BigInt(space)) + .send(); + + // Generating secure seed takes longer and is not really needed here. + // With date, it should only create collisions if the same owner + // creates multiple accounts at exactly the same time (in ms) + const seed = Date.now().toString(); + const buffer = await crypto.subtle.digest( + "SHA-256", + Buffer.concat([ + Buffer.from(getAddressEncoder().encode(owner.address)), + Buffer.from(seed), + Buffer.from(getAddressEncoder().encode(TOKEN_PROGRAM_ADDRESS)), + ]), + ); + tokenAccountAddresses[NATIVE_MINT] = getAddressDecoder().decode( + new Uint8Array(buffer), + ); + + createInstructions.push( + getCreateAccountWithSeedInstruction({ + payer: owner, + newAccount: tokenAccountAddresses[NATIVE_MINT], + base: owner.address, + baseAccount: owner, + seed: seed, + space, + amount, + programAddress: TOKEN_PROGRAM_ADDRESS, + }), + getInitializeAccount3Instruction({ + account: tokenAccountAddresses[NATIVE_MINT], + mint: NATIVE_MINT, + owner: owner.address, + }), + ); + + cleanupInstructions.push( + getCloseAccountInstruction({ + account: tokenAccountAddresses[NATIVE_MINT], + owner, + destination: owner.address, + }), + ); + } + + if (hasSolMint && SOL_WRAPPING_STRATEGY === "ata") { + const account = tokenAccounts[solMintIndex]; + if (!account.exists) { + cleanupInstructions.push( + getCloseAccountInstruction({ + account: account.address, + owner, + destination: owner.address, + }), + ); + } + } + + if ( + hasSolMint && + !Array.isArray(spec) && + spec[NATIVE_MINT] > 0 && + SOL_WRAPPING_STRATEGY !== "none" + ) { + createInstructions.push( + getTransferSolInstruction({ + source: owner, + destination: tokenAccountAddresses[NATIVE_MINT], + amount: spec[NATIVE_MINT], + }), + getSyncNativeInstruction({ + account: tokenAccountAddresses[NATIVE_MINT], + }), + ); + } + + return { + createInstructions, + cleanupInstructions, + tokenAccountAddresses, + }; +} + +/** + * Retrieves the current transfer fee configuration for a given token mint based on the current epoch. + * + * This function checks the mint's transfer fee configuration and returns the appropriate fee + * structure (older or newer) depending on the current epoch. If no transfer fee configuration is found, + * it returns `undefined`. + * + * @param {Mint} mint - The mint account of the token, which may include transfer fee extensions. + * @param {bigint} currentEpoch - The current epoch to determine the applicable transfer fee. + * + * @returns {TransferFee | undefined} - The transfer fee configuration for the given mint, or `undefined` if no transfer fee is configured. + */ +export function getCurrentTransferFee( + mint: Mint, + currentEpoch: bigint, +): TransferFee | undefined { + if (mint.extensions.__option === "None") { + return undefined; + } + const feeConfig = mint.extensions.value.find( + (x) => x.__kind === "TransferFeeConfig", + ); + if (feeConfig == null) { + return undefined; + } + const transferFee = + currentEpoch >= feeConfig.newerTransferFee.epoch + ? feeConfig.newerTransferFee + : feeConfig.olderTransferFee; + return { + feeBps: transferFee.transferFeeBasisPoints, + maxFee: transferFee.maximumFee, + }; +} diff --git a/ts-sdk/whirlpool/tests/assertInstruction.ts b/ts-sdk/whirlpool/tests/assertInstruction.ts new file mode 100644 index 000000000..72086ffa5 --- /dev/null +++ b/ts-sdk/whirlpool/tests/assertInstruction.ts @@ -0,0 +1,171 @@ +import { + getCreateAccountInstructionDataDecoder, + getCreateAccountWithSeedInstructionDataDecoder, + getTransferSolInstructionDataDecoder, + SYSTEM_PROGRAM_ADDRESS, +} from "@solana-program/system"; +import { + ASSOCIATED_TOKEN_PROGRAM_ADDRESS, + getCloseAccountInstructionDataDecoder, + getCreateAssociatedTokenInstructionDataDecoder, + getInitializeAccount3InstructionDataDecoder, + getSyncNativeInstructionDataDecoder, + TOKEN_PROGRAM_ADDRESS, +} from "@solana-program/token"; +import type { Address, IInstruction } from "@solana/web3.js"; +import assert from "assert"; + +export function assertCreateAtaInstruction( + instruction: IInstruction, + checks: { + ata: Address; + idempotent?: boolean; + owner: Address; + mint: Address; + tokenProgram?: Address; + }, +) { + assert.strictEqual( + instruction.programAddress, + ASSOCIATED_TOKEN_PROGRAM_ADDRESS, + ); + + try { + const data = getCreateAssociatedTokenInstructionDataDecoder().decode( + instruction.data ?? new Uint8Array(), + ); + const idempotent = checks.idempotent ?? false; + assert.strictEqual(data.discriminator, idempotent ? 1 : 0); + } catch { + assert.fail("Could not decode instruction data"); + } + + assert.strictEqual(instruction.accounts?.[0].address, checks.owner); + assert.strictEqual(instruction.accounts?.[1].address, checks.ata); + assert.strictEqual(instruction.accounts?.[2].address, checks.owner); + assert.strictEqual(instruction.accounts?.[3].address, checks.mint); + assert.strictEqual( + instruction.accounts?.[5].address, + checks.tokenProgram ?? TOKEN_PROGRAM_ADDRESS, + ); +} + +export function assertCloseAccountInstruction( + instruction: IInstruction, + checks: { account: Address; owner: Address }, +) { + assert.strictEqual(instruction.programAddress, TOKEN_PROGRAM_ADDRESS); + + try { + const data = getCloseAccountInstructionDataDecoder().decode( + instruction.data ?? new Uint8Array(), + ); + assert.strictEqual(data.discriminator, 9); + } catch { + assert.fail("Could not decode instruction data"); + } + + assert.strictEqual(instruction.accounts?.[0].address, checks.account); + assert.strictEqual(instruction.accounts?.[1].address, checks.owner); + assert.strictEqual(instruction.accounts?.[2].address, checks.owner); +} + +export function assertSolTransferInstruction( + instruction: IInstruction, + checks: { from: Address; to: Address; amount: bigint }, +) { + assert.strictEqual(instruction.programAddress, SYSTEM_PROGRAM_ADDRESS); + + try { + const data = getTransferSolInstructionDataDecoder().decode( + instruction.data ?? new Uint8Array(), + ); + assert.strictEqual(data.discriminator, 2); + assert.strictEqual(data.amount, checks.amount); + } catch { + assert.fail("Could not decode instruction data"); + } + + assert.strictEqual(instruction.accounts?.[0].address, checks.from); + assert.strictEqual(instruction.accounts?.[1].address, checks.to); +} + +export function assertSyncNativeInstruction( + instruction: IInstruction, + checks: { account: Address }, +) { + assert.strictEqual(instruction.programAddress, TOKEN_PROGRAM_ADDRESS); + + try { + const data = getSyncNativeInstructionDataDecoder().decode( + instruction.data ?? new Uint8Array(), + ); + assert.strictEqual(data.discriminator, 17); + } catch { + assert.fail("Could not decode instruction data"); + } + + assert.strictEqual(instruction.accounts?.[0].address, checks.account); +} + +export function assertCreateAccountInstruction( + instruction: IInstruction, + checks: { account: Address; payer: Address; owner: Address }, +) { + assert.strictEqual(instruction.programAddress, SYSTEM_PROGRAM_ADDRESS); + + try { + const data = getCreateAccountInstructionDataDecoder().decode( + instruction.data ?? new Uint8Array(), + ); + assert.strictEqual(data.discriminator, 0); + assert.strictEqual(data.programAddress, checks.owner); + } catch { + assert.fail("Could not decode instruction data"); + } + + assert.strictEqual(instruction.accounts?.[0].address, checks.payer); + assert.strictEqual(instruction.accounts?.[1].address, checks.account); +} + +export function assertCreateAccountWithSeedInstruction( + instruction: IInstruction, + checks: { account: Address; payer: Address; owner: Address; seed: string }, +) { + assert.strictEqual(instruction.programAddress, SYSTEM_PROGRAM_ADDRESS); + + try { + const data = getCreateAccountWithSeedInstructionDataDecoder().decode( + instruction.data ?? new Uint8Array(), + ); + assert.strictEqual(data.discriminator, 3); + assert.strictEqual(data.programAddress, checks.owner); + assert.strictEqual(data.seed, checks.seed); + } catch { + assert.fail("Could not decode instruction data"); + } + + assert.strictEqual(instruction.accounts?.[0].address, checks.payer); + assert.strictEqual(instruction.accounts?.[1].address, checks.account); + assert.strictEqual(instruction.accounts?.[2].address, checks.payer); +} + +export function assertInitializeAccountInstruction( + instruction: IInstruction, + checks: { account: Address; mint: Address; owner: Address }, +) { + assert.strictEqual(instruction.programAddress, TOKEN_PROGRAM_ADDRESS); + + try { + const data = getInitializeAccount3InstructionDataDecoder().decode( + instruction.data ?? new Uint8Array(), + ); + assert.strictEqual(data.discriminator, 18); + assert.strictEqual(data.owner, checks.owner); + } catch { + assert.fail("Could not decode instruction data"); + } + + assert.strictEqual(instruction.accounts?.[0].address, checks.account); + assert.strictEqual(instruction.accounts?.[1].address, checks.mint); +} diff --git a/ts-sdk/whirlpool/tests/config.test.ts b/ts-sdk/whirlpool/tests/config.test.ts new file mode 100644 index 000000000..c3628ea45 --- /dev/null +++ b/ts-sdk/whirlpool/tests/config.test.ts @@ -0,0 +1,82 @@ +import { describe, it, afterAll } from "vitest"; +import { + DEFAULT_ADDRESS, + FUNDER, + SLIPPAGE_TOLERANCE_BPS, + resetConfiguration, + setDefaultFunder, + setDefaultSlippageToleranceBps, + setSolWrappingStrategy, + setWhirlpoolsConfig, + SOL_WRAPPING_STRATEGY, + WHIRLPOOLS_CONFIG_ADDRESS, + WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS, + DEFAULT_SLIPPAGE_TOLERANCE_BPS, + DEFAULT_SOL_WRAPPING_STRATEGY, + DEFAULT_WHIRLPOOLS_CONFIG_ADDRESS, + DEFAULT_WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS, +} from "../src/config"; +import assert from "assert"; +import { + address, + createKeyPairSignerFromPrivateKeyBytes, +} from "@solana/web3.js"; + +// Tests in order, which is important here + +describe("Configuration", () => { + afterAll(() => { + resetConfiguration(); + }); + + it("Should be able to set whirlpool config", async () => { + await setWhirlpoolsConfig( + address("GdDMspJi2oQaKDtABKE24wAQgXhGBoxq8sC21st7GJ3E"), + ); + assert.strictEqual( + WHIRLPOOLS_CONFIG_ADDRESS, + "GdDMspJi2oQaKDtABKE24wAQgXhGBoxq8sC21st7GJ3E", + ); + assert.strictEqual( + WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS, + "Ez4MMUVb7VrKFcTSbi9Yz2ivXwdwCqJicnDaRHbe96Yk", + ); + }); + + it("Should be able to set default funder to an address", () => { + setDefaultFunder(DEFAULT_ADDRESS); + assert.strictEqual(FUNDER.address, DEFAULT_ADDRESS); + }); + + it("Should be able to set default funder to a signer", async () => { + const bytes = new Uint8Array(32); + const signer = await createKeyPairSignerFromPrivateKeyBytes(bytes); + setDefaultFunder(signer); + assert.strictEqual(FUNDER.address, signer.address); + }); + + it("Should be able to set the default slippage tolerance", () => { + setDefaultSlippageToleranceBps(200); + assert.strictEqual(SLIPPAGE_TOLERANCE_BPS, 200); + }); + + it("Should be able to set the sol wrapping strategy", () => { + setSolWrappingStrategy("ata"); + assert.strictEqual(SOL_WRAPPING_STRATEGY, "ata"); + }); + + it("Should be able to reset the configuration", () => { + resetConfiguration(); + assert.strictEqual( + WHIRLPOOLS_CONFIG_ADDRESS, + DEFAULT_WHIRLPOOLS_CONFIG_ADDRESS, + ); + assert.strictEqual( + WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS, + DEFAULT_WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS, + ); + assert.strictEqual(FUNDER.address, DEFAULT_ADDRESS); + assert.strictEqual(SLIPPAGE_TOLERANCE_BPS, DEFAULT_SLIPPAGE_TOLERANCE_BPS); + assert.strictEqual(SOL_WRAPPING_STRATEGY, DEFAULT_SOL_WRAPPING_STRATEGY); + }); +}); diff --git a/ts-sdk/whirlpool/tests/createPool.test.ts b/ts-sdk/whirlpool/tests/createPool.test.ts new file mode 100644 index 000000000..b1808fce4 --- /dev/null +++ b/ts-sdk/whirlpool/tests/createPool.test.ts @@ -0,0 +1,5 @@ +import { describe } from "vitest"; + +describe.skip("Create Pool", () => { + // TODO: +}); diff --git a/ts-sdk/whirlpool/tests/decreaseLiquidity.test.ts b/ts-sdk/whirlpool/tests/decreaseLiquidity.test.ts new file mode 100644 index 000000000..6433d15af --- /dev/null +++ b/ts-sdk/whirlpool/tests/decreaseLiquidity.test.ts @@ -0,0 +1,5 @@ +import { describe } from "vitest"; + +describe.skip("Decrease Liquidity", () => { + // TODO: <- +}); diff --git a/ts-sdk/whirlpool/tests/e2e.test.ts b/ts-sdk/whirlpool/tests/e2e.test.ts new file mode 100644 index 000000000..89897edc2 --- /dev/null +++ b/ts-sdk/whirlpool/tests/e2e.test.ts @@ -0,0 +1,5 @@ +import { describe } from "vitest"; + +describe.skip("e2e", () => { + // TODO: <- +}); diff --git a/ts-sdk/whirlpool/tests/harvest.test.ts b/ts-sdk/whirlpool/tests/harvest.test.ts new file mode 100644 index 000000000..22afeed7f --- /dev/null +++ b/ts-sdk/whirlpool/tests/harvest.test.ts @@ -0,0 +1,5 @@ +import { describe } from "vitest"; + +describe.skip("Harvest", () => { + // TODO: <- +}); diff --git a/ts-sdk/whirlpool/tests/increaseLiquidity.test.ts b/ts-sdk/whirlpool/tests/increaseLiquidity.test.ts new file mode 100644 index 000000000..871e8ebc5 --- /dev/null +++ b/ts-sdk/whirlpool/tests/increaseLiquidity.test.ts @@ -0,0 +1,5 @@ +import { describe } from "vitest"; + +describe.skip("Increase Liquidity", () => { + // TODO: <- +}); diff --git a/ts-sdk/whirlpool/tests/mockRpc.ts b/ts-sdk/whirlpool/tests/mockRpc.ts new file mode 100644 index 000000000..6a9c2050c --- /dev/null +++ b/ts-sdk/whirlpool/tests/mockRpc.ts @@ -0,0 +1,187 @@ +import type { + Address, + ReadonlyUint8Array, + VariableSizeDecoder, +} from "@solana/web3.js"; +import { + assertIsAddress, + createSolanaRpcFromTransport, + getAddressDecoder, + getBase58Decoder, + getBase64Decoder, +} from "@solana/web3.js"; +import assert from "assert"; +import { DEFAULT_ADDRESS } from "../src/config"; +import { getMintEncoder, TOKEN_PROGRAM_ADDRESS } from "@solana-program/token"; +import { TOKEN_2022_PROGRAM_ADDRESS } from "@solana-program/token-2022"; +import { NATIVE_MINT } from "../src/token"; +import { SYSTEM_PROGRAM_ADDRESS } from "@solana-program/system"; + +export const [ + TOKEN_MINT_1, + TOKEN_MINT_2, + TOKEN_2022_MINT, + TOKEN_2022_MINT_TRANSFER_FEE, + TOKEN_2022_MINT_TRANSFER_HOOK, +] = [...Array(25).keys()].map((i) => { + const bytes = Array.from({ length: 32 }, () => i); + return getAddressDecoder().decode(new Uint8Array(bytes)); +}); + +type AccountData = { + bytes: ReadonlyUint8Array; + owner?: Address; +}; + +export const mockAccounts: Record = { + [TOKEN_MINT_1]: { + bytes: getMintEncoder().encode({ + mintAuthority: DEFAULT_ADDRESS, + supply: 1000000000, + decimals: 6, + isInitialized: true, + freezeAuthority: null, + }), + owner: TOKEN_PROGRAM_ADDRESS, + }, + [TOKEN_MINT_2]: { + bytes: getMintEncoder().encode({ + mintAuthority: DEFAULT_ADDRESS, + supply: 1000000000, + decimals: 9, + isInitialized: true, + freezeAuthority: null, + }), + owner: TOKEN_PROGRAM_ADDRESS, + }, + [NATIVE_MINT]: { + bytes: getMintEncoder().encode({ + mintAuthority: DEFAULT_ADDRESS, + supply: 1000000000, + decimals: 9, + isInitialized: true, + freezeAuthority: null, + }), + owner: TOKEN_PROGRAM_ADDRESS, + }, + [TOKEN_2022_MINT]: { + bytes: getMintEncoder().encode({ + mintAuthority: DEFAULT_ADDRESS, + supply: 1000000000, + decimals: 9, + isInitialized: true, + freezeAuthority: null, + }), + owner: TOKEN_2022_PROGRAM_ADDRESS, + }, + [TOKEN_2022_MINT_TRANSFER_FEE]: { + bytes: getMintEncoder().encode({ + mintAuthority: DEFAULT_ADDRESS, + supply: 1000000000, + decimals: 9, + isInitialized: true, + freezeAuthority: null, + // TODO: <- transfer fee config + }), + owner: TOKEN_2022_PROGRAM_ADDRESS, + }, + [TOKEN_2022_MINT_TRANSFER_HOOK]: { + bytes: getMintEncoder().encode({ + mintAuthority: DEFAULT_ADDRESS, + supply: 1000000000, + decimals: 9, + isInitialized: true, + freezeAuthority: null, + // TODO: <- transfer hook config + }), + owner: TOKEN_2022_PROGRAM_ADDRESS, + }, +}; + +const decoders: Record> = { + base58: getBase58Decoder(), + base64: getBase64Decoder(), +}; + +function getAccountData(address: unknown, opts: unknown): unknown { + assert(typeof opts === "object"); + assert(opts != null); + assert("encoding" in opts); + assert(typeof opts.encoding === "string"); + + const decoder = decoders[opts.encoding]; + if (decoder == null) { + throw new Error(`No decoder found for ${opts}`); + } + + assert(typeof address === "string"); + assertIsAddress(address); + const data = mockAccounts[address]; + if (data == null) { + return null as T; + } + return { + data: [decoder.decode(data.bytes), opts.encoding], + executable: false, + lamports: data.bytes.length * 10, + owner: data.owner ?? SYSTEM_PROGRAM_ADDRESS, + rentEpoch: 0, + space: data.bytes.length, + } as T; +} + +function getResponseWithContext(value: unknown): T { + return { + jsonrpc: "2.0", + result: { + context: { + slot: 1, + }, + value, + }, + } as T; +} + +function getResponse(value: unknown): T { + return { + jsonrpc: "2.0", + result: value, + } as T; +} + +function mockTransport( + config: Readonly<{ + payload: unknown; + signal?: AbortSignal; + }>, +): Promise { + assert(typeof config.payload === "object"); + assert(config.payload != null); + assert("method" in config.payload); + assert(typeof config.payload.method === "string"); + assert("params" in config.payload); + assert(Array.isArray(config.payload.params)); + + switch (config.payload.method) { + case "getAccountInfo": + const address = config.payload.params[0]; + assert(typeof address === "string"); + const accountData = getAccountData(address, config.payload.params[1]); + return Promise.resolve(getResponseWithContext(accountData)); + case "getMultipleAccounts": + const addresses = config.payload.params[0]; + const opts = config.payload.params[1]; + assert(Array.isArray(addresses)); + const accountsData = addresses.map((x) => getAccountData(x, opts)); + return Promise.resolve(getResponseWithContext(accountsData)); + case "getMinimumBalanceForRentExemption": + const space = config.payload.params[0]; + assert(typeof space === "number"); + return Promise.resolve(getResponse(space * 10)); + } + return Promise.reject( + `Method ${config.payload.method} not supported in mock transport`, + ); +} + +export const rpc = createSolanaRpcFromTransport(mockTransport); diff --git a/ts-sdk/whirlpool/tests/pool.test.ts b/ts-sdk/whirlpool/tests/pool.test.ts new file mode 100644 index 000000000..3e304ce7c --- /dev/null +++ b/ts-sdk/whirlpool/tests/pool.test.ts @@ -0,0 +1,5 @@ +import { describe } from "vitest"; + +describe.skip("Fetch Pool", () => { + // TODO: <- +}); diff --git a/ts-sdk/whirlpool/tests/position.test.ts b/ts-sdk/whirlpool/tests/position.test.ts new file mode 100644 index 000000000..4e030fc6f --- /dev/null +++ b/ts-sdk/whirlpool/tests/position.test.ts @@ -0,0 +1,5 @@ +import { describe } from "vitest"; + +describe.skip("Fetch Position", () => { + // TODO: <- +}); diff --git a/ts-sdk/whirlpool/tests/swap.test.ts b/ts-sdk/whirlpool/tests/swap.test.ts new file mode 100644 index 000000000..92f88a572 --- /dev/null +++ b/ts-sdk/whirlpool/tests/swap.test.ts @@ -0,0 +1,5 @@ +import { describe } from "vitest"; + +describe.skip("Swap", () => { + // TODO: <- +}); diff --git a/ts-sdk/whirlpool/tests/token.test.ts b/ts-sdk/whirlpool/tests/token.test.ts new file mode 100644 index 000000000..a5ef5b09c --- /dev/null +++ b/ts-sdk/whirlpool/tests/token.test.ts @@ -0,0 +1,602 @@ +import { describe, it, beforeAll, afterAll, afterEach, vi } from "vitest"; +import { + mockAccounts, + rpc, + TOKEN_2022_MINT, + TOKEN_MINT_1, + TOKEN_MINT_2, +} from "./mockRpc"; +import { + AccountState, + findAssociatedTokenPda, + getTokenEncoder, + TOKEN_PROGRAM_ADDRESS, +} from "@solana-program/token"; +import { TOKEN_2022_PROGRAM_ADDRESS } from "@solana-program/token-2022"; +import { + DEFAULT_ADDRESS, + resetConfiguration, + setSolWrappingStrategy, +} from "../src/config"; +import type { Address, TransactionSigner } from "@solana/web3.js"; +import { createNoopSigner, generateKeyPairSigner } from "@solana/web3.js"; +import { NATIVE_MINT, prepareTokenAccountsInstructions } from "../src/token"; +import assert from "assert"; +import { + assertCloseAccountInstruction, + assertCreateAccountInstruction, + assertCreateAccountWithSeedInstruction, + assertCreateAtaInstruction, + assertInitializeAccountInstruction, + assertSolTransferInstruction, + assertSyncNativeInstruction, +} from "./assertInstruction"; + +describe("Token Account Creation", () => { + let signer: TransactionSigner = createNoopSigner(DEFAULT_ADDRESS); + let existingTokenAccount: Address = DEFAULT_ADDRESS; + let nonExistingTokenAccount: Address = DEFAULT_ADDRESS; + let nativeMintTokenAccount: Address = DEFAULT_ADDRESS; + + const createNativeMintTokenAccount = async () => { + mockAccounts[nativeMintTokenAccount] = mockAccounts[existingTokenAccount] = + { + bytes: getTokenEncoder().encode({ + mint: TOKEN_MINT_1, + owner: signer.address, + amount: 500, + delegate: null, + state: AccountState.Initialized, + isNative: null, + delegatedAmount: 0, + closeAuthority: null, + }), + owner: TOKEN_PROGRAM_ADDRESS, + }; + }; + + beforeAll(async () => { + vi.useFakeTimers(); + signer = await generateKeyPairSigner(); + [existingTokenAccount, nonExistingTokenAccount, nativeMintTokenAccount] = + await Promise.all( + [TOKEN_MINT_1, TOKEN_MINT_2, NATIVE_MINT].map((mint) => + findAssociatedTokenPda({ + owner: signer.address, + mint, + tokenProgram: TOKEN_PROGRAM_ADDRESS, + }).then((x) => x[0]), + ), + ); + mockAccounts[existingTokenAccount] = { + bytes: getTokenEncoder().encode({ + mint: TOKEN_MINT_1, + owner: signer.address, + amount: 500, + delegate: null, + state: AccountState.Initialized, + isNative: null, + delegatedAmount: 0, + closeAuthority: null, + }), + owner: TOKEN_PROGRAM_ADDRESS, + }; + }); + + afterAll(async () => { + vi.useRealTimers(); + delete mockAccounts[existingTokenAccount]; + }); + + afterEach(async () => { + resetConfiguration(); + }); + + it("No native mint", async () => { + const result = await prepareTokenAccountsInstructions(rpc, signer, [ + TOKEN_MINT_1, + TOKEN_MINT_2, + ]); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 2); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 1); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assert.strictEqual(result.cleanupInstructions.length, 0); + }); + + it("No native mint with balances", async () => { + const result = await prepareTokenAccountsInstructions(rpc, signer, { + [TOKEN_MINT_1]: 100n, + [TOKEN_MINT_2]: 100n, + }); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 2); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 1); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assert.strictEqual(result.cleanupInstructions.length, 0); + }); + + it("Token 2022 token", async () => { + const result = await prepareTokenAccountsInstructions(rpc, signer, [ + TOKEN_2022_MINT, + ]); + + const tokenAddress = await findAssociatedTokenPda({ + owner: signer.address, + mint: TOKEN_2022_MINT, + tokenProgram: TOKEN_2022_PROGRAM_ADDRESS, + }).then((x) => x[0]); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 1); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_2022_MINT], + tokenAddress, + ); + assert.strictEqual(result.createInstructions.length, 1); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: tokenAddress, + owner: signer.address, + mint: TOKEN_2022_MINT, + tokenProgram: TOKEN_2022_PROGRAM_ADDRESS, + }); + assert.strictEqual(result.cleanupInstructions.length, 0); + }); + + it("Native mint and wrapping is none", async () => { + setSolWrappingStrategy("none"); + + const result = await prepareTokenAccountsInstructions(rpc, signer, [ + TOKEN_MINT_1, + TOKEN_MINT_2, + NATIVE_MINT, + ]); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 2); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertCreateAtaInstruction(result.createInstructions[1], { + ata: nativeMintTokenAccount, + owner: signer.address, + mint: NATIVE_MINT, + }); + assert.strictEqual(result.cleanupInstructions.length, 0); + }); + + it("Native mint and wrapping is none with balances", async () => { + setSolWrappingStrategy("none"); + + const result = await prepareTokenAccountsInstructions(rpc, signer, { + [TOKEN_MINT_1]: 100n, + [TOKEN_MINT_2]: 100n, + [NATIVE_MINT]: 100n, + }); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 2); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertCreateAtaInstruction(result.createInstructions[1], { + ata: nativeMintTokenAccount, + owner: signer.address, + mint: NATIVE_MINT, + }); + assert.strictEqual(result.cleanupInstructions.length, 0); + }); + + it("Native mint and wrapping is ata", async () => { + setSolWrappingStrategy("ata"); + + const result = await prepareTokenAccountsInstructions(rpc, signer, [ + TOKEN_MINT_1, + TOKEN_MINT_2, + NATIVE_MINT, + ]); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 2); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertCreateAtaInstruction(result.createInstructions[1], { + ata: nativeMintTokenAccount, + owner: signer.address, + mint: NATIVE_MINT, + }); + assert.strictEqual(result.cleanupInstructions.length, 1); + assertCloseAccountInstruction(result.cleanupInstructions[0], { + account: nativeMintTokenAccount, + owner: signer.address, + }); + }); + + it("Native mint and wrapping is ata but already exists", async () => { + setSolWrappingStrategy("ata"); + await createNativeMintTokenAccount(); + + const result = await prepareTokenAccountsInstructions(rpc, signer, [ + TOKEN_MINT_1, + TOKEN_MINT_2, + NATIVE_MINT, + ]); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 1); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assert.strictEqual(result.cleanupInstructions.length, 0); + + delete mockAccounts[nativeMintTokenAccount]; + }); + + it("Native mint and wrapping is ata with balances", async () => { + setSolWrappingStrategy("ata"); + + const result = await prepareTokenAccountsInstructions(rpc, signer, { + [TOKEN_MINT_1]: 100n, + [TOKEN_MINT_2]: 100n, + [NATIVE_MINT]: 100n, + }); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 4); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertCreateAtaInstruction(result.createInstructions[1], { + ata: nativeMintTokenAccount, + owner: signer.address, + mint: NATIVE_MINT, + }); + assertSolTransferInstruction(result.createInstructions[2], { + from: signer.address, + to: result.tokenAccountAddresses[NATIVE_MINT], + amount: 100n, + }); + assertSyncNativeInstruction(result.createInstructions[3], { + account: result.tokenAccountAddresses[NATIVE_MINT], + }); + assert.strictEqual(result.cleanupInstructions.length, 1); + assertCloseAccountInstruction(result.cleanupInstructions[0], { + account: nativeMintTokenAccount, + owner: signer.address, + }); + }); + + it("Native mint and wrapping is ata but already exists with balances", async () => { + setSolWrappingStrategy("ata"); + await createNativeMintTokenAccount(); + + const result = await prepareTokenAccountsInstructions(rpc, signer, { + [TOKEN_MINT_1]: 100n, + [TOKEN_MINT_2]: 100n, + [NATIVE_MINT]: 100n, + }); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 3); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertSolTransferInstruction(result.createInstructions[1], { + from: signer.address, + to: result.tokenAccountAddresses[NATIVE_MINT], + amount: 100n, + }); + assertSyncNativeInstruction(result.createInstructions[2], { + account: result.tokenAccountAddresses[NATIVE_MINT], + }); + assert.strictEqual(result.cleanupInstructions.length, 0); + + delete mockAccounts[nativeMintTokenAccount]; + }); + + it("Native mint and wrapping is seed", async () => { + setSolWrappingStrategy("seed"); + + const result = await prepareTokenAccountsInstructions(rpc, signer, [ + TOKEN_MINT_1, + TOKEN_MINT_2, + NATIVE_MINT, + ]); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.notStrictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 3); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertCreateAccountWithSeedInstruction(result.createInstructions[1], { + account: result.tokenAccountAddresses[NATIVE_MINT], + payer: signer.address, + owner: TOKEN_PROGRAM_ADDRESS, + seed: Date.now().toString(), + }); + assertInitializeAccountInstruction(result.createInstructions[2], { + account: result.tokenAccountAddresses[NATIVE_MINT], + mint: NATIVE_MINT, + owner: signer.address, + }); + assert.strictEqual(result.cleanupInstructions.length, 1); + assertCloseAccountInstruction(result.cleanupInstructions[0], { + account: result.tokenAccountAddresses[NATIVE_MINT], + owner: signer.address, + }); + }); + + it("Native mint and wrapping is seed with balances", async () => { + setSolWrappingStrategy("seed"); + + const result = await prepareTokenAccountsInstructions(rpc, signer, { + [TOKEN_MINT_1]: 100n, + [TOKEN_MINT_2]: 100n, + [NATIVE_MINT]: 100n, + }); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.notStrictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 5); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertCreateAccountWithSeedInstruction(result.createInstructions[1], { + account: result.tokenAccountAddresses[NATIVE_MINT], + payer: signer.address, + owner: TOKEN_PROGRAM_ADDRESS, + seed: Date.now().toString(), + }); + assertInitializeAccountInstruction(result.createInstructions[2], { + account: result.tokenAccountAddresses[NATIVE_MINT], + mint: NATIVE_MINT, + owner: signer.address, + }); + assertSolTransferInstruction(result.createInstructions[3], { + from: signer.address, + to: result.tokenAccountAddresses[NATIVE_MINT], + amount: 100n, + }); + assertSyncNativeInstruction(result.createInstructions[4], { + account: result.tokenAccountAddresses[NATIVE_MINT], + }); + assert.strictEqual(result.cleanupInstructions.length, 1); + assertCloseAccountInstruction(result.cleanupInstructions[0], { + account: result.tokenAccountAddresses[NATIVE_MINT], + owner: signer.address, + }); + }); + + it("Native mint and wrapping is keypair", async () => { + setSolWrappingStrategy("keypair"); + + const result = await prepareTokenAccountsInstructions(rpc, signer, [ + TOKEN_MINT_1, + TOKEN_MINT_2, + NATIVE_MINT, + ]); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.notStrictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 3); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertCreateAccountInstruction(result.createInstructions[1], { + account: result.tokenAccountAddresses[NATIVE_MINT], + payer: signer.address, + owner: TOKEN_PROGRAM_ADDRESS, + }); + assertInitializeAccountInstruction(result.createInstructions[2], { + account: result.tokenAccountAddresses[NATIVE_MINT], + mint: NATIVE_MINT, + owner: signer.address, + }); + assert.strictEqual(result.cleanupInstructions.length, 1); + assertCloseAccountInstruction(result.cleanupInstructions[0], { + account: result.tokenAccountAddresses[NATIVE_MINT], + owner: signer.address, + }); + }); + + it("Native mint and wrapping is keypair with balances", async () => { + setSolWrappingStrategy("keypair"); + + const result = await prepareTokenAccountsInstructions(rpc, signer, { + [TOKEN_MINT_1]: 100n, + [TOKEN_MINT_2]: 100n, + [NATIVE_MINT]: 100n, + }); + + assert.strictEqual(Object.keys(result.tokenAccountAddresses).length, 3); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_1], + existingTokenAccount, + ); + assert.strictEqual( + result.tokenAccountAddresses[TOKEN_MINT_2], + nonExistingTokenAccount, + ); + assert.notStrictEqual( + result.tokenAccountAddresses[NATIVE_MINT], + nativeMintTokenAccount, + ); + assert.strictEqual(result.createInstructions.length, 5); + assertCreateAtaInstruction(result.createInstructions[0], { + ata: nonExistingTokenAccount, + owner: signer.address, + mint: TOKEN_MINT_2, + }); + assertCreateAccountInstruction(result.createInstructions[1], { + account: result.tokenAccountAddresses[NATIVE_MINT], + payer: signer.address, + owner: TOKEN_PROGRAM_ADDRESS, + }); + assertInitializeAccountInstruction(result.createInstructions[2], { + account: result.tokenAccountAddresses[NATIVE_MINT], + mint: NATIVE_MINT, + owner: signer.address, + }); + assertSolTransferInstruction(result.createInstructions[3], { + from: signer.address, + to: result.tokenAccountAddresses[NATIVE_MINT], + amount: 100n, + }); + assertSyncNativeInstruction(result.createInstructions[4], { + account: result.tokenAccountAddresses[NATIVE_MINT], + }); + assert.strictEqual(result.cleanupInstructions.length, 1); + assertCloseAccountInstruction(result.cleanupInstructions[0], { + account: result.tokenAccountAddresses[NATIVE_MINT], + owner: signer.address, + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index 0620a2292..407ec0d76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -216,117 +216,117 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.24.7, @babel/code-frame@npm:^7.8.3": - version: 7.24.7 - resolution: "@babel/code-frame@npm:7.24.7" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.25.7, @babel/code-frame@npm:^7.8.3": + version: 7.25.7 + resolution: "@babel/code-frame@npm:7.25.7" dependencies: - "@babel/highlight": "npm:^7.24.7" + "@babel/highlight": "npm:^7.25.7" picocolors: "npm:^1.0.0" - checksum: 10c0/ab0af539473a9f5aeaac7047e377cb4f4edd255a81d84a76058595f8540784cc3fbe8acf73f1e073981104562490aabfb23008cd66dc677a456a4ed5390fdde6 + checksum: 10c0/14825c298bdec914caf3d24d1383b6d4cd6b030714686004992f4fc251831ecf432236652896f99d5d341f17170ae9a07b58d8d7b15aa0df8cfa1c5a7d5474bc languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.2": - version: 7.25.2 - resolution: "@babel/compat-data@npm:7.25.2" - checksum: 10c0/5bf1f14d6e5f0d37c19543e99209ff4a94bb97915e1ce01e5334a144aa08cd56b6e62ece8135dac77e126723d63d4d4b96fc603a12c43b88c28f4b5e070270c5 +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.7, @babel/compat-data@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/compat-data@npm:7.25.8" + checksum: 10c0/8b81c17580e5fb4cbb6a3c52079f8c283fc59c0c6bd2fe14cfcf9c44b32d2eaab71b02c5633e2c679f5896f73f8ac4036ba2e67a4c806e8f428e4b11f526d7f4 languageName: node linkType: hard "@babel/core@npm:^7.21.3, @babel/core@npm:^7.23.3": - version: 7.25.2 - resolution: "@babel/core@npm:7.25.2" + version: 7.25.8 + resolution: "@babel/core@npm:7.25.8" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.24.7" - "@babel/generator": "npm:^7.25.0" - "@babel/helper-compilation-targets": "npm:^7.25.2" - "@babel/helper-module-transforms": "npm:^7.25.2" - "@babel/helpers": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.0" - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.2" - "@babel/types": "npm:^7.25.2" + "@babel/code-frame": "npm:^7.25.7" + "@babel/generator": "npm:^7.25.7" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helpers": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.8" + "@babel/template": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.8" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/a425fa40e73cb72b6464063a57c478bc2de9dbcc19c280f1b55a3d88b35d572e87e8594e7d7b4880331addb6faef641bbeb701b91b41b8806cd4deae5d74f401 + checksum: 10c0/8411ea506e6f7c8a39ab5c1524b00589fa3b087edb47389708f7fe07170929192171734666e3ea10b95a951643a531a6d09eedfe071572c9ea28516646265086 languageName: node linkType: hard -"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/generator@npm:7.25.0" +"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/generator@npm:7.25.7" dependencies: - "@babel/types": "npm:^7.25.0" + "@babel/types": "npm:^7.25.7" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" - jsesc: "npm:^2.5.1" - checksum: 10c0/d0e2dfcdc8bdbb5dded34b705ceebf2e0bc1b06795a1530e64fb6a3ccf313c189db7f60c1616effae48114e1a25adc75855bc4496f3779a396b3377bae718ce7 + jsesc: "npm:^3.0.2" + checksum: 10c0/c03a26c79864d60d04ce36b649c3fa0d6fd7b2bf6a22e22854a0457aa09206508392dd73ee40e7bc8d50b3602f9ff068afa47770cda091d332e7db1ca382ee96 languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-annotate-as-pure@npm:7.24.7" +"@babel/helper-annotate-as-pure@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-annotate-as-pure@npm:7.25.7" dependencies: - "@babel/types": "npm:^7.24.7" - checksum: 10c0/4679f7df4dffd5b3e26083ae65228116c3da34c3fff2c11ae11b259a61baec440f51e30fd236f7a0435b9d471acd93d0bc5a95df8213cbf02b1e083503d81b9a + "@babel/types": "npm:^7.25.7" + checksum: 10c0/2f020b0fa9d336b5778485cc2de3141561ec436a7591b685457a5bcdae4ce41d9ddee68169c95504e0789e5a4327e73b8b7e72e5b60e82e96d730c4d19255248 languageName: node linkType: hard -"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.24.7" +"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/0ed84abf848c79fb1cd4c1ddac12c771d32c1904d87fc3087f33cfdeb0c2e0db4e7892b74b407d9d8d0c000044f3645a7391a781f788da8410c290bb123a1f13 + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/e9dc5a7920a1d74150dec53ccd5e34f2b31ae307df7cdeec6289866f7bda97ecb1328b49a7710ecde5db5b6daad768c904a030f9a0fa3184963b0017622c42aa languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.24.7, @babel/helper-compilation-targets@npm:^7.24.8, @babel/helper-compilation-targets@npm:^7.25.2": - version: 7.25.2 - resolution: "@babel/helper-compilation-targets@npm:7.25.2" +"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-compilation-targets@npm:7.25.7" dependencies: - "@babel/compat-data": "npm:^7.25.2" - "@babel/helper-validator-option": "npm:^7.24.8" - browserslist: "npm:^4.23.1" + "@babel/compat-data": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + browserslist: "npm:^4.24.0" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 10c0/de10e986b5322c9f807350467dc845ec59df9e596a5926a3b5edbb4710d8e3b8009d4396690e70b88c3844fe8ec4042d61436dd4b92d1f5f75655cf43ab07e99 + checksum: 10c0/705be7e5274a3fdade68e3e2cf42e2b600316ab52794e13b91299a16f16c926f15886b6e9d6df20eb943ccc1cdba5a363d4766f8d01e47b8e6f4e01175f5e66c languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.24.7, @babel/helper-create-class-features-plugin@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helper-create-class-features-plugin@npm:7.25.0" +"@babel/helper-create-class-features-plugin@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-create-class-features-plugin@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-member-expression-to-functions": "npm:^7.24.8" - "@babel/helper-optimise-call-expression": "npm:^7.24.7" - "@babel/helper-replace-supers": "npm:^7.25.0" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-member-expression-to-functions": "npm:^7.25.7" + "@babel/helper-optimise-call-expression": "npm:^7.25.7" + "@babel/helper-replace-supers": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/2f8ac36cfeb45d462432acea64c78312cc9180dda7aa9337b77017961e373c323065362d2452f3d6f8bffeb254ff3f7346ac1b25c8ad7b81db813a95924f4053 + checksum: 10c0/405c3c1a137acda1206380a96993cf2cfd808b3bee1c11c4af47ee0f03a20858497aa53394d6adc5431793c543be5e02010620e871a5ab39d938ae90a54b50f2 languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.24.7, @babel/helper-create-regexp-features-plugin@npm:^7.25.0": - version: 7.25.2 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.2" +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - regexpu-core: "npm:^5.3.1" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + regexpu-core: "npm:^6.1.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/85a7e3639c118856fb1113f54fb7e3bf7698171ddfd0cd6fccccd5426b3727bc1434fe7f69090441dcde327feef9de917e00d35e47ab820047057518dd675317 + checksum: 10c0/75919fd5a67cd7be8497b56f7b9ed6b4843cb401956ba8d403aa9ae5b005bc28e35c7f27e704d820edbd1154394ed7a7984d4719916795d89d716f6980fe8bd4 languageName: node linkType: hard @@ -345,223 +345,223 @@ __metadata: languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" +"@babel/helper-member-expression-to-functions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-member-expression-to-functions@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.8" - "@babel/types": "npm:^7.24.8" - checksum: 10c0/7e14a5acc91f6cd26305a4441b82eb6f616bd70b096a4d2099a968f16b26d50207eec0b9ebfc466fefd62bd91587ac3be878117cdfec819b7151911183cb0e5a + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/1e948162ab48d84593a7c6ec9570d14c906146f1697144fc369c59dbeb00e4a062da67dd06cb0d8f98a044cd8389002dcf2ab6f5613d99c35748307846ec63fc languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-module-imports@npm:7.24.7" +"@babel/helper-module-imports@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-module-imports@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/97c57db6c3eeaea31564286e328a9fb52b0313c5cfcc7eee4bc226aebcf0418ea5b6fe78673c0e4a774512ec6c86e309d0f326e99d2b37bfc16a25a032498af0 + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/0fd0c3673835e5bf75558e184bcadc47c1f6dd2fe2016d53ebe1e5a6ae931a44e093015c2f9a6651c1a89f25c76d9246710c2b0b460b95ee069c464f2837fa2c languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.24.7, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.25.0, @babel/helper-module-transforms@npm:^7.25.2": - version: 7.25.2 - resolution: "@babel/helper-module-transforms@npm:7.25.2" +"@babel/helper-module-transforms@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-module-transforms@npm:7.25.7" dependencies: - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-simple-access": "npm:^7.24.7" - "@babel/helper-validator-identifier": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.2" + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-simple-access": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/adaa15970ace0aee5934b5a633789b5795b6229c6a9cf3e09a7e80aa33e478675eee807006a862aa9aa517935d81f88a6db8a9f5936e3a2a40ec75f8062bc329 + checksum: 10c0/f37fa7d1d4df21690535b278468cbd5faf0133a3080f282000cfa4f3ffc9462a1458f866b04b6a2f2d1eec4691236cba9a867da61270dab3ab19846e62f05090 languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" +"@babel/helper-optimise-call-expression@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-optimise-call-expression@npm:7.25.7" dependencies: - "@babel/types": "npm:^7.24.7" - checksum: 10c0/ca6a9884705dea5c95a8b3ce132d1e3f2ae951ff74987d400d1d9c215dae9c0f9e29924d8f8e131e116533d182675bc261927be72f6a9a2968eaeeaa51eb1d0f + "@babel/types": "npm:^7.25.7" + checksum: 10c0/19b4cc7e77811b1fedca4928dbc14026afef913c2ba4142e5e110ebdcb5c3b2efc0f0fbee9f362c23a194674147b9d627adea71c289b9be08b9067bc0085308b languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.24.8, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": - version: 7.24.8 - resolution: "@babel/helper-plugin-utils@npm:7.24.8" - checksum: 10c0/0376037f94a3bfe6b820a39f81220ac04f243eaee7193774b983e956c1750883ff236b30785795abbcda43fac3ece74750566830c2daa4d6e3870bb0dff34c2d +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.25.7, @babel/helper-plugin-utils@npm:^7.8.0": + version: 7.25.7 + resolution: "@babel/helper-plugin-utils@npm:7.25.7" + checksum: 10c0/241f8cf3c5b7700e91cab7cfe5b432a3c710ae3cd5bb96dc554da536a6d25f5b9f000cc0c0917501ceb4f76ba92599ee3beb25e10adaf96be59f8df89a842faf languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.24.7, @babel/helper-remap-async-to-generator@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helper-remap-async-to-generator@npm:7.25.0" +"@babel/helper-remap-async-to-generator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-remap-async-to-generator@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-wrap-function": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-wrap-function": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/0d17b5f7bb6a607edc9cc62fff8056dd9f341bf2f919884f97b99170d143022a5e7ae57922c4891e4fc360ad291e708d2f8cd8989f1d3cd7a17600159984f5a6 + checksum: 10c0/972d84876adce6ab61c87a2df47e1afc790b73cff0d1767d0a1c5d9f7aa5e91d8c581a272b66b2051a26cfbb167d8a780564705e488e3ce1f477f1c15059bc5f languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.24.7, @babel/helper-replace-supers@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helper-replace-supers@npm:7.25.0" +"@babel/helper-replace-supers@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-replace-supers@npm:7.25.7" dependencies: - "@babel/helper-member-expression-to-functions": "npm:^7.24.8" - "@babel/helper-optimise-call-expression": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-member-expression-to-functions": "npm:^7.25.7" + "@babel/helper-optimise-call-expression": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/b4b6650ab3d56c39a259367cd97f8df2f21c9cebb3716fea7bca40a150f8847bfb82f481e98927c7c6579b48a977b5a8f77318a1c6aeb497f41ecd6dbc3fdfef + checksum: 10c0/761d64ee74429f7326a6aa65e2cd5bfcb8de9e3bc3f1efb14b8f610d2410f003b0fca52778dc801d49ff8fbc90b057e8f51b27c62b0b05c95eaf23140ca1287b languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-simple-access@npm:7.24.7" +"@babel/helper-simple-access@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-simple-access@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/7230e419d59a85f93153415100a5faff23c133d7442c19e0cd070da1784d13cd29096ee6c5a5761065c44e8164f9f80e3a518c41a0256df39e38f7ad6744fed7 + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/eed1b499bfb4f613c18debd61517e3de77b6da2727ca025aa05ac81599e0269f1dddb5237db04e8bb598115d015874752e0a7f11ff38672d74a4976097417059 languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.24.7" +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/e3a9b8ac9c262ac976a1bcb5fe59694db5e6f0b4f9e7bdba5c7693b8b5e28113c23bdaa60fe8d3ec32a337091b67720b2053bcb3d5655f5406536c3d0584242b + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/5804adb893849a9d8cfb548e3812566a81d95cb0c9a10d66b52912d13f488e577c33063bf19bc06ac70e6333162a7370d67ba1a1c3544d37fb50d5f4a00db4de languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-string-parser@npm:7.24.8" - checksum: 10c0/6361f72076c17fabf305e252bf6d580106429014b3ab3c1f5c4eb3e6d465536ea6b670cc0e9a637a77a9ad40454d3e41361a2909e70e305116a23d68ce094c08 +"@babel/helper-string-parser@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-string-parser@npm:7.25.7" + checksum: 10c0/73ef2ceb81f8294678a0afe8ab0103729c0370cac2e830e0d5128b03be5f6a2635838af31d391d763e3c5a4460ed96f42fd7c9b552130670d525be665913bc4c languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-validator-identifier@npm:7.24.7" - checksum: 10c0/87ad608694c9477814093ed5b5c080c2e06d44cb1924ae8320474a74415241223cc2a725eea2640dd783ff1e3390e5f95eede978bc540e870053152e58f1d651 +"@babel/helper-validator-identifier@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-validator-identifier@npm:7.25.7" + checksum: 10c0/07438e5bf01ab2882a15027fdf39ac3b0ba1b251774a5130917907014684e2f70fef8fd620137ca062c4c4eedc388508d2ea7a3a7d9936a32785f4fe116c68c0 languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.24.7, @babel/helper-validator-option@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-validator-option@npm:7.24.8" - checksum: 10c0/73db93a34ae89201351288bee7623eed81a54000779462a986105b54ffe82069e764afd15171a428b82e7c7a9b5fec10b5d5603b216317a414062edf5c67a21f +"@babel/helper-validator-option@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-validator-option@npm:7.25.7" + checksum: 10c0/12ed418c8e3ed9ed44c8c80d823f4e42d399b5eb2e423adccb975e31a31a008cd3b5d8eab688b31f740caff4a1bb28fe06ea2fa7d635aee34cc0ad6995d50f0a languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helper-wrap-function@npm:7.25.0" +"@babel/helper-wrap-function@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-wrap-function@npm:7.25.7" dependencies: - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.0" - "@babel/types": "npm:^7.25.0" - checksum: 10c0/d54601a98384c191cbc1ff07b03a19e288ef8d5c6bfafe270b2a303d96e7304eb296002921ed464cc1b105a547d1db146eb86b0be617924dee1ba1b379cdc216 + "@babel/template": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/b5d412f72697f4a4ce4cb9784fbaf82501c63cf95066c0eadd3179e3439cbbf0aa5fa4858d93590083671943cd357aeb87286958df34aa56fdf8a4c9dea39755 languageName: node linkType: hard -"@babel/helpers@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helpers@npm:7.25.0" +"@babel/helpers@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helpers@npm:7.25.7" dependencies: - "@babel/template": "npm:^7.25.0" - "@babel/types": "npm:^7.25.0" - checksum: 10c0/b7fe007fc4194268abf70aa3810365085e290e6528dcb9fbbf7a765d43c74b6369ce0f99c5ccd2d44c413853099daa449c9a0123f0b212ac8d18643f2e8174b8 + "@babel/template": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/3b3ae9e373bd785414195ef8f59976a69d5a6ebe0ef2165fdcc5165e5c3ee09e0fcee94bb457df2ddb8c0532e4146d0a9b7a96b3497399a4bff4ffe196b30228 languageName: node linkType: hard -"@babel/highlight@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/highlight@npm:7.24.7" +"@babel/highlight@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/highlight@npm:7.25.7" dependencies: - "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" chalk: "npm:^2.4.2" js-tokens: "npm:^4.0.0" picocolors: "npm:^1.0.0" - checksum: 10c0/674334c571d2bb9d1c89bdd87566383f59231e16bcdcf5bb7835babdf03c9ae585ca0887a7b25bdf78f303984af028df52831c7989fecebb5101cc132da9393a + checksum: 10c0/1f5894fdb0a0af6101fb2822369b2eeeae32cbeae2ef73ff73fc6a0a4a20471565cd9cfa589f54ed69df66adeca7c57266031ca9134b7bd244d023a488d419aa languageName: node linkType: hard -"@babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.3": - version: 7.25.3 - resolution: "@babel/parser@npm:7.25.3" +"@babel/parser@npm:^7.25.7, @babel/parser@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/parser@npm:7.25.8" dependencies: - "@babel/types": "npm:^7.25.2" + "@babel/types": "npm:^7.25.8" bin: parser: ./bin/babel-parser.js - checksum: 10c0/874b01349aedb805d6694f867a752fdc7469778fad76aca4548d2cc6ce96087c3ba5fb917a6f8d05d2d1a74aae309b5f50f1a4dba035f5a2c9fcfe6e106d2c4e + checksum: 10c0/a1a13845b7e8dda4c970791814a4bbf60004969882f18f470e260ad822d2e1f8941948f851e9335895563610f240fa6c98481ce8019865e469502bbf21daafa4 languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.3": - version: 7.25.3 - resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.3" +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/traverse": "npm:^7.25.3" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/814b4d3f102e7556a5053d1acf57ef601cfcff39a2c81b8cdc6a5c842e3cb9838f5925d1466a5f1e6416e74c9c83586a3c07fbd7fb8610a396c2becdf9ae5790 + checksum: 10c0/c6ba97c39973897a2ab021c4a77221e1e93e853a5811d498db325da1bd692e41fa521db6d91bb709ccafd4e54ddd00869ffb35846923c3ccd49d46124b316904 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.0" +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/9645a1f47b3750acadb1353c02e71cc712d072aafe5ce115ed3a886bc14c5d9200cfb0b5b5e60e813baa549b800cf798f8714019fd246c699053cf68c428e426 + checksum: 10c0/ac284868bf410f952c6959b0d77708464127160416f003b05c8127d30e64792d671abc167ebf778b17707e32174223ea8d3ff487276991fa90297d92f0dac6e2 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.0" +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/ed1ce1c90cac46c01825339fd0f2a96fa071b016fb819d8dfaf8e96300eae30e74870cb47e4dc80d4ce2fb287869f102878b4f3b35bc927fec8b1d0d76bcf612 + checksum: 10c0/1bffc0a20c8c82b4c77515eb4c99b961b38184116f008bb42bed4e12d3379ba7b2bc6cf299bcea8118d645bb7a5e0caa83969842f16dd1fce49fb3a050e4ac65 languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.24.7" +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" - "@babel/plugin-transform-optional-chaining": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" + "@babel/plugin-transform-optional-chaining": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.13.0 - checksum: 10c0/aeb6e7aa363a47f815cf956ea1053c5dd8b786a17799f065c9688ba4b0051fe7565d258bbe9400bfcbfb3114cb9fda66983e10afe4d750bc70ff75403e15dd36 + checksum: 10c0/32223f012614a0b2657579317ded7d0d09af2aa316285715c5012f974d0f15c2ce2fe0d8e80fdd9bac6c10c21c93cc925a9dfd6c8e21ce7ba1a9fe06a58088b4 languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.0" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/45988025537a9d4a27b610fd696a18fd9ba9336621a69b4fb40560eeb10c79657f85c92a37f30c7c8fb29c22970eea0b373315795a891f1a05549a6cfe5a6bfe + checksum: 10c0/aa2ee7a5954d187de6cbcca0e0b64cfb79c4d224c332d1eb1e0e4afd92ef1a1f4bc4af24f66154097ccb348c08121a875456f47baed220b1b9e93584e6a19b65 languageName: node linkType: hard @@ -574,39 +574,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-async-generators@npm:^7.8.4": - version: 7.8.4 - resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/d13efb282838481348c71073b6be6245b35d4f2f964a8f71e4174f235009f929ef7613df25f8d2338e2d3e44bc4265a9f8638c6aaa136d7a61fe95985f9725c8 - languageName: node - linkType: hard - -"@babel/plugin-syntax-class-properties@npm:^7.12.13": - version: 7.12.13 - resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.12.13" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/95168fa186416195280b1264fb18afcdcdcea780b3515537b766cb90de6ce042d42dd6a204a39002f794ae5845b02afb0fd4861a3308a861204a55e68310a120 - languageName: node - linkType: hard - -"@babel/plugin-syntax-class-static-block@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/4464bf9115f4a2d02ce1454411baf9cfb665af1da53709c5c56953e5e2913745b0fcce82982a00463d6facbdd93445c691024e310b91431a1e2f024b158f6371 - languageName: node - linkType: hard - "@babel/plugin-syntax-dynamic-import@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3" @@ -618,168 +585,47 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/5100d658ba563829700cd8d001ddc09f4c0187b1a13de300d729c5b3e87503f75a6d6c99c1794182f7f1a9f546ee009df4f15a0ce36376e206ed0012fa7cdc24 - languageName: node - linkType: hard - -"@babel/plugin-syntax-import-assertions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.24.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/b82c53e095274ee71c248551352d73441cf65b3b3fc0107258ba4e9aef7090772a425442b3ed1c396fa207d0efafde8929c87a17d3c885b3ca2021316e87e246 - languageName: node - linkType: hard - -"@babel/plugin-syntax-import-attributes@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.24.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/eccc54d0f03c96d0eec7a6e2fa124dadbc7298345b62ffc4238f173308c4325b5598f139695ff05a95cf78412ef6903599e4b814496612bf39aad4715a16375b - languageName: node - linkType: hard - -"@babel/plugin-syntax-import-meta@npm:^7.10.4": - version: 7.10.4 - resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/0b08b5e4c3128523d8e346f8cfc86824f0da2697b1be12d71af50a31aff7a56ceb873ed28779121051475010c28d6146a6bfea8518b150b71eeb4e46190172ee - languageName: node - linkType: hard - -"@babel/plugin-syntax-json-strings@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/e98f31b2ec406c57757d115aac81d0336e8434101c224edd9a5c93cefa53faf63eacc69f3138960c8b25401315af03df37f68d316c151c4b933136716ed6906e - languageName: node - linkType: hard - -"@babel/plugin-syntax-jsx@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-syntax-jsx@npm:7.24.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/f44d927a9ae8d5ef016ff5b450e1671e56629ddc12e56b938e41fd46e141170d9dfc9a53d6cb2b9a20a7dd266a938885e6a3981c60c052a2e1daed602ac80e51 - languageName: node - linkType: hard - -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": - version: 7.10.4 - resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/2594cfbe29411ad5bc2ad4058de7b2f6a8c5b86eda525a993959438615479e59c012c14aec979e538d60a584a1a799b60d1b8942c3b18468cb9d99b8fd34cd0b - languageName: node - linkType: hard - -"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/2024fbb1162899094cfc81152449b12bd0cc7053c6d4bda8ac2852545c87d0a851b1b72ed9560673cbf3ef6248257262c3c04aabf73117215c1b9cc7dd2542ce - languageName: node - linkType: hard - -"@babel/plugin-syntax-numeric-separator@npm:^7.10.4": - version: 7.10.4 - resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/c55a82b3113480942c6aa2fcbe976ff9caa74b7b1109ff4369641dfbc88d1da348aceb3c31b6ed311c84d1e7c479440b961906c735d0ab494f688bf2fd5b9bb9 - languageName: node - linkType: hard - -"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/ee1eab52ea6437e3101a0a7018b0da698545230015fc8ab129d292980ec6dff94d265e9e90070e8ae5fed42f08f1622c14c94552c77bcac784b37f503a82ff26 - languageName: node - linkType: hard - -"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/27e2493ab67a8ea6d693af1287f7e9acec206d1213ff107a928e85e173741e1d594196f99fec50e9dde404b09164f39dec5864c767212154ffe1caa6af0bc5af - languageName: node - linkType: hard - -"@babel/plugin-syntax-optional-chaining@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3" +"@babel/plugin-syntax-import-assertions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/46edddf2faa6ebf94147b8e8540dfc60a5ab718e2de4d01b2c0bdf250a4d642c2bd47cbcbb739febcb2bf75514dbcefad3c52208787994b8d0f8822490f55e81 + checksum: 10c0/0fee0d971f3c654749fdf92e09b6556bba26ab014c8e99b7252f6a7f1ca108f17edd7ceefb5401d7b7008e98ab1b6f8c3c6a5db72862e7c7b2fcd649d000d690 languageName: node linkType: hard -"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5" +"@babel/plugin-syntax-import-attributes@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/69822772561706c87f0a65bc92d0772cea74d6bc0911537904a676d5ff496a6d3ac4e05a166d8125fce4a16605bace141afc3611074e170a994e66e5397787f3 + checksum: 10c0/fe00cdb96fd289ab126830a98e1dcf5ab7b529a6ef1c01a72506b5e7b1197d6e46c3c4d029cd90d1d61eb9a15ef77c282d156d0c02c7e32f168bb09d84150db4 languageName: node linkType: hard -"@babel/plugin-syntax-top-level-await@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" +"@babel/plugin-syntax-jsx@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-syntax-jsx@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/14bf6e65d5bc1231ffa9def5f0ef30b19b51c218fcecaa78cd1bdf7939dfdf23f90336080b7f5196916368e399934ce5d581492d8292b46a2fb569d8b2da106f + checksum: 10c0/17db499c31fcfaa94d5408726d943955d51d478353d1e2dd84eda6024f7e3d104b9456a77f8aabfae0db7f4dc32f810d08357112f7fcbe305e7c9fcf5b3cac13 languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-syntax-typescript@npm:7.24.7" +"@babel/plugin-syntax-typescript@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-syntax-typescript@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/cdabd2e8010fb0ad15b49c2c270efc97c4bfe109ead36c7bbcf22da7a74bc3e49702fc4f22f12d2d6049e8e22a5769258df1fd05f0420ae45e11bdd5bc07805a + checksum: 10c0/ed51fd81a5cf571a89fc4cf4c0e3b0b91285c367237374c133d2e5e718f3963cfa61b81997df39220a8837dc99f9e9a8ab7701d259c09fae379e4843d9db60c2 languageName: node linkType: hard @@ -795,776 +641,749 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.7" +"@babel/plugin-transform-arrow-functions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6ac05a54e5582f34ac6d5dc26499e227227ec1c7fa6fc8de1f3d40c275f140d3907f79bbbd49304da2d7008a5ecafb219d0b71d78ee3290ca22020d878041245 + checksum: 10c0/c8d75ead93f130bf113b6d29493aca695092661ef039336d2a227169c3b7895aa5e9bcc548c42a95a6eaaaf49e512317b00699940bd40ccefd77443e703d3935 languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.0" +"@babel/plugin-transform-async-generator-functions@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-remap-async-to-generator": "npm:^7.25.0" - "@babel/plugin-syntax-async-generators": "npm:^7.8.4" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-remap-async-to-generator": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5348c3a33d16e0d62f13482c6fa432185ba096d58880b08d42450f7db662d6b03e6149d495c8620897dcd3da35061068cbd6c09da7d0ec95743e55a788809e4e + checksum: 10c0/1698d0757d3dc895047120346cdbe6d539dae4a7bb930caf958c3623e89c850d378d1ebd971a1a8b4cba39c8f001cd9c25a1d6f430099022ab1e87aeddb5dd88 languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.7" +"@babel/plugin-transform-async-to-generator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.25.7" dependencies: - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-remap-async-to-generator": "npm:^7.24.7" + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-remap-async-to-generator": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/83c82e243898875af8457972a26ab29baf8a2078768ee9f35141eb3edff0f84b165582a2ff73e90a9e08f5922bf813dbf15a85c1213654385198f4591c0dc45d + checksum: 10c0/1dbefba9c1455f7a92b8c59a93c622091db945294c936fc2c09b1648308c5b4cb2ecaae92baae0d07a324ab890a8a2ee27ceb046bc120932845d27aede275821 languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.7" +"@babel/plugin-transform-block-scoped-functions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/113e86de4612ae91773ff5cb6b980f01e1da7e26ae6f6012127415d7ae144e74987bc23feb97f63ba4bc699331490ddea36eac004d76a20d5369e4cc6a7f61cd + checksum: 10c0/b1e77492295d1b271ef850a81b0404cf3d0dd6a2bcbeab28a0fd99e61c6de4bda91dff583bb42138eec61bf71282bdd3b1bebcb53b7e373035e77fd6ba66caeb languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-transform-block-scoping@npm:7.25.0" +"@babel/plugin-transform-block-scoping@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-block-scoping@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/382931c75a5d0ea560387e76cb57b03461300527e4784efcb2fb62f36c1eb0ab331327b6034def256baa0cad9050925a61f9c0d56261b6afd6a29c3065fb0bd4 + checksum: 10c0/b2057e00535cd0e8bd5ee5d4640aa2e952564aeafb1bcf4e7b6de33442422877bb0ca8669ad0a48262ec077271978c61eae87b6b3bc8f472d830fa781d6f7e44 languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-class-properties@npm:7.24.7" +"@babel/plugin-transform-class-properties@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-class-properties@npm:7.25.7" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/75018a466c7ede3d2397e158891c224ba7fca72864506ce067ddbc02fc65191d44da4d6379c996d0c7f09019e26b5c3f5f1d3a639cd98366519723886f0689d0 + checksum: 10c0/1f41e6934b20ad3e05df63959cff9bc600ff3119153b9acbbd44c1731e7df04866397e6e17799173f4c53cdee6115e155632859aee20bf47ec7dcef3f2168a47 languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-class-static-block@npm:7.24.7" +"@babel/plugin-transform-class-static-block@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-class-static-block@npm:7.25.8" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.12.0 - checksum: 10c0/b0ade39a3d09dce886f79dbd5907c3d99b48167eddb6b9bbde24a0598129654d7017e611c20494cdbea48b07ac14397cd97ea34e3754bbb2abae4e698128eccb + checksum: 10c0/4f37853aef6920875022bbb2d7c6523218d9d718291464e2cacd9cc6f2c22d86a69948d8ea38f9248843bbfe9343f3fd18cf16b1615560124198bf999e3ba612 languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-transform-classes@npm:7.25.0" +"@babel/plugin-transform-classes@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-classes@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-compilation-targets": "npm:^7.24.8" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-replace-supers": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-replace-supers": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" globals: "npm:^11.1.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/4451dccf8a7979427ae042afe381233f30764a8072faf0de1337a4fc297c6d7cb40df9e28931ac096e5b56392d0cd97d3ce10aee68288150a8701624d362a791 + checksum: 10c0/8121781e1d8acd80e6169019106f73a399475ad9c895c1988a344dfed5a6ddd340938ac55123dc1e423bb8f25f255f5d11031116ad756ba3c314595a97c973af languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-computed-properties@npm:7.24.7" +"@babel/plugin-transform-computed-properties@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-computed-properties@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/template": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/template": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/25636dbc1f605c0b8bc60aa58628a916b689473d11551c9864a855142e36742fe62d4a70400ba3b74902338e77fb3d940376c0a0ba154b6b7ec5367175233b49 + checksum: 10c0/7ad0a1c126f50935a02e77d438ebc39078a9d644b3a60de60bec32c5d9f49e7f2b193fcecb8c61bb1bc3cdd4af1e93f72d022d448511fa76a171527c633cd1bf languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-destructuring@npm:7.24.8" +"@babel/plugin-transform-destructuring@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-destructuring@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/804968c1d5f5072c717505296c1e5d5ec33e90550423de66de82bbcb78157156e8470bbe77a04ab8c710a88a06360a30103cf223ac7eff4829adedd6150de5ce + checksum: 10c0/a563123b2fb267e03aa50104005f00b56226a685938906c42c1b251462e0cc9fc89e587d5656d3324159071eb8ebda8c68a6011f11d5a00fb1436cb5a5411b7b languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.24.7" +"@babel/plugin-transform-dotall-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/793f14c9494972d294b7e7b97b747f47874b6d57d7804d3443c701becf5db192c9311be6a1835c07664486df1f5c60d33196c36fb7e11a53015e476b4c145b33 + checksum: 10c0/7f1db3ec20b7fae46db4a9c4c257d75418b0896b72c0a3de20b3044f952801480f0a2e75ebb0d64f13e8cd4db0e49aa42c5c0edff372b23c41679b1ea5dd3ed4 languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.24.7" +"@babel/plugin-transform-duplicate-keys@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/75ff7ec1117ac500e77bf20a144411d39c0fdd038f108eec061724123ce6d1bb8d5bd27968e466573ee70014f8be0043361cdb0ef388f8a182d1d97ad67e51b9 + checksum: 10c0/b4079981e2db19737a0f1a00254e7388e2d3c01ce36e9fd826e4d86d3c1755339495e29c71fd7c84a068201ec24687328d48f3bf53b32b6d6224f51d9a34da74 languageName: node linkType: hard -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.0" +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.0" - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/1c9b57ddd9b33696e88911d0e7975e1573ebc46219c4b30eb1dc746cbb71aedfac6f6dab7fdfdec54dd58f31468bf6ab56b157661ea4ffe58f906d71f89544c8 + checksum: 10c0/e4946090ff6d88d54b78265ee653079ec34c117ac046e22f66f7c4ac44249cdc2dfca385bc5bf4386db668b9948eeb12985589500188bc252e684c7714c31475 languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.7" +"@babel/plugin-transform-dynamic-import@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/eeda48372efd0a5103cb22dadb13563c975bce18ae85daafbb47d57bb9665d187da9d4fe8d07ac0a6e1288afcfcb73e4e5618bf75ff63fddf9736bfbf225203b + checksum: 10c0/9726abc1b07771a9c1e3670908ac425d21e29f54c775d10ed7a4e2bc0a18e07600f70bbc531deba3fb3ff7f6763c189200593264c6f784dac583e653b66fe754 languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.24.7" +"@babel/plugin-transform-exponentiation-operator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.25.7" dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-builder-binary-assignment-operator-visitor": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/ace3e11c94041b88848552ba8feb39ae4d6cad3696d439ff51445bd2882d8b8775d85a26c2c0edb9b5e38c9e6013cc11b0dea89ec8f93c7d9d7ee95e3645078c + checksum: 10c0/c8537b9f3cddc5a8d3710f6980196dc7a0f4389f8f82617312a5f7b8b15bcd8ddaeba783c687c3ac6031eb0a4ba0bc380a98da6bf7efe98e225602a98ad42a1e languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.7" +"@babel/plugin-transform-export-namespace-from@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/4e144d7f1c57bc63b4899dbbbdfed0880f2daa75ea9c7251c7997f106e4b390dc362175ab7830f11358cb21f6b972ca10a43a2e56cd789065f7606b082674c0c + checksum: 10c0/8a2e1205dd727a96a9adef0e981d68c61b1c286480b9136e2aa67ce3e2c742be4f87feb9fb4c5548a401aba0953d43d66e9ec36a54dea6a7c15f1ee9345baf57 languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-for-of@npm:7.24.7" +"@babel/plugin-transform-for-of@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-for-of@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/77629b1173e55d07416f05ba7353caa09d2c2149da2ca26721ab812209b63689d1be45116b68eadc011c49ced59daf5320835b15245eb7ae93ae0c5e8277cfc0 + checksum: 10c0/08a37a1742368a422d095c998ed76f60f6bf3f9cc060033be121d803fd2dddc08fe543e48ee49c022bdc9ed80893ca79d084958d83d30684178b088774754277 languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.25.1": - version: 7.25.1 - resolution: "@babel/plugin-transform-function-name@npm:7.25.1" +"@babel/plugin-transform-function-name@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-function-name@npm:7.25.7" dependencies: - "@babel/helper-compilation-targets": "npm:^7.24.8" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/traverse": "npm:^7.25.1" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e74912174d5e33d1418b840443c2e226a7b76cc017c1ed20ee30a566e4f1794d4a123be03180da046241576e8b692731807ba1f52608922acf1cb2cb6957593f + checksum: 10c0/ca98e1116c0ada7211ed43e4b7f21ca15f95bbbdad70f2fbe1ec2d90a97daedf9f22fcb0a25c8b164a5e394f509f2e4d1f7609d26dc938a58d37c5ee9b80088a languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-json-strings@npm:7.24.7" +"@babel/plugin-transform-json-strings@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-json-strings@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-json-strings": "npm:^7.8.3" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/17c72cd5bf3e90e722aabd333559275f3309e3fa0b9cea8c2944ab83ae01502c71a2be05da5101edc02b3fc8df15a8dbb9b861cbfcc8a52bf5e797cf01d3a40a + checksum: 10c0/2a6cf69ebe8deebc39c56adae75d609e16786dc4cbd83577eefdc838bd89ca8974671d47e2669b8e65ef9b7ace427f7c2c5a9fc6aa09247b10e141d15fee81cf languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.25.2": - version: 7.25.2 - resolution: "@babel/plugin-transform-literals@npm:7.25.2" +"@babel/plugin-transform-literals@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-literals@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/0796883217b0885d37e7f6d350773be349e469a812b6bf11ccf862a6edf65103d3e7c849529d65381b441685c12e756751d8c2489a0fd3f8139bb5ef93185f58 + checksum: 10c0/c2c2488102f33e566f45becdcb632e53bd052ecfb2879deb07a614b3e9437e3b624c3b16d080096d50b0b622edebd03e438acbf9260bcc41167897963f64560e languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.24.7" +"@babel/plugin-transform-logical-assignment-operators@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/dbe882eb9053931f2ab332c50fc7c2a10ef507d6421bd9831adbb4cb7c9f8e1e5fbac4fbd2e007f6a1bf1df1843547559434012f118084dc0bf42cda3b106272 + checksum: 10c0/9adc2634c94b283b682fbf71bbec553bd8448196213491a0ef9ea167993c9c36dcb2fbefbd834e113cfed843a67290131bc99e463f8702043c3f4e3a99bb807e languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.7" +"@babel/plugin-transform-member-expression-literals@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e789ae359bdf2d20e90bedef18dfdbd965c9ebae1cee398474a0c349590fda7c8b874e1a2ceee62e47e5e6ec1730e76b0f24e502164357571854271fc12cc684 + checksum: 10c0/d6936b98ae4d3daed850dc4e064042ea4375f815219ba9d8591373bf1fba4cfdb5be42623ae8882f2d666cc34af650a4855e2a5ad89e3c235d73a6f172f9969c languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-modules-amd@npm:7.24.7" +"@babel/plugin-transform-modules-amd@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-modules-amd@npm:7.25.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6df7de7fce34117ca4b2fa07949b12274c03668cbfe21481c4037b6300796d50ae40f4f170527b61b70a67f26db906747797e30dbd0d9809a441b6e220b5728f + checksum: 10c0/c0bc999206c3834c090e6559a6c8a55d7672d3573104e832223ebe7df99bd1b82fc850e15ba32f512c84b0db1cdb613b66fa60abe9abb9c7e8dcbff91649b356 languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.24.7, @babel/plugin-transform-modules-commonjs@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" +"@babel/plugin-transform-modules-commonjs@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.25.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.24.8" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-simple-access": "npm:^7.24.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-simple-access": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/f1cf552307ebfced20d3907c1dd8be941b277f0364aa655e2b5fee828c84c54065745183104dae86f1f93ea0406db970a463ef7ceaaed897623748e99640e5a7 + checksum: 10c0/2f1c945fc3c9b690b0ddcf2c80156b2e4fbf2cf15aac43ac8fe6e4b34125869528839a53d07c564e62e4aed394ebdc1d2c3b796b547374455522581c11b7599c languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.0" +"@babel/plugin-transform-modules-systemjs@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.25.0" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-validator-identifier": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/fca6198da71237e4bb1274b3b67a0c81d56013c9535361242b6bfa87d70a9597854aadb45d4d8203369be4a655e158be2a5d20af0040b1f8d1bfc47db3ad7b68 + checksum: 10c0/95eaea7082636710c61e49e58b3907e85ec79db4327411d3784f28592509fbe94a53cc3d20a36a1cf245efc6d3f0017eae15b45ffd645c1ab949bb4e1670e6bb languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-modules-umd@npm:7.24.7" +"@babel/plugin-transform-modules-umd@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-modules-umd@npm:7.25.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7791d290121db210e4338b94b4a069a1a79e4c7a8d7638d8159a97b281851bbed3048dac87a4ae718ad963005e6c14a5d28e6db2eeb2b04e031cee92fb312f85 + checksum: 10c0/8849ab04eecdb73cd37e2d7289449fa5256331832b0304c220b2a6aaa12e2d2dd87684f2813412d1fc5bdb3d6b55cc08c6386d3273fe05a65177c09bee5b6769 languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.24.7" +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/41a0b0f2d0886318237440aa3b489f6d0305361d8671121777d9ff89f9f6de9d0c02ce93625049061426c8994064ef64deae8b819d1b14c00374a6a2336fb5d9 + checksum: 10c0/eb55fec55dc930cd122911f3e4a421320fa8b1b4de85bfd7ef11b46c611ec69b0213c114a6e1c6bc224d6b954ff183a0caa7251267d5258ecc0f00d6d9ca1d52 languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-new-target@npm:7.24.7" +"@babel/plugin-transform-new-target@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-new-target@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/2540808a35e1a978e537334c43dab439cf24c93e7beb213a2e71902f6710e60e0184316643790c0a6644e7a8021e52f7ab8165e6b3e2d6651be07bdf517b67df + checksum: 10c0/8e5dce6d027e0f3fd394578ea1af7f515de157793a15c23a5aad7034a6d8a4005ef280238e67a232bb4dd4fafd3a264fed462deb149128ddd9ce59ff6f575cff languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.7" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7243c8ff734ed5ef759dd8768773c4b443c12e792727e759a1aec2c7fa2bfdd24f1ecb42e292a7b3d8bd3d7f7b861cf256a8eb4ba144fc9cc463892c303083d9 + checksum: 10c0/3cb7c44cffccae42e104755acb31b4f00bc27d8c88102ae6f30dca508832f98fa5b746bead0fc7c0c6ddcf83f336829be4b64245c6c7ce26b3ef591937ec54a4 languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.24.7" +"@babel/plugin-transform-numeric-separator@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e18e09ca5a6342645d00ede477731aa6e8714ff357efc9d7cda5934f1703b3b6fb7d3298dce3ce3ba53e9ff1158eab8f1aadc68874cc21a6099d33a1ca457789 + checksum: 10c0/d23b3ebc50513f24510791ac2cad43e3c6ea08579f54dccfd4ed5e5d5084f02da0576ea42ea999fb51e1f94f42857cac96a1a29ac6728fc262fbe87ec966dc18 languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.7" +"@babel/plugin-transform-object-rest-spread@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.25.8" dependencies: - "@babel/helper-compilation-targets": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" - "@babel/plugin-transform-parameters": "npm:^7.24.7" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/plugin-transform-parameters": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/9ad64bc003f583030f9da50614b485852f8edac93f8faf5d1cd855201a4852f37c5255ae4daf70dd4375bdd4874e16e39b91f680d4668ec219ba05441ce286eb + checksum: 10c0/058d5f5bb61068997fb78855011dd175d441da84717640852bbfd12a5919acf8d8c5a14c1debfe87d230f3f4c47c22fcad3d7fa1acd72e5e48b2fff93b6c1dd9 languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-object-super@npm:7.24.7" +"@babel/plugin-transform-object-super@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-object-super@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-replace-supers": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-replace-supers": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/770cebb4b4e1872c216b17069db9a13b87dfee747d359dc56d9fcdd66e7544f92dc6ab1861a4e7e0528196aaff2444e4f17dc84efd8eaf162d542b4ba0943869 + checksum: 10c0/7f2968d4da997101b63fd3b74445c9b16f56bd32cd8a0a16c368af9d3e983e7675c1b05d18601f32307cb06e7d884ee11d13ff18a1f6830c0db243a9a852afab languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.7" +"@babel/plugin-transform-optional-catch-binding@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/1e2f10a018f7d03b3bde6c0b70d063df8d5dd5209861d4467726cf834f5e3d354e2276079dc226aa8e6ece35f5c9b264d64b8229a8bb232829c01e561bcfb07a + checksum: 10c0/f4360e62ca4aa998db31548d0ef06836d958bcb29dee58f5c62d0c29b6b2bff1b54871195bd032825fe3dd79a4fd8275e165148c8d4b57694bcf72135c8f7d24 languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.24.7, @babel/plugin-transform-optional-chaining@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.8" +"@babel/plugin-transform-optional-chaining@npm:^7.25.7, @babel/plugin-transform-optional-chaining@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.25.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" - "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/4ffbe1aad7dec7c9aa2bf6ceb4b2f91f96815b2784f2879bde80e46934f59d64a12cb2c6262e40897c4754d77d2c35d8a5cfed63044fdebf94978b1ed3d14b17 + checksum: 10c0/a1cdbfc249619fa6b37e57f81600701281629d86a57e616b0c2b29816d0c43114a2296ce089564afd3aa7870c8aad62e907658ffef2c110662af14ee23d5247f languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-parameters@npm:7.24.7" +"@babel/plugin-transform-parameters@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-parameters@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/53bf190d6926771545d5184f1f5f3f5144d0f04f170799ad46a43f683a01fab8d5fe4d2196cf246774530990c31fe1f2b9f0def39f0a5ddbb2340b924f5edf01 + checksum: 10c0/b40ba70278842ce1e800d7ab400df730994941550da547ef453780023bd61a9b8acf4b9fb8419c1b5bcbe09819a1146ff59369db11db07eb71870bef86a12422 languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-private-methods@npm:7.24.7" +"@babel/plugin-transform-private-methods@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-private-methods@npm:7.25.7" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5b7bf923b738fbe3ad6c33b260e0a7451be288edfe4ef516303fa787a1870cd87533bfbf61abb779c22ed003c2fc484dec2436fe75a48756f686c0241173d364 + checksum: 10c0/92e076f63f7c4696e1321dafdd56c4212eb41784cdadba0ebc39091f959a76d357c3df61a6c668be81d6b6ad8964ee458e85752ab0c6cfbbaf2066903edda732 languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.24.7" +"@babel/plugin-transform-private-property-in-object@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.25.8" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-create-class-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c6fa7defb90b1b0ed46f24ff94ff2e77f44c1f478d1090e81712f33cf992dda5ba347016f030082a2f770138bac6f4a9c2c1565e9f767a125901c77dd9c239ba + checksum: 10c0/61b5e3a4eb94caf38d6e9ff7bff1ac8927758141aaa4891036d3490866ecee53beaefd7893519fec42a4c55f33374a17fc0e49694cdaf95668082073f0fe4a79 languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-property-literals@npm:7.24.7" +"@babel/plugin-transform-property-literals@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-property-literals@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/52564b58f3d111dc02d241d5892a4b01512e98dfdf6ef11b0ed62f8b11b0acacccef0fc229b44114fe8d1a57a8b70780b11bdd18b807d3754a781a07d8f57433 + checksum: 10c0/6d5bccdc772207906666ad5201bd91e4e132e1d806dbcf4163a1d08e18c57cc3795578c4e10596514bcd6afaf9696f478ea4f0dea890176d93b9cb077b9e5c55 languageName: node linkType: hard "@babel/plugin-transform-react-constant-elements@npm:^7.21.3": - version: 7.25.1 - resolution: "@babel/plugin-transform-react-constant-elements@npm:7.25.1" + version: 7.25.7 + resolution: "@babel/plugin-transform-react-constant-elements@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/8e9a61e8d74804ad3e4c8051463b2d8c42be5aa1f381f7b0db3ac8696a5cb5faead54036b1e4bcd53f6ab74c0bb3e45e4d9a1a2f50b9a575a8d7965b77d89c28 + checksum: 10c0/2261a793e65b4236ac256096ee8ad40e1149b4202d3d5d4464ca92e87980bc1886ccb2fe1282e668c82fd49db2afadfcea6e943a75fbe56ceb58c33245bac0dc languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-display-name@npm:7.24.7" +"@babel/plugin-transform-react-display-name@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-display-name@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c14a07a9e75723c96f1a0a306b8a8e899ff1c6a0cc3d62bcda79bb1b54e4319127b258651c513a1a47da152cdc22e16525525a30ae5933a2980c7036fd0b4d24 + checksum: 10c0/a0c537cc7c328ed7468d3b6a37bf0d9cb15d94afcdf3f2849ce6e5a68494fc61f0fa4fc529482a6b95b00f3c5c734f310bf18085293bff40702789f06c816f36 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-development@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.24.7" +"@babel/plugin-transform-react-jsx-development@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.25.7" dependencies: - "@babel/plugin-transform-react-jsx": "npm:^7.24.7" + "@babel/plugin-transform-react-jsx": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/fce647db50f90a5291681f0f97865d9dc76981262dff71d6d0332e724b85343de5860c26f9e9a79e448d61e1d70916b07ce91e8c7f2b80dceb4b16aee41794d8 + checksum: 10c0/a3dc14644d09a6d22875af7b5584393ab53e467e0531cd192fc6242504dacaffa421e89265ba7f84fd4edef2b7b100d2e2ebf092a4dce2b55cf9c5fe29390c18 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.24.7": - version: 7.25.2 - resolution: "@babel/plugin-transform-react-jsx@npm:7.25.2" +"@babel/plugin-transform-react-jsx@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-jsx@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/plugin-syntax-jsx": "npm:^7.24.7" - "@babel/types": "npm:^7.25.2" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/plugin-syntax-jsx": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/8c5b515f38118471197605e02bea54a8a4283010e3c55bad8cfb78de59ad63612b14d40baca63689afdc9d57b147aac4c7794fe5f7736c9e1ed6dd38784be624 + checksum: 10c0/6766b0357b8bbfcb77fca5350f06cf822c89bbe75ddcaea24614601ef23957504da24e76597d743038ce8fa081373b0663c8ad0c86d7c7226e8185f0680b8b56 languageName: node linkType: hard -"@babel/plugin-transform-react-pure-annotations@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.24.7" +"@babel/plugin-transform-react-pure-annotations@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/fae517d293d9c93b7b920458c3e4b91cb0400513889af41ba184a5f3acc8bfef27242cc262741bb8f87870df376f1733a0d0f52b966d342e2aaaf5607af8f73d + checksum: 10c0/d92c9b511850fb6dea71966a0d4f313d67e317db7fc3633a7ff2e27d6df2e95cbc91c4c25abdb6c8db651fcda842a0cb7433835a8a9d4a3fdc5d452068428101 languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-regenerator@npm:7.24.7" +"@babel/plugin-transform-regenerator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-regenerator@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" regenerator-transform: "npm:^0.15.2" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d2dc2c788fdae9d97217e70d46ba8ca9db0035c398dc3e161552b0c437113719a75c04f201f9c91ddc8d28a1da60d0b0853f616dead98a396abb9c845c44892b + checksum: 10c0/7ee3a57c4050bc908ef7ac392d810826b294970a7182f4ec34a8ca93dbe36deb21bc862616d46a6f3d881d6b5749930e1679e875b638a00866d844a4250df212 languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-reserved-words@npm:7.24.7" +"@babel/plugin-transform-reserved-words@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-reserved-words@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/2229de2768615e7f5dc0bbc55bc121b5678fd6d2febd46c74a58e42bb894d74cd5955c805880f4e02d0e1cf94f6886270eda7fafc1be9305a1ec3b9fd1d063f5 + checksum: 10c0/920c98130daff6c1288fb13a9a2d2e45863bba93e619cb88d90e1f5b5cb358a3ee8880a425a3adb1b4bd5dbb6bd0500eea3370fc612633045eec851b08cc586c languageName: node linkType: hard "@babel/plugin-transform-runtime@npm:^7.22.9": - version: 7.24.7 - resolution: "@babel/plugin-transform-runtime@npm:7.24.7" + version: 7.25.7 + resolution: "@babel/plugin-transform-runtime@npm:7.25.7" dependencies: - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" babel-plugin-polyfill-corejs2: "npm:^0.4.10" - babel-plugin-polyfill-corejs3: "npm:^0.10.1" + babel-plugin-polyfill-corejs3: "npm:^0.10.6" babel-plugin-polyfill-regenerator: "npm:^0.6.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/a33f5095872bbba00b8ee553dfe6941477e69a017a2e65e9dd86e80dab5c627635093b796eb1eb22aaaf2f874704f63ad1d99b952b83b59ef6b368ae04e5bb41 + checksum: 10c0/9b2514e9079361ac8e7e500ffd522dad869d61a3894302da7e29bbac80de00276c8a1b4394d1dcf0b51c57b2c854919928df9648be336139fdf1d6ecd6d1bb32 languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.7" +"@babel/plugin-transform-shorthand-properties@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/41b155bdbb3be66618358488bf7731b3b2e8fff2de3dbfd541847720a9debfcec14db06a117abedd03c9cd786db20a79e2a86509a4f19513f6e1b610520905cf + checksum: 10c0/4250f89a0072f0f400be7a2e3515227b8e2518737899bd57d497e5173284a0e05d812e4a3c219ffcd484e9fa9a01c19fce5acd77bbb898f4d594512c56701eb4 languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-spread@npm:7.24.7" +"@babel/plugin-transform-spread@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-spread@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/facba1553035f76b0d2930d4ada89a8cd0f45b79579afd35baefbfaf12e3b86096995f4b0c402cf9ee23b3f2ea0a4460c3b1ec0c192d340962c948bb223d4e66 + checksum: 10c0/258bd1b52388cd7425d0ae25fa39538734f7540ea503a1d8a72211d33f6f214cb4e3b73d6cd03016cbcff5d41169f1e578b9ea331965ad224d223591983e90a7 languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.24.7" +"@babel/plugin-transform-sticky-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5a74ed2ed0a3ab51c3d15fcaf09d9e2fe915823535c7a4d7b019813177d559b69677090e189ec3d5d08b619483eb5ad371fbcfbbff5ace2a76ba33ee566a1109 + checksum: 10c0/0e466cfc3ca1e0db4bb11eb630215b0e1f43066d7678325e5ddadcf5a118b2351a528f67205729c32ac5b78ab68ab7f40517dd33bcb1fb6b456509f5f54ce097 languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-template-literals@npm:7.24.7" +"@babel/plugin-transform-template-literals@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-template-literals@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/3630f966257bcace122f04d3157416a09d40768c44c3a800855da81146b009187daa21859d1c3b7d13f4e19e8888e60613964b175b2275d451200fb6d8d6cfe6 + checksum: 10c0/a3455303b6841cb536ac66d1a2d03c194b9f371519482d8d1e8edbd33bf5ca7cdd5db1586b2b0ea5f909ebf74a0eafacf0fb28d257e4905445282dcdccfa6139 languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.8" +"@babel/plugin-transform-typeof-symbol@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/2f570a4fbbdc5fd85f48165a97452826560051e3b8efb48c3bb0a0a33ee8485633439e7b71bfe3ef705583a1df43f854f49125bd759abdedc195b2cf7e60012a + checksum: 10c0/ce1a0744a900b05de1372a70508c4148f17eb941c482da26eb369b9f0347570dce45470c8a86d907bc3a0443190344da1e18489ecfecb30388ab6178e8a9916b languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.24.7": - version: 7.25.2 - resolution: "@babel/plugin-transform-typescript@npm:7.25.2" +"@babel/plugin-transform-typescript@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-typescript@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-create-class-features-plugin": "npm:^7.25.0" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" - "@babel/plugin-syntax-typescript": "npm:^7.24.7" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" + "@babel/plugin-syntax-typescript": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/b3c941da39ee7ecf72df1b78a01d4108160438245f2ab61befe182f51d17fd0034733c6d079b7efad81e03a66438aa3881a671cd68c5eb0fc775df86b88df996 + checksum: 10c0/5fa839b9560221698edff5e00b5cccc658c7875efaa7971c66d478f5b026770f12dd47b1be024463a44f9e29b4e14e8ddddbf4a2b324b0b94f58370dd5ae7195 languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.24.7" +"@babel/plugin-transform-unicode-escapes@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/8b18e2e66af33471a6971289492beff5c240e56727331db1d34c4338a6a368a82a7ed6d57ec911001b6d65643aed76531e1e7cac93265fb3fb2717f54d845e69 + checksum: 10c0/8b1f71fda0a832c6e26ba4c00f99e9033e6f9b36ced542a512921f4ad861a70e2fec2bd54a91a5ca2efa46aaa8c8893e4c602635c4ef172bd3ed6eef3178c70b languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.24.7" +"@babel/plugin-transform-unicode-property-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/bc57656eb94584d1b74a385d378818ac2b3fca642e3f649fead8da5fb3f9de22f8461185936915dfb33d5a9104e62e7a47828331248b09d28bb2d59e9276de3e + checksum: 10c0/b4bfcf7529138d00671bf5cdfe606603d52cfe57ec1be837da57683f404fc0b0c171834a02515eb03379e5c806121866d097b90e31cb437d21d0ea59368ad82b languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.24.7" +"@babel/plugin-transform-unicode-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/83f72a345b751566b601dc4d07e9f2c8f1bc0e0c6f7abb56ceb3095b3c9d304de73f85f2f477a09f8cc7edd5e65afd0ff9e376cdbcbea33bc0c28f3705b38fd9 + checksum: 10c0/73ae34c02ea8b7ac7e4efa690f8c226089c074e3fef658d2a630ad898a93550d84146ce05e073c271c8b2bbba61cbbfd5a2002a7ea940dcad3274e5b5dcb6bcf languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.24.7" +"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/7457c0ee8e80a80cb6fdc1fe54ab115b52815627616ce9151be8ef292fc99d04a910ec24f11382b4f124b89374264396892b086886bd2a9c2317904d87c9b21b + checksum: 10c0/39e45ae3db7adfc3457b1d6ba5608ffbace957ad019785967e5357a6639f261765bda12363f655d39265f5a2834af26327037751420191d0b73152ccc7ce3c35 languageName: node linkType: hard "@babel/preset-env@npm:^7.20.2, @babel/preset-env@npm:^7.22.9": - version: 7.25.3 - resolution: "@babel/preset-env@npm:7.25.3" - dependencies: - "@babel/compat-data": "npm:^7.25.2" - "@babel/helper-compilation-targets": "npm:^7.25.2" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-validator-option": "npm:^7.24.8" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.3" - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.0" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.0" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.24.7" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.0" + version: 7.25.8 + resolution: "@babel/preset-env@npm:7.25.8" + dependencies: + "@babel/compat-data": "npm:^7.25.8" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.7" + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.25.7" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.7" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-async-generators": "npm:^7.8.4" - "@babel/plugin-syntax-class-properties": "npm:^7.12.13" - "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" - "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" - "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" - "@babel/plugin-syntax-import-assertions": "npm:^7.24.7" - "@babel/plugin-syntax-import-attributes": "npm:^7.24.7" - "@babel/plugin-syntax-import-meta": "npm:^7.10.4" - "@babel/plugin-syntax-json-strings": "npm:^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" - "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" - "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" - "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" - "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" - "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" - "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" + "@babel/plugin-syntax-import-assertions": "npm:^7.25.7" + "@babel/plugin-syntax-import-attributes": "npm:^7.25.7" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" - "@babel/plugin-transform-arrow-functions": "npm:^7.24.7" - "@babel/plugin-transform-async-generator-functions": "npm:^7.25.0" - "@babel/plugin-transform-async-to-generator": "npm:^7.24.7" - "@babel/plugin-transform-block-scoped-functions": "npm:^7.24.7" - "@babel/plugin-transform-block-scoping": "npm:^7.25.0" - "@babel/plugin-transform-class-properties": "npm:^7.24.7" - "@babel/plugin-transform-class-static-block": "npm:^7.24.7" - "@babel/plugin-transform-classes": "npm:^7.25.0" - "@babel/plugin-transform-computed-properties": "npm:^7.24.7" - "@babel/plugin-transform-destructuring": "npm:^7.24.8" - "@babel/plugin-transform-dotall-regex": "npm:^7.24.7" - "@babel/plugin-transform-duplicate-keys": "npm:^7.24.7" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.0" - "@babel/plugin-transform-dynamic-import": "npm:^7.24.7" - "@babel/plugin-transform-exponentiation-operator": "npm:^7.24.7" - "@babel/plugin-transform-export-namespace-from": "npm:^7.24.7" - "@babel/plugin-transform-for-of": "npm:^7.24.7" - "@babel/plugin-transform-function-name": "npm:^7.25.1" - "@babel/plugin-transform-json-strings": "npm:^7.24.7" - "@babel/plugin-transform-literals": "npm:^7.25.2" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7" - "@babel/plugin-transform-member-expression-literals": "npm:^7.24.7" - "@babel/plugin-transform-modules-amd": "npm:^7.24.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" - "@babel/plugin-transform-modules-systemjs": "npm:^7.25.0" - "@babel/plugin-transform-modules-umd": "npm:^7.24.7" - "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7" - "@babel/plugin-transform-new-target": "npm:^7.24.7" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.7" - "@babel/plugin-transform-numeric-separator": "npm:^7.24.7" - "@babel/plugin-transform-object-rest-spread": "npm:^7.24.7" - "@babel/plugin-transform-object-super": "npm:^7.24.7" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7" - "@babel/plugin-transform-optional-chaining": "npm:^7.24.8" - "@babel/plugin-transform-parameters": "npm:^7.24.7" - "@babel/plugin-transform-private-methods": "npm:^7.24.7" - "@babel/plugin-transform-private-property-in-object": "npm:^7.24.7" - "@babel/plugin-transform-property-literals": "npm:^7.24.7" - "@babel/plugin-transform-regenerator": "npm:^7.24.7" - "@babel/plugin-transform-reserved-words": "npm:^7.24.7" - "@babel/plugin-transform-shorthand-properties": "npm:^7.24.7" - "@babel/plugin-transform-spread": "npm:^7.24.7" - "@babel/plugin-transform-sticky-regex": "npm:^7.24.7" - "@babel/plugin-transform-template-literals": "npm:^7.24.7" - "@babel/plugin-transform-typeof-symbol": "npm:^7.24.8" - "@babel/plugin-transform-unicode-escapes": "npm:^7.24.7" - "@babel/plugin-transform-unicode-property-regex": "npm:^7.24.7" - "@babel/plugin-transform-unicode-regex": "npm:^7.24.7" - "@babel/plugin-transform-unicode-sets-regex": "npm:^7.24.7" + "@babel/plugin-transform-arrow-functions": "npm:^7.25.7" + "@babel/plugin-transform-async-generator-functions": "npm:^7.25.8" + "@babel/plugin-transform-async-to-generator": "npm:^7.25.7" + "@babel/plugin-transform-block-scoped-functions": "npm:^7.25.7" + "@babel/plugin-transform-block-scoping": "npm:^7.25.7" + "@babel/plugin-transform-class-properties": "npm:^7.25.7" + "@babel/plugin-transform-class-static-block": "npm:^7.25.8" + "@babel/plugin-transform-classes": "npm:^7.25.7" + "@babel/plugin-transform-computed-properties": "npm:^7.25.7" + "@babel/plugin-transform-destructuring": "npm:^7.25.7" + "@babel/plugin-transform-dotall-regex": "npm:^7.25.7" + "@babel/plugin-transform-duplicate-keys": "npm:^7.25.7" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.7" + "@babel/plugin-transform-dynamic-import": "npm:^7.25.8" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.25.7" + "@babel/plugin-transform-export-namespace-from": "npm:^7.25.8" + "@babel/plugin-transform-for-of": "npm:^7.25.7" + "@babel/plugin-transform-function-name": "npm:^7.25.7" + "@babel/plugin-transform-json-strings": "npm:^7.25.8" + "@babel/plugin-transform-literals": "npm:^7.25.7" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.25.8" + "@babel/plugin-transform-member-expression-literals": "npm:^7.25.7" + "@babel/plugin-transform-modules-amd": "npm:^7.25.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.25.7" + "@babel/plugin-transform-modules-systemjs": "npm:^7.25.7" + "@babel/plugin-transform-modules-umd": "npm:^7.25.7" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.25.7" + "@babel/plugin-transform-new-target": "npm:^7.25.7" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.25.8" + "@babel/plugin-transform-numeric-separator": "npm:^7.25.8" + "@babel/plugin-transform-object-rest-spread": "npm:^7.25.8" + "@babel/plugin-transform-object-super": "npm:^7.25.7" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.25.8" + "@babel/plugin-transform-optional-chaining": "npm:^7.25.8" + "@babel/plugin-transform-parameters": "npm:^7.25.7" + "@babel/plugin-transform-private-methods": "npm:^7.25.7" + "@babel/plugin-transform-private-property-in-object": "npm:^7.25.8" + "@babel/plugin-transform-property-literals": "npm:^7.25.7" + "@babel/plugin-transform-regenerator": "npm:^7.25.7" + "@babel/plugin-transform-reserved-words": "npm:^7.25.7" + "@babel/plugin-transform-shorthand-properties": "npm:^7.25.7" + "@babel/plugin-transform-spread": "npm:^7.25.7" + "@babel/plugin-transform-sticky-regex": "npm:^7.25.7" + "@babel/plugin-transform-template-literals": "npm:^7.25.7" + "@babel/plugin-transform-typeof-symbol": "npm:^7.25.7" + "@babel/plugin-transform-unicode-escapes": "npm:^7.25.7" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.25.7" + "@babel/plugin-transform-unicode-regex": "npm:^7.25.7" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.25.7" "@babel/preset-modules": "npm:0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2: "npm:^0.4.10" - babel-plugin-polyfill-corejs3: "npm:^0.10.4" + babel-plugin-polyfill-corejs3: "npm:^0.10.6" babel-plugin-polyfill-regenerator: "npm:^0.6.1" - core-js-compat: "npm:^3.37.1" + core-js-compat: "npm:^3.38.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/9287dc2e296fe2aa3367d84c2a799db17c9d1e48bba86525f47c6f51f5ba2e2cce454f45f4ae2ef928f9077c0640b04556b55b94835675ceeca94a0c5133205e + checksum: 10c0/a45cd64ca082262998f6cf508b413ff8a9e967bf33e58337a1fe41c6c939a4c25cc73cd58387792c00d43905cf5fb0ea5ef88dfdc2addf2e8133743088c86c72 languageName: node linkType: hard @@ -1582,96 +1401,89 @@ __metadata: linkType: hard "@babel/preset-react@npm:^7.18.6, @babel/preset-react@npm:^7.22.5": - version: 7.24.7 - resolution: "@babel/preset-react@npm:7.24.7" + version: 7.25.7 + resolution: "@babel/preset-react@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-validator-option": "npm:^7.24.7" - "@babel/plugin-transform-react-display-name": "npm:^7.24.7" - "@babel/plugin-transform-react-jsx": "npm:^7.24.7" - "@babel/plugin-transform-react-jsx-development": "npm:^7.24.7" - "@babel/plugin-transform-react-pure-annotations": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + "@babel/plugin-transform-react-display-name": "npm:^7.25.7" + "@babel/plugin-transform-react-jsx": "npm:^7.25.7" + "@babel/plugin-transform-react-jsx-development": "npm:^7.25.7" + "@babel/plugin-transform-react-pure-annotations": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/9658b685b25cedaadd0b65c4e663fbc7f57394b5036ddb4c99b1a75b0711fb83292c1c625d605c05b73413fc7a6dc20e532627f6a39b6dc8d4e00415479b054c + checksum: 10c0/b133b1a2f46c70a337d8b1ef442e09e3dbdaecb0d6bed8f1cb64dfddc31c16e248b017385ab909caeebd8462111c9c0e1c5409deb10f2be5cb5bcfdaa4d27718 languageName: node linkType: hard "@babel/preset-typescript@npm:^7.21.0, @babel/preset-typescript@npm:^7.22.5": - version: 7.24.7 - resolution: "@babel/preset-typescript@npm:7.24.7" + version: 7.25.7 + resolution: "@babel/preset-typescript@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-validator-option": "npm:^7.24.7" - "@babel/plugin-syntax-jsx": "npm:^7.24.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.24.7" - "@babel/plugin-transform-typescript": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + "@babel/plugin-syntax-jsx": "npm:^7.25.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.25.7" + "@babel/plugin-transform-typescript": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/986bc0978eedb4da33aba8e1e13a3426dd1829515313b7e8f4ba5d8c18aff1663b468939d471814e7acf4045d326ae6cff37239878d169ac3fe53a8fde71f8ee - languageName: node - linkType: hard - -"@babel/regjsgen@npm:^0.8.0": - version: 0.8.0 - resolution: "@babel/regjsgen@npm:0.8.0" - checksum: 10c0/4f3ddd8c7c96d447e05c8304c1d5ba3a83fcabd8a716bc1091c2f31595cdd43a3a055fff7cb5d3042b8cb7d402d78820fcb4e05d896c605a7d8bcf30f2424c4a + checksum: 10c0/8dc1258e3c5230bbe42ff9811f08924509238e6bd32fa0b7b0c0a6c5e1419512a8e1f733e1b114454d367b7c164beca2cf33acf2ed9e0d99be010c1c5cdbef0c languageName: node linkType: hard "@babel/runtime-corejs3@npm:^7.22.6": - version: 7.25.0 - resolution: "@babel/runtime-corejs3@npm:7.25.0" + version: 7.25.7 + resolution: "@babel/runtime-corejs3@npm:7.25.7" dependencies: core-js-pure: "npm:^3.30.2" regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/7c9e7896749b5968bc6a7638cf1735e5d2dc791780f4f46daf15a45777780cd0485d1357e92f54b03f815269064dc84d771e83486d49e18b847ffa8cfb6a6afa + checksum: 10c0/37217edf5f02c0e7ccb78af380b26b06dadc9b031a1bcec22a9cfb540d85470b61ebe1e5cd7e32689a6c0f786015c2ee1a73a16852574c3a46341105e457a87c languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.3, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.24.8, @babel/runtime@npm:^7.8.4": - version: 7.25.0 - resolution: "@babel/runtime@npm:7.25.0" +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.3, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.8.4": + version: 7.25.7 + resolution: "@babel/runtime@npm:7.25.7" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/bd3faf246170826cef2071a94d7b47b49d532351360ecd17722d03f6713fd93a3eb3dbd9518faa778d5e8ccad7392a7a604e56bd37aaad3f3aa68d619ccd983d + checksum: 10c0/86b7829d2fc9343714a9afe92757cf96c4dc799006ca61d73cda62f4b9e29bfa1ce36794955bc6cb4c188f5b10db832c949339895e1bbe81a69022d9d578ce29 languageName: node linkType: hard -"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/template@npm:7.25.0" +"@babel/template@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/template@npm:7.25.7" dependencies: - "@babel/code-frame": "npm:^7.24.7" - "@babel/parser": "npm:^7.25.0" - "@babel/types": "npm:^7.25.0" - checksum: 10c0/4e31afd873215744c016e02b04f43b9fa23205d6d0766fb2e93eb4091c60c1b88897936adb895fb04e3c23de98dfdcbe31bc98daaa1a4e0133f78bb948e1209b + "@babel/code-frame": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/8ae9e36e4330ee83d4832531d1d9bec7dc2ef6a2a8afa1ef1229506fd60667abcb17f306d1c3d7e582251270597022990c845d5d69e7add70a5aea66720decb9 languageName: node linkType: hard -"@babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.1, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.3": - version: 7.25.3 - resolution: "@babel/traverse@npm:7.25.3" +"@babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/traverse@npm:7.25.7" dependencies: - "@babel/code-frame": "npm:^7.24.7" - "@babel/generator": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.3" - "@babel/template": "npm:^7.25.0" - "@babel/types": "npm:^7.25.2" + "@babel/code-frame": "npm:^7.25.7" + "@babel/generator": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.7" + "@babel/template": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: 10c0/4c8a1966fa90b53a783a4afd2fcdaa6ab1a912e6621dca9fcc6633e80ccb9491620e88caf73b537da4e16cefd537b548c87d7087868d5b0066414dea375c0e9b + checksum: 10c0/75d73e52c507a7a7a4c7971d6bf4f8f26fdd094e0d3a0193d77edf6a5efa36fc3db91ec5cc48e8b94e6eb5d5ad21af0a1040e71309172851209415fd105efb1a languageName: node linkType: hard -"@babel/types@npm:^7.21.3, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.2, @babel/types@npm:^7.4.4": - version: 7.25.2 - resolution: "@babel/types@npm:7.25.2" +"@babel/types@npm:^7.21.3, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8, @babel/types@npm:^7.4.4": + version: 7.25.8 + resolution: "@babel/types@npm:7.25.8" dependencies: - "@babel/helper-string-parser": "npm:^7.24.8" - "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/helper-string-parser": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" to-fast-properties: "npm:^2.0.0" - checksum: 10c0/e489435856be239f8cc1120c90a197e4c2865385121908e5edb7223cfdff3768cba18f489adfe0c26955d9e7bbb1fb10625bc2517505908ceb0af848989bd864 + checksum: 10c0/55ca2d6df6426c98db2769ce884ce5e9de83a512ea2dd7bcf56c811984dc14351cacf42932a723630c5afcff2455809323decd645820762182f10b7b5252b59f languageName: node linkType: hard @@ -1735,20 +1547,20 @@ __metadata: languageName: node linkType: hard -"@docsearch/css@npm:3.6.1": - version: 3.6.1 - resolution: "@docsearch/css@npm:3.6.1" - checksum: 10c0/546b7b725044d006fe5fd2061763fbd1f944d9db21c7b86adb2d11e7bd5eee41b102f1ecccb001bb1603ef7503282cc9ad204482db62e4bc0b038c46a9cd9e6d +"@docsearch/css@npm:3.6.2": + version: 3.6.2 + resolution: "@docsearch/css@npm:3.6.2" + checksum: 10c0/f9f8af55814a8a8dfbac78972cff2c264d4e5508de61d893dbc07544c8e1dcb044803ba150c56f4d245f8f5f88d84fa7f6226038b813850bd602f4bf48123793 languageName: node linkType: hard "@docsearch/react@npm:^3.5.2": - version: 3.6.1 - resolution: "@docsearch/react@npm:3.6.1" + version: 3.6.2 + resolution: "@docsearch/react@npm:3.6.2" dependencies: "@algolia/autocomplete-core": "npm:1.9.3" "@algolia/autocomplete-preset-algolia": "npm:1.9.3" - "@docsearch/css": "npm:3.6.1" + "@docsearch/css": "npm:3.6.2" algoliasearch: "npm:^4.19.1" peerDependencies: "@types/react": ">= 16.8.0 < 19.0.0" @@ -1764,7 +1576,7 @@ __metadata: optional: true search-insights: optional: true - checksum: 10c0/890d46ed1f971a6af9f64377c9e510e4b39324bfedcc143c7bd35ba883f8fdac3dc844b0a0000059fd3dec16a0443e7f723d65c468ca7bafd03be546caf38479 + checksum: 10c0/8fcf47de8786d097005912347fe566577361193026d58b610d5540ef26fd3bf1b30bfe986e23357fd1ee5b97f0a5deb102de3bda79c069536e49a9f3d4b0fc76 languageName: node linkType: hard @@ -2297,21 +2109,21 @@ __metadata: linkType: hard "@emnapi/core@npm:^1.1.0": - version: 1.2.0 - resolution: "@emnapi/core@npm:1.2.0" + version: 1.3.1 + resolution: "@emnapi/core@npm:1.3.1" dependencies: "@emnapi/wasi-threads": "npm:1.0.1" tslib: "npm:^2.4.0" - checksum: 10c0/a9cf024c1982cd965f6888d1b4514926ad3675fa9d0bd792c9a0770fb592c4c4d20aa1e97a225a7682f9c7900231751434820d5558fd5a00929c2ee976ce5265 + checksum: 10c0/d3be1044ad704e2c486641bc18908523490f28c7d38bd12d9c1d4ce37d39dae6c4aecd2f2eaf44c6e3bd90eaf04e0591acc440b1b038cdf43cce078a355a0ea0 languageName: node linkType: hard "@emnapi/runtime@npm:^1.1.0": - version: 1.2.0 - resolution: "@emnapi/runtime@npm:1.2.0" + version: 1.3.1 + resolution: "@emnapi/runtime@npm:1.3.1" dependencies: tslib: "npm:^2.4.0" - checksum: 10c0/7005ff8b67724c9e61b6cd79a3decbdb2ce25d24abd4d3d187472f200ee6e573329c30264335125fb136bd813aa9cf9f4f7c9391d04b07dd1e63ce0a3427be57 + checksum: 10c0/060ffede50f1b619c15083312b80a9e62a5b0c87aa8c1b54854c49766c9d69f8d1d3d87bd963a647071263a320db41b25eaa50b74d6a80dcc763c23dbeaafd6c languageName: node linkType: hard @@ -2324,239 +2136,570 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.4.0 - resolution: "@eslint-community/eslint-utils@npm:4.4.0" - dependencies: - eslint-visitor-keys: "npm:^3.3.0" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/7e559c4ce59cd3a06b1b5a517b593912e680a7f981ae7affab0d01d709e99cd5647019be8fafa38c350305bc32f1f7d42c7073edde2ab536c745e365f37b607e +"@esbuild/aix-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/aix-ppc64@npm:0.21.5" + conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0": - version: 4.11.0 - resolution: "@eslint-community/regexpp@npm:4.11.0" - checksum: 10c0/0f6328869b2741e2794da4ad80beac55cba7de2d3b44f796a60955b0586212ec75e6b0253291fd4aad2100ad471d1480d8895f2b54f1605439ba4c875e05e523 +"@esbuild/aix-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/aix-ppc64@npm:0.23.1" + conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@eslint/config-array@npm:^0.18.0": - version: 0.18.0 - resolution: "@eslint/config-array@npm:0.18.0" - dependencies: - "@eslint/object-schema": "npm:^2.1.4" - debug: "npm:^4.3.1" - minimatch: "npm:^3.1.2" - checksum: 10c0/0234aeb3e6b052ad2402a647d0b4f8a6aa71524bafe1adad0b8db1dfe94d7f5f26d67c80f79bb37ac61361a1d4b14bb8fb475efe501de37263cf55eabb79868f +"@esbuild/android-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm64@npm:0.21.5" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@eslint/core@npm:^0.6.0": - version: 0.6.0 - resolution: "@eslint/core@npm:0.6.0" - checksum: 10c0/fffdb3046ad6420f8cb9204b6466fdd8632a9baeebdaf2a97d458a4eac0e16653ba50d82d61835d7d771f6ced0ec942ec482b2fbccc300e45f2cbf784537f240 +"@esbuild/android-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm64@npm:0.23.1" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@eslint/eslintrc@npm:^3.1.0": - version: 3.1.0 - resolution: "@eslint/eslintrc@npm:3.1.0" - dependencies: - ajv: "npm:^6.12.4" - debug: "npm:^4.3.2" - espree: "npm:^10.0.1" - globals: "npm:^14.0.0" - ignore: "npm:^5.2.0" - import-fresh: "npm:^3.2.1" - js-yaml: "npm:^4.1.0" - minimatch: "npm:^3.1.2" - strip-json-comments: "npm:^3.1.1" - checksum: 10c0/5b7332ed781edcfc98caa8dedbbb843abfb9bda2e86538529c843473f580e40c69eb894410eddc6702f487e9ee8f8cfa8df83213d43a8fdb549f23ce06699167 +"@esbuild/android-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm@npm:0.21.5" + conditions: os=android & cpu=arm languageName: node linkType: hard -"@eslint/js@npm:9.12.0": - version: 9.12.0 - resolution: "@eslint/js@npm:9.12.0" - checksum: 10c0/325650a59a1ce3d97c69441501ebaf415607248bacbe8c8ca35adc7cb73b524f592f266a75772f496b06f3239e3ee1996722a242148085f0ee5fb3dd7065897c +"@esbuild/android-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm@npm:0.23.1" + conditions: os=android & cpu=arm languageName: node linkType: hard -"@eslint/object-schema@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/object-schema@npm:2.1.4" - checksum: 10c0/e9885532ea70e483fb007bf1275968b05bb15ebaa506d98560c41a41220d33d342e19023d5f2939fed6eb59676c1bda5c847c284b4b55fce521d282004da4dda +"@esbuild/android-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-x64@npm:0.21.5" + conditions: os=android & cpu=x64 languageName: node linkType: hard -"@eslint/plugin-kit@npm:^0.2.0": - version: 0.2.0 - resolution: "@eslint/plugin-kit@npm:0.2.0" - dependencies: - levn: "npm:^0.4.1" - checksum: 10c0/00b92bc52ad09b0e2bbbb30591c02a895f0bec3376759562590e8a57a13d096b22f8c8773b6bf791a7cf2ea614123b3d592fd006c51ac5fd0edbb90ea6d8760c +"@esbuild/android-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-x64@npm:0.23.1" + conditions: os=android & cpu=x64 languageName: node linkType: hard -"@hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0": - version: 9.3.0 - resolution: "@hapi/hoek@npm:9.3.0" - checksum: 10c0/a096063805051fb8bba4c947e293c664b05a32b47e13bc654c0dd43813a1cec993bdd8f29ceb838020299e1d0f89f68dc0d62a603c13c9cc8541963f0beca055 +"@esbuild/darwin-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-arm64@npm:0.21.5" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@hapi/topo@npm:^5.1.0": - version: 5.1.0 - resolution: "@hapi/topo@npm:5.1.0" - dependencies: - "@hapi/hoek": "npm:^9.0.0" - checksum: 10c0/b16b06d9357947149e032bdf10151eb71aea8057c79c4046bf32393cb89d0d0f7ca501c40c0f7534a5ceca078de0700d2257ac855c15e59fe4e00bba2f25c86f +"@esbuild/darwin-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-arm64@npm:0.23.1" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@humanfs/core@npm:^0.19.0": - version: 0.19.0 - resolution: "@humanfs/core@npm:0.19.0" - checksum: 10c0/f87952d5caba6ae427a620eff783c5d0b6cef0cfc256dec359cdaa636c5f161edb8d8dad576742b3de7f0b2f222b34aad6870248e4b7d2177f013426cbcda232 +"@esbuild/darwin-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-x64@npm:0.21.5" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@humanfs/node@npm:^0.16.5": - version: 0.16.5 - resolution: "@humanfs/node@npm:0.16.5" - dependencies: - "@humanfs/core": "npm:^0.19.0" - "@humanwhocodes/retry": "npm:^0.3.0" - checksum: 10c0/41c365ab09e7c9eaeed373d09243195aef616d6745608a36fc3e44506148c28843872f85e69e2bf5f1e992e194286155a1c1cecfcece6a2f43875e37cd243935 +"@esbuild/darwin-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-x64@npm:0.23.1" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 +"@esbuild/freebsd-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-arm64@npm:0.21.5" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@humanwhocodes/retry@npm:^0.3.0": - version: 0.3.0 - resolution: "@humanwhocodes/retry@npm:0.3.0" - checksum: 10c0/7111ec4e098b1a428459b4e3be5a5d2a13b02905f805a2468f4fa628d072f0de2da26a27d04f65ea2846f73ba51f4204661709f05bfccff645e3cedef8781bb6 +"@esbuild/freebsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-arm64@npm:0.23.1" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@humanwhocodes/retry@npm:^0.3.1": - version: 0.3.1 - resolution: "@humanwhocodes/retry@npm:0.3.1" - checksum: 10c0/f0da1282dfb45e8120480b9e2e275e2ac9bbe1cf016d046fdad8e27cc1285c45bb9e711681237944445157b430093412b4446c1ab3fc4bb037861b5904101d3b +"@esbuild/freebsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-x64@npm:0.21.5" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@isaacs/cliui@npm:^8.0.2": - version: 8.0.2 - resolution: "@isaacs/cliui@npm:8.0.2" - dependencies: - string-width: "npm:^5.1.2" - string-width-cjs: "npm:string-width@^4.2.0" - strip-ansi: "npm:^7.0.1" - strip-ansi-cjs: "npm:strip-ansi@^6.0.1" - wrap-ansi: "npm:^8.1.0" - wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" - checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e +"@esbuild/freebsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-x64@npm:0.23.1" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@jest/schemas@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/schemas@npm:29.6.3" - dependencies: - "@sinclair/typebox": "npm:^0.27.8" - checksum: 10c0/b329e89cd5f20b9278ae1233df74016ebf7b385e0d14b9f4c1ad18d096c4c19d1e687aa113a9c976b16ec07f021ae53dea811fb8c1248a50ac34fbe009fdf6be +"@esbuild/linux-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm64@npm:0.21.5" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@jest/types@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/types@npm:29.6.3" - dependencies: - "@jest/schemas": "npm:^29.6.3" - "@types/istanbul-lib-coverage": "npm:^2.0.0" - "@types/istanbul-reports": "npm:^3.0.0" - "@types/node": "npm:*" - "@types/yargs": "npm:^17.0.8" - chalk: "npm:^4.0.0" - checksum: 10c0/ea4e493dd3fb47933b8ccab201ae573dcc451f951dc44ed2a86123cd8541b82aa9d2b1031caf9b1080d6673c517e2dcc25a44b2dc4f3fbc37bfc965d444888c0 +"@esbuild/linux-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm64@npm:0.23.1" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.5 - resolution: "@jridgewell/gen-mapping@npm:0.3.5" - dependencies: - "@jridgewell/set-array": "npm:^1.2.1" - "@jridgewell/sourcemap-codec": "npm:^1.4.10" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10c0/1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb +"@esbuild/linux-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm@npm:0.21.5" + conditions: os=linux & cpu=arm languageName: node linkType: hard -"@jridgewell/resolve-uri@npm:^3.1.0": - version: 3.1.2 - resolution: "@jridgewell/resolve-uri@npm:3.1.2" - checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e +"@esbuild/linux-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm@npm:0.23.1" + conditions: os=linux & cpu=arm languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.2.1": - version: 1.2.1 - resolution: "@jridgewell/set-array@npm:1.2.1" - checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4 +"@esbuild/linux-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ia32@npm:0.21.5" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@jridgewell/source-map@npm:^0.3.3": - version: 0.3.6 - resolution: "@jridgewell/source-map@npm:0.3.6" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" - checksum: 10c0/6a4ecc713ed246ff8e5bdcc1ef7c49aaa93f7463d948ba5054dda18b02dcc6a055e2828c577bcceee058f302ce1fc95595713d44f5c45e43d459f88d267f2f04 +"@esbuild/linux-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ia32@npm:0.23.1" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": - version: 1.5.0 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" - checksum: 10c0/2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 +"@esbuild/linux-loong64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-loong64@npm:0.21.5" + conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": - version: 0.3.25 - resolution: "@jridgewell/trace-mapping@npm:0.3.25" - dependencies: - "@jridgewell/resolve-uri": "npm:^3.1.0" - "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10c0/3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4 +"@esbuild/linux-loong64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-loong64@npm:0.23.1" + conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@kinobi-so/errors@npm:0.22.0": - version: 0.22.0 - resolution: "@kinobi-so/errors@npm:0.22.0" - dependencies: - "@kinobi-so/node-types": "npm:0.22.0" - chalk: "npm:^5.3.0" - commander: "npm:^12.1.0" - bin: - errors: bin/cli.mjs - checksum: 10c0/79ebd0a8bab51d789590a10af98203566000ef51ed5e1ff80c8a6266e892125f6d8da7ef5c618d97cd28f4da2a78913da421b1ab091f31f130bf2ed537351453 +"@esbuild/linux-mips64el@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-mips64el@npm:0.21.5" + conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@kinobi-so/node-types@npm:0.22.0": +"@esbuild/linux-mips64el@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-mips64el@npm:0.23.1" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ppc64@npm:0.21.5" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ppc64@npm:0.23.1" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-riscv64@npm:0.21.5" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-riscv64@npm:0.23.1" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-s390x@npm:0.21.5" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-s390x@npm:0.23.1" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-x64@npm:0.21.5" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-x64@npm:0.23.1" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/netbsd-x64@npm:0.21.5" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/netbsd-x64@npm:0.23.1" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-arm64@npm:0.23.1" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/openbsd-x64@npm:0.21.5" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-x64@npm:0.23.1" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/sunos-x64@npm:0.21.5" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/sunos-x64@npm:0.23.1" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-arm64@npm:0.21.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-arm64@npm:0.23.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-ia32@npm:0.21.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-ia32@npm:0.23.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-x64@npm:0.21.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-x64@npm:0.23.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": + version: 4.4.0 + resolution: "@eslint-community/eslint-utils@npm:4.4.0" + dependencies: + eslint-visitor-keys: "npm:^3.3.0" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10c0/7e559c4ce59cd3a06b1b5a517b593912e680a7f981ae7affab0d01d709e99cd5647019be8fafa38c350305bc32f1f7d42c7073edde2ab536c745e365f37b607e + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0": + version: 4.11.1 + resolution: "@eslint-community/regexpp@npm:4.11.1" + checksum: 10c0/fbcc1cb65ef5ed5b92faa8dc542e035269065e7ebcc0b39c81a4fe98ad35cfff20b3c8df048641de15a7757e07d69f85e2579c1a5055f993413ba18c055654f8 + languageName: node + linkType: hard + +"@eslint/config-array@npm:^0.18.0": + version: 0.18.0 + resolution: "@eslint/config-array@npm:0.18.0" + dependencies: + "@eslint/object-schema": "npm:^2.1.4" + debug: "npm:^4.3.1" + minimatch: "npm:^3.1.2" + checksum: 10c0/0234aeb3e6b052ad2402a647d0b4f8a6aa71524bafe1adad0b8db1dfe94d7f5f26d67c80f79bb37ac61361a1d4b14bb8fb475efe501de37263cf55eabb79868f + languageName: node + linkType: hard + +"@eslint/core@npm:^0.7.0": + version: 0.7.0 + resolution: "@eslint/core@npm:0.7.0" + checksum: 10c0/3cdee8bc6cbb96ac6103d3ead42e59830019435839583c9eb352b94ed558bd78e7ffad5286dc710df21ec1e7bd8f52aa6574c62457a4dd0f01f3736fa4a7d87a + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^3.1.0": + version: 3.1.0 + resolution: "@eslint/eslintrc@npm:3.1.0" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.3.2" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" + strip-json-comments: "npm:^3.1.1" + checksum: 10c0/5b7332ed781edcfc98caa8dedbbb843abfb9bda2e86538529c843473f580e40c69eb894410eddc6702f487e9ee8f8cfa8df83213d43a8fdb549f23ce06699167 + languageName: node + linkType: hard + +"@eslint/js@npm:9.13.0": + version: 9.13.0 + resolution: "@eslint/js@npm:9.13.0" + checksum: 10c0/672257bffe17777b8a98bd80438702904cc7a0b98b9c2e426a8a10929198b3553edf8a3fc20feed4133c02e7c8f7331a0ef1b23e5dab8e4469f7f1791beff1e0 + languageName: node + linkType: hard + +"@eslint/object-schema@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/object-schema@npm:2.1.4" + checksum: 10c0/e9885532ea70e483fb007bf1275968b05bb15ebaa506d98560c41a41220d33d342e19023d5f2939fed6eb59676c1bda5c847c284b4b55fce521d282004da4dda + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.2.0": + version: 0.2.1 + resolution: "@eslint/plugin-kit@npm:0.2.1" + dependencies: + levn: "npm:^0.4.1" + checksum: 10c0/34b1ecb35df97b0adeb6a43366fc1b8aa1a54d23fc9753019277e80a7295724fddb547a795fd59c9eb56d690bbf0d76d7f2286cb0f5db367a86a763d5acbde5f + languageName: node + linkType: hard + +"@hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0": + version: 9.3.0 + resolution: "@hapi/hoek@npm:9.3.0" + checksum: 10c0/a096063805051fb8bba4c947e293c664b05a32b47e13bc654c0dd43813a1cec993bdd8f29ceb838020299e1d0f89f68dc0d62a603c13c9cc8541963f0beca055 + languageName: node + linkType: hard + +"@hapi/topo@npm:^5.1.0": + version: 5.1.0 + resolution: "@hapi/topo@npm:5.1.0" + dependencies: + "@hapi/hoek": "npm:^9.0.0" + checksum: 10c0/b16b06d9357947149e032bdf10151eb71aea8057c79c4046bf32393cb89d0d0f7ca501c40c0f7534a5ceca078de0700d2257ac855c15e59fe4e00bba2f25c86f + languageName: node + linkType: hard + +"@humanfs/core@npm:^0.19.0": + version: 0.19.0 + resolution: "@humanfs/core@npm:0.19.0" + checksum: 10c0/f87952d5caba6ae427a620eff783c5d0b6cef0cfc256dec359cdaa636c5f161edb8d8dad576742b3de7f0b2f222b34aad6870248e4b7d2177f013426cbcda232 + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.5": + version: 0.16.5 + resolution: "@humanfs/node@npm:0.16.5" + dependencies: + "@humanfs/core": "npm:^0.19.0" + "@humanwhocodes/retry": "npm:^0.3.0" + checksum: 10c0/41c365ab09e7c9eaeed373d09243195aef616d6745608a36fc3e44506148c28843872f85e69e2bf5f1e992e194286155a1c1cecfcece6a2f43875e37cd243935 + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.3.0, @humanwhocodes/retry@npm:^0.3.1": + version: 0.3.1 + resolution: "@humanwhocodes/retry@npm:0.3.1" + checksum: 10c0/f0da1282dfb45e8120480b9e2e275e2ac9bbe1cf016d046fdad8e27cc1285c45bb9e711681237944445157b430093412b4446c1ab3fc4bb037861b5904101d3b + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e + languageName: node + linkType: hard + +"@jest/expect-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect-utils@npm:29.7.0" + dependencies: + jest-get-type: "npm:^29.6.3" + checksum: 10c0/60b79d23a5358dc50d9510d726443316253ecda3a7fb8072e1526b3e0d3b14f066ee112db95699b7a43ad3f0b61b750c72e28a5a1cac361d7a2bb34747fa938a + languageName: node + linkType: hard + +"@jest/schemas@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/schemas@npm:29.6.3" + dependencies: + "@sinclair/typebox": "npm:^0.27.8" + checksum: 10c0/b329e89cd5f20b9278ae1233df74016ebf7b385e0d14b9f4c1ad18d096c4c19d1e687aa113a9c976b16ec07f021ae53dea811fb8c1248a50ac34fbe009fdf6be + languageName: node + linkType: hard + +"@jest/types@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/types@npm:29.6.3" + dependencies: + "@jest/schemas": "npm:^29.6.3" + "@types/istanbul-lib-coverage": "npm:^2.0.0" + "@types/istanbul-reports": "npm:^3.0.0" + "@types/node": "npm:*" + "@types/yargs": "npm:^17.0.8" + chalk: "npm:^4.0.0" + checksum: 10c0/ea4e493dd3fb47933b8ccab201ae573dcc451f951dc44ed2a86123cd8541b82aa9d2b1031caf9b1080d6673c517e2dcc25a44b2dc4f3fbc37bfc965d444888c0 + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": "npm:^1.2.1" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e + languageName: node + linkType: hard + +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4 + languageName: node + linkType: hard + +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.6 + resolution: "@jridgewell/source-map@npm:0.3.6" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + checksum: 10c0/6a4ecc713ed246ff8e5bdcc1ef7c49aaa93f7463d948ba5054dda18b02dcc6a055e2828c577bcceee058f302ce1fc95595713d44f5c45e43d459f88d267f2f04 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 10c0/2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4 + languageName: node + linkType: hard + +"@kinobi-so/errors@npm:0.22.0": + version: 0.22.0 + resolution: "@kinobi-so/errors@npm:0.22.0" + dependencies: + "@kinobi-so/node-types": "npm:0.22.0" + chalk: "npm:^5.3.0" + commander: "npm:^12.1.0" + bin: + errors: bin/cli.mjs + checksum: 10c0/79ebd0a8bab51d789590a10af98203566000ef51ed5e1ff80c8a6266e892125f6d8da7ef5c618d97cd28f4da2a78913da421b1ab091f31f130bf2ed537351453 + languageName: node + linkType: hard + +"@kinobi-so/node-types@npm:0.22.0": version: 0.22.0 resolution: "@kinobi-so/node-types@npm:0.22.0" checksum: 10c0/9549d18c955d2be941803f49549bbf3861d37950ba7981075a29a6fcee2066e24095f05342c3d102c5b370f92cc6f304a2529ce4c60d39921fd5c1b1790a2bf4 @@ -2667,8 +2810,8 @@ __metadata: linkType: hard "@mdx-js/mdx@npm:^3.0.0": - version: 3.0.1 - resolution: "@mdx-js/mdx@npm:3.0.1" + version: 3.1.0 + resolution: "@mdx-js/mdx@npm:3.1.0" dependencies: "@types/estree": "npm:^1.0.0" "@types/estree-jsx": "npm:^1.0.0" @@ -2676,14 +2819,15 @@ __metadata: "@types/mdx": "npm:^2.0.0" collapse-white-space: "npm:^2.0.0" devlop: "npm:^1.0.0" - estree-util-build-jsx: "npm:^3.0.0" estree-util-is-identifier-name: "npm:^3.0.0" - estree-util-to-js: "npm:^2.0.0" + estree-util-scope: "npm:^1.0.0" estree-walker: "npm:^3.0.0" - hast-util-to-estree: "npm:^3.0.0" hast-util-to-jsx-runtime: "npm:^2.0.0" markdown-extensions: "npm:^2.0.0" - periscopic: "npm:^3.0.0" + recma-build-jsx: "npm:^1.0.0" + recma-jsx: "npm:^1.0.0" + recma-stringify: "npm:^1.0.0" + rehype-recma: "npm:^1.0.0" remark-mdx: "npm:^3.0.0" remark-parse: "npm:^11.0.0" remark-rehype: "npm:^11.0.0" @@ -2693,19 +2837,19 @@ __metadata: unist-util-stringify-position: "npm:^4.0.0" unist-util-visit: "npm:^5.0.0" vfile: "npm:^6.0.0" - checksum: 10c0/8cd7084f1242209bbeef81f69ea670ffffa0656dda2893bbd46b1b2b26078a57f9d993f8f82ad8ba16bc969189235140007185276d7673471827331521eae2e0 + checksum: 10c0/e586ab772dcfee2bab334d5aac54c711e6d6d550085271c38a49c629b3e3954b5f41f488060761284a5e00649d0638d6aba6c0a7c66f91db80dee0ccc304ab32 languageName: node linkType: hard "@mdx-js/react@npm:^3.0.0, @mdx-js/react@npm:^3.0.1": - version: 3.0.1 - resolution: "@mdx-js/react@npm:3.0.1" + version: 3.1.0 + resolution: "@mdx-js/react@npm:3.1.0" dependencies: "@types/mdx": "npm:^2.0.0" peerDependencies: "@types/react": ">=16" react: ">=16" - checksum: 10c0/d210d926ef488d39ad65f04d821936b668eadcdde3b6421e94ec4200ca7ad17f17d24c5cbc543882586af9f08b10e2eea715c728ce6277487945e05c5199f532 + checksum: 10c0/381ed1211ba2b8491bf0ad9ef0d8d1badcdd114e1931d55d44019d4b827cc2752586708f9c7d2f9c3244150ed81f1f671a6ca95fae0edd5797fb47a22e06ceca languageName: node linkType: hard @@ -2721,22 +2865,15 @@ __metadata: linkType: hard "@noble/curves@npm:^1.4.2": - version: 1.4.2 - resolution: "@noble/curves@npm:1.4.2" + version: 1.6.0 + resolution: "@noble/curves@npm:1.6.0" dependencies: - "@noble/hashes": "npm:1.4.0" - checksum: 10c0/65620c895b15d46e8087939db6657b46a1a15cd4e0e4de5cd84b97a0dfe0af85f33a431bb21ac88267e3dc508618245d4cb564213959d66a84d690fe18a63419 - languageName: node - linkType: hard - -"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.4.0": - version: 1.4.0 - resolution: "@noble/hashes@npm:1.4.0" - checksum: 10c0/8c3f005ee72e7b8f9cff756dfae1241485187254e3f743873e22073d63906863df5d4f13d441b7530ea614b7a093f0d889309f28b59850f33b66cb26a779a4a5 + "@noble/hashes": "npm:1.5.0" + checksum: 10c0/f3262aa4d39148e627cd82b5ac1c93f88c5bb46dd2566b5e8e52ffac3a0fc381ad30c2111656fd2bd3b0d37d43d540543e0d93a5ff96a6cb184bc3bfe10d1cd9 languageName: node linkType: hard -"@noble/hashes@npm:^1.5.0": +"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:^1.5.0": version: 1.5.0 resolution: "@noble/hashes@npm:1.5.0" checksum: 10c0/1b46539695fbfe4477c0822d90c881a04d4fa2921c08c552375b444a48cac9930cb1ee68de0a3c7859e676554d0f3771999716606dc4d8f826e414c11692cdd9 @@ -2792,72 +2929,72 @@ __metadata: languageName: node linkType: hard -"@nx/nx-darwin-arm64@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-darwin-arm64@npm:20.0.2" +"@nx/nx-darwin-arm64@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-darwin-arm64@npm:20.0.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@nx/nx-darwin-x64@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-darwin-x64@npm:20.0.2" +"@nx/nx-darwin-x64@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-darwin-x64@npm:20.0.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@nx/nx-freebsd-x64@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-freebsd-x64@npm:20.0.2" +"@nx/nx-freebsd-x64@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-freebsd-x64@npm:20.0.3" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@nx/nx-linux-arm-gnueabihf@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-linux-arm-gnueabihf@npm:20.0.2" +"@nx/nx-linux-arm-gnueabihf@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-linux-arm-gnueabihf@npm:20.0.3" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@nx/nx-linux-arm64-gnu@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-linux-arm64-gnu@npm:20.0.2" +"@nx/nx-linux-arm64-gnu@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-linux-arm64-gnu@npm:20.0.3" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@nx/nx-linux-arm64-musl@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-linux-arm64-musl@npm:20.0.2" +"@nx/nx-linux-arm64-musl@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-linux-arm64-musl@npm:20.0.3" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@nx/nx-linux-x64-gnu@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-linux-x64-gnu@npm:20.0.2" +"@nx/nx-linux-x64-gnu@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-linux-x64-gnu@npm:20.0.3" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@nx/nx-linux-x64-musl@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-linux-x64-musl@npm:20.0.2" +"@nx/nx-linux-x64-musl@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-linux-x64-musl@npm:20.0.3" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@nx/nx-win32-arm64-msvc@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-win32-arm64-msvc@npm:20.0.2" +"@nx/nx-win32-arm64-msvc@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-win32-arm64-msvc@npm:20.0.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@nx/nx-win32-x64-msvc@npm:20.0.2": - version: 20.0.2 - resolution: "@nx/nx-win32-x64-msvc@npm:20.0.2" +"@nx/nx-win32-x64-msvc@npm:20.0.3": + version: 20.0.3 + resolution: "@nx/nx-win32-x64-msvc@npm:20.0.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -2882,11 +3019,22 @@ __metadata: "@kinobi-so/nodes-from-anchor": "npm:^0.22.0" "@kinobi-so/renderers-js": "npm:^0.22.0" "@orca-so/whirlpools-program": "npm:*" - "@solana/web3.js": "npm:^2.0.0-preview.4" + "@solana/web3.js": "npm:^2.0.0-rc.1" kinobi: "npm:^0.22.0" typescript: "npm:^5.6.3" peerDependencies: - "@solana/web3.js": ^2.0.0-preview.4 + "@solana/web3.js": ^2.0.0-rc.1 + languageName: unknown + linkType: soft + +"@orca-so/whirlpools-core@npm:*, @orca-so/whirlpools-core@workspace:ts-sdk/core": + version: 0.0.0-use.local + resolution: "@orca-so/whirlpools-core@workspace:ts-sdk/core" + dependencies: + "@orca-so/whirlpools-client": "npm:*" + "@orca-so/whirlpools-rust-core": "npm:*" + typescript: "npm:^5.6.3" + wasm-pack: "npm:^0.13.0" languageName: unknown linkType: soft @@ -2894,6 +3042,7 @@ __metadata: version: 0.0.0-use.local resolution: "@orca-so/whirlpools-docs-legacy@workspace:docs/legacy" dependencies: + "@orca-so/whirlpools": "npm:*" "@orca-so/whirlpools-sdk": "npm:*" typedoc: "npm:^0.26.10" typescript: "npm:^5.6.3" @@ -2913,6 +3062,7 @@ __metadata: resolution: "@orca-so/whirlpools-docs-ts@workspace:docs/ts" dependencies: "@orca-so/whirlpools": "npm:*" + "@orca-so/whirlpools-sdk": "npm:*" typedoc: "npm:^0.26.10" typescript: "npm:^5.6.3" languageName: unknown @@ -2954,17 +3104,13 @@ __metadata: version: 0.0.0-use.local resolution: "@orca-so/whirlpools-monorepo@workspace:." dependencies: - "@types/bn.js": "npm:~5.1.6" - "@types/mocha": "npm:^10.0.9" "@types/node": "npm:^22.7.6" - "@types/sinon": "npm:^17.0.3" husky: "npm:^9.1.6" lint-staged: "npm:^15.2.10" - mocha: "npm:^10.7.3" nx: "npm:^20.0.2" rimraf: "npm:^6.0.1" - sinon: "npm:^19.0.2" - ts-mocha: "npm:^10.0.0" + tsup: "npm:^8.3.0" + vitest: "npm:^2.1.3" languageName: unknown linkType: soft @@ -2981,6 +3127,21 @@ __metadata: "@kinobi-so/nodes-from-anchor": "npm:^0.22.0" "@kinobi-so/renderers-rust": "npm:^0.22.0" "@orca-so/whirlpools-program": "npm:*" + "@orca-so/whirlpools-rust-core": "npm:*" + languageName: unknown + linkType: soft + +"@orca-so/whirlpools-rust-core@npm:*, @orca-so/whirlpools-rust-core@workspace:rust-sdk/core": + version: 0.0.0-use.local + resolution: "@orca-so/whirlpools-rust-core@workspace:rust-sdk/core" + dependencies: + "@orca-so/whirlpools-rust-macros": "npm:*" + languageName: unknown + linkType: soft + +"@orca-so/whirlpools-rust-macros@npm:*, @orca-so/whirlpools-rust-macros@workspace:rust-sdk/macros": + version: 0.0.0-use.local + resolution: "@orca-so/whirlpools-rust-macros@workspace:rust-sdk/macros" languageName: unknown linkType: soft @@ -2999,7 +3160,6 @@ __metadata: "@project-serum/anchor": "npm:~0.26.0" "@solana/spl-token": "npm:^0.4.8" "@solana/web3.js": "npm:^1.95.2" - "@types/mocha": "npm:^10.0.9" "@types/mz": "npm:^2.7.3" mz: "npm:^2.7.0" typescript: "npm:^5.6.3" @@ -3015,6 +3175,8 @@ __metadata: "@orca-so/whirlpools-program": "npm:*" "@solana/spl-token": "npm:^0.4.8" "@solana/web3.js": "npm:^1.90.0" + "@types/bn.js": "npm:~5.1.6" + "@types/jest": "npm:^29.5.13" decimal.js: "npm:^10.4.3" tiny-invariant: "npm:^1.3.1" typescript: "npm:^5.6.3" @@ -3032,7 +3194,15 @@ __metadata: resolution: "@orca-so/whirlpools@workspace:ts-sdk/whirlpool" dependencies: "@orca-so/whirlpools-client": "npm:*" + "@orca-so/whirlpools-core": "npm:*" + "@solana-program/memo": "npm:^0.5.0" + "@solana-program/system": "npm:^0.5.0" + "@solana-program/token": "npm:^0.2.1" + "@solana-program/token-2022": "npm:^0.1.0" + "@solana/web3.js": "npm:^2.0.0-rc.1" typescript: "npm:^5.6.3" + peerDependencies: + "@solana/web3.js": ^2.0.0-rc.1 languageName: unknown linkType: soft @@ -3071,9 +3241,9 @@ __metadata: linkType: hard "@polka/url@npm:^1.0.0-next.24": - version: 1.0.0-next.25 - resolution: "@polka/url@npm:1.0.0-next.25" - checksum: 10c0/ef61f0a0fe94bb6e1143fc5b9d5a12e6ca9dbd2c57843ebf81db432c21b9f1005c09e8a1ef8b6d5ddfa42146ca65b640feb2d353bd0d3546da46ba59e48a5349 + version: 1.0.0-next.28 + resolution: "@polka/url@npm:1.0.0-next.28" + checksum: 10c0/acc5ea62597e4da2fb42dbee02749d07f102ae7d6d2c966bf7e423c79cd65d1621da305af567e6e7c232f3b565e242d1ec932cbb3dcc0db1508d02e9a2cafa2e languageName: node linkType: hard @@ -3100,445 +3270,385 @@ __metadata: languageName: node linkType: hard -"@shikijs/core@npm:1.16.2": - version: 1.16.2 - resolution: "@shikijs/core@npm:1.16.2" - dependencies: - "@shikijs/vscode-textmate": "npm:^9.2.0" - "@types/hast": "npm:^3.0.4" - checksum: 10c0/1fe12b7db380194d21b8c8c64897a29b2b3b6ef69db6e6ddce784faf8bd54ce2040f152802c95e55654b3f286b07af1d6f2017b40a241236a8647567b4bdcad0 +"@rollup/rollup-android-arm-eabi@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.24.0" + conditions: os=android & cpu=arm languageName: node linkType: hard -"@shikijs/vscode-textmate@npm:^9.2.0": - version: 9.2.0 - resolution: "@shikijs/vscode-textmate@npm:9.2.0" - checksum: 10c0/9f89e02bd930953bb15ad50b079ac15e1704cdc4f7d1d188f6d1eea87cf74e5dced59cd724ba9466116158eec75b71117fcd9915757a7615856d0ed366957704 +"@rollup/rollup-android-arm64@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-android-arm64@npm:4.24.0" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@sideway/address@npm:^4.1.5": - version: 4.1.5 - resolution: "@sideway/address@npm:4.1.5" - dependencies: - "@hapi/hoek": "npm:^9.0.0" - checksum: 10c0/638eb6f7e7dba209053dd6c8da74d7cc995e2b791b97644d0303a7dd3119263bcb7225a4f6804d4db2bc4f96e5a9d262975a014f58eae4d1753c27cbc96ef959 +"@rollup/rollup-darwin-arm64@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.24.0" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@sideway/formula@npm:^3.0.1": - version: 3.0.1 - resolution: "@sideway/formula@npm:3.0.1" - checksum: 10c0/3fe81fa9662efc076bf41612b060eb9b02e846ea4bea5bd114f1662b7f1541e9dedcf98aff0d24400bcb92f113964a50e0290b86e284edbdf6346fa9b7e2bf2c +"@rollup/rollup-darwin-x64@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.24.0" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@sideway/pinpoint@npm:^2.0.0": - version: 2.0.0 - resolution: "@sideway/pinpoint@npm:2.0.0" - checksum: 10c0/d2ca75dacaf69b8fc0bb8916a204e01def3105ee44d8be16c355e5f58189eb94039e15ce831f3d544f229889ccfa35562a0ce2516179f3a7ee1bbe0b71e55b36 +"@rollup/rollup-linux-arm-gnueabihf@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.24.0" + conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@sinclair/typebox@npm:^0.27.8": - version: 0.27.8 - resolution: "@sinclair/typebox@npm:0.27.8" - checksum: 10c0/ef6351ae073c45c2ac89494dbb3e1f87cc60a93ce4cde797b782812b6f97da0d620ae81973f104b43c9b7eaa789ad20ba4f6a1359f1cc62f63729a55a7d22d4e +"@rollup/rollup-linux-arm-musleabihf@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.24.0" + conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@sindresorhus/is@npm:^4.6.0": - version: 4.6.0 - resolution: "@sindresorhus/is@npm:4.6.0" - checksum: 10c0/33b6fb1d0834ec8dd7689ddc0e2781c2bfd8b9c4e4bacbcb14111e0ae00621f2c264b8a7d36541799d74888b5dccdf422a891a5cb5a709ace26325eedc81e22e +"@rollup/rollup-linux-arm64-gnu@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.24.0" + conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@sindresorhus/is@npm:^5.2.0": - version: 5.6.0 - resolution: "@sindresorhus/is@npm:5.6.0" - checksum: 10c0/66727344d0c92edde5760b5fd1f8092b717f2298a162a5f7f29e4953e001479927402d9d387e245fb9dc7d3b37c72e335e93ed5875edfc5203c53be8ecba1b52 +"@rollup/rollup-linux-arm64-musl@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.24.0" + conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@sinonjs/commons@npm:^3.0.1": - version: 3.0.1 - resolution: "@sinonjs/commons@npm:3.0.1" - dependencies: - type-detect: "npm:4.0.8" - checksum: 10c0/1227a7b5bd6c6f9584274db996d7f8cee2c8c350534b9d0141fc662eaf1f292ea0ae3ed19e5e5271c8fd390d27e492ca2803acd31a1978be2cdc6be0da711403 +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.24.0" + conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^13.0.1": - version: 13.0.1 - resolution: "@sinonjs/fake-timers@npm:13.0.1" - dependencies: - "@sinonjs/commons": "npm:^3.0.1" - checksum: 10c0/4d0a0f83d0847780675ee8287ae41a19f2dba372256df5383db1a84491a752114bf1724024a52a0d85f240f705b88a64271322c475158e8162e5e5b4568a7399 +"@rollup/rollup-linux-riscv64-gnu@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.24.0" + conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^13.0.2": - version: 13.0.2 - resolution: "@sinonjs/fake-timers@npm:13.0.2" - dependencies: - "@sinonjs/commons": "npm:^3.0.1" - checksum: 10c0/fc68fd872dff8a3457f7b0cf4e3c06db5ab35332a19da58165bb2e02b2016911dd77c6d5bd8995f8d9e012f3379b065ea37c3f240d0aa6716a591ba89912a486 +"@rollup/rollup-linux-s390x-gnu@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.24.0" + conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@sinonjs/samsam@npm:^8.0.1": - version: 8.0.2 - resolution: "@sinonjs/samsam@npm:8.0.2" - dependencies: - "@sinonjs/commons": "npm:^3.0.1" - lodash.get: "npm:^4.4.2" - type-detect: "npm:^4.1.0" - checksum: 10c0/31d74c415040161f2963a202d7f866bedbb5a9b522a74b08a17086c15a75c3ef2893eecebb0c65a7b1603ef4ebdf83fa73cbe384b4cd679944918ed833200443 +"@rollup/rollup-linux-x64-gnu@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.24.0" + conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@sinonjs/text-encoding@npm:^0.7.3": - version: 0.7.3 - resolution: "@sinonjs/text-encoding@npm:0.7.3" - checksum: 10c0/b112d1e97af7f99fbdc63c7dbcd35d6a60764dfec85cfcfff532e55cce8ecd8453f9fa2139e70aea47142c940fd90cd201d19f370b9a0141700d8a6de3116815 +"@rollup/rollup-linux-x64-musl@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.24.0" + conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@slorber/remark-comment@npm:^1.0.0": - version: 1.0.0 - resolution: "@slorber/remark-comment@npm:1.0.0" - dependencies: - micromark-factory-space: "npm:^1.0.0" - micromark-util-character: "npm:^1.1.0" - micromark-util-symbol: "npm:^1.0.1" - checksum: 10c0/b8da9d8f560740959c421d3ce5be43952eace1c95cb65402d9473a15e66463346a37fb5f121a6b22a83af51e8845b0b4ff3c321f14ce31bd58fb126acf6c8ed9 +"@rollup/rollup-win32-arm64-msvc@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.24.0" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@solana/accounts@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/accounts@npm:2.0.0-rc.0" - dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/rpc-spec": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" - peerDependencies: - typescript: ">=5" - checksum: 10c0/6eeb6d6bd665881bc13a3e65d82cae1c3a612f13f72cfb44517304d2fe89eabc30cf420c7d034c78b68a3615db0d93ab5b2fbeaa0c78677b40acc7f2af0cf8e9 +"@rollup/rollup-win32-ia32-msvc@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.24.0" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@solana/addresses@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/addresses@npm:2.0.0-rc.0" - dependencies: - "@solana/assertions": "npm:2.0.0-rc.0" - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - peerDependencies: - typescript: ">=5" - checksum: 10c0/96ba9d2360851d131a6dcbc914b3af8cb5036048cb679a5bd4246f7ec8d1c90a285cf5d1de7b014f06c304774420238ccf2fd7e343a6f4eb6e0d020f5c002e20 +"@rollup/rollup-win32-x64-msvc@npm:4.24.0": + version: 4.24.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.24.0" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@solana/assertions@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/assertions@npm:2.0.0-rc.0" +"@shikijs/core@npm:1.22.0": + version: 1.22.0 + resolution: "@shikijs/core@npm:1.22.0" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" - peerDependencies: - typescript: ">=5" - checksum: 10c0/0a47275d54bfb43d1e4010dff5e29ed658339111b4717eec1b147bc1bebcb6cfaa79c0120feacc40fba10cf3ec4bff92c317a7edfeae30876c851395c5d9d461 + "@shikijs/engine-javascript": "npm:1.22.0" + "@shikijs/engine-oniguruma": "npm:1.22.0" + "@shikijs/types": "npm:1.22.0" + "@shikijs/vscode-textmate": "npm:^9.3.0" + "@types/hast": "npm:^3.0.4" + hast-util-to-html: "npm:^9.0.3" + checksum: 10c0/d663fee39180680ccb9ea8dd5abb397e953375989a4fd52fb65a2616388db21d1d0a715a68afae93c4b48f0e037bd0c3a600cd52fb8560461ba87e2102e00cd1 languageName: node linkType: hard -"@solana/buffer-layout-utils@npm:^0.2.0": - version: 0.2.0 - resolution: "@solana/buffer-layout-utils@npm:0.2.0" +"@shikijs/engine-javascript@npm:1.22.0": + version: 1.22.0 + resolution: "@shikijs/engine-javascript@npm:1.22.0" dependencies: - "@solana/buffer-layout": "npm:^4.0.0" - "@solana/web3.js": "npm:^1.32.0" - bigint-buffer: "npm:^1.1.5" - bignumber.js: "npm:^9.0.1" - checksum: 10c0/ed093999d7c0f93527a9b261a9a2a59e10b5ef78fc416fa896b86036fb4dadf923d17db68bffdc3e91eadecdb8b8cddd8ee37f12429980fcaba321e7b8a35d27 + "@shikijs/types": "npm:1.22.0" + "@shikijs/vscode-textmate": "npm:^9.3.0" + oniguruma-to-js: "npm:0.4.3" + checksum: 10c0/f1a2c3c6ad5db549229dafe11a57bef2b0896e5c1b33dec15bd323e4e785dc469a277b088a89f774a66b30c8c62e9e5b76d3d485f46096dc290329aab33d92eb languageName: node linkType: hard -"@solana/buffer-layout@npm:^4.0.0, @solana/buffer-layout@npm:^4.0.1": - version: 4.0.1 - resolution: "@solana/buffer-layout@npm:4.0.1" +"@shikijs/engine-oniguruma@npm:1.22.0": + version: 1.22.0 + resolution: "@shikijs/engine-oniguruma@npm:1.22.0" dependencies: - buffer: "npm:~6.0.3" - checksum: 10c0/6535f3908cf6dfc405b665795f0c2eaa0482a8c6b1811403945cf7b450e7eb7b40acce3e8af046f2fcc3eea1a15e61d48c418315d813bee4b720d56b00053305 + "@shikijs/types": "npm:1.22.0" + "@shikijs/vscode-textmate": "npm:^9.3.0" + checksum: 10c0/a57f2352dc35e6f3705348488c0ec2b91a99380489917bddc1d1444b775ba529fc99491ac0c16d0add6d2552ca9fd197e88bd47b0166d163bfc6a80345294452 languageName: node linkType: hard -"@solana/codecs-core@npm:2.0.0-preview.2": - version: 2.0.0-preview.2 - resolution: "@solana/codecs-core@npm:2.0.0-preview.2" +"@shikijs/types@npm:1.22.0": + version: 1.22.0 + resolution: "@shikijs/types@npm:1.22.0" dependencies: - "@solana/errors": "npm:2.0.0-preview.2" - checksum: 10c0/545340b797bbf5bfbc79c2ca66aa87265b04632e3abd4ec042b7e8e92ed5738726c75a8c8dffd3ea6c793b4f8cd0c74caac72fb41a49a17132f2bb194ab8722f + "@shikijs/vscode-textmate": "npm:^9.3.0" + "@types/hast": "npm:^3.0.4" + checksum: 10c0/220ba56b046dd07cb5e12c02f061e926129d5295fba60c4910a45d65312cdcbcc120329ec550195fdb85ab60ae9e3af31430bffce3ceba80b30d21e32467c013 languageName: node linkType: hard -"@solana/codecs-core@npm:2.0.0-preview.4": - version: 2.0.0-preview.4 - resolution: "@solana/codecs-core@npm:2.0.0-preview.4" - dependencies: - "@solana/errors": "npm:2.0.0-preview.4" - peerDependencies: - typescript: ">=5" - checksum: 10c0/fe6d52cec3b747a8ecf752675b57e7f01c5c1d6287d0ec339b49979afba0c37f6c357f4b0b75edb9a6f7876134ba8c1eb77daa3df5b3cdfc938fdebde5d98278 +"@shikijs/vscode-textmate@npm:^9.3.0": + version: 9.3.0 + resolution: "@shikijs/vscode-textmate@npm:9.3.0" + checksum: 10c0/6aa80798b7d7f8be8029bb397ce1b9b75c0d0963d6aa444b9ae165595ceee931cf3767ca1681ba71a6e27484eeccab584bd38db3420da477f1a8d745040b1b1f languageName: node linkType: hard -"@solana/codecs-core@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/codecs-core@npm:2.0.0-rc.0" +"@sideway/address@npm:^4.1.5": + version: 4.1.5 + resolution: "@sideway/address@npm:4.1.5" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" - peerDependencies: - typescript: ">=5" - checksum: 10c0/4a11046617e5b1c9021b6c57d17908267231303b2f8c9f62ca55ffd76702456af8b839318ef340bd1ca41cff9de353b922953fe69b1e507ddb0aef58c85d1741 + "@hapi/hoek": "npm:^9.0.0" + checksum: 10c0/638eb6f7e7dba209053dd6c8da74d7cc995e2b791b97644d0303a7dd3119263bcb7225a4f6804d4db2bc4f96e5a9d262975a014f58eae4d1753c27cbc96ef959 languageName: node linkType: hard -"@solana/codecs-core@npm:2.0.0-rc.1": - version: 2.0.0-rc.1 - resolution: "@solana/codecs-core@npm:2.0.0-rc.1" - dependencies: - "@solana/errors": "npm:2.0.0-rc.1" - peerDependencies: - typescript: ">=5" - checksum: 10c0/3b1fd09727bf850d191292b14e1afb64cda4e57f898c06483f40d0402c4f07f1d4df555f028f664701e647834c74924818857443666d039f4e44c8c01f31f427 +"@sideway/formula@npm:^3.0.1": + version: 3.0.1 + resolution: "@sideway/formula@npm:3.0.1" + checksum: 10c0/3fe81fa9662efc076bf41612b060eb9b02e846ea4bea5bd114f1662b7f1541e9dedcf98aff0d24400bcb92f113964a50e0290b86e284edbdf6346fa9b7e2bf2c languageName: node linkType: hard -"@solana/codecs-data-structures@npm:2.0.0-preview.2": - version: 2.0.0-preview.2 - resolution: "@solana/codecs-data-structures@npm:2.0.0-preview.2" - dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.2" - "@solana/codecs-numbers": "npm:2.0.0-preview.2" - "@solana/errors": "npm:2.0.0-preview.2" - checksum: 10c0/b06e1cef79305ef3328db7a641e9f8303611e173d99b47ad0934f6793d69fa876e274c9b91373c00c80166fbec74fb3439d6198c8461a6b174e0b808391825bd +"@sideway/pinpoint@npm:^2.0.0": + version: 2.0.0 + resolution: "@sideway/pinpoint@npm:2.0.0" + checksum: 10c0/d2ca75dacaf69b8fc0bb8916a204e01def3105ee44d8be16c355e5f58189eb94039e15ce831f3d544f229889ccfa35562a0ce2516179f3a7ee1bbe0b71e55b36 + languageName: node + linkType: hard + +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 10c0/ef6351ae073c45c2ac89494dbb3e1f87cc60a93ce4cde797b782812b6f97da0d620ae81973f104b43c9b7eaa789ad20ba4f6a1359f1cc62f63729a55a7d22d4e languageName: node linkType: hard -"@solana/codecs-data-structures@npm:2.0.0-preview.4": - version: 2.0.0-preview.4 - resolution: "@solana/codecs-data-structures@npm:2.0.0-preview.4" +"@sindresorhus/is@npm:^4.6.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: 10c0/33b6fb1d0834ec8dd7689ddc0e2781c2bfd8b9c4e4bacbcb14111e0ae00621f2c264b8a7d36541799d74888b5dccdf422a891a5cb5a709ace26325eedc81e22e + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^5.2.0": + version: 5.6.0 + resolution: "@sindresorhus/is@npm:5.6.0" + checksum: 10c0/66727344d0c92edde5760b5fd1f8092b717f2298a162a5f7f29e4953e001479927402d9d387e245fb9dc7d3b37c72e335e93ed5875edfc5203c53be8ecba1b52 + languageName: node + linkType: hard + +"@slorber/remark-comment@npm:^1.0.0": + version: 1.0.0 + resolution: "@slorber/remark-comment@npm:1.0.0" dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.4" - "@solana/codecs-numbers": "npm:2.0.0-preview.4" - "@solana/errors": "npm:2.0.0-preview.4" + micromark-factory-space: "npm:^1.0.0" + micromark-util-character: "npm:^1.1.0" + micromark-util-symbol: "npm:^1.0.1" + checksum: 10c0/b8da9d8f560740959c421d3ce5be43952eace1c95cb65402d9473a15e66463346a37fb5f121a6b22a83af51e8845b0b4ff3c321f14ce31bd58fb126acf6c8ed9 + languageName: node + linkType: hard + +"@solana-program/memo@npm:^0.5.0": + version: 0.5.3 + resolution: "@solana-program/memo@npm:0.5.3" peerDependencies: - typescript: ">=5" - checksum: 10c0/9274fbfe029654e6f3cf43a8e82c575c6fab406f6db6b77ee443a2288abf730c4c3c2defd479f9fc4e3d0b9a4334018ba821b4bddcd546586f99e4f778004c33 + "@solana/web3.js": 2.0.0-rc.1 + checksum: 10c0/4fb2f868841d001bdb0bf3c19d26d12fd917ce0ac4c33e3415a66038471bc04695a201b33284b14d2e4dfe0f8d40033251c3622642633ab83925f3db282ee852 languageName: node linkType: hard -"@solana/codecs-data-structures@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/codecs-data-structures@npm:2.0.0-rc.0" - dependencies: - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-numbers": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" +"@solana-program/system@npm:^0.5.0": + version: 0.5.3 + resolution: "@solana-program/system@npm:0.5.3" peerDependencies: - typescript: ">=5" - checksum: 10c0/ae3c24137e066cb57214ecdcaa790b3513afcde119146f7704fc723add8a768d9e5c032153985e7dad3f1d8f84ab9ad8dc70b800a3976b8adfffbd6f57f21c39 + "@solana/web3.js": 2.0.0-rc.1 + checksum: 10c0/9d0fde40ceb45a2913c13d83ae14d4a6a88e6e3e22fdef41066b6ed85cba8a1c33054a37ac7ffd827bfc45c5b0f91111af7e455b2c9b951b99d4e48c538d1663 languageName: node linkType: hard -"@solana/codecs-numbers@npm:2.0.0-preview.2": - version: 2.0.0-preview.2 - resolution: "@solana/codecs-numbers@npm:2.0.0-preview.2" - dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.2" - "@solana/errors": "npm:2.0.0-preview.2" - checksum: 10c0/8a2275085dd25ff106ba20d42f7769648ef3efcff5516725a69af08c48c99c2a9224de9b4a0d1ccf51bb463fc48a54b6b82853d4d8a31ba21648a2daff56c373 +"@solana-program/token-2022@npm:^0.1.0": + version: 0.1.0 + resolution: "@solana-program/token-2022@npm:0.1.0" + peerDependencies: + "@solana/web3.js": 2.0.0-rc.1 + checksum: 10c0/5a8b7eba8e4da0048ee04f77154d98d139f76a6640c9c44edd60e01d7920b46fd6f64f9817b1d1b522e4c3e95a0a8f8489e3613ab5be5c5634451493bfd93f3c languageName: node linkType: hard -"@solana/codecs-numbers@npm:2.0.0-preview.4": - version: 2.0.0-preview.4 - resolution: "@solana/codecs-numbers@npm:2.0.0-preview.4" - dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.4" - "@solana/errors": "npm:2.0.0-preview.4" +"@solana-program/token@npm:^0.2.1": + version: 0.2.1 + resolution: "@solana-program/token@npm:0.2.1" peerDependencies: - typescript: ">=5" - checksum: 10c0/02ea792e055f6c798ca140d00d429e0ae6d37b9b42ff3ad950dba98666e18324eeaabd13cdcc584c64a21b10ef3706aaeb23691ba53520dba462fbc071bd63aa + "@solana/web3.js": 2.0.0-preview.4 + checksum: 10c0/5ebc58bf5f9626a8247ab66a474190215c7e3300f5441fc053832dc959a48ebca040f390fdacfa552b2ef2b2bed85ee574639be9e69c8c89c8e9130e68125ef4 languageName: node linkType: hard -"@solana/codecs-numbers@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/codecs-numbers@npm:2.0.0-rc.0" +"@solana/accounts@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/accounts@npm:2.0.0-rc.1" dependencies: - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/rpc-spec": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/53512bc11a1c7a5bb097f97e9062217948d7789d8483a494e943ab6c2d7699c57ef48f2bd34175f9e97acdabf94af09db13e6bb732ccc8f4156bedec14ba1e1a + checksum: 10c0/07ab0a10ce46ce82a6bd80726de221850be0828e8c493247907903fdc6a27dbee8c3f937913718dc1457f7f13c06ebe77b8e53a45b961a8ffd0a03ae751253d5 languageName: node linkType: hard -"@solana/codecs-numbers@npm:2.0.0-rc.1": +"@solana/addresses@npm:2.0.0-rc.1": version: 2.0.0-rc.1 - resolution: "@solana/codecs-numbers@npm:2.0.0-rc.1" + resolution: "@solana/addresses@npm:2.0.0-rc.1" dependencies: + "@solana/assertions": "npm:2.0.0-rc.1" "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/baf888bbd9c9ed2420207329c735def60a2b3d94d4a0dd1a92703f4de165a96dfd5b66e4fe954d6a7fae12b6b95c41da500499f100b6d5cfad6420d4bfe71b50 + checksum: 10c0/3aabe755fd7fb7dee2edfd73faa15f83d97860d4f852bdbf6f90bec08909b4df7f623b1f714ff6951b05b01ed091bbffb7b68a76da0ccea238047b0610efe084 languageName: node linkType: hard -"@solana/codecs-strings@npm:2.0.0-preview.2": - version: 2.0.0-preview.2 - resolution: "@solana/codecs-strings@npm:2.0.0-preview.2" +"@solana/assertions@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/assertions@npm:2.0.0-rc.1" dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.2" - "@solana/codecs-numbers": "npm:2.0.0-preview.2" - "@solana/errors": "npm:2.0.0-preview.2" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - checksum: 10c0/76f741de87bb8b95912467981fe3263d10cc12c3ba66f31d60c28474de57170b7ba0d0f1f6ee9ce6902a137433787a6fc72395ce451a08809207e4d85a621729 + typescript: ">=5" + checksum: 10c0/2c9b6881e80671813a58723441c4aee325255017602e1195f48bc9ba4b609da965b51e56835eb5897a7d1978a4e09749eb4a2aafddcf2b47a5bf949f4d906ac7 languageName: node linkType: hard -"@solana/codecs-strings@npm:2.0.0-preview.4": - version: 2.0.0-preview.4 - resolution: "@solana/codecs-strings@npm:2.0.0-preview.4" +"@solana/buffer-layout-utils@npm:^0.2.0": + version: 0.2.0 + resolution: "@solana/buffer-layout-utils@npm:0.2.0" dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.4" - "@solana/codecs-numbers": "npm:2.0.0-preview.4" - "@solana/errors": "npm:2.0.0-preview.4" - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: ">=5" - checksum: 10c0/c1db4d3d2989390461ddf5ae3a08ac25b2b520290565b46469db1fade0600aea4adf501f3c683ef46baabc25cdd9f4e857b267e0cde91f6de4417efc9b0b9ce3 + "@solana/buffer-layout": "npm:^4.0.0" + "@solana/web3.js": "npm:^1.32.0" + bigint-buffer: "npm:^1.1.5" + bignumber.js: "npm:^9.0.1" + checksum: 10c0/ed093999d7c0f93527a9b261a9a2a59e10b5ef78fc416fa896b86036fb4dadf923d17db68bffdc3e91eadecdb8b8cddd8ee37f12429980fcaba321e7b8a35d27 languageName: node linkType: hard -"@solana/codecs-strings@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/codecs-strings@npm:2.0.0-rc.0" +"@solana/buffer-layout@npm:^4.0.0, @solana/buffer-layout@npm:^4.0.1": + version: 4.0.1 + resolution: "@solana/buffer-layout@npm:4.0.1" dependencies: - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-numbers": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: ">=5" - checksum: 10c0/b5ac5f013a2605ed948e7f3acc550885b9706ebb775bf14c119be2f7cf5913ce4a617756309e424b12aa8c26932a641b3854282f598f47c4ec259cfc288dd343 + buffer: "npm:~6.0.3" + checksum: 10c0/6535f3908cf6dfc405b665795f0c2eaa0482a8c6b1811403945cf7b450e7eb7b40acce3e8af046f2fcc3eea1a15e61d48c418315d813bee4b720d56b00053305 languageName: node linkType: hard -"@solana/codecs-strings@npm:rc": +"@solana/codecs-core@npm:2.0.0-rc.1": version: 2.0.0-rc.1 - resolution: "@solana/codecs-strings@npm:2.0.0-rc.1" + resolution: "@solana/codecs-core@npm:2.0.0-rc.1" dependencies: - "@solana/codecs-core": "npm:2.0.0-rc.1" - "@solana/codecs-numbers": "npm:2.0.0-rc.1" "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 typescript: ">=5" - checksum: 10c0/7f3483407de7e324075a85f2f8c91103021d6b8f38cfd4cf78603cbd7b00ea8b828a0cb9b61fb2b0db6d3e733fdf358006de23278cf3b103af1f1de4f3f66233 - languageName: node - linkType: hard - -"@solana/codecs@npm:2.0.0-preview.2": - version: 2.0.0-preview.2 - resolution: "@solana/codecs@npm:2.0.0-preview.2" - dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.2" - "@solana/codecs-data-structures": "npm:2.0.0-preview.2" - "@solana/codecs-numbers": "npm:2.0.0-preview.2" - "@solana/codecs-strings": "npm:2.0.0-preview.2" - "@solana/options": "npm:2.0.0-preview.2" - checksum: 10c0/50f8177c042b1a34c83b66ecd0ff67cb0713dc3c4fbac6988d14224ee784d25d626a791eec74a77b60a83be0b5b708832c09067bcee9bad2eede19a0b77c6a82 + checksum: 10c0/3b1fd09727bf850d191292b14e1afb64cda4e57f898c06483f40d0402c4f07f1d4df555f028f664701e647834c74924818857443666d039f4e44c8c01f31f427 languageName: node linkType: hard -"@solana/codecs@npm:2.0.0-preview.4": - version: 2.0.0-preview.4 - resolution: "@solana/codecs@npm:2.0.0-preview.4" +"@solana/codecs-data-structures@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/codecs-data-structures@npm:2.0.0-rc.1" dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.4" - "@solana/codecs-data-structures": "npm:2.0.0-preview.4" - "@solana/codecs-numbers": "npm:2.0.0-preview.4" - "@solana/codecs-strings": "npm:2.0.0-preview.4" - "@solana/options": "npm:2.0.0-preview.4" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-numbers": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/49a736614a6a4b9747cd040bd61537cbdd58940ed4cdb509d601a1dd05f33f6407bc7d3d8b894962b4a47c59df561098ce50cf2303620b7bc69fe458266ea5c7 + checksum: 10c0/e22dd6369917dbfe5e540045b94007bfe27c240651ff6063558b0c5c82a06e7b1fa2a95aaba51e6210702d1c462d4dde198c3c00c4b3211360606ca36131965e languageName: node linkType: hard -"@solana/codecs@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/codecs@npm:2.0.0-rc.0" +"@solana/codecs-numbers@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/codecs-numbers@npm:2.0.0-rc.1" dependencies: - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-data-structures": "npm:2.0.0-rc.0" - "@solana/codecs-numbers": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/options": "npm:2.0.0-rc.0" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/9826fdc8e6c3d2829223fa939161859bbe3b8a70dab18f292239ce5910329ac96e466a8379739d0faad6884b15ad10a4c9c59ba087d253376f5c1f3674cd6ff5 - languageName: node - linkType: hard - -"@solana/errors@npm:2.0.0-preview.2": - version: 2.0.0-preview.2 - resolution: "@solana/errors@npm:2.0.0-preview.2" - dependencies: - chalk: "npm:^5.3.0" - commander: "npm:^12.0.0" - bin: - errors: bin/cli.js - checksum: 10c0/5f71ef1306e3c4c858854e5b29750c200c0e49bb9a3e4e2633dd9daa40dc92a940e39e23423b936b110e2bdca092fac546983cde9145a1ad97601ac4d4fdb211 + checksum: 10c0/baf888bbd9c9ed2420207329c735def60a2b3d94d4a0dd1a92703f4de165a96dfd5b66e4fe954d6a7fae12b6b95c41da500499f100b6d5cfad6420d4bfe71b50 languageName: node linkType: hard -"@solana/errors@npm:2.0.0-preview.4": - version: 2.0.0-preview.4 - resolution: "@solana/errors@npm:2.0.0-preview.4" +"@solana/codecs-strings@npm:2.0.0-rc.1, @solana/codecs-strings@npm:rc": + version: 2.0.0-rc.1 + resolution: "@solana/codecs-strings@npm:2.0.0-rc.1" dependencies: - chalk: "npm:^5.3.0" - commander: "npm:^12.1.0" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-numbers": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 typescript: ">=5" - bin: - errors: bin/cli.mjs - checksum: 10c0/457a4e35a8a28c1ad7fc75cf1fde6159b920cebce9c6c46af54b001ccecae9c1f366703de9cad238e784a2b76ae180f0b7c9c63d2f7c972d67cd8165960fdae9 + checksum: 10c0/7f3483407de7e324075a85f2f8c91103021d6b8f38cfd4cf78603cbd7b00ea8b828a0cb9b61fb2b0db6d3e733fdf358006de23278cf3b103af1f1de4f3f66233 languageName: node linkType: hard -"@solana/errors@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/errors@npm:2.0.0-rc.0" +"@solana/codecs@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/codecs@npm:2.0.0-rc.1" dependencies: - chalk: "npm:^5.3.0" - commander: "npm:^12.1.0" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-data-structures": "npm:2.0.0-rc.1" + "@solana/codecs-numbers": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" + "@solana/options": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - bin: - errors: bin/cli.mjs - checksum: 10c0/387d4def12a3254cef21269a3eb32d4e322a878b233d2bb15293cec3ff8b2538299dc1a7a7d6f773f7f402e05d98c1c020a98686976106267730c39390cee542 + checksum: 10c0/5f4a30b1fed60c9442ab73cbe413fe528e5b316f602eb745b0de84a9622ceb8af9e7a7a9f8e2f5d730280858f9e4e0ab861729311c0aa55cc253427707815ef2 languageName: node linkType: hard @@ -3556,414 +3666,389 @@ __metadata: languageName: node linkType: hard -"@solana/fast-stable-stringify@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/fast-stable-stringify@npm:2.0.0-rc.0" +"@solana/fast-stable-stringify@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/fast-stable-stringify@npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/6e8ff881fe0fc12020dbcda35219fb8bbc407803e6acb8bad6b4f44c782f7ab124e883164896afbc712b923ee7f09700becb06974e3e3d91343992c642c3f298 + checksum: 10c0/8c18da5d7657dc1219e7b533bc7cc07ea16d84a7a5b4a4b375d38e4792281fe1bcdad03db9d8d4698c8e5ba5f12aa6bdc1b87a6a6248209a748d1c0cd0fe2e3f languageName: node linkType: hard -"@solana/functional@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/functional@npm:2.0.0-rc.0" +"@solana/functional@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/functional@npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/4498e8ba2ac4d77fb8f34e144ac72572e0f72d81a32c7c0f307d5ad49863719f190c3ccd9b15eb4f8df0738abaf0503985329ca47659c0f5b7660961f17152b2 + checksum: 10c0/e2f251287f9752f34bfa1fdd6fb1fc9ae698fc6160493e52fb1803d9a51c939831d08cf18f5401ce4d54a9dacaf05aa282381bd3c48ab8dacafac5eda2a9ac59 languageName: node linkType: hard -"@solana/instructions@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/instructions@npm:2.0.0-rc.0" +"@solana/instructions@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/instructions@npm:2.0.0-rc.1" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/6e411df8ba0c26a9457456d4139a6573b810a073e09f7ad28fbb2b63f06470189dfc17a264455e66ee15b810b299b8ed9cc4cd4d02460a3c261bc9c5b34d151e + checksum: 10c0/63ff54721433fcaabbd7ff8e99fb47681e4c54f68912d93cbca761122d067e8a621a380993e19c52f0e7858a9ef819db4a8948c1fd7afffd80a241cc6488c17e languageName: node linkType: hard -"@solana/keys@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/keys@npm:2.0.0-rc.0" +"@solana/keys@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/keys@npm:2.0.0-rc.1" dependencies: - "@solana/assertions": "npm:2.0.0-rc.0" - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" + "@solana/assertions": "npm:2.0.0-rc.1" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/b490ae6b7049aca71fd2a8ce0bcfa27c122f06580d2e66d017f4ed40cf9261c501819510293fe61704f3dbe4e02bc0e8216c94eb5a2dae1de156edca2d992cba - languageName: node - linkType: hard - -"@solana/options@npm:2.0.0-preview.2": - version: 2.0.0-preview.2 - resolution: "@solana/options@npm:2.0.0-preview.2" - dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.2" - "@solana/codecs-numbers": "npm:2.0.0-preview.2" - checksum: 10c0/e749161b042145d826d6bc1874e37b2fda725e737dd010c696fe1d7300a93eb48a80c2d2376361cd658ee04b4398194fdfa16e858c39ad737337491a8a71e095 + checksum: 10c0/e69a1b32b0043c67cb8b21b82aff953d1d43d11a03d4e2533ed68184a7ac3a3d982d0760e0a4a7659331f89090db08633f335643fad17937c4ad33152f3c80d3 languageName: node linkType: hard -"@solana/options@npm:2.0.0-preview.4": - version: 2.0.0-preview.4 - resolution: "@solana/options@npm:2.0.0-preview.4" +"@solana/options@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/options@npm:2.0.0-rc.1" dependencies: - "@solana/codecs-core": "npm:2.0.0-preview.4" - "@solana/codecs-data-structures": "npm:2.0.0-preview.4" - "@solana/codecs-numbers": "npm:2.0.0-preview.4" - "@solana/codecs-strings": "npm:2.0.0-preview.4" - "@solana/errors": "npm:2.0.0-preview.4" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-data-structures": "npm:2.0.0-rc.1" + "@solana/codecs-numbers": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/c2b802ee449af09231ad38fff48f21c7dd8bc747415451575c8fded3d91c58cafac61829d3d215d19423e212235ab3ad98efeb96bcfbe3587e3181ccd389cd81 + checksum: 10c0/967dc01c12b0433412a74cb498262f7d0bdf4c3b002936d8f5761bcb189929c35fe0b32c2f793796a975366e2c1245dd34c1818e4f44f483932fdfa3fde4f3e9 languageName: node linkType: hard -"@solana/options@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/options@npm:2.0.0-rc.0" +"@solana/programs@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/programs@npm:2.0.0-rc.1" dependencies: - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-data-structures": "npm:2.0.0-rc.0" - "@solana/codecs-numbers": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/169714af2ac8ca453bc694eea48567ed160ab73e59d9b48de8bbb77dd8bcfcc393e92f4af3d3e8efbbca7dffb813bbcb7985651f0941791aa529641abc98ccb6 + checksum: 10c0/8b35c592ff352f7f0abea75936c69950d29d8ff2282fb99fee0a48c5d3acdbb3759504d8b8c1dadd9a1d2814b782d6d4c65f9d547b8eecc0e46cf96e0887d95a languageName: node linkType: hard -"@solana/programs@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/programs@npm:2.0.0-rc.0" - dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" +"@solana/promises@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/promises@npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/a769fbe25c25f46c2afae2d5f4dbc05dfc4d0d49bf9cddb2ebd8e5eb3b075cc09d5244c9d82112ecf8e8c11961a2414d68a86b8f4d2a225f38d23efb5c0941b5 + checksum: 10c0/37b5f0bcc0a71a6ad00e31320fff51c0d3c54a868a9360139467d0e2a894b5a65d916e4c68b1305eaff8c8d3b1045eeb1c4e04eafe6ee7772de01251c826de97 languageName: node linkType: hard -"@solana/rpc-api@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-api@npm:2.0.0-rc.0" +"@solana/rpc-api@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-api@npm:2.0.0-rc.1" dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/keys": "npm:2.0.0-rc.0" - "@solana/rpc-parsed-types": "npm:2.0.0-rc.0" - "@solana/rpc-spec": "npm:2.0.0-rc.0" - "@solana/rpc-transformers": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" - "@solana/transaction-messages": "npm:2.0.0-rc.0" - "@solana/transactions": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/keys": "npm:2.0.0-rc.1" + "@solana/rpc-parsed-types": "npm:2.0.0-rc.1" + "@solana/rpc-spec": "npm:2.0.0-rc.1" + "@solana/rpc-transformers": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" + "@solana/transaction-messages": "npm:2.0.0-rc.1" + "@solana/transactions": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/ebaa915c24afc17d228ae07a0e90835e1b1cd1740545285522593af5ec909d7086ede0713110590dd24b3f7b93dc154061d30439843e3beb053ec8c3f306bdbb + checksum: 10c0/c3aaf2a116a3cacf5e813d5179dec4e53f1aaf472debf36f1b42d0fa241a890ae342b2cbc898354bb41440885b2a76ad58454072638648e4de769462e0414710 languageName: node linkType: hard -"@solana/rpc-parsed-types@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-parsed-types@npm:2.0.0-rc.0" +"@solana/rpc-parsed-types@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-parsed-types@npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/3f8154bd4385df2b04e9e1d777a43941f8ac72b6664b0ec3dd755b79a18b5ca7131d62a5eba06470dbdd087acd0fd5a6e6d10beb1e35460ed8027262fe1424de + checksum: 10c0/455b947db4255e932121926f3f8162cfcd4ec754bdbd534a4c68737c1fe7449de6ca9f4ff812eaf356819a4061fbdfafd0a917cb3d4f54aa3d140f79613d77ae languageName: node linkType: hard -"@solana/rpc-spec-types@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-spec-types@npm:2.0.0-rc.0" +"@solana/rpc-spec-types@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-spec-types@npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/f5441ee0342aadccebb0cd6acaf55930eabdb44ed25e7a6e75e46817bdb9e14c6c57f4a62d66369fee25a8df88da85de53cb2c6bfbd8a9be83c59fa8ccd3d0d2 + checksum: 10c0/21dec7ef60371c0c0fc00dfb45bb9819645e954cb265c28425f52c31cc5e826fd09fb81d723992125ce54d0aa75c9dd701109bafad7c795ebfce66f4916c7a23 languageName: node linkType: hard -"@solana/rpc-spec@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-spec@npm:2.0.0-rc.0" +"@solana/rpc-spec@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-spec@npm:2.0.0-rc.1" dependencies: - "@solana/rpc-spec-types": "npm:2.0.0-rc.0" + "@solana/rpc-spec-types": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/82847390cde9cbd1c013eef5c50b841850830f44418acb71c9944d7e112eadc543b34ad35ab273ff69637393bad9e345be7b6e0c3f0b45eb454fc3f48ab17a5c + checksum: 10c0/83ff066722274dd28698ac345c80903795582e4fe3053a846dac77da4b89b87a4c6e0c9ee6f56282bef4ca4e8f80c2eca1c41c77abf128cdcb02f24cf04bff90 languageName: node linkType: hard -"@solana/rpc-subscriptions-api@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-subscriptions-api@npm:2.0.0-rc.0" +"@solana/rpc-subscriptions-api@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-subscriptions-api@npm:2.0.0-rc.1" dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/keys": "npm:2.0.0-rc.0" - "@solana/rpc-subscriptions-spec": "npm:2.0.0-rc.0" - "@solana/rpc-transformers": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" - "@solana/transaction-messages": "npm:2.0.0-rc.0" - "@solana/transactions": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/keys": "npm:2.0.0-rc.1" + "@solana/rpc-subscriptions-spec": "npm:2.0.0-rc.1" + "@solana/rpc-transformers": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" + "@solana/transaction-messages": "npm:2.0.0-rc.1" + "@solana/transactions": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/cd2c69ea489b07578d8373e9de1b19a9de7251db8f670f31a9a5c573875e339a1cdc4d11d891ba5d09830e5eed59d732344460d2012d278b882f50ae9d9e15ae + checksum: 10c0/a6b8a25ba4dc5c9f42cf0eb961b83921023cf8851b324d7cad65a4289918434af19fe72ee9b74f5ffa83ac5f5361b588dad72d0c68cb309c2df715b19f74dc9c languageName: node linkType: hard -"@solana/rpc-subscriptions-spec@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-subscriptions-spec@npm:2.0.0-rc.0" +"@solana/rpc-subscriptions-spec@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-subscriptions-spec@npm:2.0.0-rc.1" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/rpc-spec-types": "npm:2.0.0-rc.0" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/rpc-spec-types": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/70cd27d7b9c042a5fb375b8fd04bb19d7fc54412b1e72758cc98a69c01c7dbbcda64478fa0981bf1778ee42ae7c2e616a3506518081ac268eedd81e5d1774dea + checksum: 10c0/b7cd94528c5a24c32cab0a88991cbd8261975359b2c1465c8d0ce715b08314d7c455d223246654562d55d9181bda4fc47554f5b1f4233faa304367922f57eae8 languageName: node linkType: hard -"@solana/rpc-subscriptions-transport-websocket@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-subscriptions-transport-websocket@npm:2.0.0-rc.0" +"@solana/rpc-subscriptions-transport-websocket@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-subscriptions-transport-websocket@npm:2.0.0-rc.1" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/rpc-subscriptions-spec": "npm:2.0.0-rc.0" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/rpc-subscriptions-spec": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" ws: ^8.14.0 - checksum: 10c0/35ec23f0cc7502bd08ec4e868cdd3bce456fb800cd62236718195d8deb325c03343eab678894d661b093c52965f384c4c0d6aca927d5fbf263bd256a7734da2d + checksum: 10c0/53bba18581c777065b219ca1ceeb7e1615e6c48ee84c3c5f12db067971a32ab8a9d6bdafde8fb7b752abe3e600670f804698b59fcb920f995b1134b353def780 languageName: node linkType: hard -"@solana/rpc-subscriptions@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-subscriptions@npm:2.0.0-rc.0" +"@solana/rpc-subscriptions@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-subscriptions@npm:2.0.0-rc.1" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/fast-stable-stringify": "npm:2.0.0-rc.0" - "@solana/functional": "npm:2.0.0-rc.0" - "@solana/rpc-subscriptions-api": "npm:2.0.0-rc.0" - "@solana/rpc-subscriptions-spec": "npm:2.0.0-rc.0" - "@solana/rpc-subscriptions-transport-websocket": "npm:2.0.0-rc.0" - "@solana/rpc-transformers": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/fast-stable-stringify": "npm:2.0.0-rc.1" + "@solana/functional": "npm:2.0.0-rc.1" + "@solana/promises": "npm:2.0.0-rc.1" + "@solana/rpc-subscriptions-api": "npm:2.0.0-rc.1" + "@solana/rpc-subscriptions-spec": "npm:2.0.0-rc.1" + "@solana/rpc-subscriptions-transport-websocket": "npm:2.0.0-rc.1" + "@solana/rpc-transformers": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/33f2d96315005218440524a5f219de3c73813dcd48e4cd92c1b7aecd377ddb564ac028685fd7d1b6aeb5b020cdc77373645ef0ebc7916efb06eef5b6f984867c + checksum: 10c0/84f40a79919277ec80b98d584c87c6c9e7e4eaed1c5c6aed2ecb06dfe21f5020289f10d2f445c1fe9aba4fb9b5fd4ad1b7327f8a24b9a676bb4d17d19b6645b6 languageName: node linkType: hard -"@solana/rpc-transformers@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-transformers@npm:2.0.0-rc.0" +"@solana/rpc-transformers@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-transformers@npm:2.0.0-rc.1" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/functional": "npm:2.0.0-rc.0" - "@solana/rpc-spec": "npm:2.0.0-rc.0" - "@solana/rpc-subscriptions-spec": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/functional": "npm:2.0.0-rc.1" + "@solana/rpc-spec": "npm:2.0.0-rc.1" + "@solana/rpc-subscriptions-spec": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/1603722234eb744e2dbde03196542a0a8cddb2c8a9ebb88be1d24f9f65144fd637c305ab4161c491943fdc58e3e8a39b924957f826d5c8901bbb26d59c0376cb + checksum: 10c0/cb9b70504ad339dab0f285999c2a933dd96b2408f381a0bfdb20be7327791475114c6731cb09b1ef7c92b7add35af36289d69cda5c67000b59169da09a10fe13 languageName: node linkType: hard -"@solana/rpc-transport-http@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-transport-http@npm:2.0.0-rc.0" +"@solana/rpc-transport-http@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-transport-http@npm:2.0.0-rc.1" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/rpc-spec": "npm:2.0.0-rc.0" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/rpc-spec": "npm:2.0.0-rc.1" undici-types: "npm:^6.19.5" peerDependencies: typescript: ">=5" - checksum: 10c0/06d2c26436cef817d772f8ec0b26c91c3878bf80c25b2793aebb3aa04861c07838811f1c3041370c4133774a63be05eba927afe964afcfce77301447334cfccf + checksum: 10c0/b6147cae062cef8e19107b6ccb29c601fdb78378b16d2ac6dbafe6f9e7823fb3072cea7e0672dad1c5a0d28f667f33b3fd1944e3b097fa4a943f0c8d55854028 languageName: node linkType: hard -"@solana/rpc-types@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc-types@npm:2.0.0-rc.0" +"@solana/rpc-types@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc-types@npm:2.0.0-rc.1" dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-numbers": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-numbers": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/17c81cb7a9363384be44ceb64679746e8ee9da177a990a29ee2d5348e018b9d1fb98995a138171cbe9a7e92f7ca9d4f1573d35544781d8218814ec1831735651 + checksum: 10c0/a32a59e13452eaeb01a5f0f248a37492911d0c035f3e6bc37bfcae82243f1f5d3c61d34e224f2e63196832b31c658bcac4c960979571fbc427e6ba604e8221b6 languageName: node linkType: hard -"@solana/rpc@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/rpc@npm:2.0.0-rc.0" +"@solana/rpc@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/rpc@npm:2.0.0-rc.1" dependencies: - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/fast-stable-stringify": "npm:2.0.0-rc.0" - "@solana/functional": "npm:2.0.0-rc.0" - "@solana/rpc-api": "npm:2.0.0-rc.0" - "@solana/rpc-spec": "npm:2.0.0-rc.0" - "@solana/rpc-transformers": "npm:2.0.0-rc.0" - "@solana/rpc-transport-http": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/fast-stable-stringify": "npm:2.0.0-rc.1" + "@solana/functional": "npm:2.0.0-rc.1" + "@solana/rpc-api": "npm:2.0.0-rc.1" + "@solana/rpc-spec": "npm:2.0.0-rc.1" + "@solana/rpc-transformers": "npm:2.0.0-rc.1" + "@solana/rpc-transport-http": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/306077bcf6ac285f6aa2faafd2bec1a2bb9377082548783b1574450bd738213364d2706da0d6bb7dee1f6beb226f7738b0a5d8a17a10633b523eb4195fdf9157 + checksum: 10c0/2b9d4c05ddbe61c9070a784aeda846f6fa5f4e385dd857b0954e2019bb1a94889a989dba7c683c3e7eaca75c7da1535c17c4da87c7040b181caf9a5fcfaabeb6 languageName: node linkType: hard -"@solana/signers@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/signers@npm:2.0.0-rc.0" +"@solana/signers@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/signers@npm:2.0.0-rc.1" dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/instructions": "npm:2.0.0-rc.0" - "@solana/keys": "npm:2.0.0-rc.0" - "@solana/transaction-messages": "npm:2.0.0-rc.0" - "@solana/transactions": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/instructions": "npm:2.0.0-rc.1" + "@solana/keys": "npm:2.0.0-rc.1" + "@solana/transaction-messages": "npm:2.0.0-rc.1" + "@solana/transactions": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/a28bc82d53e822452f1b48a13673f18d21f37f0a19c4cbe0bc865e0c692f7f22b13bc953e520b98a7b1312b9cd42bfefd0cf82076ed1d8779759040a3ef02f2d + checksum: 10c0/1959c59c3b616aa679690f381ecc46eb83cb902ec2a0c50e9fc6349d438cd1a8840b14c4288609edb74123e04e9587d00b7b8c3c31fec3a6a95f947d819e552f languageName: node linkType: hard -"@solana/spl-token-group@npm:^0.0.5": - version: 0.0.5 - resolution: "@solana/spl-token-group@npm:0.0.5" +"@solana/spl-token-group@npm:^0.0.7": + version: 0.0.7 + resolution: "@solana/spl-token-group@npm:0.0.7" dependencies: - "@solana/codecs": "npm:2.0.0-preview.4" - "@solana/spl-type-length-value": "npm:0.1.0" + "@solana/codecs": "npm:2.0.0-rc.1" peerDependencies: - "@solana/web3.js": ^1.94.0 - checksum: 10c0/f7140e21165c24f8ab5d7d74138c5d776b96f1f56f0652e641bb94aac2c4f4ba2f7b48c74fe754f962c27a652ecdf6e0be12491ace99116859330a71454b653b + "@solana/web3.js": ^1.95.3 + checksum: 10c0/e1ebeb30c4dd3c179ee9d4bf02635c0ca3daea18526a25c824eb4db8882db768563f20813ac600a41fe153892ce66c0c7538e2639f530945940477edddfa731f languageName: node linkType: hard -"@solana/spl-token-metadata@npm:^0.1.3": - version: 0.1.4 - resolution: "@solana/spl-token-metadata@npm:0.1.4" +"@solana/spl-token-metadata@npm:^0.1.6": + version: 0.1.6 + resolution: "@solana/spl-token-metadata@npm:0.1.6" dependencies: - "@solana/codecs": "npm:2.0.0-preview.2" - "@solana/spl-type-length-value": "npm:0.1.0" + "@solana/codecs": "npm:2.0.0-rc.1" peerDependencies: - "@solana/web3.js": ^1.91.6 - checksum: 10c0/d2f27b944e26bff2353c362aee0b61b2d030d4df02332898e96d109c2408721e4c652f30dfe1b77a2f6ec72112137e5c79fcda55ec92405d8ead9aa23159a623 + "@solana/web3.js": ^1.95.3 + checksum: 10c0/a2ea535ac28cf9b8f499c2e2aced7ce9134b0728a0c1d4c8f2dfce8fe01ae66d94ccaca8f1f677c9613d3dbc913845c29df785efeafc25d9398e830fba4a626f languageName: node linkType: hard "@solana/spl-token@npm:^0.4.8": - version: 0.4.8 - resolution: "@solana/spl-token@npm:0.4.8" + version: 0.4.9 + resolution: "@solana/spl-token@npm:0.4.9" dependencies: "@solana/buffer-layout": "npm:^4.0.0" "@solana/buffer-layout-utils": "npm:^0.2.0" - "@solana/spl-token-group": "npm:^0.0.5" - "@solana/spl-token-metadata": "npm:^0.1.3" + "@solana/spl-token-group": "npm:^0.0.7" + "@solana/spl-token-metadata": "npm:^0.1.6" buffer: "npm:^6.0.3" peerDependencies: - "@solana/web3.js": ^1.94.0 - checksum: 10c0/6570a439d93544b9822fc67fd94b443a465ddd2be9683937fe67deea6a71b72c04b80da5a895abfbb2e276dac83ae0401c990e7a4fdf7cf01168288b7345da55 - languageName: node - linkType: hard - -"@solana/spl-type-length-value@npm:0.1.0": - version: 0.1.0 - resolution: "@solana/spl-type-length-value@npm:0.1.0" - dependencies: - buffer: "npm:^6.0.3" - checksum: 10c0/a8f2fd6308dffa27827799146857a778ff807380578e187023f8fe90ebf8a68ed1f9f74a0c196cde7b757ea188ff2af040a727c18bb3c86a82f62fe3ec4c43bb + "@solana/web3.js": ^1.95.3 + checksum: 10c0/66f22a026fbc34a5e28391fc75c9a902e852fadf6538d18464b4f036d95d75ecccb2d96f07cbebdc6cb530558566c4296e613761969431fef549ec10e8d4024f languageName: node linkType: hard -"@solana/sysvars@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/sysvars@npm:2.0.0-rc.0" +"@solana/sysvars@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/sysvars@npm:2.0.0-rc.1" dependencies: - "@solana/accounts": "npm:2.0.0-rc.0" - "@solana/codecs": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" + "@solana/accounts": "npm:2.0.0-rc.1" + "@solana/codecs": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/9e3eaf1ff92e8bd558ccfdf46f27f876689785237a61f2a1617f85c6bdb1f391c927144886a8d78502c7d73e44dba226e1322beabb7566a24f9cc485b1a27279 + checksum: 10c0/a7f405ecfe822851c64d6c03d6a139f426170f35b36b870a092e0cd1aa360a81b0fb64a9e07510dc781858744070a4f110f95328cac9f7305706438580922d51 languageName: node linkType: hard -"@solana/transaction-confirmation@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/transaction-confirmation@npm:2.0.0-rc.0" +"@solana/transaction-confirmation@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/transaction-confirmation@npm:2.0.0-rc.1" dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/keys": "npm:2.0.0-rc.0" - "@solana/rpc": "npm:2.0.0-rc.0" - "@solana/rpc-subscriptions": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" - "@solana/transaction-messages": "npm:2.0.0-rc.0" - "@solana/transactions": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/keys": "npm:2.0.0-rc.1" + "@solana/promises": "npm:2.0.0-rc.1" + "@solana/rpc": "npm:2.0.0-rc.1" + "@solana/rpc-subscriptions": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" + "@solana/transaction-messages": "npm:2.0.0-rc.1" + "@solana/transactions": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/50dda209118dc7b04a5d98f1390ecdf02e2cb51b1b90af4f72e2b9e1fe93f0136542d39bcb7280fb96b5feac74256b372543fa9efeaa866ce6f94cd2a7d313ca + checksum: 10c0/40c4d70867f350de64867540b0b4dce0b42347245b5b6e4146c8e6a447b1b11815a33b3665224b2ff0540bfb996c0025ae1b932210af60ac46e2df4ccaa806db languageName: node linkType: hard -"@solana/transaction-messages@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/transaction-messages@npm:2.0.0-rc.0" +"@solana/transaction-messages@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/transaction-messages@npm:2.0.0-rc.1" dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-data-structures": "npm:2.0.0-rc.0" - "@solana/codecs-numbers": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/functional": "npm:2.0.0-rc.0" - "@solana/instructions": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-data-structures": "npm:2.0.0-rc.1" + "@solana/codecs-numbers": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/functional": "npm:2.0.0-rc.1" + "@solana/instructions": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/df58624cd704177da6e38fffe512c04dec70335e7bde1a811f6444c9bc3b5d692ffae1f417df401b50b01fade0a9b33f82492eb316688b87cba782d9e9625b4c + checksum: 10c0/3db2fcbde33037a4b6f4e6e896d76ac36eb33958f77b6983fcdcdb3352053dc915b6e2c171a1e5911e5a4c91fbc28a9a90225a03a144bd4020bcf53c168d050d languageName: node linkType: hard -"@solana/transactions@npm:2.0.0-rc.0": - version: 2.0.0-rc.0 - resolution: "@solana/transactions@npm:2.0.0-rc.0" +"@solana/transactions@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/transactions@npm:2.0.0-rc.1" dependencies: - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/codecs-core": "npm:2.0.0-rc.0" - "@solana/codecs-data-structures": "npm:2.0.0-rc.0" - "@solana/codecs-numbers": "npm:2.0.0-rc.0" - "@solana/codecs-strings": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/functional": "npm:2.0.0-rc.0" - "@solana/instructions": "npm:2.0.0-rc.0" - "@solana/keys": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" - "@solana/transaction-messages": "npm:2.0.0-rc.0" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/codecs-core": "npm:2.0.0-rc.1" + "@solana/codecs-data-structures": "npm:2.0.0-rc.1" + "@solana/codecs-numbers": "npm:2.0.0-rc.1" + "@solana/codecs-strings": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/functional": "npm:2.0.0-rc.1" + "@solana/instructions": "npm:2.0.0-rc.1" + "@solana/keys": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" + "@solana/transaction-messages": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/5a1274bec1bb033bbac5f30af90603d267b145f860b80be75a3344dd4fb8b5f171c4eb76a1d87152b16ce2e93e2c4c340141f8b4c1fa660b031269e9718c42c9 + checksum: 10c0/dc99c1bc263f2317e721f20cd0c237e606cb9bfbfe88e7c0c3af0f7ccc8c1262f8a938c5833535536fc53ed47426114fef9b4d675ee0143ce7adffe534d4c750 languageName: node linkType: hard "@solana/web3.js@npm:^1.32.0, @solana/web3.js@npm:^1.68.0, @solana/web3.js@npm:^1.90.0, @solana/web3.js@npm:^1.95.2": - version: 1.95.2 - resolution: "@solana/web3.js@npm:1.95.2" + version: 1.95.4 + resolution: "@solana/web3.js@npm:1.95.4" dependencies: - "@babel/runtime": "npm:^7.24.8" + "@babel/runtime": "npm:^7.25.0" "@noble/curves": "npm:^1.4.2" "@noble/hashes": "npm:^1.4.0" "@solana/buffer-layout": "npm:^4.0.1" @@ -3978,34 +4063,34 @@ __metadata: node-fetch: "npm:^2.7.0" rpc-websockets: "npm:^9.0.2" superstruct: "npm:^2.0.2" - checksum: 10c0/cb43f9657b9ff00392c9e4d6168ed5cf4b0a1f8add0cb944e1153f4d3607ec46bffc9601eae84cf9f5231fcc553b5d7ddb98c186365b6ac2ca0cc9c8991c2605 - languageName: node - linkType: hard - -"@solana/web3.js@npm:^2.0.0-preview.4": - version: 2.0.0-rc.0 - resolution: "@solana/web3.js@npm:2.0.0-rc.0" - dependencies: - "@solana/accounts": "npm:2.0.0-rc.0" - "@solana/addresses": "npm:2.0.0-rc.0" - "@solana/codecs": "npm:2.0.0-rc.0" - "@solana/errors": "npm:2.0.0-rc.0" - "@solana/functional": "npm:2.0.0-rc.0" - "@solana/instructions": "npm:2.0.0-rc.0" - "@solana/keys": "npm:2.0.0-rc.0" - "@solana/programs": "npm:2.0.0-rc.0" - "@solana/rpc": "npm:2.0.0-rc.0" - "@solana/rpc-parsed-types": "npm:2.0.0-rc.0" - "@solana/rpc-subscriptions": "npm:2.0.0-rc.0" - "@solana/rpc-types": "npm:2.0.0-rc.0" - "@solana/signers": "npm:2.0.0-rc.0" - "@solana/sysvars": "npm:2.0.0-rc.0" - "@solana/transaction-confirmation": "npm:2.0.0-rc.0" - "@solana/transaction-messages": "npm:2.0.0-rc.0" - "@solana/transactions": "npm:2.0.0-rc.0" + checksum: 10c0/87e02de9f731d717ce280b2ba02323d666868b51e3ce92229f7e21e00ae14c9813b6e0e8cde5d66def54d933f66f12580346d88fc9c4a1624d88246a05788735 + languageName: node + linkType: hard + +"@solana/web3.js@npm:^2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/web3.js@npm:2.0.0-rc.1" + dependencies: + "@solana/accounts": "npm:2.0.0-rc.1" + "@solana/addresses": "npm:2.0.0-rc.1" + "@solana/codecs": "npm:2.0.0-rc.1" + "@solana/errors": "npm:2.0.0-rc.1" + "@solana/functional": "npm:2.0.0-rc.1" + "@solana/instructions": "npm:2.0.0-rc.1" + "@solana/keys": "npm:2.0.0-rc.1" + "@solana/programs": "npm:2.0.0-rc.1" + "@solana/rpc": "npm:2.0.0-rc.1" + "@solana/rpc-parsed-types": "npm:2.0.0-rc.1" + "@solana/rpc-subscriptions": "npm:2.0.0-rc.1" + "@solana/rpc-types": "npm:2.0.0-rc.1" + "@solana/signers": "npm:2.0.0-rc.1" + "@solana/sysvars": "npm:2.0.0-rc.1" + "@solana/transaction-confirmation": "npm:2.0.0-rc.1" + "@solana/transaction-messages": "npm:2.0.0-rc.1" + "@solana/transactions": "npm:2.0.0-rc.1" peerDependencies: typescript: ">=5" - checksum: 10c0/ef1e53969ddab94d94adb46fea730da0dfc39ede19733c2352a376e87910b760a5b382032e70aafb981a992d51226b27b75f6aed6bab3f28d1399861d29f7560 + checksum: 10c0/7d7d0928a4dcd8fba108723829cf6bd255746533faf6643d05b8821e53d9ca0aad860d53b948779157e02a5a90f7f2606eec95c399fa53745cdbefce5773a9cc languageName: node linkType: hard @@ -4166,11 +4251,11 @@ __metadata: linkType: hard "@swc/helpers@npm:^0.5.11": - version: 0.5.12 - resolution: "@swc/helpers@npm:0.5.12" + version: 0.5.13 + resolution: "@swc/helpers@npm:0.5.13" dependencies: tslib: "npm:^2.4.0" - checksum: 10c0/44693c0f34d772d63f3a6fb461964ec583055549a96df9790afec125b2ba06929a63cf9a165a9aaf22317779f460f8caafa94458b70d5cb2bc057b6ba9b5d02c + checksum: 10c0/b9df578401fc62405da9a6c31e79e447a2fd90f68b25b1daee12f2caf2821991bb89106f0397bc1acb4c4d84a8ce079d04b60b65f534496952e3bf8c9a52f40f languageName: node linkType: hard @@ -4273,33 +4358,50 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.5": - version: 1.0.5 - resolution: "@types/estree@npm:1.0.5" - checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d - languageName: node - linkType: hard - -"@types/estree@npm:^1.0.6": +"@types/estree@npm:*, @types/estree@npm:1.0.6, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.5, @types/estree@npm:^1.0.6": version: 1.0.6 resolution: "@types/estree@npm:1.0.6" checksum: 10c0/cdfd751f6f9065442cd40957c07fd80361c962869aa853c1c2fd03e101af8b9389d8ff4955a43a6fcfa223dd387a089937f95be0f3eec21ca527039fd2d9859a languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33": - version: 4.19.5 - resolution: "@types/express-serve-static-core@npm:4.19.5" +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^5.0.0": + version: 5.0.0 + resolution: "@types/express-serve-static-core@npm:5.0.0" + dependencies: + "@types/node": "npm:*" + "@types/qs": "npm:*" + "@types/range-parser": "npm:*" + "@types/send": "npm:*" + checksum: 10c0/671a67a5b367e19aa634dcd515364212490f10efb938fc1097082085a883ccb11c81ec96a3c2b5cc67d5756e5cb1ccbf1de192806f8193bb7de341994beb4ea6 + languageName: node + linkType: hard + +"@types/express-serve-static-core@npm:^4.17.33": + version: 4.19.6 + resolution: "@types/express-serve-static-core@npm:4.19.6" dependencies: "@types/node": "npm:*" "@types/qs": "npm:*" "@types/range-parser": "npm:*" "@types/send": "npm:*" - checksum: 10c0/ba8d8d976ab797b2602c60e728802ff0c98a00f13d420d82770f3661b67fa36ea9d3be0b94f2ddd632afe1fbc6e41620008b01db7e4fabdd71a2beb5539b0725 + checksum: 10c0/4281f4ead71723f376b3ddf64868ae26244d434d9906c101cf8d436d4b5c779d01bd046e4ea0ed1a394d3e402216fabfa22b1fa4dba501061cd7c81c54045983 + languageName: node + linkType: hard + +"@types/express@npm:*": + version: 5.0.0 + resolution: "@types/express@npm:5.0.0" + dependencies: + "@types/body-parser": "npm:*" + "@types/express-serve-static-core": "npm:^5.0.0" + "@types/qs": "npm:*" + "@types/serve-static": "npm:*" + checksum: 10c0/0d74b53aefa69c3b3817ee9b5145fd50d7dbac52a8986afc2d7500085c446656d0b6dc13158c04e2d9f18f4324d4d93b0452337c5ff73dd086dca3e4ff11f47b languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.13": +"@types/express@npm:^4.17.13": version: 4.17.21 resolution: "@types/express@npm:4.17.21" dependencies: @@ -4389,6 +4491,16 @@ __metadata: languageName: node linkType: hard +"@types/jest@npm:^29.5.13": + version: 29.5.13 + resolution: "@types/jest@npm:29.5.13" + dependencies: + expect: "npm:^29.0.0" + pretty-format: "npm:^29.0.0" + checksum: 10c0/9c31af0b155387b9860908830de63c6b79011d7c87c8b61b39da124e26e55423dd51b006749aafe4f0ef3a065016619a1f93ef4b055157d43727f448e67824b7 + languageName: node + linkType: hard + "@types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" @@ -4396,13 +4508,6 @@ __metadata: languageName: node linkType: hard -"@types/json5@npm:^0.0.29": - version: 0.0.29 - resolution: "@types/json5@npm:0.0.29" - checksum: 10c0/6bf5337bc447b706bb5b4431d37686aa2ea6d07cfd6f79cc31de80170d6ff9b1c7384a9c0ccbc45b3f512bae9e9f75c2e12109806a15331dc94e8a8db6dbb4ac - languageName: node - linkType: hard - "@types/mdast@npm:^4.0.0, @types/mdast@npm:^4.0.2": version: 4.0.4 resolution: "@types/mdast@npm:4.0.4" @@ -4426,13 +4531,6 @@ __metadata: languageName: node linkType: hard -"@types/mocha@npm:^10.0.9": - version: 10.0.9 - resolution: "@types/mocha@npm:10.0.9" - checksum: 10c0/76dd782ac7e971ea159d4a7fd40c929afa051e040be3f41187ff03a2d7b3279e19828ddaa498ba1757b3e6b91316263bb7640db0e906938275b97a06e087b989 - languageName: node - linkType: hard - "@types/ms@npm:*": version: 0.7.34 resolution: "@types/ms@npm:0.7.34" @@ -4458,12 +4556,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": - version: 22.1.0 - resolution: "@types/node@npm:22.1.0" +"@types/node@npm:*, @types/node@npm:^22.7.6": + version: 22.7.7 + resolution: "@types/node@npm:22.7.7" dependencies: - undici-types: "npm:~6.13.0" - checksum: 10c0/553dafcb842b889c036d43b390d464e8ffcf3ca455ddd5b1a1ef98396381eafbeb0c112a15cc6bf9662b72bc25fc45efc4b6f604760e1e84c410f1b7936c488b + undici-types: "npm:~6.19.2" + checksum: 10c0/07268a1e990ad9d9b1865092881317ea679a46eb6706d83a8874eec75fdddae6cfd6452e4e68b651561183e2a8f8548276f3155744bc402c2545978c19b70d65 languageName: node linkType: hard @@ -4481,15 +4579,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^22.7.6": - version: 22.7.6 - resolution: "@types/node@npm:22.7.6" - dependencies: - undici-types: "npm:~6.19.2" - checksum: 10c0/d4406a63afce981c363fb1d1954aaf1759ad2d487c0833ebf667565ea4e45ff217d6fab4b5343badbdeccdf9d2e4a0841d633e0c929ceabcb33c288663dd0c73 - languageName: node - linkType: hard - "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -4505,16 +4594,16 @@ __metadata: linkType: hard "@types/prop-types@npm:*": - version: 15.7.12 - resolution: "@types/prop-types@npm:15.7.12" - checksum: 10c0/1babcc7db6a1177779f8fde0ccc78d64d459906e6ef69a4ed4dd6339c920c2e05b074ee5a92120fe4e9d9f1a01c952f843ebd550bee2332fc2ef81d1706878f8 + version: 15.7.13 + resolution: "@types/prop-types@npm:15.7.13" + checksum: 10c0/1b20fc67281902c6743379960247bc161f3f0406ffc0df8e7058745a85ea1538612109db0406290512947f9632fe9e10e7337bf0ce6338a91d6c948df16a7c61 languageName: node linkType: hard "@types/qs@npm:*": - version: 6.9.15 - resolution: "@types/qs@npm:6.9.15" - checksum: 10c0/49c5ff75ca3adb18a1939310042d273c9fc55920861bd8e5100c8a923b3cda90d759e1a95e18334092da1c8f7b820084687770c83a1ccef04fb2c6908117c823 + version: 6.9.16 + resolution: "@types/qs@npm:6.9.16" + checksum: 10c0/a4e871b80fff623755e356fd1f225aea45ff7a29da30f99fddee1a05f4f5f33485b314ab5758145144ed45708f97e44595aa9a8368e9bbc083932f931b12dbb6 languageName: node linkType: hard @@ -4557,17 +4646,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*": - version: 18.3.3 - resolution: "@types/react@npm:18.3.3" - dependencies: - "@types/prop-types": "npm:*" - csstype: "npm:^3.0.2" - checksum: 10c0/fe455f805c5da13b89964c3d68060cebd43e73ec15001a68b34634604a78140e6fc202f3f61679b9d809dde6d7a7c2cb3ed51e0fd1462557911db09879b55114 - languageName: node - linkType: hard - -"@types/react@npm:^18.3.11": +"@types/react@npm:*, @types/react@npm:^18.3.11": version: 18.3.11 resolution: "@types/react@npm:18.3.11" dependencies: @@ -4623,22 +4702,6 @@ __metadata: languageName: node linkType: hard -"@types/sinon@npm:^17.0.3": - version: 17.0.3 - resolution: "@types/sinon@npm:17.0.3" - dependencies: - "@types/sinonjs__fake-timers": "npm:*" - checksum: 10c0/6fc3aa497fd87826375de3dbddc2bf01c281b517c32c05edf95b5ad906382dc221bca01ca9d44fc7d5cb4c768f996f268154e87633a45b3c0b5cddca7ef5e2be - languageName: node - linkType: hard - -"@types/sinonjs__fake-timers@npm:*": - version: 8.1.5 - resolution: "@types/sinonjs__fake-timers@npm:8.1.5" - checksum: 10c0/2b8bdc246365518fc1b08f5720445093cce586183acca19a560be6ef81f824bd9a96c090e462f622af4d206406dadf2033c5daf99a51c1096da6494e5c8dc32e - languageName: node - linkType: hard - "@types/sockjs@npm:^0.3.33": version: 0.3.36 resolution: "@types/sockjs@npm:0.3.36" @@ -4648,6 +4711,13 @@ __metadata: languageName: node linkType: hard +"@types/stack-utils@npm:^2.0.0": + version: 2.0.3 + resolution: "@types/stack-utils@npm:2.0.3" + checksum: 10c0/1f4658385ae936330581bcb8aa3a066df03867d90281cdf89cc356d404bd6579be0f11902304e1f775d92df22c6dd761d4451c804b0a4fba973e06211e9bd77c + languageName: node + linkType: hard + "@types/unist@npm:*, @types/unist@npm:^3.0.0": version: 3.0.3 resolution: "@types/unist@npm:3.0.3" @@ -4795,34 +4865,116 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.10.0": - version: 8.10.0 - resolution: "@typescript-eslint/utils@npm:8.10.0" +"@typescript-eslint/utils@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/utils@npm:8.10.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" + "@typescript-eslint/scope-manager": "npm:8.10.0" + "@typescript-eslint/types": "npm:8.10.0" + "@typescript-eslint/typescript-estree": "npm:8.10.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + checksum: 10c0/a21a2933517176abd00fcd5d8d80023e35dc3d89d5746bbac43790b4e984ab1f371117db08048bce7f42d54c64f4e0e35161149f8f34fd25a27bff9d1110fd16 + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.10.0" + dependencies: + "@typescript-eslint/types": "npm:8.10.0" + eslint-visitor-keys: "npm:^3.4.3" + checksum: 10c0/14721c4ac939640d5fd1ee1b6eeb07604b11a6017e319e21dcc71e7aac2992341fc7ae1992d977bad4433b6a1d0d1c0c279e6927316b26245f6e333f922fa458 + languageName: node + linkType: hard + +"@ungap/structured-clone@npm:^1.0.0": + version: 1.2.0 + resolution: "@ungap/structured-clone@npm:1.2.0" + checksum: 10c0/8209c937cb39119f44eb63cf90c0b73e7c754209a6411c707be08e50e29ee81356dca1a848a405c8bdeebfe2f5e4f831ad310ae1689eeef65e7445c090c6657d + languageName: node + linkType: hard + +"@vitest/expect@npm:2.1.3": + version: 2.1.3 + resolution: "@vitest/expect@npm:2.1.3" + dependencies: + "@vitest/spy": "npm:2.1.3" + "@vitest/utils": "npm:2.1.3" + chai: "npm:^5.1.1" + tinyrainbow: "npm:^1.2.0" + checksum: 10c0/0837adcbb938feebcc083664afc5c4d12e42f1f2442b6f1bedc6b5650a8ff2448b1f10713b45afb099c839fb5cf766c971736267fa9b0fe2ac87f3e2d7f782c2 + languageName: node + linkType: hard + +"@vitest/mocker@npm:2.1.3": + version: 2.1.3 + resolution: "@vitest/mocker@npm:2.1.3" + dependencies: + "@vitest/spy": "npm:2.1.3" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.11" + peerDependencies: + "@vitest/spy": 2.1.3 + msw: ^2.3.5 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10c0/03c80628d092244f21a0ba9041665fc75f987d0d11fab1ae0b7027ec21e503f65057e8c24b936602c5f852d83fbb183da13d05dba117c99785b41b3dafd105ce + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:2.1.3, @vitest/pretty-format@npm:^2.1.3": + version: 2.1.3 + resolution: "@vitest/pretty-format@npm:2.1.3" + dependencies: + tinyrainbow: "npm:^1.2.0" + checksum: 10c0/5a6ee872a8adf5e2764f2b5b2276d8a2199be4ef14777ab693428caf359481851400af10b59721d4972289c955ffe7277954a662b04cfb10233824574c7074ba + languageName: node + linkType: hard + +"@vitest/runner@npm:2.1.3": + version: 2.1.3 + resolution: "@vitest/runner@npm:2.1.3" dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.10.0" - "@typescript-eslint/types": "npm:8.10.0" - "@typescript-eslint/typescript-estree": "npm:8.10.0" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - checksum: 10c0/a21a2933517176abd00fcd5d8d80023e35dc3d89d5746bbac43790b4e984ab1f371117db08048bce7f42d54c64f4e0e35161149f8f34fd25a27bff9d1110fd16 + "@vitest/utils": "npm:2.1.3" + pathe: "npm:^1.1.2" + checksum: 10c0/d5b077643265d10025e22fa64a0e54c3d4fddc23e05f9fcd143dbcc4080851b0df31985986e57890a974577a18d3af624758b6062801d7dd96f9b4f2eaf591f1 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.10.0": - version: 8.10.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.10.0" +"@vitest/snapshot@npm:2.1.3": + version: 2.1.3 + resolution: "@vitest/snapshot@npm:2.1.3" dependencies: - "@typescript-eslint/types": "npm:8.10.0" - eslint-visitor-keys: "npm:^3.4.3" - checksum: 10c0/14721c4ac939640d5fd1ee1b6eeb07604b11a6017e319e21dcc71e7aac2992341fc7ae1992d977bad4433b6a1d0d1c0c279e6927316b26245f6e333f922fa458 + "@vitest/pretty-format": "npm:2.1.3" + magic-string: "npm:^0.30.11" + pathe: "npm:^1.1.2" + checksum: 10c0/a3dcea6a5f7581b6a34dc3bf5f7bd42a05e2ccf6e1171d9f1b759688aebe650e6412564d066aeaa45e83ac549d453b6a3edcf774a8ac728c0c639f8dc919039f languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.0.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 10c0/8209c937cb39119f44eb63cf90c0b73e7c754209a6411c707be08e50e29ee81356dca1a848a405c8bdeebfe2f5e4f831ad310ae1689eeef65e7445c090c6657d +"@vitest/spy@npm:2.1.3": + version: 2.1.3 + resolution: "@vitest/spy@npm:2.1.3" + dependencies: + tinyspy: "npm:^3.0.0" + checksum: 10c0/8d85a5c2848c5bd81892af989aebad65d0c7ae74094aa98ad4f35ecf80755259c7a748a8e7bf683b2906fac29a51fc0ffa82f8fc073b36dbd8a0418261fccdba + languageName: node + linkType: hard + +"@vitest/utils@npm:2.1.3": + version: 2.1.3 + resolution: "@vitest/utils@npm:2.1.3" + dependencies: + "@vitest/pretty-format": "npm:2.1.3" + loupe: "npm:^3.1.1" + tinyrainbow: "npm:^1.2.0" + checksum: 10c0/55a044e43b84c0f8f573d8578107f26440678b6f506c8d9fee88b7ef120d19efd27c9be77985c107113b0f3f3db298dcee57074e1c1c214bee7a097fd08a209b languageName: node linkType: hard @@ -5074,20 +5226,20 @@ __metadata: linkType: hard "acorn-walk@npm:^8.0.0": - version: 8.3.3 - resolution: "acorn-walk@npm:8.3.3" + version: 8.3.4 + resolution: "acorn-walk@npm:8.3.4" dependencies: acorn: "npm:^8.11.0" - checksum: 10c0/4a9e24313e6a0a7b389e712ba69b66b455b4cb25988903506a8d247e7b126f02060b05a8a5b738a9284214e4ca95f383dd93443a4ba84f1af9b528305c7f243b + checksum: 10c0/76537ac5fb2c37a64560feaf3342023dadc086c46da57da363e64c6148dc21b57d49ace26f949e225063acb6fb441eabffd89f7a3066de5ad37ab3e328927c62 languageName: node linkType: hard "acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.11.0, acorn@npm:^8.12.0, acorn@npm:^8.7.1, acorn@npm:^8.8.2": - version: 8.12.1 - resolution: "acorn@npm:8.12.1" + version: 8.13.0 + resolution: "acorn@npm:8.13.0" bin: acorn: bin/acorn - checksum: 10c0/51fb26cd678f914e13287e886da2d7021f8c2bc0ccc95e03d3e0447ee278dd3b40b9c57dc222acd5881adcf26f3edc40901a4953403232129e3876793cd17386 + checksum: 10c0/f35dd53d68177c90699f4c37d0bb205b8abe036d955d0eb011ddb7f14a81e6fd0f18893731c457c1b5bd96754683f4c3d80d9a5585ddecaa53cdf84e0b3d68f7 languageName: node linkType: hard @@ -5185,13 +5337,13 @@ __metadata: linkType: hard "algoliasearch-helper@npm:^3.13.3": - version: 3.22.3 - resolution: "algoliasearch-helper@npm:3.22.3" + version: 3.22.5 + resolution: "algoliasearch-helper@npm:3.22.5" dependencies: "@algolia/events": "npm:^4.0.1" peerDependencies: algoliasearch: ">= 3.1 < 6" - checksum: 10c0/c522eedd6cef022cd5c23ad3ec24691ce555ea1401cdd8c1cd650070b083dbd10bb6e859436d3a22659cc7a3ec9c056accbc6c02f957e1e316c2f5b3ec387f92 + checksum: 10c0/ac23bf64e8ae4f1388c121cb23ec0d2e2a996e77493a7da8141338e6b60be565c9085363ac7d0277469645474ce61c8a06ecbb6e4f0462736b79f3b1b54031b2 languageName: node linkType: hard @@ -5227,7 +5379,7 @@ __metadata: languageName: node linkType: hard -"ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": +"ansi-colors@npm:^4.1.1": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" checksum: 10c0/ec87a2f59902f74e61eada7f6e6fe20094a628dab765cfdbd03c3477599368768cffccdb5d3bb19a1b6c99126783a143b1fee31aab729b31ffe5836c7e5e28b9 @@ -5260,9 +5412,9 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.0.1 - resolution: "ansi-regex@npm:6.0.1" - checksum: 10c0/cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08 + version: 6.1.0 + resolution: "ansi-regex@npm:6.1.0" + checksum: 10c0/a91daeddd54746338478eef88af3439a7edf30f8e23196e2d6ed182da9add559c601266dbef01c2efa46a958ad6f1f8b176799657616c702b5b02e799e7fd8dc languageName: node linkType: hard @@ -5352,13 +5504,6 @@ __metadata: languageName: node linkType: hard -"arrify@npm:^1.0.0": - version: 1.0.1 - resolution: "arrify@npm:1.0.1" - checksum: 10c0/c35c8d1a81bcd5474c0c57fe3f4bad1a4d46a5fa353cedcff7a54da315df60db71829e69104b859dff96c5d68af46bd2be259fe5e50dc6aa9df3b36bea0383ab - languageName: node - linkType: hard - "asap@npm:^2.0.3": version: 2.0.6 resolution: "asap@npm:2.0.6" @@ -5366,12 +5511,19 @@ __metadata: languageName: node linkType: hard +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 + languageName: node + linkType: hard + "astring@npm:^1.8.0": - version: 1.8.6 - resolution: "astring@npm:1.8.6" + version: 1.9.0 + resolution: "astring@npm:1.9.0" bin: astring: bin/astring - checksum: 10c0/31f09144597048c11072417959a412f208f8f95ba8dce408dfbc3367acb929f31fbcc00ed5eb61ccbf7c2f1173b9ac8bfcaaa37134a9455050c669b2b036ed88 + checksum: 10c0/e7519544d9824494e80ef0e722bb3a0c543a31440d59691c13aeaceb75b14502af536b23f08db50aa6c632dafaade54caa25f0788aa7550b6b2d6e2df89e0830 languageName: node linkType: hard @@ -5407,27 +5559,36 @@ __metadata: languageName: node linkType: hard +"axios@npm:^0.26.1": + version: 0.26.1 + resolution: "axios@npm:0.26.1" + dependencies: + follow-redirects: "npm:^1.14.8" + checksum: 10c0/77ad7f1e6ca04fcd3fa8af1795b09d8b7c005b71a31f28d99ba40cda0bdcc12a4627801d7fac5efa62b9f667a8402bd54c669039694373bc8d44f6be611f785c + languageName: node + linkType: hard + "axios@npm:^1.7.4": - version: 1.7.4 - resolution: "axios@npm:1.7.4" + version: 1.7.7 + resolution: "axios@npm:1.7.7" dependencies: follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: 10c0/5ea1a93140ca1d49db25ef8e1bd8cfc59da6f9220159a944168860ad15a2743ea21c5df2967795acb15cbe81362f5b157fdebbea39d53117ca27658bab9f7f17 + checksum: 10c0/4499efc89e86b0b49ffddc018798de05fab26e3bf57913818266be73279a6418c3ce8f9e934c7d2d707ab8c095e837fc6c90608fb7715b94d357720b5f568af7 languageName: node linkType: hard "babel-loader@npm:^9.1.3": - version: 9.1.3 - resolution: "babel-loader@npm:9.1.3" + version: 9.2.1 + resolution: "babel-loader@npm:9.2.1" dependencies: find-cache-dir: "npm:^4.0.0" schema-utils: "npm:^4.0.0" peerDependencies: "@babel/core": ^7.12.0 webpack: ">=5" - checksum: 10c0/e3fc3c9e02bd908b37e8e8cd4f3d7280cf6ac45e33fc203aedbb615135a0fecc33bf92573b71a166a827af029d302c0b060354985cd91d510320bd70a2f949eb + checksum: 10c0/efb82faff4c7c27e9c15bb28bf11c73200e61cf365118a9514e8d74dd489d0afc2a0d5aaa62cb4254eefc2ab631579224d95a03fd245410f28ea75e24de54ba4 languageName: node linkType: hard @@ -5453,7 +5614,7 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs3@npm:^0.10.1, babel-plugin-polyfill-corejs3@npm:^0.10.4": +"babel-plugin-polyfill-corejs3@npm:^0.10.6": version: 0.10.6 resolution: "babel-plugin-polyfill-corejs3@npm:0.10.6" dependencies: @@ -5544,6 +5705,17 @@ __metadata: languageName: node linkType: hard +"binary-install@npm:^1.0.1": + version: 1.1.0 + resolution: "binary-install@npm:1.1.0" + dependencies: + axios: "npm:^0.26.1" + rimraf: "npm:^3.0.2" + tar: "npm:^6.1.11" + checksum: 10c0/c0c94a81262c037a1a84f12ff9acfe667b7938b126e764b0f066d5be128d21e0bb8ac5700f4d89f8f7b860b660882deddeaca300dea0ff218d94676999a133a1 + languageName: node + linkType: hard + "bindings@npm:^1.3.0": version: 1.5.0 resolution: "bindings@npm:1.5.0" @@ -5679,24 +5851,17 @@ __metadata: languageName: node linkType: hard -"browser-stdout@npm:^1.3.1": - version: 1.3.1 - resolution: "browser-stdout@npm:1.3.1" - checksum: 10c0/c40e482fd82be872b6ea7b9f7591beafbf6f5ba522fe3dade98ba1573a1c29a11101564993e4eb44e5488be8f44510af072df9a9637c739217eb155ceb639205 - languageName: node - linkType: hard - -"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.23.0, browserslist@npm:^4.23.1, browserslist@npm:^4.23.3": - version: 4.23.3 - resolution: "browserslist@npm:4.23.3" +"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.23.0, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0": + version: 4.24.0 + resolution: "browserslist@npm:4.24.0" dependencies: - caniuse-lite: "npm:^1.0.30001646" - electron-to-chromium: "npm:^1.5.4" + caniuse-lite: "npm:^1.0.30001663" + electron-to-chromium: "npm:^1.5.28" node-releases: "npm:^2.0.18" update-browserslist-db: "npm:^1.1.0" bin: browserslist: cli.js - checksum: 10c0/3063bfdf812815346447f4796c8f04601bf5d62003374305fd323c2a463e42776475bcc5309264e39bcf9a8605851e53560695991a623be988138b3ff8c66642 + checksum: 10c0/95e76ad522753c4c470427f6e3c8a4bb5478ff448841e22b3d3e53f89ecaf17b6984666d6c7e715c370f1e7fa0cf684f42e34e554236a8b2fab38ea76b9e4c52 languageName: node linkType: hard @@ -5709,7 +5874,7 @@ __metadata: languageName: node linkType: hard -"buffer-from@npm:^1.0.0, buffer-from@npm:^1.1.0": +"buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 @@ -5753,6 +5918,17 @@ __metadata: languageName: node linkType: hard +"bundle-require@npm:^5.0.0": + version: 5.0.0 + resolution: "bundle-require@npm:5.0.0" + dependencies: + load-tsconfig: "npm:^0.2.3" + peerDependencies: + esbuild: ">=0.18" + checksum: 10c0/92c46df02586e0ebd66ee4831c9b5775adb3c32a43fe2b2aaf7bc675135c141f751de6a9a26b146d64c607c5b40f9eef5f10dce3c364f602d4bed268444c32c6 + languageName: node + linkType: hard + "bytes@npm:3.0.0": version: 3.0.0 resolution: "bytes@npm:3.0.0" @@ -5767,6 +5943,13 @@ __metadata: languageName: node linkType: hard +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 10c0/4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10 + languageName: node + linkType: hard + "cacache@npm:^18.0.0": version: 18.0.4 resolution: "cacache@npm:18.0.4" @@ -5839,7 +6022,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^6.0.0, camelcase@npm:^6.2.0, camelcase@npm:^6.3.0": +"camelcase@npm:^6.2.0, camelcase@npm:^6.3.0": version: 6.3.0 resolution: "camelcase@npm:6.3.0" checksum: 10c0/0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710 @@ -5865,10 +6048,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001646": - version: 1.0.30001651 - resolution: "caniuse-lite@npm:1.0.30001651" - checksum: 10c0/7821278952a6dbd17358e5d08083d258f092e2a530f5bc1840657cb140fbbc5ec44293bc888258c44a18a9570cde149ed05819ac8320b9710cf22f699891e6ad +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001646, caniuse-lite@npm:^1.0.30001663": + version: 1.0.30001669 + resolution: "caniuse-lite@npm:1.0.30001669" + checksum: 10c0/f125f23440d3dbb6c25ffb8d55f4ce48af36a84d0932b152b3b74f143a4170cbe92e02b0a9676209c86609bf7bf34119ff10cc2bc7c1b7ea40e936cc16598408 languageName: node linkType: hard @@ -5879,6 +6062,19 @@ __metadata: languageName: node linkType: hard +"chai@npm:^5.1.1": + version: 5.1.1 + resolution: "chai@npm:5.1.1" + dependencies: + assertion-error: "npm:^2.0.1" + check-error: "npm:^2.1.1" + deep-eql: "npm:^5.0.1" + loupe: "npm:^3.1.0" + pathval: "npm:^2.0.0" + checksum: 10c0/e7f00e5881e3d5224f08fe63966ed6566bd9fdde175863c7c16dd5240416de9b34c4a0dd925f4fd64ad56256ca6507d32cf6131c49e1db65c62578eb31d4566c + languageName: node + linkType: hard + "chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -5942,6 +6138,13 @@ __metadata: languageName: node linkType: hard +"check-error@npm:^2.1.1": + version: 2.1.1 + resolution: "check-error@npm:2.1.1" + checksum: 10c0/979f13eccab306cf1785fa10941a590b4e7ea9916ea2a4f8c87f0316fc3eab07eabefb6e587424ef0f88cbcd3805791f172ea739863ca3d7ce2afc54641c7f0e + languageName: node + linkType: hard + "cheerio-select@npm:^2.1.0": version: 2.1.0 resolution: "cheerio-select@npm:2.1.0" @@ -5971,7 +6174,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.4.2, chokidar@npm:^3.5.3": +"chokidar@npm:^3.4.2, chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -6089,17 +6292,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^7.0.2": - version: 7.0.4 - resolution: "cliui@npm:7.0.4" - dependencies: - string-width: "npm:^4.2.0" - strip-ansi: "npm:^6.0.0" - wrap-ansi: "npm:^7.0.0" - checksum: 10c0/6035f5daf7383470cef82b3d3db00bec70afb3423538c50394386ffbbab135e26c3689c41791f911fa71b62d13d3863c712fdd70f0fbdffd938a1e6fd09aac00 - languageName: node - linkType: hard - "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -6219,7 +6411,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^12.0.0, commander@npm:^12.1.0, commander@npm:~12.1.0": +"commander@npm:^12.1.0, commander@npm:~12.1.0": version: 12.1.0 resolution: "commander@npm:12.1.0" checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9 @@ -6233,6 +6425,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^4.0.0": + version: 4.1.1 + resolution: "commander@npm:4.1.1" + checksum: 10c0/84a76c08fe6cc08c9c93f62ac573d2907d8e79138999312c92d4155bc2325d487d64d13f669b2000c9f8caf70493c1be2dac74fec3c51d5a04f8bc3ae1830bab + languageName: node + linkType: hard + "commander@npm:^5.1.0": version: 5.1.0 resolution: "commander@npm:5.1.0" @@ -6329,6 +6528,13 @@ __metadata: languageName: node linkType: hard +"consola@npm:^3.2.3": + version: 3.2.3 + resolution: "consola@npm:3.2.3" + checksum: 10c0/c606220524ec88a05bb1baf557e9e0e04a0c08a9c35d7a08652d99de195c4ddcb6572040a7df57a18ff38bbc13ce9880ad032d56630cef27bef72768ef0ac078 + languageName: node + linkType: hard + "content-disposition@npm:0.5.2": version: 0.5.2 resolution: "content-disposition@npm:0.5.2" @@ -6366,10 +6572,10 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.6.0": - version: 0.6.0 - resolution: "cookie@npm:0.6.0" - checksum: 10c0/f2318b31af7a31b4ddb4a678d024514df5e705f9be5909a192d7f116cfb6d45cbacf96a473fa733faa95050e7cff26e7832bb3ef94751592f1387b71c8956686 +"cookie@npm:0.7.1": + version: 0.7.1 + resolution: "cookie@npm:0.7.1" + checksum: 10c0/5de60c67a410e7c8dc8a46a4b72eb0fe925871d057c9a5d2c0e8145c4270a4f81076de83410c4d397179744b478e33cd80ccbcc457abf40a9409ad27dcd21dde languageName: node linkType: hard @@ -6396,26 +6602,26 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.37.1, core-js-compat@npm:^3.38.0": - version: 3.38.0 - resolution: "core-js-compat@npm:3.38.0" +"core-js-compat@npm:^3.38.0, core-js-compat@npm:^3.38.1": + version: 3.38.1 + resolution: "core-js-compat@npm:3.38.1" dependencies: browserslist: "npm:^4.23.3" - checksum: 10c0/9d653a448b8a491034358d2f052e63dda86f75fb65646e2d313a938212470ba1c2f5a83bf31cc583d6c87a9e8d7b0d49458447cab2ff36c4caa097ae381de336 + checksum: 10c0/d8bc8a35591fc5fbf3e376d793f298ec41eb452619c7ef9de4ea59b74be06e9fda799e0dcbf9ba59880dae87e3b41fb191d744ffc988315642a1272bb9442b31 languageName: node linkType: hard "core-js-pure@npm:^3.30.2": - version: 3.38.0 - resolution: "core-js-pure@npm:3.38.0" - checksum: 10c0/331937ef8c29fd6dc2f87e14a125d7e959881abfced84670cdd289949c85dd992013f9a8f85e9a234b55f912d3638a5873499f672b473a483d2750b22fafe8ac + version: 3.38.1 + resolution: "core-js-pure@npm:3.38.1" + checksum: 10c0/466adbc0468b8c2a95b9bc49829492dece2cc6584d757c5b38555a26ed3d71f8364ac1ea3128a0a949e004e0e60206cc535ed84320982c3efb9a40c1785ddcc6 languageName: node linkType: hard "core-js@npm:^3.31.1": - version: 3.38.0 - resolution: "core-js@npm:3.38.0" - checksum: 10c0/3218ae19bfe0c6560663012cbd3e7f3dc1b36d50fc71e8c365f3b119185e8a35ac4e8bb9698ae510b3c201ef93f40bdc29f9215716ccf31aca28f77969bb4ed0 + version: 3.38.1 + resolution: "core-js@npm:3.38.1" + checksum: 10c0/7df063b6f13a54e46515817ac3e235c6c598a4d3de65cd188a061fc250642be313b895fb9fb2f36e1e31890a1bb4ef61d82666a340413f540b7ce3c65689739b languageName: node linkType: hard @@ -6726,22 +6932,15 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:~4.3.6": - version: 4.3.6 - resolution: "debug@npm:4.3.6" +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.6, debug@npm:~4.3.6": + version: 4.3.7 + resolution: "debug@npm:4.3.7" dependencies: - ms: "npm:2.1.2" + ms: "npm:^2.1.3" peerDependenciesMeta: supports-color: optional: true - checksum: 10c0/3293416bff072389c101697d4611c402a6bacd1900ac20c0492f61a9cdd6b3b29750fc7f5e299f8058469ef60ff8fb79b86395a30374fbd2490113c1c7112285 - languageName: node - linkType: hard - -"decamelize@npm:^4.0.0": - version: 4.0.0 - resolution: "decamelize@npm:4.0.0" - checksum: 10c0/e06da03fc05333e8cd2778c1487da67ffbea5b84e03ca80449519b8fa61f888714bbc6f459ea963d5641b4aa98832130eb5cd193d90ae9f0a27eee14be8e278d + checksum: 10c0/1471db19c3b06d485a622d62f65947a19a23fbd0dd73f7fd3eafb697eec5360cde447fb075919987899b1a2096e85d35d4eb5a4de09a57600ac9cf7e6c8e768b languageName: node linkType: hard @@ -6770,6 +6969,13 @@ __metadata: languageName: node linkType: hard +"deep-eql@npm:^5.0.1": + version: 5.0.2 + resolution: "deep-eql@npm:5.0.2" + checksum: 10c0/7102cf3b7bb719c6b9c0db2e19bf0aa9318d141581befe8c7ce8ccd39af9eaa4346e5e05adef7f9bd7015da0f13a3a25dcfe306ef79dc8668aedbecb658dd247 + languageName: node + linkType: hard + "deep-extend@npm:^0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -6952,27 +7158,6 @@ __metadata: languageName: node linkType: hard -"diff@npm:^3.1.0": - version: 3.5.0 - resolution: "diff@npm:3.5.0" - checksum: 10c0/fc62d5ba9f6d1b8b5833380969037007913d4886997838c247c54ec6934f09ae5a07e17ae28b1f016018149d81df8ad89306f52eac1afa899e0bed49015a64d1 - languageName: node - linkType: hard - -"diff@npm:^5.2.0": - version: 5.2.0 - resolution: "diff@npm:5.2.0" - checksum: 10c0/aed0941f206fe261ecb258dc8d0ceea8abbde3ace5827518ff8d302f0fc9cc81ce116c4d8f379151171336caf0516b79e01abdc1ed1201b6440d895a66689eb4 - languageName: node - linkType: hard - -"diff@npm:^7.0.0": - version: 7.0.0 - resolution: "diff@npm:7.0.0" - checksum: 10c0/251fd15f85ffdf814cfc35a728d526b8d2ad3de338dcbd011ac6e57c461417090766b28995f8ff733135b5fbc3699c392db1d5e27711ac4e00244768cd1d577b - languageName: node - linkType: hard - "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -7125,17 +7310,17 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.4": - version: 1.5.8 - resolution: "electron-to-chromium@npm:1.5.8" - checksum: 10c0/801de2afa0479ffa0cd0e36b7865241dcd3a66a92fca28457431d2dc2bd9c2d066ab07578b419426c504df196f078c63283ee47140c28039d224ec2631acbcee +"electron-to-chromium@npm:^1.5.28": + version: 1.5.41 + resolution: "electron-to-chromium@npm:1.5.41" + checksum: 10c0/97b82383963029e6ed0bd7a71eb527f640c8cf658c9e43c776b0257b3c65e366590ac54135683a21e4474a156b8be78717d6e94d3c1def84b69f92bf48f2390f languageName: node linkType: hard "emoji-regex@npm:^10.3.0": - version: 10.3.0 - resolution: "emoji-regex@npm:10.3.0" - checksum: 10c0/b4838e8dcdceb44cf47f59abe352c25ff4fe7857acaf5fb51097c427f6f75b44d052eb907a7a3b86f86bc4eae3a93f5c2b7460abe79c407307e6212d65c91163 + version: 10.4.0 + resolution: "emoji-regex@npm:10.4.0" + checksum: 10c0/a3fcedfc58bfcce21a05a5f36a529d81e88d602100145fcca3dc6f795e3c8acc4fc18fe773fbf9b6d6e9371205edb3afa2668ec3473fa2aa7fd47d2a9d46482d languageName: node linkType: hard @@ -7232,7 +7417,7 @@ __metadata: languageName: node linkType: hard -"entities@npm:^4.2.0, entities@npm:^4.4.0": +"entities@npm:^4.2.0, entities@npm:^4.4.0, entities@npm:^4.5.0": version: 4.5.0 resolution: "entities@npm:4.5.0" checksum: 10c0/5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 @@ -7308,10 +7493,197 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.1.1, escalade@npm:^3.1.2": - version: 3.1.2 - resolution: "escalade@npm:3.1.2" - checksum: 10c0/6b4adafecd0682f3aa1cd1106b8fff30e492c7015b178bc81b2d2f75106dabea6c6d6e8508fc491bd58e597c74abb0e8e2368f943ecb9393d4162e3c2f3cf287 +"esast-util-from-estree@npm:^2.0.0": + version: 2.0.0 + resolution: "esast-util-from-estree@npm:2.0.0" + dependencies: + "@types/estree-jsx": "npm:^1.0.0" + devlop: "npm:^1.0.0" + estree-util-visit: "npm:^2.0.0" + unist-util-position-from-estree: "npm:^2.0.0" + checksum: 10c0/6c619bc6963314f8f64b32e3b101b321bf121f659e62b11e70f425619c2db6f1d25f4c594a57fd00908da96c67d9bfbf876eb5172abf9e13f47a71796f6630ff + languageName: node + linkType: hard + +"esast-util-from-js@npm:^2.0.0": + version: 2.0.1 + resolution: "esast-util-from-js@npm:2.0.1" + dependencies: + "@types/estree-jsx": "npm:^1.0.0" + acorn: "npm:^8.0.0" + esast-util-from-estree: "npm:^2.0.0" + vfile-message: "npm:^4.0.0" + checksum: 10c0/3a446fb0b0d7bcd7e0157aa44b3b692802a08c93edbea81cc0f7fe4437bfdfb4b72e4563fe63b4e36d390086b71185dba4ac921f4180cc6349985c263cc74421 + languageName: node + linkType: hard + +"esbuild@npm:^0.21.3": + version: 0.21.5 + resolution: "esbuild@npm:0.21.5" + dependencies: + "@esbuild/aix-ppc64": "npm:0.21.5" + "@esbuild/android-arm": "npm:0.21.5" + "@esbuild/android-arm64": "npm:0.21.5" + "@esbuild/android-x64": "npm:0.21.5" + "@esbuild/darwin-arm64": "npm:0.21.5" + "@esbuild/darwin-x64": "npm:0.21.5" + "@esbuild/freebsd-arm64": "npm:0.21.5" + "@esbuild/freebsd-x64": "npm:0.21.5" + "@esbuild/linux-arm": "npm:0.21.5" + "@esbuild/linux-arm64": "npm:0.21.5" + "@esbuild/linux-ia32": "npm:0.21.5" + "@esbuild/linux-loong64": "npm:0.21.5" + "@esbuild/linux-mips64el": "npm:0.21.5" + "@esbuild/linux-ppc64": "npm:0.21.5" + "@esbuild/linux-riscv64": "npm:0.21.5" + "@esbuild/linux-s390x": "npm:0.21.5" + "@esbuild/linux-x64": "npm:0.21.5" + "@esbuild/netbsd-x64": "npm:0.21.5" + "@esbuild/openbsd-x64": "npm:0.21.5" + "@esbuild/sunos-x64": "npm:0.21.5" + "@esbuild/win32-arm64": "npm:0.21.5" + "@esbuild/win32-ia32": "npm:0.21.5" + "@esbuild/win32-x64": "npm:0.21.5" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/fa08508adf683c3f399e8a014a6382a6b65542213431e26206c0720e536b31c09b50798747c2a105a4bbba1d9767b8d3615a74c2f7bf1ddf6d836cd11eb672de + languageName: node + linkType: hard + +"esbuild@npm:^0.23.0": + version: 0.23.1 + resolution: "esbuild@npm:0.23.1" + dependencies: + "@esbuild/aix-ppc64": "npm:0.23.1" + "@esbuild/android-arm": "npm:0.23.1" + "@esbuild/android-arm64": "npm:0.23.1" + "@esbuild/android-x64": "npm:0.23.1" + "@esbuild/darwin-arm64": "npm:0.23.1" + "@esbuild/darwin-x64": "npm:0.23.1" + "@esbuild/freebsd-arm64": "npm:0.23.1" + "@esbuild/freebsd-x64": "npm:0.23.1" + "@esbuild/linux-arm": "npm:0.23.1" + "@esbuild/linux-arm64": "npm:0.23.1" + "@esbuild/linux-ia32": "npm:0.23.1" + "@esbuild/linux-loong64": "npm:0.23.1" + "@esbuild/linux-mips64el": "npm:0.23.1" + "@esbuild/linux-ppc64": "npm:0.23.1" + "@esbuild/linux-riscv64": "npm:0.23.1" + "@esbuild/linux-s390x": "npm:0.23.1" + "@esbuild/linux-x64": "npm:0.23.1" + "@esbuild/netbsd-x64": "npm:0.23.1" + "@esbuild/openbsd-arm64": "npm:0.23.1" + "@esbuild/openbsd-x64": "npm:0.23.1" + "@esbuild/sunos-x64": "npm:0.23.1" + "@esbuild/win32-arm64": "npm:0.23.1" + "@esbuild/win32-ia32": "npm:0.23.1" + "@esbuild/win32-x64": "npm:0.23.1" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/08c2ed1105cc3c5e3a24a771e35532fe6089dd24a39c10097899072cef4a99f20860e41e9294e000d86380f353b04d8c50af482483d7f69f5208481cce61eec7 + languageName: node + linkType: hard + +"escalade@npm:^3.1.1, escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 languageName: node linkType: hard @@ -7336,6 +7708,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507 + languageName: node + linkType: hard + "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -7377,13 +7756,6 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^4.0.0": - version: 4.0.0 - resolution: "eslint-visitor-keys@npm:4.0.0" - checksum: 10c0/76619f42cf162705a1515a6868e6fc7567e185c7063a05621a8ac4c3b850d022661262c21d9f1fc1d144ecf0d5d64d70a3f43c15c3fc969a61ace0fb25698cf5 - languageName: node - linkType: hard - "eslint-visitor-keys@npm:^4.1.0": version: 4.1.0 resolution: "eslint-visitor-keys@npm:4.1.0" @@ -7392,15 +7764,15 @@ __metadata: linkType: hard "eslint@npm:^9.12.0": - version: 9.12.0 - resolution: "eslint@npm:9.12.0" + version: 9.13.0 + resolution: "eslint@npm:9.13.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.11.0" "@eslint/config-array": "npm:^0.18.0" - "@eslint/core": "npm:^0.6.0" + "@eslint/core": "npm:^0.7.0" "@eslint/eslintrc": "npm:^3.1.0" - "@eslint/js": "npm:9.12.0" + "@eslint/js": "npm:9.13.0" "@eslint/plugin-kit": "npm:^0.2.0" "@humanfs/node": "npm:^0.16.5" "@humanwhocodes/module-importer": "npm:^1.0.1" @@ -7437,22 +7809,11 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 10c0/67cf6ea3ea28dcda7dd54aac33e2d4028eb36991d13defb0d2339c3eaa877d5dddd12cd4416ddc701a68bcde9e0bb9e65524c2e4e9914992c724f5b51e949dda - languageName: node - linkType: hard - -"espree@npm:^10.0.1": - version: 10.1.0 - resolution: "espree@npm:10.1.0" - dependencies: - acorn: "npm:^8.12.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^4.0.0" - checksum: 10c0/52e6feaa77a31a6038f0c0e3fce93010a4625701925b0715cd54a2ae190b3275053a0717db698697b32653788ac04845e489d6773b508d6c2e8752f3c57470a0 + checksum: 10c0/d3577444152182a9d8ea8c6a6acb073d3a2773ad73a6b646f432746583ec4bfcd6a44fcc2e37d05d276984e583c46c2d289b3b981ca8f8b4052756a152341d19 languageName: node linkType: hard -"espree@npm:^10.2.0": +"espree@npm:^10.0.1, espree@npm:^10.2.0": version: 10.2.0 resolution: "espree@npm:10.2.0" dependencies: @@ -7533,6 +7894,16 @@ __metadata: languageName: node linkType: hard +"estree-util-scope@npm:^1.0.0": + version: 1.0.0 + resolution: "estree-util-scope@npm:1.0.0" + dependencies: + "@types/estree": "npm:^1.0.0" + devlop: "npm:^1.0.0" + checksum: 10c0/ef8a573cc899277c613623a1722f630e2163abbc6e9e2f49e758c59b81b484e248b585df6df09a38c00fbfb6390117997cc80c1347b7a86bc1525d9e462b60d5 + languageName: node + linkType: hard + "estree-util-to-js@npm:^2.0.0": version: 2.0.0 resolution: "estree-util-to-js@npm:2.0.0" @@ -7563,7 +7934,7 @@ __metadata: languageName: node linkType: hard -"estree-walker@npm:^3.0.0": +"estree-walker@npm:^3.0.0, estree-walker@npm:^3.0.3": version: 3.0.3 resolution: "estree-walker@npm:3.0.3" dependencies: @@ -7624,7 +7995,7 @@ __metadata: languageName: node linkType: hard -"execa@npm:^5.0.0": +"execa@npm:^5.0.0, execa@npm:^5.1.1": version: 5.1.1 resolution: "execa@npm:5.1.1" dependencies: @@ -7658,6 +8029,19 @@ __metadata: languageName: node linkType: hard +"expect@npm:^29.0.0": + version: 29.7.0 + resolution: "expect@npm:29.7.0" + dependencies: + "@jest/expect-utils": "npm:^29.7.0" + jest-get-type: "npm:^29.6.3" + jest-matcher-utils: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + checksum: 10c0/2eddeace66e68b8d8ee5f7be57f3014b19770caaf6815c7a08d131821da527fb8c8cb7b3dcd7c883d2d3d8d184206a4268984618032d1e4b16dc8d6596475d41 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -7666,15 +8050,15 @@ __metadata: linkType: hard "express@npm:^4.17.3": - version: 4.21.0 - resolution: "express@npm:4.21.0" + version: 4.21.1 + resolution: "express@npm:4.21.1" dependencies: accepts: "npm:~1.3.8" array-flatten: "npm:1.1.1" body-parser: "npm:1.20.3" content-disposition: "npm:0.5.4" content-type: "npm:~1.0.4" - cookie: "npm:0.6.0" + cookie: "npm:0.7.1" cookie-signature: "npm:1.0.6" debug: "npm:2.6.9" depd: "npm:2.0.0" @@ -7700,7 +8084,7 @@ __metadata: type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 10c0/4cf7ca328f3fdeb720f30ccb2ea7708bfa7d345f9cc460b64a82bf1b2c91e5b5852ba15a9a11b2a165d6089acf83457fc477dc904d59cd71ed34c7a91762c6cc + checksum: 10c0/0c287867e5f6129d3def1edd9b63103a53c40d4dc8628839d4b6827e35eb8f0de5a4656f9d85f4457eba584f9871ebb2ad26c750b36bd75d9bbb8bcebdc4892c languageName: node linkType: hard @@ -7769,18 +8153,9 @@ __metadata: linkType: hard "fast-uri@npm:^3.0.1": - version: 3.0.1 - resolution: "fast-uri@npm:3.0.1" - checksum: 10c0/3cd46d6006083b14ca61ffe9a05b8eef75ef87e9574b6f68f2e17ecf4daa7aaadeff44e3f0f7a0ef4e0f7e7c20fc07beec49ff14dc72d0b500f00386592f2d10 - languageName: node - linkType: hard - -"fast-url-parser@npm:1.1.3": - version: 1.1.3 - resolution: "fast-url-parser@npm:1.1.3" - dependencies: - punycode: "npm:^1.3.2" - checksum: 10c0/d85c5c409cf0215417380f98a2d29c23a95004d93ff0d8bdf1af5f1a9d1fc608ac89ac6ffe863783d2c73efb3850dd35390feb1de3296f49877bfee0392eb5d3 + version: 3.0.3 + resolution: "fast-uri@npm:3.0.3" + checksum: 10c0/4b2c5ce681a062425eae4f15cdc8fc151fd310b2f69b1f96680677820a8b49c3cd6e80661a406e19d50f0c40a3f8bffdd458791baf66f4a879d80be28e10a320 languageName: node linkType: hard @@ -7811,6 +8186,18 @@ __metadata: languageName: node linkType: hard +"fdir@npm:^6.4.0": + version: 6.4.2 + resolution: "fdir@npm:6.4.2" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/34829886f34a3ca4170eca7c7180ec4de51a3abb4d380344063c0ae2e289b11d2ba8b724afee974598c83027fea363ff598caf2b51bc4e6b1e0d8b80cc530573 + languageName: node + linkType: hard + "feed@npm:^4.2.2": version: 4.2.2 resolution: "feed@npm:4.2.2" @@ -7953,23 +8340,23 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.6": - version: 1.15.6 - resolution: "follow-redirects@npm:1.15.6" +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.8, follow-redirects@npm:^1.15.6": + version: 1.15.9 + resolution: "follow-redirects@npm:1.15.9" peerDependenciesMeta: debug: optional: true - checksum: 10c0/9ff767f0d7be6aa6870c82ac79cf0368cd73e01bbc00e9eb1c2a16fbb198ec105e3c9b6628bb98e9f3ac66fe29a957b9645bcb9a490bb7aa0d35f908b6b85071 + checksum: 10c0/5829165bd112c3c0e82be6c15b1a58fa9dcfaede3b3c54697a82fe4a62dd5ae5e8222956b448d2f98e331525f05d00404aba7d696de9e761ef6e42fdc780244f languageName: node linkType: hard "foreground-child@npm:^3.1.0": - version: 3.2.1 - resolution: "foreground-child@npm:3.2.1" + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" dependencies: cross-spawn: "npm:^7.0.0" signal-exit: "npm:^4.0.1" - checksum: 10c0/9a53a33dbd87090e9576bef65fb4a71de60f6863a8062a7b11bc1cbe3cc86d428677d7c0b9ef61cdac11007ac580006f78bd5638618d564cfd5e6fd713d6878f + checksum: 10c0/028f1d41000553fcfa6c4bb5c372963bf3d9bf0b1f25a87d1a6253014343fb69dfb1b42d9625d7cf44c8ba429940f3d0ff718b62105d4d4a4f6ef8ca0a53faa2 languageName: node linkType: hard @@ -8012,13 +8399,13 @@ __metadata: linkType: hard "form-data@npm:^4.0.0": - version: 4.0.0 - resolution: "form-data@npm:4.0.0" + version: 4.0.1 + resolution: "form-data@npm:4.0.1" dependencies: asynckit: "npm:^0.4.0" combined-stream: "npm:^1.0.8" mime-types: "npm:^2.1.12" - checksum: 10c0/cb6f3ac49180be03ff07ba3ff125f9eba2ff0b277fb33c7fc47569fc5e616882c5b1c69b9904c4c4187e97dd0419dd03b134174756f296dec62041e6527e2c6e + checksum: 10c0/bb102d570be8592c23f4ea72d7df9daa50c7792eb0cf1c5d7e506c1706e7426a4e4ae48a35b109e91c85f1c0ec63774a21ae252b66f4eb981cb8efef7d0463c8 languageName: node linkType: hard @@ -8121,7 +8508,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:~2.3.2": +"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -8131,7 +8518,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" dependencies: @@ -8162,9 +8549,9 @@ __metadata: linkType: hard "get-east-asian-width@npm:^1.0.0": - version: 1.2.0 - resolution: "get-east-asian-width@npm:1.2.0" - checksum: 10c0/914b1e217cf38436c24b4c60b4c45289e39a45bf9e65ef9fd343c2815a1a02b8a0215aeec8bf9c07c516089004b6e3826332481f40a09529fcadbf6e579f286b + version: 1.3.0 + resolution: "get-east-asian-width@npm:1.3.0" + checksum: 10c0/1a049ba697e0f9a4d5514c4623781c5246982bdb61082da6b5ae6c33d838e52ce6726407df285cdbb27ec1908b333cf2820989bd3e986e37bb20979437fdf34b languageName: node linkType: hard @@ -8280,19 +8667,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.1.0": - version: 8.1.0 - resolution: "glob@npm:8.1.0" - dependencies: - fs.realpath: "npm:^1.0.0" - inflight: "npm:^1.0.4" - inherits: "npm:2" - minimatch: "npm:^5.0.1" - once: "npm:^1.3.0" - checksum: 10c0/cb0b5cab17a59c57299376abe5646c7070f8acb89df5595b492dba3bfb43d301a46c01e5695f01154e6553168207cb60d4eaf07d3be4bc3eb9b0457c5c561d0f - languageName: node - linkType: hard - "global-dirs@npm:^3.0.0": version: 3.0.1 resolution: "global-dirs@npm:3.0.1" @@ -8563,9 +8937,28 @@ __metadata: languageName: node linkType: hard +"hast-util-to-html@npm:^9.0.3": + version: 9.0.3 + resolution: "hast-util-to-html@npm:9.0.3" + dependencies: + "@types/hast": "npm:^3.0.0" + "@types/unist": "npm:^3.0.0" + ccount: "npm:^2.0.0" + comma-separated-tokens: "npm:^2.0.0" + hast-util-whitespace: "npm:^3.0.0" + html-void-elements: "npm:^3.0.0" + mdast-util-to-hast: "npm:^13.0.0" + property-information: "npm:^6.0.0" + space-separated-tokens: "npm:^2.0.0" + stringify-entities: "npm:^4.0.0" + zwitch: "npm:^2.0.4" + checksum: 10c0/af938a03034727f6c944d3855732d72f71a3bcd920d36b9ba3e083df2217faf81713740934db64673aca69d76b60abe80052e47c0702323fd0bd5dce03b67b8d + languageName: node + linkType: hard + "hast-util-to-jsx-runtime@npm:^2.0.0": - version: 2.3.0 - resolution: "hast-util-to-jsx-runtime@npm:2.3.0" + version: 2.3.2 + resolution: "hast-util-to-jsx-runtime@npm:2.3.2" dependencies: "@types/estree": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" @@ -8582,7 +8975,7 @@ __metadata: style-to-object: "npm:^1.0.0" unist-util-position: "npm:^5.0.0" vfile-message: "npm:^4.0.0" - checksum: 10c0/df7a36dcc792df7667a54438f044b721753d5e09692606d23bf7336bf4651670111fe7728eebbf9f0e4f96ab3346a05bb23037fa1b1d115482b3bc5bde8b6912 + checksum: 10c0/97761b2a48b8bc37da3d66cb4872312ae06c6e8f9be59e33b04b21fa5af371a39cb23b3ca165dd8e898ba1caf9b76399da35c957e68bad02a587a3a324216d56 languageName: node linkType: hard @@ -8730,8 +9123,8 @@ __metadata: linkType: hard "html-webpack-plugin@npm:^5.5.3": - version: 5.6.0 - resolution: "html-webpack-plugin@npm:5.6.0" + version: 5.6.2 + resolution: "html-webpack-plugin@npm:5.6.2" dependencies: "@types/html-minifier-terser": "npm:^6.0.0" html-minifier-terser: "npm:^6.0.2" @@ -8746,7 +9139,7 @@ __metadata: optional: true webpack: optional: true - checksum: 10c0/50d1a0f90d512463ea8d798985d91a7ccc9d5e461713dedb240125b2ff0671f58135dd9355f7969af341ff4725e73b2defbc0984cfdce930887a48506d970002 + checksum: 10c0/4a6e8367d47e9265aaebd30cd83076bb4a1006eda526b7273f06328f68d1ad2d088da29bd10b41e5016352e8dc1f2b63707a36dde26bed438a01c23cd3799844 languageName: node linkType: hard @@ -8831,8 +9224,8 @@ __metadata: linkType: hard "http-proxy-middleware@npm:^2.0.3": - version: 2.0.6 - resolution: "http-proxy-middleware@npm:2.0.6" + version: 2.0.7 + resolution: "http-proxy-middleware@npm:2.0.7" dependencies: "@types/http-proxy": "npm:^1.17.8" http-proxy: "npm:^1.18.1" @@ -8844,7 +9237,7 @@ __metadata: peerDependenciesMeta: "@types/express": optional: true - checksum: 10c0/25a0e550dd1900ee5048a692e0e9b2b6339d06d487a705d90c47e359e9c6561d648cd7862d001d090e651c9efffa1b6e5160fcf1f299b5fa4935f76e9754eb11 + checksum: 10c0/8d00a61eb215b83826460b07489d8bb095368ec16e02a9d63e228dcf7524e7c20d61561e5476de1391aecd4ec32ea093279cdc972115b311f8e0a95a24c9e47e languageName: node linkType: hard @@ -8945,14 +9338,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.0.4, ignore@npm:^5.2.0, ignore@npm:^5.3.1": - version: 5.3.1 - resolution: "ignore@npm:5.3.1" - checksum: 10c0/703f7f45ffb2a27fb2c5a8db0c32e7dee66b33a225d28e8db4e1be6474795f606686a6e3bcc50e1aa12f2042db4c9d4a7d60af3250511de74620fbed052ea4cd - languageName: node - linkType: hard - -"ignore@npm:^5.2.4": +"ignore@npm:^5.0.4, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 @@ -9060,10 +9446,10 @@ __metadata: languageName: node linkType: hard -"inline-style-parser@npm:0.2.3": - version: 0.2.3 - resolution: "inline-style-parser@npm:0.2.3" - checksum: 10c0/21b46d39a39c8aeaa738346650469388e8a412dd276ab75aa3d85b1883311e89c86a1fdbb8c2f1958f4c979bae74067f6ba0385455b125faf4fa77e1dbb94799 +"inline-style-parser@npm:0.2.4": + version: 0.2.4 + resolution: "inline-style-parser@npm:0.2.4" + checksum: 10c0/ddc0b210eaa03e0f98d677b9836242c583c7c6051e84ce0e704ae4626e7871c5b78f8e30853480218b446355745775df318d4f82d33087ff7e393245efa9a881 languageName: node linkType: hard @@ -9152,11 +9538,11 @@ __metadata: linkType: hard "is-core-module@npm:^2.13.0": - version: 2.15.0 - resolution: "is-core-module@npm:2.15.0" + version: 2.15.1 + resolution: "is-core-module@npm:2.15.1" dependencies: hasown: "npm:^2.0.2" - checksum: 10c0/da161f3d9906f459486da65609b2f1a2dfdc60887c689c234d04e88a062cb7920fa5be5fb7ab08dc43b732929653c4135ef05bf77888ae2a9040ce76815eb7b1 + checksum: 10c0/53432f10c69c40bfd2fa8914133a68709ff9498c86c3bf5fca3cdf3145a56fd2168cbf4a43b29843a6202a120a5f9c5ffba0a4322e1e3441739bc0b641682612 languageName: node linkType: hard @@ -9295,13 +9681,6 @@ __metadata: languageName: node linkType: hard -"is-plain-obj@npm:^2.1.0": - version: 2.1.0 - resolution: "is-plain-obj@npm:2.1.0" - checksum: 10c0/e5c9814cdaa627a9ad0a0964ded0e0491bfd9ace405c49a5d63c88b30a162f1512c069d5b80997893c4d0181eadc3fed02b4ab4b81059aba5620bfcdfdeb9c53 - languageName: node - linkType: hard - "is-plain-obj@npm:^3.0.0": version: 3.0.0 resolution: "is-plain-obj@npm:3.0.0" @@ -9325,15 +9704,6 @@ __metadata: languageName: node linkType: hard -"is-reference@npm:^3.0.0": - version: 3.0.2 - resolution: "is-reference@npm:3.0.2" - dependencies: - "@types/estree": "npm:*" - checksum: 10c0/652d31b405e8e8269071cee78fe874b072745012eba202c6dc86880fd603a65ae043e3160990ab4a0a4b33567cbf662eecf3bc6b3c2c1550e6c2b6cf885ce5aa - languageName: node - linkType: hard - "is-regexp@npm:^1.0.0": version: 1.0.0 resolution: "is-regexp@npm:1.0.0" @@ -9457,21 +9827,17 @@ __metadata: linkType: hard "jackspeak@npm:^4.0.1": - version: 4.0.1 - resolution: "jackspeak@npm:4.0.1" + version: 4.0.2 + resolution: "jackspeak@npm:4.0.2" dependencies: "@isaacs/cliui": "npm:^8.0.2" - "@pkgjs/parseargs": "npm:^0.11.0" - dependenciesMeta: - "@pkgjs/parseargs": - optional: true - checksum: 10c0/c87997d9c9c5b7366259b1f2a444ef148692f8eedad5307caca939babbb60af2b47d306e5c63bf9d5fefbab2ab48d4da275188c3de525d0e716cc21b784bbccb + checksum: 10c0/b26039d11c0163a95b1e58851b9ac453cce64ad6d1eb98a00b303ad5eeb761b29d33c9419d1e16c016d3f7151c8edf7df223e6cf93a1907655fd95d6ce85c0de languageName: node linkType: hard "jayson@npm:^4.1.1": - version: 4.1.1 - resolution: "jayson@npm:4.1.1" + version: 4.1.2 + resolution: "jayson@npm:4.1.2" dependencies: "@types/connect": "npm:^3.4.33" "@types/node": "npm:^12.12.54" @@ -9487,11 +9853,11 @@ __metadata: ws: "npm:^7.5.10" bin: jayson: bin/jayson.js - checksum: 10c0/cee6fd5c2b432514955846981b96bd7359356ea3e839206996c8371dca1801ad3e2b685913c7f6519f701cd3c35b8c99b0b40f69fb3218fcbb92962cfa7fd665 + checksum: 10c0/c3e0be127c2450fc8d4003386d29762a8a02ac9554801770729b64cf6d76c973ee1165761571c7455f5a3d1369a3ddde16c184b9df62405896ae05b8152cd571 languageName: node linkType: hard -"jest-diff@npm:^29.4.1": +"jest-diff@npm:^29.4.1, jest-diff@npm:^29.7.0": version: 29.7.0 resolution: "jest-diff@npm:29.7.0" dependencies: @@ -9510,6 +9876,35 @@ __metadata: languageName: node linkType: hard +"jest-matcher-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-matcher-utils@npm:29.7.0" + dependencies: + chalk: "npm:^4.0.0" + jest-diff: "npm:^29.7.0" + jest-get-type: "npm:^29.6.3" + pretty-format: "npm:^29.7.0" + checksum: 10c0/0d0e70b28fa5c7d4dce701dc1f46ae0922102aadc24ed45d594dd9b7ae0a8a6ef8b216718d1ab79e451291217e05d4d49a82666e1a3cc2b428b75cd9c933244e + languageName: node + linkType: hard + +"jest-message-util@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-message-util@npm:29.7.0" + dependencies: + "@babel/code-frame": "npm:^7.12.13" + "@jest/types": "npm:^29.6.3" + "@types/stack-utils": "npm:^2.0.0" + chalk: "npm:^4.0.0" + graceful-fs: "npm:^4.2.9" + micromatch: "npm:^4.0.4" + pretty-format: "npm:^29.7.0" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.3" + checksum: 10c0/850ae35477f59f3e6f27efac5215f706296e2104af39232bb14e5403e067992afb5c015e87a9243ec4d9df38525ef1ca663af9f2f4766aa116f127247008bd22 + languageName: node + linkType: hard + "jest-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-util@npm:29.7.0" @@ -9569,6 +9964,13 @@ __metadata: languageName: node linkType: hard +"joycon@npm:^3.1.1": + version: 3.1.1 + resolution: "joycon@npm:3.1.1" + checksum: 10c0/131fb1e98c9065d067fd49b6e685487ac4ad4d254191d7aa2c9e3b90f4e9ca70430c43cad001602bdbdabcf58717d3b5c5b7461c1bd8e39478c8de706b3fe6ae + languageName: node + linkType: hard + "js-sha256@npm:^0.9.0": version: 0.9.0 resolution: "js-sha256@npm:0.9.0" @@ -9613,21 +10015,12 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^2.5.1": - version: 2.5.2 - resolution: "jsesc@npm:2.5.2" - bin: - jsesc: bin/jsesc - checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88 - languageName: node - linkType: hard - -"jsesc@npm:~0.5.0": - version: 0.5.0 - resolution: "jsesc@npm:0.5.0" +"jsesc@npm:^3.0.2, jsesc@npm:~3.0.2": + version: 3.0.2 + resolution: "jsesc@npm:3.0.2" bin: jsesc: bin/jsesc - checksum: 10c0/f93792440ae1d80f091b65f8ceddf8e55c4bb7f1a09dee5dcbdb0db5612c55c0f6045625aa6b7e8edb2e0a4feabd80ee48616dbe2d37055573a84db3d24f96d9 + checksum: 10c0/ef22148f9e793180b14d8a145ee6f9f60f301abf443288117b4b6c53d0ecd58354898dc506ccbb553a5f7827965cd38bc5fb726575aae93c5e8915e2de8290e1 languageName: node linkType: hard @@ -9685,17 +10078,6 @@ __metadata: languageName: node linkType: hard -"json5@npm:^1.0.2": - version: 1.0.2 - resolution: "json5@npm:1.0.2" - dependencies: - minimist: "npm:^1.2.0" - bin: - json5: lib/cli.js - checksum: 10c0/9ee316bf21f000b00752e6c2a3b79ecf5324515a5c60ee88983a1910a45426b643a4f3461657586e8aeca87aaf96f0a519b0516d2ae527a6c3e7eed80f68717f - languageName: node - linkType: hard - "json5@npm:^2.1.2, json5@npm:^2.2.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" @@ -9739,13 +10121,6 @@ __metadata: languageName: node linkType: hard -"just-extend@npm:^6.2.0": - version: 6.2.0 - resolution: "just-extend@npm:6.2.0" - checksum: 10c0/d41cbdb6d85b986d4deaf2144d81d4f7266cd408fc95189d046d63f610c2dc486b141aeb6ef319c2d76fe904d45a6bb31f19b098ff0427c35688e0c383fc0511 - languageName: node - linkType: hard - "keyv@npm:^4.5.3, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -9791,12 +10166,12 @@ __metadata: linkType: hard "launch-editor@npm:^2.6.0": - version: 2.8.1 - resolution: "launch-editor@npm:2.8.1" + version: 2.9.1 + resolution: "launch-editor@npm:2.9.1" dependencies: picocolors: "npm:^1.0.0" shell-quote: "npm:^1.8.1" - checksum: 10c0/e18fcda6617a995306602871c7a71ddcfdd82d88a57508ae970be86bfb6685f131cf9ddb8896df4e8e4cde6d0e2d14318d2b41314eaae6abf03ca205948daa27 + checksum: 10c0/891f1d136ed8e4ea12e16c196a0d2e07f23c7b983e3ab532b2be1775fb244909581507cce97c50f9d5ca92680b53e4a75c72ddcf20184aa6c4da6ebbe87703f5 languageName: node linkType: hard @@ -9868,8 +10243,8 @@ __metadata: linkType: hard "listr2@npm:~8.2.4": - version: 8.2.4 - resolution: "listr2@npm:8.2.4" + version: 8.2.5 + resolution: "listr2@npm:8.2.5" dependencies: cli-truncate: "npm:^4.0.0" colorette: "npm:^2.0.20" @@ -9877,7 +10252,14 @@ __metadata: log-update: "npm:^6.1.0" rfdc: "npm:^1.4.1" wrap-ansi: "npm:^9.0.0" - checksum: 10c0/df5b129e9767de1997973cec6103cd4bd6fc3b3367685b7c23048d12b61d5b7e44fecd8a3d3534c0e1c963bd5ac43ca501d14712f46fa101050037be323a5c16 + checksum: 10c0/f5a9599514b00c27d7eb32d1117c83c61394b2a985ec20e542c798bf91cf42b19340215701522736f5b7b42f557e544afeadec47866e35e5d4f268f552729671 + languageName: node + linkType: hard + +"load-tsconfig@npm:^0.2.3": + version: 0.2.5 + resolution: "load-tsconfig@npm:0.2.5" + checksum: 10c0/bf2823dd26389d3497b6567f07435c5a7a58d9df82e879b0b3892f87d8db26900f84c85bc329ef41c0540c0d6a448d1c23ddc64a80f3ff6838b940f3915a3fcb languageName: node linkType: hard @@ -9941,13 +10323,6 @@ __metadata: languageName: node linkType: hard -"lodash.get@npm:^4.4.2": - version: 4.4.2 - resolution: "lodash.get@npm:4.4.2" - checksum: 10c0/48f40d471a1654397ed41685495acb31498d5ed696185ac8973daef424a749ca0c7871bf7b665d5c14f5cc479394479e0307e781f61d5573831769593411be6e - languageName: node - linkType: hard - "lodash.memoize@npm:^4.1.2": version: 4.1.2 resolution: "lodash.memoize@npm:4.1.2" @@ -9962,6 +10337,13 @@ __metadata: languageName: node linkType: hard +"lodash.sortby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.sortby@npm:4.7.0" + checksum: 10c0/fc48fb54ff7669f33bb32997cab9460757ee99fafaf72400b261c3e10fde21538e47d8cfcbe6a25a31bcb5b7b727c27d52626386fc2de24eb059a6d64a89cdf5 + languageName: node + linkType: hard + "lodash.uniq@npm:^4.5.0": version: 4.5.0 resolution: "lodash.uniq@npm:4.5.0" @@ -9976,7 +10358,7 @@ __metadata: languageName: node linkType: hard -"log-symbols@npm:^4.0.0, log-symbols@npm:^4.1.0": +"log-symbols@npm:^4.0.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" dependencies: @@ -10017,6 +10399,13 @@ __metadata: languageName: node linkType: hard +"loupe@npm:^3.1.0, loupe@npm:^3.1.1": + version: 3.1.2 + resolution: "loupe@npm:3.1.2" + checksum: 10c0/b13c02e3ddd6a9d5f8bf84133b3242de556512d824dddeea71cce2dbd6579c8f4d672381c4e742d45cf4423d0701765b4a6e5fbc24701def16bc2b40f8daa96a + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -10041,9 +10430,9 @@ __metadata: linkType: hard "lru-cache@npm:^11.0.0": - version: 11.0.0 - resolution: "lru-cache@npm:11.0.0" - checksum: 10c0/827ff0e0739f9b0f30f92f5a5fc97c6a2bd3ae32c0452bc58cb7411d6c589d49536073027293f2d1f02d0c2e72b63b162f238df7e9ff6f4cc0345f92afec4d1d + version: 11.0.1 + resolution: "lru-cache@npm:11.0.1" + checksum: 10c0/8bad6603dc67eb5b03520fba05bce5df6473dbba58ac4c6067ed088d29225a0a04416bb1462acd8c1f819d1fbf37920446a1c36bafd9c384bcc54cee0d3b697a languageName: node linkType: hard @@ -10063,10 +10452,12 @@ __metadata: languageName: node linkType: hard -"make-error@npm:^1.1.1": - version: 1.3.6 - resolution: "make-error@npm:1.3.6" - checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f +"magic-string@npm:^0.30.11": + version: 0.30.12 + resolution: "magic-string@npm:0.30.12" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + checksum: 10c0/469f457d18af37dfcca8617086ea8a65bcd8b60ba8a1182cb024ce43e470ace3c9d1cb6bee58d3b311768fb16bc27bd50bdeebcaa63dadd0fd46cac4d2e11d5f languageName: node linkType: hard @@ -10183,15 +10574,15 @@ __metadata: linkType: hard "mdast-util-gfm-autolink-literal@npm:^2.0.0": - version: 2.0.0 - resolution: "mdast-util-gfm-autolink-literal@npm:2.0.0" + version: 2.0.1 + resolution: "mdast-util-gfm-autolink-literal@npm:2.0.1" dependencies: "@types/mdast": "npm:^4.0.0" ccount: "npm:^2.0.0" devlop: "npm:^1.0.0" mdast-util-find-and-replace: "npm:^3.0.0" micromark-util-character: "npm:^2.0.0" - checksum: 10c0/821ef91db108f05b321c54fdf4436df9d6badb33e18f714d8d52c0e70f988f5b6b118cdd4d607b4cb3bef1718304ce7e9fb25fa580622c3d20d68c1489c64875 + checksum: 10c0/963cd22bd42aebdec7bdd0a527c9494d024d1ad0739c43dc040fee35bdfb5e29c22564330a7418a72b5eab51d47a6eff32bc0255ef3ccb5cebfe8970e91b81b6 languageName: node linkType: hard @@ -10260,8 +10651,8 @@ __metadata: linkType: hard "mdast-util-mdx-expression@npm:^2.0.0": - version: 2.0.0 - resolution: "mdast-util-mdx-expression@npm:2.0.0" + version: 2.0.1 + resolution: "mdast-util-mdx-expression@npm:2.0.1" dependencies: "@types/estree-jsx": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" @@ -10269,13 +10660,13 @@ __metadata: devlop: "npm:^1.0.0" mdast-util-from-markdown: "npm:^2.0.0" mdast-util-to-markdown: "npm:^2.0.0" - checksum: 10c0/512848cbc44b9dc7cffc1bb3f95f7e67f0d6562870e56a67d25647f475d411e136b915ba417c8069fb36eac1839d0209fb05fb323d377f35626a82fcb0879363 + checksum: 10c0/9a1e57940f66431f10312fa239096efa7627f375e7933b5d3162c0b5c1712a72ac87447aff2b6838d2bbd5c1311b188718cc90b33b67dc67a88550e0a6ef6183 languageName: node linkType: hard "mdast-util-mdx-jsx@npm:^3.0.0": - version: 3.1.2 - resolution: "mdast-util-mdx-jsx@npm:3.1.2" + version: 3.1.3 + resolution: "mdast-util-mdx-jsx@npm:3.1.3" dependencies: "@types/estree-jsx": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" @@ -10287,10 +10678,9 @@ __metadata: mdast-util-to-markdown: "npm:^2.0.0" parse-entities: "npm:^4.0.0" stringify-entities: "npm:^4.0.0" - unist-util-remove-position: "npm:^5.0.0" unist-util-stringify-position: "npm:^4.0.0" vfile-message: "npm:^4.0.0" - checksum: 10c0/855b60c3db9bde2fe142bd366597f7bd5892fc288428ba054e26ffcffc07bfe5648c0792d614ba6e08b1eab9784ffc3c1267cf29dfc6db92b419d68b5bcd487d + checksum: 10c0/1b0b64215efbbbb1ee9ba2a2b3e5f11859dada7dff162949a0d503aefbd75c0308f17d404df126c54acea06d2224905915b2cac2e6c999514c919bd963b8de24 languageName: node linkType: hard @@ -10463,8 +10853,8 @@ __metadata: linkType: hard "micromark-extension-directive@npm:^3.0.0": - version: 3.0.1 - resolution: "micromark-extension-directive@npm:3.0.1" + version: 3.0.2 + resolution: "micromark-extension-directive@npm:3.0.2" dependencies: devlop: "npm:^1.0.0" micromark-factory-space: "npm:^2.0.0" @@ -10473,7 +10863,7 @@ __metadata: micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" parse-entities: "npm:^4.0.0" - checksum: 10c0/9d226fba0ce18f326d2b28cf2b981c78f6c0c7c2f85e810bf4b12a788dfa4b694386589b081da165227da573ff547238f39c5258d09954b055f167bba1af4983 + checksum: 10c0/74137485375f02c1b640c2120dd6b9f6aa1e39ca5cd2463df7974ef1cc80203f5ef90448ce009973355a49ba169ef1441eabe57a36877c7b86373788612773da languageName: node linkType: hard @@ -10599,8 +10989,8 @@ __metadata: linkType: hard "micromark-extension-mdx-jsx@npm:^3.0.0": - version: 3.0.0 - resolution: "micromark-extension-mdx-jsx@npm:3.0.0" + version: 3.0.1 + resolution: "micromark-extension-mdx-jsx@npm:3.0.1" dependencies: "@types/acorn": "npm:^4.0.0" "@types/estree": "npm:^1.0.0" @@ -10609,10 +10999,11 @@ __metadata: micromark-factory-mdx-expression: "npm:^2.0.0" micromark-factory-space: "npm:^2.0.0" micromark-util-character: "npm:^2.0.0" + micromark-util-events-to-acorn: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" vfile-message: "npm:^4.0.0" - checksum: 10c0/18a81c8def7f3a2088dc435bba19e649c19f679464b1a01e2c680f9518820e70fb0974b8403c790aee8f44205833a280b56ba157fe5a5b2903b476c5de5ba353 + checksum: 10c0/11e65abd6b57bcf82665469cd1ff238b7cfc4ebb4942a0361df2dc7dd4ab133681b2bcbd4c388dddf6e4db062665d31efeb48cc844ee61c8d8de9d167cc946d8 languageName: node linkType: hard @@ -10682,18 +11073,19 @@ __metadata: linkType: hard "micromark-factory-mdx-expression@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-mdx-expression@npm:2.0.1" + version: 2.0.2 + resolution: "micromark-factory-mdx-expression@npm:2.0.2" dependencies: "@types/estree": "npm:^1.0.0" devlop: "npm:^1.0.0" + micromark-factory-space: "npm:^2.0.0" micromark-util-character: "npm:^2.0.0" micromark-util-events-to-acorn: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" unist-util-position-from-estree: "npm:^2.0.0" vfile-message: "npm:^4.0.0" - checksum: 10c0/d9cf475a73a7fbfa09aba0d057e033d57e45b7adff78692be9efb4405c4a1717ece4594a632f92a4302e4f8f2ae96355785b616e3f5b2fe8599ec24cfdeee12d + checksum: 10c0/87372775ae06478ab754efa058a5e382972f634c14f0afa303111037c30abf733fe65329a7e59cda969266e63f82104d9ed8ff9ada39189eab0651b6540ca64a languageName: node linkType: hard @@ -11030,14 +11422,14 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.7.6": - version: 2.9.0 - resolution: "mini-css-extract-plugin@npm:2.9.0" + version: 2.9.1 + resolution: "mini-css-extract-plugin@npm:2.9.1" dependencies: schema-utils: "npm:^4.0.0" tapable: "npm:^2.2.1" peerDependencies: webpack: ^5.0.0 - checksum: 10c0/46e20747ea250420db8a82801b9779299ce3cd5ec4d6dd75e00904c39cc80f0f01decaa534b8cb9658d7d3b656b919cb2cc84b1ba7e2394d2d6548578a5c2901 + checksum: 10c0/19361902ef028b9875aafa3931d99643c2d95824ba343a501c83ff61d069a430fcfc523ca796765798b564570da2199f5a28cd51b9528ddbcfdc9271c61400d0 languageName: node linkType: hard @@ -11075,15 +11467,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.1, minimatch@npm:^5.1.6": - version: 5.1.6 - resolution: "minimatch@npm:5.1.6" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/3defdfd230914f22a8da203747c42ee3c405c39d4d37ffda284dac5e45b7e1f6c49aa8be606509002898e73091ff2a3bbfc59c2c6c71d4660609f63aa92f98e3 - languageName: node - linkType: hard - "minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.5 resolution: "minimatch@npm:9.0.5" @@ -11184,17 +11567,6 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^0.5.1": - version: 0.5.6 - resolution: "mkdirp@npm:0.5.6" - dependencies: - minimist: "npm:^1.2.6" - bin: - mkdirp: bin/cmd.js - checksum: 10c0/e2e2be789218807b58abced04e7b49851d9e46e88a2f9539242cc8a92c9b5c3a0b9bab360bd3014e02a140fc4fbc58e31176c408b493f8a2a6f4986bd7527b01 - languageName: node - linkType: hard - "mkdirp@npm:^1.0.3": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" @@ -11204,37 +11576,6 @@ __metadata: languageName: node linkType: hard -"mocha@npm:^10.7.3": - version: 10.7.3 - resolution: "mocha@npm:10.7.3" - dependencies: - ansi-colors: "npm:^4.1.3" - browser-stdout: "npm:^1.3.1" - chokidar: "npm:^3.5.3" - debug: "npm:^4.3.5" - diff: "npm:^5.2.0" - escape-string-regexp: "npm:^4.0.0" - find-up: "npm:^5.0.0" - glob: "npm:^8.1.0" - he: "npm:^1.2.0" - js-yaml: "npm:^4.1.0" - log-symbols: "npm:^4.1.0" - minimatch: "npm:^5.1.6" - ms: "npm:^2.1.3" - serialize-javascript: "npm:^6.0.2" - strip-json-comments: "npm:^3.1.1" - supports-color: "npm:^8.1.1" - workerpool: "npm:^6.5.1" - yargs: "npm:^16.2.0" - yargs-parser: "npm:^20.2.9" - yargs-unparser: "npm:^2.0.0" - bin: - _mocha: bin/_mocha - mocha: bin/mocha.js - checksum: 10c0/76a205905ec626262d903954daca31ba8e0dd4347092f627b98b8508dcdb5b30be62ec8f7a405fab3b2e691bdc099721c3291b330c3ee85b8ec40d3d179f8728 - languageName: node - linkType: hard - "mrmime@npm:^2.0.0": version: 2.0.0 resolution: "mrmime@npm:2.0.0" @@ -11249,13 +11590,6 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.2": - version: 2.1.2 - resolution: "ms@npm:2.1.2" - checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc - languageName: node - linkType: hard - "ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" @@ -11302,13 +11636,20 @@ __metadata: languageName: node linkType: hard -"negotiator@npm:0.6.3, negotiator@npm:^0.6.3": +"negotiator@npm:0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 languageName: node linkType: hard +"negotiator@npm:^0.6.3": + version: 0.6.4 + resolution: "negotiator@npm:0.6.4" + checksum: 10c0/3e677139c7fb7628a6f36335bf11a885a62c21d5390204590a1a214a5631fcbe5ea74ef6a610b60afe84b4d975cbe0566a23f20ee17c77c73e74b80032108dea + languageName: node + linkType: hard + "neo-async@npm:^2.6.2": version: 2.6.2 resolution: "neo-async@npm:2.6.2" @@ -11316,19 +11657,6 @@ __metadata: languageName: node linkType: hard -"nise@npm:^6.1.1": - version: 6.1.1 - resolution: "nise@npm:6.1.1" - dependencies: - "@sinonjs/commons": "npm:^3.0.1" - "@sinonjs/fake-timers": "npm:^13.0.1" - "@sinonjs/text-encoding": "npm:^0.7.3" - just-extend: "npm:^6.2.0" - path-to-regexp: "npm:^8.1.0" - checksum: 10c0/09471adb738dc3be2981cc7815c90879ed6a5a3e162202ca66e12f9a5a0956bea718d0ec2f0c07acc26e3f958481b8fb30c30da76c13620e922f3b9dcd249c50 - languageName: node - linkType: hard - "no-case@npm:^3.0.4": version: 3.0.4 resolution: "no-case@npm:3.0.4" @@ -11373,13 +11701,13 @@ __metadata: linkType: hard "node-gyp-build@npm:^4.3.0": - version: 4.8.1 - resolution: "node-gyp-build@npm:4.8.1" + version: 4.8.2 + resolution: "node-gyp-build@npm:4.8.2" bin: node-gyp-build: bin.js node-gyp-build-optional: optional.js node-gyp-build-test: build-test.js - checksum: 10c0/e36ca3d2adf2b9cca316695d7687207c19ac6ed326d6d7c68d7112cebe0de4f82d6733dff139132539fcc01cf5761f6c9082a21864ab9172edf84282bc849ce7 + checksum: 10c0/d816b43974d31d6257b6e87d843f2626c72389a285208394bc57a7766b210454d2642860a5e5b5c333d8ecabaeabad3b31b94f58cf8ca1aabdef0c320d02baaa languageName: node linkType: hard @@ -11502,20 +11830,20 @@ __metadata: linkType: hard "nx@npm:^20.0.2": - version: 20.0.2 - resolution: "nx@npm:20.0.2" + version: 20.0.3 + resolution: "nx@npm:20.0.3" dependencies: "@napi-rs/wasm-runtime": "npm:0.2.4" - "@nx/nx-darwin-arm64": "npm:20.0.2" - "@nx/nx-darwin-x64": "npm:20.0.2" - "@nx/nx-freebsd-x64": "npm:20.0.2" - "@nx/nx-linux-arm-gnueabihf": "npm:20.0.2" - "@nx/nx-linux-arm64-gnu": "npm:20.0.2" - "@nx/nx-linux-arm64-musl": "npm:20.0.2" - "@nx/nx-linux-x64-gnu": "npm:20.0.2" - "@nx/nx-linux-x64-musl": "npm:20.0.2" - "@nx/nx-win32-arm64-msvc": "npm:20.0.2" - "@nx/nx-win32-x64-msvc": "npm:20.0.2" + "@nx/nx-darwin-arm64": "npm:20.0.3" + "@nx/nx-darwin-x64": "npm:20.0.3" + "@nx/nx-freebsd-x64": "npm:20.0.3" + "@nx/nx-linux-arm-gnueabihf": "npm:20.0.3" + "@nx/nx-linux-arm64-gnu": "npm:20.0.3" + "@nx/nx-linux-arm64-musl": "npm:20.0.3" + "@nx/nx-linux-x64-gnu": "npm:20.0.3" + "@nx/nx-linux-x64-musl": "npm:20.0.3" + "@nx/nx-win32-arm64-msvc": "npm:20.0.3" + "@nx/nx-win32-x64-msvc": "npm:20.0.3" "@yarnpkg/lockfile": "npm:^1.1.0" "@yarnpkg/parsers": "npm:3.0.0-rc.46" "@zkochan/js-yaml": "npm:0.0.7" @@ -11579,7 +11907,7 @@ __metadata: bin: nx: bin/nx.js nx-cloud: bin/nx-cloud.js - checksum: 10c0/96c7dd5d74a3e9388cbc40a664ce1a9d558c811448d1a5b82b1f5d5ca1326971b00c330d83226602a44c1d6ffb69e3e681caad5ecf8edd6cb502a5a5dc3ec22a + checksum: 10c0/56f14a7490b99a966207b682f455d17c93acf3522e7e5c6c6e45808d5b7bef1587842f8c4de1c746086be962b6fae8fcf5fcc6ea7aa221b0ee55ed22ff0ef0c3 languageName: node linkType: hard @@ -11675,6 +12003,15 @@ __metadata: languageName: node linkType: hard +"oniguruma-to-js@npm:0.4.3": + version: 0.4.3 + resolution: "oniguruma-to-js@npm:0.4.3" + dependencies: + regex: "npm:^4.3.2" + checksum: 10c0/47d8a4089b1fd0ae4b9781907a92222ae549756ddb72a177a85fdc3bda8e59ce2840710dd03e448b80c9878aa8f4e14519fccc3652da71fc3e8bc048d5cb6acb + languageName: node + linkType: hard + "open@npm:^8.0.9, open@npm:^8.4.0": version: 8.4.2 resolution: "open@npm:8.4.2" @@ -11813,9 +12150,9 @@ __metadata: linkType: hard "package-json-from-dist@npm:^1.0.0": - version: 1.0.0 - resolution: "package-json-from-dist@npm:1.0.0" - checksum: 10c0/e3ffaf6ac1040ab6082a658230c041ad14e72fabe99076a2081bb1d5d41210f11872403fc09082daf4387fc0baa6577f96c9c0e94c90c394fd57794b66aa4033 + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b languageName: node linkType: hard @@ -11893,21 +12230,21 @@ __metadata: linkType: hard "parse5-htmlparser2-tree-adapter@npm:^7.0.0": - version: 7.0.0 - resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0" + version: 7.1.0 + resolution: "parse5-htmlparser2-tree-adapter@npm:7.1.0" dependencies: - domhandler: "npm:^5.0.2" + domhandler: "npm:^5.0.3" parse5: "npm:^7.0.0" - checksum: 10c0/e820cacb8486e6f7ede403327d18480df086d70e32ede2f6654d8c3a8b4b8dc4a4d5c21c03c18a92ba2466c513b93ca63be4a138dd73cd0995f384eb3b9edf11 + checksum: 10c0/e5a4e0b834c84c9e244b5749f8d007f4baaeafac7a1da2c54be3421ffd9ef8fdec4f198bf55cda22e88e6ba95e9943f6ed5aa3ae5900b39972ebf5dc8c3f4722 languageName: node linkType: hard "parse5@npm:^7.0.0": - version: 7.1.2 - resolution: "parse5@npm:7.1.2" + version: 7.2.0 + resolution: "parse5@npm:7.2.0" dependencies: - entities: "npm:^4.4.0" - checksum: 10c0/297d7af8224f4b5cb7f6617ecdae98eeaed7f8cbd78956c42785e230505d5a4f07cef352af10d3006fa5c1544b76b57784d3a22d861ae071bbc460c649482bf4 + entities: "npm:^4.5.0" + checksum: 10c0/76d68684708befb41ff1d5e0e9835f566afb3950807d340941afc9dbe4c9c28db2414bda0c8503d459de863463869b8540c6abf8c9742cffa0b9b31eecd37951 languageName: node linkType: hard @@ -12011,26 +12348,19 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:2.2.1": - version: 2.2.1 - resolution: "path-to-regexp@npm:2.2.1" - checksum: 10c0/f4b51090a73dad5ce0720f13ce8528ac77914bc927d72cc4ba05ab32770ad3a8d2e431962734b688b9ed863d4098d858da6ff4746037e4e24259cbd3b2c32b79 +"path-to-regexp@npm:3.3.0": + version: 3.3.0 + resolution: "path-to-regexp@npm:3.3.0" + checksum: 10c0/ffa0ebe7088d38d435a8d08b0fe6e8c93ceb2a81a65d4dd1d9a538f52e09d5e3474ed5f553cb3b180d894b0caa10698a68737ab599fd1e56b4663d1a64c9f77b languageName: node linkType: hard "path-to-regexp@npm:^1.7.0": - version: 1.8.0 - resolution: "path-to-regexp@npm:1.8.0" + version: 1.9.0 + resolution: "path-to-regexp@npm:1.9.0" dependencies: isarray: "npm:0.0.1" - checksum: 10c0/7b25d6f27a8de03f49406d16195450f5ced694398adea1510b0f949d9660600d1769c5c6c83668583b7e6b503f3caf1ede8ffc08135dbe3e982f034f356fbb5c - languageName: node - linkType: hard - -"path-to-regexp@npm:^8.1.0": - version: 8.1.0 - resolution: "path-to-regexp@npm:8.1.0" - checksum: 10c0/1c46be3806ab081bedc51eb238fcb026b61b15f19e8924b26e7dad88812dda499efe357a780665dc915dcab3be67213f145f5e2921b8fc8c6c497608d4e092ed + checksum: 10c0/de9ddb01b84d9c2c8e2bed18630d8d039e2d6f60a6538595750fa08c7a6482512257464c8da50616f266ab2cdd2428387e85f3b089e4c3f25d0c537e898a0751 languageName: node linkType: hard @@ -12041,21 +12371,24 @@ __metadata: languageName: node linkType: hard -"periscopic@npm:^3.0.0": - version: 3.1.0 - resolution: "periscopic@npm:3.1.0" - dependencies: - "@types/estree": "npm:^1.0.0" - estree-walker: "npm:^3.0.0" - is-reference: "npm:^3.0.0" - checksum: 10c0/fb5ce7cd810c49254cdf1cd3892811e6dd1a1dfbdf5f10a0a33fb7141baac36443c4cad4f0e2b30abd4eac613f6ab845c2bc1b7ce66ae9694c7321e6ada5bd96 +"pathe@npm:^1.1.2": + version: 1.1.2 + resolution: "pathe@npm:1.1.2" + checksum: 10c0/64ee0a4e587fb0f208d9777a6c56e4f9050039268faaaaecd50e959ef01bf847b7872785c36483fa5cdcdbdfdb31fef2ff222684d4fc21c330ab60395c681897 languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1": - version: 1.0.1 - resolution: "picocolors@npm:1.0.1" - checksum: 10c0/c63cdad2bf812ef0d66c8db29583802355d4ca67b9285d846f390cc15c2f6ccb94e8cb7eb6a6e97fc5990a6d3ad4ae42d86c84d3146e667c739a4234ed50d400 +"pathval@npm:^2.0.0": + version: 2.0.0 + resolution: "pathval@npm:2.0.0" + checksum: 10c0/602e4ee347fba8a599115af2ccd8179836a63c925c23e04bd056d0674a64b39e3a081b643cc7bc0b84390517df2d800a46fcc5598d42c155fe4977095c2f77c5 + languageName: node + linkType: hard + +"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.0": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 languageName: node linkType: hard @@ -12066,6 +12399,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^4.0.2": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: 10c0/7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc + languageName: node + linkType: hard + "pidtree@npm:~0.6.0": version: 0.6.0 resolution: "pidtree@npm:0.6.0" @@ -12075,6 +12415,13 @@ __metadata: languageName: node linkType: hard +"pirates@npm:^4.0.1": + version: 4.0.6 + resolution: "pirates@npm:4.0.6" + checksum: 10c0/00d5fa51f8dded94d7429700fb91a0c1ead00ae2c7fd27089f0c5b63e6eca36197fe46384631872690a66f390c5e27198e99006ab77ae472692ab9c2ca903f36 + languageName: node + linkType: hard + "pkg-dir@npm:^7.0.0": version: 7.0.0 resolution: "pkg-dir@npm:7.0.0" @@ -12178,6 +12525,29 @@ __metadata: languageName: node linkType: hard +"postcss-load-config@npm:^6.0.1": + version: 6.0.1 + resolution: "postcss-load-config@npm:6.0.1" + dependencies: + lilconfig: "npm:^3.1.1" + peerDependencies: + jiti: ">=1.21.0" + postcss: ">=8.0.9" + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + checksum: 10c0/74173a58816dac84e44853f7afbd283f4ef13ca0b6baeba27701214beec33f9e309b128f8102e2b173e8d45ecba45d279a9be94b46bf48d219626aa9b5730848 + languageName: node + linkType: hard + "postcss-loader@npm:^7.3.3": version: 7.3.4 resolution: "postcss-loader@npm:7.3.4" @@ -12526,14 +12896,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.21, postcss@npm:^8.4.24, postcss@npm:^8.4.26, postcss@npm:^8.4.33, postcss@npm:^8.4.38": - version: 8.4.41 - resolution: "postcss@npm:8.4.41" +"postcss@npm:^8.4.21, postcss@npm:^8.4.24, postcss@npm:^8.4.26, postcss@npm:^8.4.33, postcss@npm:^8.4.38, postcss@npm:^8.4.43": + version: 8.4.47 + resolution: "postcss@npm:8.4.47" dependencies: nanoid: "npm:^3.3.7" - picocolors: "npm:^1.0.1" - source-map-js: "npm:^1.2.0" - checksum: 10c0/c1828fc59e7ec1a3bf52b3a42f615dba53c67960ed82a81df6441b485fe43c20aba7f4e7c55425762fd99c594ecabbaaba8cf5b30fd79dfec5b52a9f63a2d690 + picocolors: "npm:^1.1.0" + source-map-js: "npm:^1.2.1" + checksum: 10c0/929f68b5081b7202709456532cee2a145c1843d391508c5a09de2517e8c4791638f71dd63b1898dba6712f8839d7a6da046c72a5e44c162e908f5911f57b5f44 languageName: node linkType: hard @@ -12563,7 +12933,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.7.0": +"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" dependencies: @@ -12581,19 +12951,7 @@ __metadata: languageName: node linkType: hard -"prism-react-renderer@npm:^2.3.0": - version: 2.3.1 - resolution: "prism-react-renderer@npm:2.3.1" - dependencies: - "@types/prismjs": "npm:^1.26.0" - clsx: "npm:^2.0.0" - peerDependencies: - react: ">=16.0.0" - checksum: 10c0/566932127ca18049a651aa038a8f8c7c1ca15950d21b659c2ce71fd95bd03bef2b5d40c489e7aa3453eaf15d984deef542a609d7842e423e6a13427dd90bd371 - languageName: node - linkType: hard - -"prism-react-renderer@npm:^2.4.0": +"prism-react-renderer@npm:^2.3.0, prism-react-renderer@npm:^2.4.0": version: 2.4.0 resolution: "prism-react-renderer@npm:2.4.0" dependencies: @@ -12695,13 +13053,6 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^1.3.2": - version: 1.4.1 - resolution: "punycode@npm:1.4.1" - checksum: 10c0/354b743320518aef36f77013be6e15da4db24c2b4f62c5f1eb0529a6ed02fbaf1cb52925785f6ab85a962f2b590d9cd5ad730b70da72b5f180e2556b8bd3ca08 - languageName: node - linkType: hard - "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -12901,11 +13252,11 @@ __metadata: linkType: hard "react-json-view-lite@npm:^1.2.0": - version: 1.4.0 - resolution: "react-json-view-lite@npm:1.4.0" + version: 1.5.0 + resolution: "react-json-view-lite@npm:1.5.0" peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: 10c0/80dd21b14f9dcd93b2f473084aaa934594834a98ae2ed5725c98fae34486226d2eaa69a0bc4233f89b7bab4825e2d393efd6f7d39d59aa37a5bb44a61785f7e5 + checksum: 10c0/e707717cb6b9d6cca5b138cdfb066e35ee7e493d1c88d4497e3a3a42b7651c8ff924ff53ad2da142a12b23b11379d39f38d8eee278c98c46cd6bc8844864b285 languageName: node linkType: hard @@ -13040,6 +13391,54 @@ __metadata: languageName: node linkType: hard +"recma-build-jsx@npm:^1.0.0": + version: 1.0.0 + resolution: "recma-build-jsx@npm:1.0.0" + dependencies: + "@types/estree": "npm:^1.0.0" + estree-util-build-jsx: "npm:^3.0.0" + vfile: "npm:^6.0.0" + checksum: 10c0/ca30f5163887b44c74682355da2625f7b49f33267699d22247913e513e043650cbdd6a7497cf13c60f09ad9e7bc2bd35bd20853672773c19188569814b56bb04 + languageName: node + linkType: hard + +"recma-jsx@npm:^1.0.0": + version: 1.0.0 + resolution: "recma-jsx@npm:1.0.0" + dependencies: + acorn-jsx: "npm:^5.0.0" + estree-util-to-js: "npm:^2.0.0" + recma-parse: "npm:^1.0.0" + recma-stringify: "npm:^1.0.0" + unified: "npm:^11.0.0" + checksum: 10c0/26c2af6dd69336c810468b778be1e4cbac5702cf9382454f17c29cf9b03a4fde47d10385bb26a7ccb34f36fe01af34c24cab9fb0deeed066ea53294be0081f07 + languageName: node + linkType: hard + +"recma-parse@npm:^1.0.0": + version: 1.0.0 + resolution: "recma-parse@npm:1.0.0" + dependencies: + "@types/estree": "npm:^1.0.0" + esast-util-from-js: "npm:^2.0.0" + unified: "npm:^11.0.0" + vfile: "npm:^6.0.0" + checksum: 10c0/37c0990859a562d082e02d475ca5f4c8ef0840d285270f6699fe888cbb06260f97eb098585eda4aae416182c207fd19cf05e4f0b2dcf55cbf81dde4406d95545 + languageName: node + linkType: hard + +"recma-stringify@npm:^1.0.0": + version: 1.0.0 + resolution: "recma-stringify@npm:1.0.0" + dependencies: + "@types/estree": "npm:^1.0.0" + estree-util-to-js: "npm:^2.0.0" + unified: "npm:^11.0.0" + vfile: "npm:^6.0.0" + checksum: 10c0/c2ed4c0e8cf8a09aedcd47c5d016d47f6e1ff6c2d4b220e2abaf1b77713bf404756af2ea3ea7999aec5862e8825aff035edceb370c7fd8603a7e9da03bd6987e + languageName: node + linkType: hard + "recursive-readdir@npm:^2.2.2": version: 2.2.3 resolution: "recursive-readdir@npm:2.2.3" @@ -13049,12 +13448,12 @@ __metadata: languageName: node linkType: hard -"regenerate-unicode-properties@npm:^10.1.0": - version: 10.1.1 - resolution: "regenerate-unicode-properties@npm:10.1.1" +"regenerate-unicode-properties@npm:^10.2.0": + version: 10.2.0 + resolution: "regenerate-unicode-properties@npm:10.2.0" dependencies: regenerate: "npm:^1.4.2" - checksum: 10c0/89adb5ee5ba081380c78f9057c02e156a8181969f6fcca72451efc45612e0c3df767b4333f8d8479c274d9c6fe52ec4854f0d8a22ef95dccbe87da8e5f2ac77d + checksum: 10c0/5510785eeaf56bbfdf4e663d6753f125c08d2a372d4107bc1b756b7bf142e2ed80c2733a8b54e68fb309ba37690e66a0362699b0e21d5c1f0255dea1b00e6460 languageName: node linkType: hard @@ -13081,17 +13480,24 @@ __metadata: languageName: node linkType: hard -"regexpu-core@npm:^5.3.1": - version: 5.3.2 - resolution: "regexpu-core@npm:5.3.2" +"regex@npm:^4.3.2": + version: 4.3.3 + resolution: "regex@npm:4.3.3" + checksum: 10c0/543caebc029af8e6205513accf1b32bcafd71a6c48d39af63ce667d043d11d3c81f5c3fa6d9729175c23257180c5588de9e7ae9fe8a1c1d8924699265764dea2 + languageName: node + linkType: hard + +"regexpu-core@npm:^6.1.1": + version: 6.1.1 + resolution: "regexpu-core@npm:6.1.1" dependencies: - "@babel/regjsgen": "npm:^0.8.0" regenerate: "npm:^1.4.2" - regenerate-unicode-properties: "npm:^10.1.0" - regjsparser: "npm:^0.9.1" + regenerate-unicode-properties: "npm:^10.2.0" + regjsgen: "npm:^0.8.0" + regjsparser: "npm:^0.11.0" unicode-match-property-ecmascript: "npm:^2.0.0" unicode-match-property-value-ecmascript: "npm:^2.1.0" - checksum: 10c0/7945d5ab10c8bbed3ca383d4274687ea825aee4ab93a9c51c6e31e1365edd5ea807f6908f800ba017b66c462944ba68011164e7055207747ab651f8111ef3770 + checksum: 10c0/07d49697e20f9b65977535abba4858b7f5171c13f7c366be53ec1886d3d5f69f1b98cc6a6e63cf271adda077c3366a4c851c7473c28bbd69cf5a6b6b008efc3e languageName: node linkType: hard @@ -13113,14 +13519,21 @@ __metadata: languageName: node linkType: hard -"regjsparser@npm:^0.9.1": - version: 0.9.1 - resolution: "regjsparser@npm:0.9.1" +"regjsgen@npm:^0.8.0": + version: 0.8.0 + resolution: "regjsgen@npm:0.8.0" + checksum: 10c0/44f526c4fdbf0b29286101a282189e4dbb303f4013cf3fea058668d96d113b9180d3d03d1e13f6d4cbde38b7728bf951aecd9dc199938c080093a9a6f0d7a6bd + languageName: node + linkType: hard + +"regjsparser@npm:^0.11.0": + version: 0.11.1 + resolution: "regjsparser@npm:0.11.1" dependencies: - jsesc: "npm:~0.5.0" + jsesc: "npm:~3.0.2" bin: regjsparser: bin/parser - checksum: 10c0/fe44fcf19a99fe4f92809b0b6179530e5ef313ff7f87df143b08ce9a2eb3c4b6189b43735d645be6e8f4033bfb015ed1ca54f0583bc7561bed53fd379feb8225 + checksum: 10c0/be4b40981a596b31eacd84ee12cfa474f1d33a6c05f7e995e8ec9d5ad8f1c3fbf7a5b690a05c443e1f312a1c0b16d4ea0b3384596a61d4fda97aa322879bb3cd languageName: node linkType: hard @@ -13135,6 +13548,17 @@ __metadata: languageName: node linkType: hard +"rehype-recma@npm:^1.0.0": + version: 1.0.0 + resolution: "rehype-recma@npm:1.0.0" + dependencies: + "@types/estree": "npm:^1.0.0" + "@types/hast": "npm:^3.0.0" + hast-util-to-estree: "npm:^3.0.0" + checksum: 10c0/be60d7433a7f788a14f41da3e93ba9d9272c908ddef47757026cc4bbcc912f6301d56810349adf876d294a8d048626a0dbf6988aaa574afbfc29eac1ddc1eb74 + languageName: node + linkType: hard + "relateurl@npm:^0.2.7": version: 0.2.7 resolution: "relateurl@npm:0.2.7" @@ -13194,12 +13618,12 @@ __metadata: linkType: hard "remark-mdx@npm:^3.0.0": - version: 3.0.1 - resolution: "remark-mdx@npm:3.0.1" + version: 3.1.0 + resolution: "remark-mdx@npm:3.1.0" dependencies: mdast-util-mdx: "npm:^3.0.0" micromark-extension-mdxjs: "npm:^3.0.0" - checksum: 10c0/9e16cd5ff3b30620bd25351a2dd1701627fa5555785b35ee5fe07bd1e6793a9c825cc1f6af9e54a44351f74879f8b5ea2bce8e5a21379aeab58935e76a4d69ce + checksum: 10c0/247800fa8561624bdca5776457c5965d99e5e60080e80262c600fe12ddd573862e029e39349e1e36e4c3bf79c8e571ecf4d3d2d8c13485b758391fb500e24a1a languageName: node linkType: hard @@ -13216,15 +13640,15 @@ __metadata: linkType: hard "remark-rehype@npm:^11.0.0": - version: 11.1.0 - resolution: "remark-rehype@npm:11.1.0" + version: 11.1.1 + resolution: "remark-rehype@npm:11.1.1" dependencies: "@types/hast": "npm:^3.0.0" "@types/mdast": "npm:^4.0.0" mdast-util-to-hast: "npm:^13.0.0" unified: "npm:^11.0.0" vfile: "npm:^6.0.0" - checksum: 10c0/7a9534847ea70e78cf09227a4302af7e491f625fd092351a1b1ee27a2de0a369ac4acf069682e8a8ec0a55847b3e83f0be76b2028aa90e98e69e21420b9794c3 + checksum: 10c0/68f986e8ee758d415e93babda2a0d89477c15b7c200edc23b8b1d914dd6e963c5fc151a11cbbbcfa7dd237367ff3ef86e302be90f31f37a17b0748668bd8c65b languageName: node linkType: hard @@ -13294,6 +13718,13 @@ __metadata: languageName: node linkType: hard +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2 + languageName: node + linkType: hard + "resolve-pathname@npm:^3.0.0": version: 3.0.0 resolution: "resolve-pathname@npm:3.0.0" @@ -13407,9 +13838,72 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.19.0, rollup@npm:^4.20.0": + version: 4.24.0 + resolution: "rollup@npm:4.24.0" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.24.0" + "@rollup/rollup-android-arm64": "npm:4.24.0" + "@rollup/rollup-darwin-arm64": "npm:4.24.0" + "@rollup/rollup-darwin-x64": "npm:4.24.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.24.0" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.24.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.24.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.24.0" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.24.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.24.0" + "@rollup/rollup-linux-s390x-gnu": "npm:4.24.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.24.0" + "@rollup/rollup-linux-x64-musl": "npm:4.24.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.24.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.24.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.24.0" + "@types/estree": "npm:1.0.6" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/77fb549c1de8afd1142d2da765adbb0cdab9f13c47df5217f00b5cf40b74219caa48c6ba2157f6249313ee81b6fa4c4fa8b3d2a0347ad6220739e00e580a808d + languageName: node + linkType: hard + "rpc-websockets@npm:^9.0.2": - version: 9.0.2 - resolution: "rpc-websockets@npm:9.0.2" + version: 9.0.4 + resolution: "rpc-websockets@npm:9.0.4" dependencies: "@swc/helpers": "npm:^0.5.11" "@types/uuid": "npm:^8.3.4" @@ -13425,7 +13919,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10c0/2f3b104a41f353a0c4e6f94474b347b42ea8c917d918259ea5b69878d082c2b8f83bdf5a9038714f536641700dbf7f102ce0c50505345fd8d61ee5d42dd72799 + checksum: 10c0/4fe4849810ae25b05107cdfc3ffdba77fd6e1d20101eb730814bd84c4692954037d12beb852cd7cd7b7b052864b24dc2488c2045c0a2fb59bd81659db73d4e8f languageName: node linkType: hard @@ -13437,8 +13931,8 @@ __metadata: linkType: hard "rtlcss@npm:^4.1.0": - version: 4.2.0 - resolution: "rtlcss@npm:4.2.0" + version: 4.3.0 + resolution: "rtlcss@npm:4.3.0" dependencies: escalade: "npm:^3.1.1" picocolors: "npm:^1.0.0" @@ -13446,7 +13940,7 @@ __metadata: strip-json-comments: "npm:^3.1.1" bin: rtlcss: bin/rtlcss.js - checksum: 10c0/8d1512c36f426bc4f133bc14ab06f11f3f7880a88491ddab81733551465f72adace688653f13fbb6d343961c08503ede5b204bf224e8adf8941a045d5756f537 + checksum: 10c0/ec59db839e1446b4cd6dcef618c8986f00d67e0ac3c2d40bd9041f1909aaacd668072c90849906ca692dea25cd993f46e9188b4c36adfa5bd3eebeb945fb28f2 languageName: node linkType: hard @@ -13605,7 +14099,7 @@ __metadata: languageName: node linkType: hard -"serialize-javascript@npm:^6.0.0, serialize-javascript@npm:^6.0.1, serialize-javascript@npm:^6.0.2": +"serialize-javascript@npm:^6.0.0, serialize-javascript@npm:^6.0.1": version: 6.0.2 resolution: "serialize-javascript@npm:6.0.2" dependencies: @@ -13615,18 +14109,17 @@ __metadata: linkType: hard "serve-handler@npm:^6.1.5": - version: 6.1.5 - resolution: "serve-handler@npm:6.1.5" + version: 6.1.6 + resolution: "serve-handler@npm:6.1.6" dependencies: bytes: "npm:3.0.0" content-disposition: "npm:0.5.2" - fast-url-parser: "npm:1.1.3" mime-types: "npm:2.1.18" minimatch: "npm:3.1.2" path-is-inside: "npm:1.0.2" - path-to-regexp: "npm:2.2.1" + path-to-regexp: "npm:3.3.0" range-parser: "npm:1.2.0" - checksum: 10c0/6fd393ae37a0305107e634ca545322b00605322189fe70d8f1a4a90a101c4e354768c610efe5a7ef1af3820cec5c33d97467c88151f35a3cb41d8ff2075ef802 + checksum: 10c0/1e1cb6bbc51ee32bc1505f2e0605bdc2e96605c522277c977b67f83be9d66bd1eec8604388714a4d728e036d86b629bc9aec02120ea030d3d2c3899d44696503 languageName: node linkType: hard @@ -13738,13 +14231,16 @@ __metadata: linkType: hard "shiki@npm:^1.16.2": - version: 1.16.2 - resolution: "shiki@npm:1.16.2" - dependencies: - "@shikijs/core": "npm:1.16.2" - "@shikijs/vscode-textmate": "npm:^9.2.0" + version: 1.22.0 + resolution: "shiki@npm:1.22.0" + dependencies: + "@shikijs/core": "npm:1.22.0" + "@shikijs/engine-javascript": "npm:1.22.0" + "@shikijs/engine-oniguruma": "npm:1.22.0" + "@shikijs/types": "npm:1.22.0" + "@shikijs/vscode-textmate": "npm:^9.3.0" "@types/hast": "npm:^3.0.4" - checksum: 10c0/504cf61924ecb38cc826a933e73f7f5673f0be811e68b235ace204436ddb61b675ea1b9d8234fe14814d016a6ac222ed53e89e2267e6d6e08855ef6734ce04df + checksum: 10c0/750ee1751340ad65368921a4a4f29249b9632c8b547a0c4052eb8a467be0da8b3af7a5e8751482a9e387f67053f8c8a7e5f50bf1be6fcf6f91ed3952bd20965e languageName: node linkType: hard @@ -13760,6 +14256,13 @@ __metadata: languageName: node linkType: hard +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + "signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -13774,20 +14277,6 @@ __metadata: languageName: node linkType: hard -"sinon@npm:^19.0.2": - version: 19.0.2 - resolution: "sinon@npm:19.0.2" - dependencies: - "@sinonjs/commons": "npm:^3.0.1" - "@sinonjs/fake-timers": "npm:^13.0.2" - "@sinonjs/samsam": "npm:^8.0.1" - diff: "npm:^7.0.0" - nise: "npm:^6.1.1" - supports-color: "npm:^7.2.0" - checksum: 10c0/a5d988d55643677e55bbc70c3aa6c9977f8a7cf55d157278ea8e4474d9acbec16d9c44056bd763e4f5988daf0fb75370099cf90105243dbb8742978478d53c40 - languageName: node - linkType: hard - "sirv@npm:^2.0.3": version: 2.0.4 resolution: "sirv@npm:2.0.4" @@ -13919,14 +14408,14 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.0": - version: 1.2.0 - resolution: "source-map-js@npm:1.2.0" - checksum: 10c0/7e5f896ac10a3a50fe2898e5009c58ff0dc102dcb056ed27a354623a0ece8954d4b2649e1a1b2b52ef2e161d26f8859c7710350930751640e71e374fe2d321a4 +"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf languageName: node linkType: hard -"source-map-support@npm:^0.5.6, source-map-support@npm:~0.5.20": +"source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -13936,6 +14425,15 @@ __metadata: languageName: node linkType: hard +"source-map@npm:0.8.0-beta.0": + version: 0.8.0-beta.0 + resolution: "source-map@npm:0.8.0-beta.0" + dependencies: + whatwg-url: "npm:^7.0.0" + checksum: 10c0/fb4d9bde9a9fdb2c29b10e5eae6c71d10e09ef467e1afb75fdec2eb7e11fa5b343a2af553f74f18b695dbc0b81f9da2e9fa3d7a317d5985e9939499ec6087835 + languageName: node + linkType: hard + "source-map@npm:^0.6.0, source-map@npm:~0.6.0": version: 0.6.1 resolution: "source-map@npm:0.6.1" @@ -14014,6 +14512,22 @@ __metadata: languageName: node linkType: hard +"stack-utils@npm:^2.0.3": + version: 2.0.6 + resolution: "stack-utils@npm:2.0.6" + dependencies: + escape-string-regexp: "npm:^2.0.0" + checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a + languageName: node + linkType: hard + +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 + languageName: node + linkType: hard + "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -14028,7 +14542,7 @@ __metadata: languageName: node linkType: hard -"std-env@npm:^3.0.1": +"std-env@npm:^3.0.1, std-env@npm:^3.7.0": version: 3.7.0 resolution: "std-env@npm:3.7.0" checksum: 10c0/60edf2d130a4feb7002974af3d5a5f3343558d1ccf8d9b9934d225c638606884db4a20d2fe6440a09605bca282af6b042ae8070a10490c0800d69e82e478f41e @@ -14184,11 +14698,11 @@ __metadata: linkType: hard "style-to-object@npm:^1.0.0": - version: 1.0.6 - resolution: "style-to-object@npm:1.0.6" + version: 1.0.8 + resolution: "style-to-object@npm:1.0.8" dependencies: - inline-style-parser: "npm:0.2.3" - checksum: 10c0/be5e8e3f0e35c0338de4112b9d861db576a52ebbd97f2501f1fb2c900d05c8fc42c5114407fa3a7f8b39301146cd8ca03a661bf52212394125a9629d5b771aba + inline-style-parser: "npm:0.2.4" + checksum: 10c0/daa6646b1ff18258c0ca33ed281fbe73485c8391192db1b56ce89d40c93ea64507a41e8701d0dadfe771bc2f540c46c9b295135f71584c8e5cb23d6a19be9430 languageName: node linkType: hard @@ -14204,6 +14718,24 @@ __metadata: languageName: node linkType: hard +"sucrase@npm:^3.35.0": + version: 3.35.0 + resolution: "sucrase@npm:3.35.0" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.2" + commander: "npm:^4.0.0" + glob: "npm:^10.3.10" + lines-and-columns: "npm:^1.1.6" + mz: "npm:^2.7.0" + pirates: "npm:^4.0.1" + ts-interface-checker: "npm:^0.1.9" + bin: + sucrase: bin/sucrase + sucrase-node: bin/sucrase-node + checksum: 10c0/ac85f3359d2c2ecbf5febca6a24ae9bf96c931f05fde533c22a94f59c6a74895e5d5f0e871878dfd59c2697a75ebb04e4b2224ef0bfc24ca1210735c2ec191ef + languageName: node + linkType: hard + "superstruct@npm:^0.15.4": version: 0.15.5 resolution: "superstruct@npm:0.15.5" @@ -14227,7 +14759,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^7.1.0, supports-color@npm:^7.2.0": +"supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" dependencies: @@ -14236,7 +14768,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0, supports-color@npm:^8.1.1": +"supports-color@npm:^8.0.0": version: 8.1.1 resolution: "supports-color@npm:8.1.1" dependencies: @@ -14340,8 +14872,8 @@ __metadata: linkType: hard "terser@npm:^5.10.0, terser@npm:^5.15.1, terser@npm:^5.26.0": - version: 5.31.6 - resolution: "terser@npm:5.31.6" + version: 5.36.0 + resolution: "terser@npm:5.36.0" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -14349,7 +14881,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10c0/b17d02b65a52a5041430572b3c514475820f5e7590fa93773c0f5b4be601ccf3f6d745bf5a79f3ee58187cf85edf61c24ddf4345783839fccb44c9c8fa9b427e + checksum: 10c0/f4ed2bead19f64789ddcfb85b7cef78f3942f967b8890c54f57d1e35bc7d547d551c6a4c32210bce6ba45b1c738314bbfac6acbc6c762a45cd171777d0c120d9 languageName: node linkType: hard @@ -14413,6 +14945,51 @@ __metadata: languageName: node linkType: hard +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c + languageName: node + linkType: hard + +"tinyexec@npm:^0.3.0": + version: 0.3.1 + resolution: "tinyexec@npm:0.3.1" + checksum: 10c0/11e7a7c5d8b3bddf8b5cbe82a9290d70a6fad84d528421d5d18297f165723cb53d2e737d8f58dcce5ca56f2e4aa2d060f02510b1f8971784f97eb3e9aec28f09 + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.1": + version: 0.2.9 + resolution: "tinyglobby@npm:0.2.9" + dependencies: + fdir: "npm:^6.4.0" + picomatch: "npm:^4.0.2" + checksum: 10c0/f65f847afe70f56de069d4f1f9c3b0c1a76aaf2b0297656754734a83b9bac8e105b5534dfbea8599560476b88f7b747d0855370a957a07246d18b976addb87ec + languageName: node + linkType: hard + +"tinypool@npm:^1.0.0": + version: 1.0.1 + resolution: "tinypool@npm:1.0.1" + checksum: 10c0/90939d6a03f1519c61007bf416632dc1f0b9c1a9dd673c179ccd9e36a408437384f984fc86555a5d040d45b595abc299c3bb39d354439e98a090766b5952e73d + languageName: node + linkType: hard + +"tinyrainbow@npm:^1.2.0": + version: 1.2.0 + resolution: "tinyrainbow@npm:1.2.0" + checksum: 10c0/7f78a4b997e5ba0f5ecb75e7ed786f30bab9063716e7dff24dd84013fb338802e43d176cb21ed12480561f5649a82184cf31efb296601a29d38145b1cdb4c192 + languageName: node + linkType: hard + +"tinyspy@npm:^3.0.0": + version: 3.0.2 + resolution: "tinyspy@npm:3.0.2" + checksum: 10c0/55ffad24e346622b59292e097c2ee30a63919d5acb7ceca87fc0d1c223090089890587b426e20054733f97a58f20af2c349fb7cc193697203868ab7ba00bcea0 + languageName: node + linkType: hard + "tmp@npm:~0.2.1": version: 0.2.3 resolution: "tmp@npm:0.2.3" @@ -14457,6 +15034,15 @@ __metadata: languageName: node linkType: hard +"tr46@npm:^1.0.1": + version: 1.0.1 + resolution: "tr46@npm:1.0.1" + dependencies: + punycode: "npm:^2.1.0" + checksum: 10c0/41525c2ccce86e3ef30af6fa5e1464e6d8bb4286a58ea8db09228f598889581ef62347153f6636cd41553dc41685bdfad0a9d032ef58df9fbb0792b3447d0f04 + languageName: node + linkType: hard + "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -14464,6 +15050,15 @@ __metadata: languageName: node linkType: hard +"tree-kill@npm:^1.2.2": + version: 1.2.2 + resolution: "tree-kill@npm:1.2.2" + bin: + tree-kill: cli.js + checksum: 10c0/7b1b7c7f17608a8f8d20a162e7957ac1ef6cd1636db1aba92f4e072dc31818c2ff0efac1e3d91064ede67ed5dc57c565420531a8134090a12ac10cf792ab14d2 + languageName: node + linkType: hard + "trim-lines@npm:^3.0.0": version: 3.0.1 resolution: "trim-lines@npm:3.0.1" @@ -14487,50 +15082,10 @@ __metadata: languageName: node linkType: hard -"ts-mocha@npm:^10.0.0": - version: 10.0.0 - resolution: "ts-mocha@npm:10.0.0" - dependencies: - ts-node: "npm:7.0.1" - tsconfig-paths: "npm:^3.5.0" - peerDependencies: - mocha: ^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X - dependenciesMeta: - tsconfig-paths: - optional: true - bin: - ts-mocha: bin/ts-mocha - checksum: 10c0/d21ba7a379f80b010ef1115ca3d94ca7490bfdb5a0d65fd2e1b500d992c99c2e68346c41e645589df785bbd7bed1baaa0529fbcfd5444d0bd00efdcd9b4f32ed - languageName: node - linkType: hard - -"ts-node@npm:7.0.1": - version: 7.0.1 - resolution: "ts-node@npm:7.0.1" - dependencies: - arrify: "npm:^1.0.0" - buffer-from: "npm:^1.1.0" - diff: "npm:^3.1.0" - make-error: "npm:^1.1.1" - minimist: "npm:^1.2.0" - mkdirp: "npm:^0.5.1" - source-map-support: "npm:^0.5.6" - yn: "npm:^2.0.0" - bin: - ts-node: dist/bin.js - checksum: 10c0/d6307766a716a77999e11c7f310312cf9d6addb98859d71e71d611ecafa6bdb90f07365f9acf7e9489cb43cfc2211486303172c3bcda370d20f0be54884fe647 - languageName: node - linkType: hard - -"tsconfig-paths@npm:^3.5.0": - version: 3.15.0 - resolution: "tsconfig-paths@npm:3.15.0" - dependencies: - "@types/json5": "npm:^0.0.29" - json5: "npm:^1.0.2" - minimist: "npm:^1.2.6" - strip-bom: "npm:^3.0.0" - checksum: 10c0/5b4f301a2b7a3766a986baf8fc0e177eb80bdba6e396792ff92dc23b5bca8bb279fc96517dcaaef63a3b49bebc6c4c833653ec58155780bc906bdbcf7dda0ef5 +"ts-interface-checker@npm:^0.1.9": + version: 0.1.13 + resolution: "ts-interface-checker@npm:0.1.13" + checksum: 10c0/232509f1b84192d07b81d1e9b9677088e590ac1303436da1e92b296e9be8e31ea042e3e1fd3d29b1742ad2c959e95afe30f63117b8f1bc3a3850070a5142fea7 languageName: node linkType: hard @@ -14546,9 +15101,50 @@ __metadata: linkType: hard "tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.0": - version: 2.6.3 - resolution: "tslib@npm:2.6.3" - checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a + version: 2.8.0 + resolution: "tslib@npm:2.8.0" + checksum: 10c0/31e4d14dc1355e9b89e4d3c893a18abb7f90b6886b089c2da91224d0a7752c79f3ddc41bc1aa0a588ac895bd97bb99c5bc2bfdb2f86de849f31caeb3ba79bbe5 + languageName: node + linkType: hard + +"tsup@npm:^8.3.0": + version: 8.3.0 + resolution: "tsup@npm:8.3.0" + dependencies: + bundle-require: "npm:^5.0.0" + cac: "npm:^6.7.14" + chokidar: "npm:^3.6.0" + consola: "npm:^3.2.3" + debug: "npm:^4.3.5" + esbuild: "npm:^0.23.0" + execa: "npm:^5.1.1" + joycon: "npm:^3.1.1" + picocolors: "npm:^1.0.1" + postcss-load-config: "npm:^6.0.1" + resolve-from: "npm:^5.0.0" + rollup: "npm:^4.19.0" + source-map: "npm:0.8.0-beta.0" + sucrase: "npm:^3.35.0" + tinyglobby: "npm:^0.2.1" + tree-kill: "npm:^1.2.2" + peerDependencies: + "@microsoft/api-extractor": ^7.36.0 + "@swc/core": ^1 + postcss: ^8.4.12 + typescript: ">=4.5.0" + peerDependenciesMeta: + "@microsoft/api-extractor": + optional: true + "@swc/core": + optional: true + postcss: + optional: true + typescript: + optional: true + bin: + tsup: dist/cli-default.js + tsup-node: dist/cli-node.js + checksum: 10c0/7f7132e48fca2284fd721077c6462c440dabdc95bcacf2e9837f81d2ca9771f804ff4f8b81a743e8fc6c3def856cf3ae99421c0568a7f030196abdc9e12e97e8 languageName: node linkType: hard @@ -14561,20 +15157,6 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8": - version: 4.0.8 - resolution: "type-detect@npm:4.0.8" - checksum: 10c0/8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd - languageName: node - linkType: hard - -"type-detect@npm:^4.1.0": - version: 4.1.0 - resolution: "type-detect@npm:4.1.0" - checksum: 10c0/df8157ca3f5d311edc22885abc134e18ff8ffbc93d6a9848af5b682730ca6a5a44499259750197250479c5331a8a75b5537529df5ec410622041650a7f293e2a - languageName: node - linkType: hard - "type-fest@npm:^1.0.1": version: 1.4.0 resolution: "type-fest@npm:1.4.0" @@ -14667,30 +15249,23 @@ __metadata: linkType: hard "undici-types@npm:^6.19.5": - version: 6.19.5 - resolution: "undici-types@npm:6.19.5" - checksum: 10c0/be5b0eb4ca67c4bffde28ab9ed5cba24e458e2b6639150a693fd499d6a3e289a2144c149df82504b205be4556b4b54064e1a7175e5710b117e14a9d8c73da62e - languageName: node - linkType: hard - -"undici-types@npm:~6.13.0": - version: 6.13.0 - resolution: "undici-types@npm:6.13.0" - checksum: 10c0/2de55181f569c77a4f08063f8bf2722fcbb6ea312a26a9e927bd1f5ea5cf3a281c5ddf23155061db083e0a25838f54813543ff13b0ac34d230d5c1205ead66c1 + version: 6.20.0 + resolution: "undici-types@npm:6.20.0" + checksum: 10c0/68e659a98898d6a836a9a59e6adf14a5d799707f5ea629433e025ac90d239f75e408e2e5ff086afc3cace26f8b26ee52155293564593fbb4a2f666af57fc59bf languageName: node linkType: hard "undici-types@npm:~6.19.2": - version: 6.19.6 - resolution: "undici-types@npm:6.19.6" - checksum: 10c0/9b2264c5700e7169c6c62c643aac56cd8984c5fd7e18ed31ff11780260e137f6340dee8317a2e6e0ae3c49f5e5ef6fa577ea07193cbaa535265cba76a267cae9 + version: 6.19.8 + resolution: "undici-types@npm:6.19.8" + checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344 languageName: node linkType: hard "unicode-canonical-property-names-ecmascript@npm:^2.0.0": - version: 2.0.0 - resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.0" - checksum: 10c0/0fe812641bcfa3ae433025178a64afb5d9afebc21a922dafa7cba971deebb5e4a37350423890750132a85c936c290fb988146d0b1bd86838ad4897f4fc5bd0de + version: 2.0.1 + resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1" + checksum: 10c0/f83bc492fdbe662860795ef37a85910944df7310cac91bd778f1c19ebc911e8b9cde84e703de631e5a2fcca3905e39896f8fc5fc6a44ddaf7f4aff1cda24f381 languageName: node linkType: hard @@ -14712,9 +15287,9 @@ __metadata: linkType: hard "unicode-match-property-value-ecmascript@npm:^2.1.0": - version: 2.1.0 - resolution: "unicode-match-property-value-ecmascript@npm:2.1.0" - checksum: 10c0/f5b9499b9e0ffdc6027b744d528f17ec27dd7c15da03254ed06851feec47e0531f20d410910c8a49af4a6a190f4978413794c8d75ce112950b56d583b5d5c7f2 + version: 2.2.0 + resolution: "unicode-match-property-value-ecmascript@npm:2.2.0" + checksum: 10c0/1d0a2deefd97974ddff5b7cb84f9884177f4489928dfcebb4b2b091d6124f2739df51fc6ea15958e1b5637ac2a24cff9bf21ea81e45335086ac52c0b4c717d6d languageName: node linkType: hard @@ -14794,16 +15369,6 @@ __metadata: languageName: node linkType: hard -"unist-util-remove-position@npm:^5.0.0": - version: 5.0.0 - resolution: "unist-util-remove-position@npm:5.0.0" - dependencies: - "@types/unist": "npm:^3.0.0" - unist-util-visit: "npm:^5.0.0" - checksum: 10c0/e8c76da4399446b3da2d1c84a97c607b37d03d1d92561e14838cbe4fdcb485bfc06c06cfadbb808ccb72105a80643976d0660d1fe222ca372203075be9d71105 - languageName: node - linkType: hard - "unist-util-stringify-position@npm:^4.0.0": version: 4.0.0 resolution: "unist-util-stringify-position@npm:4.0.0" @@ -14849,16 +15414,16 @@ __metadata: linkType: hard "update-browserslist-db@npm:^1.1.0": - version: 1.1.0 - resolution: "update-browserslist-db@npm:1.1.0" + version: 1.1.1 + resolution: "update-browserslist-db@npm:1.1.1" dependencies: - escalade: "npm:^3.1.2" - picocolors: "npm:^1.0.1" + escalade: "npm:^3.2.0" + picocolors: "npm:^1.1.0" peerDependencies: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 10c0/a7452de47785842736fb71547651c5bbe5b4dc1e3722ccf48a704b7b34e4dcf633991eaa8e4a6a517ffb738b3252eede3773bef673ef9021baa26b056d63a5b9 + checksum: 10c0/536a2979adda2b4be81b07e311bd2f3ad5e978690987956bc5f514130ad50cac87cd22c710b686d79731e00fbee8ef43efe5fcd72baa241045209195d43dcc80 languageName: node linkType: hard @@ -14992,13 +15557,129 @@ __metadata: linkType: hard "vfile@npm:^6.0.0, vfile@npm:^6.0.1": - version: 6.0.2 - resolution: "vfile@npm:6.0.2" + version: 6.0.3 + resolution: "vfile@npm:6.0.3" dependencies: "@types/unist": "npm:^3.0.0" - unist-util-stringify-position: "npm:^4.0.0" vfile-message: "npm:^4.0.0" - checksum: 10c0/96b7e060b332ff1b05462053bd9b0f39062c00c5eabb78fc75603cc808d5f77c4379857fffca3e30a28e0aad2d51c065dfcd4a43fbe15b1fc9c2aaa9ac1be8e1 + checksum: 10c0/e5d9eb4810623f23758cfc2205323e33552fb5972e5c2e6587babe08fe4d24859866277404fb9e2a20afb71013860d96ec806cb257536ae463c87d70022ab9ef + languageName: node + linkType: hard + +"vite-node@npm:2.1.3": + version: 2.1.3 + resolution: "vite-node@npm:2.1.3" + dependencies: + cac: "npm:^6.7.14" + debug: "npm:^4.3.6" + pathe: "npm:^1.1.2" + vite: "npm:^5.0.0" + bin: + vite-node: vite-node.mjs + checksum: 10c0/1b06139880a8170651e025e8c35aa92a917f8ec8f24507cda5bf4be09843f6447e1f494932a8d7eb98124f1c8c9fee02283ef318ddd57e2b861d2d85a409a206 + languageName: node + linkType: hard + +"vite@npm:^5.0.0": + version: 5.4.9 + resolution: "vite@npm:5.4.9" + dependencies: + esbuild: "npm:^0.21.3" + fsevents: "npm:~2.3.3" + postcss: "npm:^8.4.43" + rollup: "npm:^4.20.0" + peerDependencies: + "@types/node": ^18.0.0 || >=20.0.0 + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/e9c59f2c639047e37c79bbbb151c7a55a3dc27932957cf4cf0447ee0bdcc1ddfd9b1fb3ba0465371c01ba3616d62561327855794c2d652213c3a10a32e6d369d + languageName: node + linkType: hard + +"vitest@npm:^2.1.3": + version: 2.1.3 + resolution: "vitest@npm:2.1.3" + dependencies: + "@vitest/expect": "npm:2.1.3" + "@vitest/mocker": "npm:2.1.3" + "@vitest/pretty-format": "npm:^2.1.3" + "@vitest/runner": "npm:2.1.3" + "@vitest/snapshot": "npm:2.1.3" + "@vitest/spy": "npm:2.1.3" + "@vitest/utils": "npm:2.1.3" + chai: "npm:^5.1.1" + debug: "npm:^4.3.6" + magic-string: "npm:^0.30.11" + pathe: "npm:^1.1.2" + std-env: "npm:^3.7.0" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^0.3.0" + tinypool: "npm:^1.0.0" + tinyrainbow: "npm:^1.2.0" + vite: "npm:^5.0.0" + vite-node: "npm:2.1.3" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@types/node": ^18.0.0 || >=20.0.0 + "@vitest/browser": 2.1.3 + "@vitest/ui": 2.1.3 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 10c0/7688fdce37205e7f3b448039df216e103e3a52994af0201993e22decbb558d129a734001b991f3c3d80bf4a4ef91ca6a5665a7395d5b051249da60a0016eda36 + languageName: node + linkType: hard + +"wasm-pack@npm:^0.13.0": + version: 0.13.0 + resolution: "wasm-pack@npm:0.13.0" + dependencies: + binary-install: "npm:^1.0.1" + bin: + wasm-pack: run.js + checksum: 10c0/71ed64c9b0082d51098ec71041ce68a9323d7a0027e3a9c0b694c5931f83ce2a58f1df7255c68239ca4ab702e2daf5c550a7886f8af048f0cb76945a510268b6 languageName: node linkType: hard @@ -15044,6 +15725,13 @@ __metadata: languageName: node linkType: hard +"webidl-conversions@npm:^4.0.2": + version: 4.0.2 + resolution: "webidl-conversions@npm:4.0.2" + checksum: 10c0/def5c5ac3479286dffcb604547628b2e6b46c5c5b8a8cfaa8c71dc3bafc85859bde5fbe89467ff861f571ab38987cf6ab3d6e7c80b39b999e50e803c12f3164f + languageName: node + linkType: hard + "webpack-bundle-analyzer@npm:^4.9.0": version: 4.10.2 resolution: "webpack-bundle-analyzer@npm:4.10.2" @@ -15147,8 +15835,8 @@ __metadata: linkType: hard "webpack@npm:^5.88.1": - version: 5.94.0 - resolution: "webpack@npm:5.94.0" + version: 5.95.0 + resolution: "webpack@npm:5.95.0" dependencies: "@types/estree": "npm:^1.0.5" "@webassemblyjs/ast": "npm:^1.12.1" @@ -15178,7 +15866,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 10c0/b4d1b751f634079bd177a89eef84d80fa5bb8d6fc15d72ab40fc2b9ca5167a79b56585e1a849e9e27e259803ee5c4365cb719e54af70a43c06358ec268ff4ebf + checksum: 10c0/b9e6d0f8ebcbf0632494ac0b90fe4acb8f4a9b83f7ace4a67a15545a36fe58599c912ab58e625e1bf58ab3b0916c75fe99da6196d412ee0cab0b5065edd84238 languageName: node linkType: hard @@ -15224,6 +15912,17 @@ __metadata: languageName: node linkType: hard +"whatwg-url@npm:^7.0.0": + version: 7.1.0 + resolution: "whatwg-url@npm:7.1.0" + dependencies: + lodash.sortby: "npm:^4.7.0" + tr46: "npm:^1.0.1" + webidl-conversions: "npm:^4.0.2" + checksum: 10c0/2785fe4647690e5a0225a79509ba5e21fdf4a71f9de3eabdba1192483fe006fc79961198e0b99f82751557309f17fc5a07d4d83c251aa5b2f85ba71e674cbee9 + languageName: node + linkType: hard + "which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" @@ -15257,6 +15956,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + languageName: node + linkType: hard + "widest-line@npm:^4.0.1": version: 4.0.1 resolution: "widest-line@npm:4.0.1" @@ -15280,13 +15991,6 @@ __metadata: languageName: node linkType: hard -"workerpool@npm:^6.5.1": - version: 6.5.1 - resolution: "workerpool@npm:6.5.1" - checksum: 10c0/58e8e969782292cb3a7bfba823f1179a7615250a0cefb4841d5166234db1880a3d0fe83a31dd8d648329ec92c2d0cd1890ad9ec9e53674bb36ca43e9753cdeac - languageName: node - linkType: hard - "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" @@ -15416,20 +16120,20 @@ __metadata: linkType: hard "yaml@npm:^2.5.1": - version: 2.5.1 - resolution: "yaml@npm:2.5.1" + version: 2.6.0 + resolution: "yaml@npm:2.6.0" bin: yaml: bin.mjs - checksum: 10c0/40fba5682898dbeeb3319e358a968fe886509fab6f58725732a15f8dda3abac509f91e76817c708c9959a15f786f38ff863c1b88062d7c1162c5334a7d09cb4a + checksum: 10c0/9e74cdb91cc35512a1c41f5ce509b0e93cc1d00eff0901e4ba831ee75a71ddf0845702adcd6f4ee6c811319eb9b59653248462ab94fa021ab855543a75396ceb languageName: node linkType: hard "yaml@npm:~2.5.0": - version: 2.5.0 - resolution: "yaml@npm:2.5.0" + version: 2.5.1 + resolution: "yaml@npm:2.5.1" bin: yaml: bin.mjs - checksum: 10c0/771a1df083c8217cf04ef49f87244ae2dd7d7457094425e793b8f056159f167602ce172aa32d6bca21f787d24ec724aee3cecde938f6643564117bd151452631 + checksum: 10c0/40fba5682898dbeeb3319e358a968fe886509fab6f58725732a15f8dda3abac509f91e76817c708c9959a15f786f38ff863c1b88062d7c1162c5334a7d09cb4a languageName: node linkType: hard @@ -15440,40 +16144,6 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.9": - version: 20.2.9 - resolution: "yargs-parser@npm:20.2.9" - checksum: 10c0/0685a8e58bbfb57fab6aefe03c6da904a59769bd803a722bb098bd5b0f29d274a1357762c7258fb487512811b8063fb5d2824a3415a0a4540598335b3b086c72 - languageName: node - linkType: hard - -"yargs-unparser@npm:^2.0.0": - version: 2.0.0 - resolution: "yargs-unparser@npm:2.0.0" - dependencies: - camelcase: "npm:^6.0.0" - decamelize: "npm:^4.0.0" - flat: "npm:^5.0.2" - is-plain-obj: "npm:^2.1.0" - checksum: 10c0/a5a7d6dc157efa95122e16780c019f40ed91d4af6d2bac066db8194ed0ec5c330abb115daa5a79ff07a9b80b8ea80c925baacf354c4c12edd878c0529927ff03 - languageName: node - linkType: hard - -"yargs@npm:^16.2.0": - version: 16.2.0 - resolution: "yargs@npm:16.2.0" - dependencies: - cliui: "npm:^7.0.2" - escalade: "npm:^3.1.1" - get-caller-file: "npm:^2.0.5" - require-directory: "npm:^2.1.1" - string-width: "npm:^4.2.0" - y18n: "npm:^5.0.5" - yargs-parser: "npm:^20.2.2" - checksum: 10c0/b1dbfefa679848442454b60053a6c95d62f2d2e21dd28def92b647587f415969173c6e99a0f3bab4f1b67ee8283bf735ebe3544013f09491186ba9e8a9a2b651 - languageName: node - linkType: hard - "yargs@npm:^17.6.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" @@ -15489,13 +16159,6 @@ __metadata: languageName: node linkType: hard -"yn@npm:^2.0.0": - version: 2.0.0 - resolution: "yn@npm:2.0.0" - checksum: 10c0/a52d74080871f22b3af8a6068d8579b86bf2bb81a968f6e406aa6e1ee85ba15f2e1d334184df6cd81024cec32a3cc8dc1f2f09ec4957b58b7b038b3cdef5cbd1 - languageName: node - linkType: hard - "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" @@ -15510,7 +16173,7 @@ __metadata: languageName: node linkType: hard -"zwitch@npm:^2.0.0": +"zwitch@npm:^2.0.0, zwitch@npm:^2.0.4": version: 2.0.4 resolution: "zwitch@npm:2.0.4" checksum: 10c0/3c7830cdd3378667e058ffdb4cf2bb78ac5711214e2725900873accb23f3dfe5f9e7e5a06dcdc5f29605da976fc45c26d9a13ca334d6eea2245a15e77b8fc06e