diff --git a/Cargo.lock b/Cargo.lock index e9573da0a..90328581d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5612,6 +5612,15 @@ version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" +[[package]] +name = "token-2022-cpi-guard-pinocchio-program" +version = "0.1.0" +dependencies = [ + "pinocchio", + "pinocchio-log", + "pinocchio-system", +] + [[package]] name = "token-2022-default-account-state-pinocchio-program" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index f442bd27f..30c8f8dd9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,6 +73,7 @@ members = [ "tokens/token-2022/permanent-delegate/pinocchio/program", "tokens/token-2022/multiple-extensions/pinocchio/program", "tokens/token-2022/immutable-owner/pinocchio/program", + "tokens/token-2022/cpi-guard/pinocchio/program", ] resolver = "2" diff --git a/tokens/token-2022/cpi-guard/pinocchio/cicd.sh b/tokens/token-2022/cpi-guard/pinocchio/cicd.sh new file mode 100644 index 000000000..ae995a5be --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/cicd.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e + +# This script is for quick building & deploying of the program. +# It also serves as a reference for the commands used for building & deploying Solana programs. +# Run this bad boy with "bash cicd.sh" or "./cicd.sh" + +cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so +solana program deploy ./program/target/so/token_2022_cpi_guard_pinocchio_program.so diff --git a/tokens/token-2022/cpi-guard/pinocchio/package.json b/tokens/token-2022/cpi-guard/pinocchio/package.json new file mode 100644 index 000000000..ae3e23594 --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/package.json @@ -0,0 +1,24 @@ +{ + "type": "module", + "scripts": { + "test": "mocha --import=tsx -t 1000000 ./tests/test.ts", + "build-and-test": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./tests/fixtures && pnpm test", + "build": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so", + "deploy": "solana program deploy ./program/target/so/token_2022_cpi_guard_pinocchio_program.so" + }, + "dependencies": { + "@solana-program/system": "^0.16.0", + "@solana-program/token-2022": "^0.20.0", + "@solana/kit": "^8.5.0", + "litesvm": "^1.6.1" + }, + "devDependencies": { + "@types/chai": "^5.2.3", + "@types/mocha": "^10.0.10", + "@types/node": "^26.6.5", + "chai": "^6.3.0", + "mocha": "^12.0.3", + "typescript": "^7.0.2", + "tsx": "^4.23.15" + } +} diff --git a/tokens/token-2022/cpi-guard/pinocchio/pnpm-lock.yaml b/tokens/token-2022/cpi-guard/pinocchio/pnpm-lock.yaml new file mode 100644 index 000000000..424371022 --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/pnpm-lock.yaml @@ -0,0 +1,1846 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + glob@>=9.0.0 <=14.0.1: '>=14.0.2' + minimatch@<11.0.1: '>=11.0.1' + +importers: + + .: + dependencies: + '@solana-program/system': + specifier: ^0.16.0 + version: 0.16.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana-program/token-2022': + specifier: ^0.20.0 + version: 0.20.1(@solana/kit@8.6.0(typescript@7.0.2))(@solana/sysvars@8.6.0(typescript@7.0.2)) + '@solana/kit': + specifier: ^8.5.0 + version: 8.6.0(typescript@7.0.2) + litesvm: + specifier: ^1.6.1 + version: 1.6.2(typescript@7.0.2) + devDependencies: + '@types/chai': + specifier: ^5.2.3 + version: 5.2.3 + '@types/mocha': + specifier: ^10.0.10 + version: 10.0.10 + '@types/node': + specifier: ^26.6.5 + version: 26.6.6 + chai: + specifier: ^6.3.0 + version: 6.3.0 + mocha: + specifier: ^12.0.3 + version: 12.0.3 + tsx: + specifier: ^4.23.15 + version: 4.23.15 + typescript: + specifier: ^7.0.2 + version: 7.0.2 + +packages: + + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@isaacs/nonrecursive-glob-match@1.0.3': + resolution: {integrity: sha512-SI7kyKHq4XXDRozw+r9GlRZkia1ZkFrpLW98r2IC2Bpr8YkFGE3fvjzmxCG0x78A++69HmDNrDvSMYBZmHGpKA==} + + '@solana-program/record@0.6.0': + resolution: {integrity: sha512-8NeDjYA8OVWiL7sZqURsYFPXoT/i1c2A1Wt4k5MOMEItehX8fUOj7uCspU85lC+so+tsEmJ09qO0t8vN8kk/ZQ==} + peerDependencies: + '@solana/kit': ^8.5.0 + + '@solana-program/system@0.14.0': + resolution: {integrity: sha512-Pjs2RINZHYmk/pqWNBCuQmfNjZT9woPJ/w7QkzzCSwcqcokbARtxsnIdgj4lJVxvr1DuxG8JGIbKnq6z1QRY6Q==} + peerDependencies: + '@solana/kit': ^8.0.0 + + '@solana-program/system@0.16.0': + resolution: {integrity: sha512-/RG6q2E2vG/XpdOt8Jj/kbQktPlL5JyJuNGAeN9wDcxKDKQtrGTJpDrJgQUxiEy23fsPNXQbLN8XeCtYoMof3Q==} + peerDependencies: + '@solana/kit': ^8.5.0 + + '@solana-program/token-2022@0.20.1': + resolution: {integrity: sha512-HTQ5vLr/WmKMYJHDfUlZYD7qwJUebso6B7fI0JmdPZTP2Ol+NfgZ/2KTWQNvpjLsBHvn7ex1T9bjyzsqJSlCgA==} + peerDependencies: + '@solana/kit': ^8.5.0 + '@solana/sysvars': ^8.0.0 + '@solana/zk-sdk': ^0.5.4 + peerDependenciesMeta: + '@solana/zk-sdk': + optional: true + + '@solana-program/token@0.16.0': + resolution: {integrity: sha512-VuFIu5vXsw1zwqls4/sGB88234oucmpuig553A33UnrbYnPZ8yXmqLYULBD92/k1pCGnMK+NMLWvsKzlZQ/1Kw==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@solana/kit': ^8.0.0 + + '@solana-program/zk-elgamal-proof@0.5.0': + resolution: {integrity: sha512-2shlu/0a/WFjERyFyhZevXG7WXRUz0kmy5DPEse3TOjH0s4fTU+Uk9kE5ijPhF85Fh662m4xT1ZZm+KBGq5y1g==} + peerDependencies: + '@solana/kit': ^8.5.0 + + '@solana/accounts@8.6.0': + resolution: {integrity: sha512-yIcrKjbUXzs1K6KkcRJfAHFOsn8Jpp9AeczcHOHQoBv11AxHM5KmdCTv8rnv7OObq696sd3gpbamVxtqnL0meQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/addresses@8.6.0': + resolution: {integrity: sha512-V30spa+zKsY7i4elEEOZQB/1xpRc0CzbSypI/yTZwj/Bg1o09T6A+pflMDTBoIWH3sglmigdK1jApEOOA7Bypg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/assertions@8.6.0': + resolution: {integrity: sha512-zQFbZoPFE3GqBw/7JyZxaH5t/Ibm7eHOmOfRI542/zz0BHWSnMkR0N5aSndPJd9creMUP+mFtX8hAr6bZ6rDBg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-core@8.6.0': + resolution: {integrity: sha512-1N2XZ1yCJGmdTE3g5Fh6/UOE6y46qing+7CZpxfrgB4Q+1l+R/d0z4G15IpQUNl3vzqML8CFF791f/A1XSVmJA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-data-structures@8.6.0': + resolution: {integrity: sha512-BLwclFSLVqugUktXucjGfpUFSaX4V7payjSi6x0DDdLs6PaFfjiH3ykQPV5QRkTeOlf0xC6dOMUUntDhYzVyGw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-numbers@8.6.0': + resolution: {integrity: sha512-GRIArvWJiYxH5w1RMKn7IOCLy0uYB/WRT2kFW/uyXHzL1VNFyud2BIzG0D3iM+AxTd85SdS/x93aV7NEw0mTOQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-strings@8.6.0': + resolution: {integrity: sha512-bLS/o5NdCRb9xj23zLACPjxYvDhdjvSDH4XoBAmQ1CPn3cDvVqVvAz0T41Bs/LMykhamkmpqTcWLoTOVqjTz3w==} + engines: {node: '>=20.18.0'} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.4.0' + peerDependenciesMeta: + fastestsmallesttextencoderdecoder: + optional: true + typescript: + optional: true + + '@solana/codecs@8.6.0': + resolution: {integrity: sha512-7vUVLdYlTay3rsijiBPN4g992V8RXbgY2DNAXrsE6eHFnwaX8gzdDNASgF4Z0mbgNC026qdLG6LTY4l16tvE8g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/errors@8.6.0': + resolution: {integrity: sha512-viHL51ymR1HZB7ZTp0ESkLOyHCa4bPfok9dvRYbMmYokY5ys1xinISKHUhcOHsg9zbuAWBRJUOnZRWAPbb4+yA==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/fast-stable-stringify@8.6.0': + resolution: {integrity: sha512-PVuzLesqjvuW1qeg0brkUtpRnQYCLS0mB7SsFu+iio+dxFzbrrHzkSYVoUBEEbjXysCq1L350Frs1+v7CEsXGQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/fixed-points@8.6.0': + resolution: {integrity: sha512-yS0XIHwWETtTjAgUHPhpQpcigPvC6phba3vW7rvVPSvVz1FhxNki82ojyl1pISglK7IkUTYcGhaXDhsY/oz8rQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/functional@8.6.0': + resolution: {integrity: sha512-greLf2tiMJ5oWaSdp3zkAcUF3sIG3CU1UssxoMYNHy/xywbZifKnOl5syQjKY1XdYPZZmLAWJBFYCkzVns5bxA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/instruction-plans@8.6.0': + resolution: {integrity: sha512-hq1bLZStauHKmwHWheCoF9UxcFlJsYm9X4saUj4llkJl6GmTrDTmeiE93mJngz4GO6cAkm65D/AjYRcp69jUVw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/instructions@8.6.0': + resolution: {integrity: sha512-1mXhgf5XaIJir02TgkUwzNRJs8mCCRRRsW45ZwqCp66bnIxmxEy3a91twgGXvBfE6dvzzg3TNSjcfqGQ/ADBog==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/keys@8.6.0': + resolution: {integrity: sha512-vxj3zmcHfY0EqDSJR8nn7w/qQAdCG3uSyGGcIfLgf/ZhVUgVDYDUyUqrxSL5DxAs64czhSu+ufRh7B5AKwMtaQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/kit@8.6.0': + resolution: {integrity: sha512-UaigU+LiTzkU237FxfiJhxufvEfb1J02djJOnGpSz1GAjZtbZ8oc4EkQ1bS4sHewSRyR9RUk6yhBb5bLHG0w4w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/nominal-types@8.6.0': + resolution: {integrity: sha512-uuRReiuEWfTTwtlJNvTSStuHrDF45Itl2k3BGg/4kHWxqUdtS5u4PK4bMgzoPWoyPorDj5y6TEMa+MydM5D7Sg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/offchain-messages@8.6.0': + resolution: {integrity: sha512-VFic3fotmL9fIjs7Amk402CMWLeWwhNQvAF9cyZO++x42oU2FNeTe27rxfgFLYPaIHaRonlII+5pmsHQHA240Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/options@8.6.0': + resolution: {integrity: sha512-WFsTtIQukNGGHRImcmn8Se8o6A4vu4wY0fuLSeB/L7C45FPoQI2fTIud6hf9g2fum0dR3U0pFNIciwQjlVq2LA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/plugin-core@8.6.0': + resolution: {integrity: sha512-wvjpR66FreDxDXfF5RrIay7aXW+JfcmSj1TiDu+rUyWaV1Xu390E/KKL3dM6OfkIOtP66H9M9w1XihB8syMkfg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/plugin-interfaces@8.6.0': + resolution: {integrity: sha512-ta+JYsKD7GMUoBLbeE1nYKDPN9nOwQN1y04xR4tbyfDbNsGLPz3fTKH8Y48bOs552sW4OcUB8F3pGVZefqPyWg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/program-client-core@8.6.0': + resolution: {integrity: sha512-e6Wx2Y2UrQ0dPB6hndVcyUXQwBt9/DLr8k2P7tRgW0JNVhHNylZQ6aYQAqxZzS8Z92gGz7l3XL+r9tCLKBkIVw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/programs@8.6.0': + resolution: {integrity: sha512-JKGtqXtiT4zon7xZkmys2G1/HchwbNjzbP+E+0Rp/Cko+svB9w9SE2PROEVJZS8UH98lbi1epjsHYAgESamwvg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/promises@8.6.0': + resolution: {integrity: sha512-HLlAMwXnEyhg9HxVJGDlWgFlM4QUt/Qq0nL69bbC7COCHhUQFRcKLq5uIbaXPy7FNJlNBSTTCBZwI0IK9up0SQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-api@8.6.0': + resolution: {integrity: sha512-NFHtOB9z4HyV8frN84o+d9jKj5luRzrySZJLgwMgcG/Q2fWahTDrP+ZqRKLmqibvFBg/fwhcxl77+TfKZjpvhA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-parsed-types@8.6.0': + resolution: {integrity: sha512-wZKtQOS3RdHZqJ3ycpdibup31tfbY6lHYGUKjmzeF6N2E2y7WEpB7qiEr9AMBB00mDUtorcqBMpOli6PyT4Gog==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-spec-types@8.6.0': + resolution: {integrity: sha512-6+2F2BN2CXp4g7cnvLp2mRo/XwdN5At7f3HbdEablxNe1UvI5S8WIEY3l/Y+nh2NQIaEVz9fLjmTYV+UfZNzEg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-spec@8.6.0': + resolution: {integrity: sha512-V1c+r6HXTb/nCEl5SHKLPzzb6aMEbr0lFOcgjEX8TQ8fE6ZlLzNz3tKvcgbBlOJCeyVXSrcNl3tv8i8xNp+n/g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-api@8.6.0': + resolution: {integrity: sha512-Cbyi0ZpwNCcxRgjjc1vKVWBdwNOAKGT1VjryfQU/FDySUo2Lg8u5LUsJb6d53QD5dhEU+0nooxfBmRUUyebZug==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-channel-websocket@8.6.0': + resolution: {integrity: sha512-k1UmMiIJFeo7wAUTiqg7Ni6gdsJAd65D3Wxqdtf5iBX9TjkvWGrL3KXdJq2ZzS1c9eqd220W0v7fkFTA8tfX5Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-spec@8.6.0': + resolution: {integrity: sha512-m7lBQS9hgzWN1ZI+JUy5rV8ctG7oy0WbGHoj4vevB4esK2SYUyI0eQB4GrQhVwGnkyTxATS/R91ZZzWYDKGXlg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions@8.6.0': + resolution: {integrity: sha512-ZaoFtiKg25KqYykBslB8TDWqfm7S162FyTJvFI0HL0U94K1O675IG2h913mes3voatigpqLneFxkNrVs5yE7tA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-transformers@8.6.0': + resolution: {integrity: sha512-aSfctQeLTszEQdNGDrPWbi/7voJYrYo/rvIZRDbokYQRDwMuphw7kENGdwaQB7A9XSX0tsPe+dKkbxjWf0Druw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-transport-http@8.6.0': + resolution: {integrity: sha512-jr7ef/UOIO7bRjI7DEXji3J7nCFO3jIYPGw3L0fyF7VEJox9Bh8TNHsn9G9jv1kqdwkUnFrPPWVMvmAWQwSmvg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-types@8.6.0': + resolution: {integrity: sha512-gg05ZjZq8sFcf0JKO6/MQ1oYSFQuT5SU51dhirGjfl8UCxX/Q6ocsUgzb9a/zPNrRsXJkduaZF1bARah7MrrYw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc@8.6.0': + resolution: {integrity: sha512-u5dg96ThDVAeklC9vtVpuYL7wRqkyolm++qYKd6yL7tPRdKZNxdGHbFHQR2qIcMQ0oVfEA9tGnQhplj+6Yt/0g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/signers@8.6.0': + resolution: {integrity: sha512-q8FNQfGnMsHc7VLBhh+TwsMfodiYtYhoTqNj6lDIP2bz93l173rzcZWSRH/hg/7ksFdhHuV4nEkWj0L65N0S0Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/subscribable@8.6.0': + resolution: {integrity: sha512-z6qRloUTxoI459dUV2K/HQZO1HYuP5f6NQxXxd25TtM2TDpnjOzoO3pJAlOZP3cwXGgtGk6UWmMEY1a4j0TILw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/sysvars@8.6.0': + resolution: {integrity: sha512-oAIVThVcZr2qDwdvc3Fx+CKCbG1d4VwwRDXbu/tDKVDUIZXDWoTP//BX0u1FimkuirMHHW9Sl+AsSGFba0KPew==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transaction-confirmation@8.6.0': + resolution: {integrity: sha512-kd7LwN1k6L+k9jXMjzm6KqGDuUsETZ1pWMnWY7ZT+1bDjRPbki/RylQc+2CIF7YYphT5GIloTmUziAAmhyw4eQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transaction-introspection@8.6.0': + resolution: {integrity: sha512-/7MYRLnM7AF0983oaicjhvWWQEdeFgknBiKG5LVFd8WT68m5vL18d7/fZHkvsA41zWkIIrRVuh0PM4COeENNlQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transaction-messages@8.6.0': + resolution: {integrity: sha512-Zb7mB8Xu+AXaNiSmgghsyliGNoi7HO4hKdyQC0Qth4hW9QOBMdjSJ687KIUwsAzDSVXwdIbsnkUPpwCl1fcMdw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transactions@8.6.0': + resolution: {integrity: sha512-m2i0dxDtB9mGqhJd714OQpKzGFp9cQbU80kwIBFflOrHdZ2cJzZ61xjGe+vegz/WGsqPec604pUbHKXXIFkNjg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/mocha@10.0.10': + resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} + + '@types/node@26.6.6': + resolution: {integrity: sha512-MzQj+8Kx3XI40OmUAE6Qoh58ZMNstNNMwn2nfd3qWsfe7nDNSqJNzes4njhz6AHwrSHOffSLwXU6yb474Q4aog==} + + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + argparse@3.0.4: + resolution: {integrity: sha512-fwWK3Zq22l4XJJjx5mcBHGikIk+hJqO+32dPm0Jur7+rtG5x1scOjSfdT9ZKeWHPpsya/l0HHK4tDImBkTrtvA==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} + engines: {node: 20 || >=22} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + chai@6.3.0: + resolution: {integrity: sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==} + engines: {node: '>=18'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + commander@15.0.0: + resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==} + engines: {node: '>=22.12.0'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + diff@9.0.0: + resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==} + engines: {node: '>=0.3.1'} + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + glob@14.0.3: + resolution: {integrity: sha512-A1vjIwC3qpdCso45Iw127gnp7sPhqgY8lUQhDrArIs+GbmfaaVPFuoyy7WyLT9EPZCRZ7j7aLdwUhQmHWesEow==} + engines: {node: 18 || 20 || >=22} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + js-yaml@5.5.0: + resolution: {integrity: sha512-paNr4LFIFPjeeSmwNYdrb8FafLLG/Cr2Af3GjbsHJ5CxIjH4r0c2emlmRdAtpPAieP1gRVzk6buBbVP5gBMGAg==} + hasBin: true + + litesvm-darwin-arm64@1.6.2: + resolution: {integrity: sha512-J3JKQaLdK2nQcdrDg8GB3xis8VlrFG2MJwUTTzdRgrvo291RrAdEo8qoO3zzC/BU5jgwsvBCgX4LD2zqdAjOyw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + litesvm-darwin-x64@1.6.2: + resolution: {integrity: sha512-zdAw4c7KnOcysHkUVrPBH2+x+4+7ViYYD8hWYYqZ7OOT4HFFsAV5iIhjul+bl5fMU9qae55lvD1RF4fK1rCgbg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + litesvm-linux-arm64-gnu@1.6.2: + resolution: {integrity: sha512-vMWOPszLOyT3oQxAdANSzSUpJ1uEdTUArI+zruXSW1/nrXn/3zagOBrDxjZhQi0QqK9wT6QN32DfDTfB4xjS/A==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + litesvm-linux-arm64-musl@1.6.2: + resolution: {integrity: sha512-Xw3KPkJEQ90LSOWP2xCGdOO4Y/dRdXJWGTgI8jNObGs0x/Apu0TOXuec/XZUNCvEba4aRwM/Wo3nS6llq5uAng==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + litesvm-linux-x64-gnu@1.6.2: + resolution: {integrity: sha512-6kTBeCnGnAGqPH0ifxix/VGiVVCKBH9zrcx5D2zzZ9ZZkqJEQZiQxGxR36WccYYTWxOxN76M7YDtI9tuMhgw5g==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + litesvm-linux-x64-musl@1.6.2: + resolution: {integrity: sha512-55R3umCLBkX2f+9J55yHAgY5n1zpgzJH/njLnrXFYzTrwv836qR4FsTjIPuxX4QqvnBleJpF2h4wrc+/5R5S+Q==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + litesvm@1.6.2: + resolution: {integrity: sha512-eh6yZg35NiL7CCCBgaLCXvLm+zFF5QaZnAo6ovbbTQDY63wJSzYLc2KqOwowO7d3pNQkJti8toXYL12H0Qyu7A==} + engines: {node: '>= 20'} + + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} + engines: {node: 20 || >=22} + + minimatch@11.0.4: + resolution: {integrity: sha512-/UJ1dEoVQTjPNDh6SGlUo+ueLMmoHTas4q+8yaAR/5t6nLAIiBDJtoYUh20IYleix7ehiQkgczb84PE3uzHkxg==} + engines: {node: 20 || >=22} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + mocha@12.0.3: + resolution: {integrity: sha512-beammieDdiWdkjANWeWPpkxUROYGi5FN88fPOkLiticz7HTg3Y+Pho3EYE6SUdcuWnZ3h2WD8EXCA55JF4o6wg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + path-scurry@3.0.0: + resolution: {integrity: sha512-1pTbQqH1wIwMi/eleQ5leFTTCkzFsPcgXNjwOA8YGGW/W4/kHT3dssE7Z6NH+zuqNLOzOB0uaD61yl7cAcVhgg==} + engines: {node: 18 || 20 || >=22} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + serialize-javascript@7.1.4: + resolution: {integrity: sha512-FqlEuoTq/zRmA4Lg6aOqyH3lCHbUtCB0bmHCeFniX2GBdDqMJM3FwdvEhlE5Pim1dlt2FfBdVPmUNNiGhhKqpw==} + engines: {node: '>=20.0.0'} + + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + tsx@4.23.15: + resolution: {integrity: sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + + undici-types@8.12.3: + resolution: {integrity: sha512-EXE4ydL3S76dFb27UFjNVZHTyv/TLdATj/KUe29ptdcg6qXL48J2tZ3126E5kICj5jn781OR+XlVH1N6Mz8jbA==} + + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} + + workerpool@10.0.3: + resolution: {integrity: sha512-6z2Iis68Wqth93/G/wJP9u+R3O+d2XTlgWChGCwuT1qLbBsOYueGRZuJ++v3mtDP5KjYdy+WzvWC+VWETSVXJA==} + + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + +snapshots: + + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + + '@isaacs/nonrecursive-glob-match@1.0.3': {} + + '@solana-program/record@0.6.0(@solana/kit@8.6.0(typescript@7.0.2))': + dependencies: + '@solana-program/system': 0.16.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana/kit': 8.6.0(typescript@7.0.2) + + '@solana-program/system@0.14.0(@solana/kit@8.6.0(typescript@7.0.2))': + dependencies: + '@solana/kit': 8.6.0(typescript@7.0.2) + + '@solana-program/system@0.16.0(@solana/kit@8.6.0(typescript@7.0.2))': + dependencies: + '@solana/kit': 8.6.0(typescript@7.0.2) + + '@solana-program/token-2022@0.20.1(@solana/kit@8.6.0(typescript@7.0.2))(@solana/sysvars@8.6.0(typescript@7.0.2))': + dependencies: + '@solana-program/record': 0.6.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana-program/system': 0.16.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana-program/zk-elgamal-proof': 0.5.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana/kit': 8.6.0(typescript@7.0.2) + '@solana/sysvars': 8.6.0(typescript@7.0.2) + + '@solana-program/token@0.16.0(@solana/kit@8.6.0(typescript@7.0.2))': + dependencies: + '@solana-program/system': 0.14.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana/kit': 8.6.0(typescript@7.0.2) + + '@solana-program/zk-elgamal-proof@0.5.0(@solana/kit@8.6.0(typescript@7.0.2))': + dependencies: + '@solana-program/system': 0.16.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana/kit': 8.6.0(typescript@7.0.2) + + '@solana/accounts@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/addresses@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/assertions': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/nominal-types': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/assertions@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/codecs-core@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/codecs-data-structures@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/codecs-numbers@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/codecs-strings@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/codecs@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-data-structures': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/fixed-points': 8.6.0(typescript@7.0.2) + '@solana/options': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@8.6.0(typescript@7.0.2)': + dependencies: + chalk: 5.6.2 + commander: 15.0.0 + optionalDependencies: + typescript: 7.0.2 + + '@solana/fast-stable-stringify@8.6.0(typescript@7.0.2)': + optionalDependencies: + typescript: 7.0.2 + + '@solana/fixed-points@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/functional@8.6.0(typescript@7.0.2)': + optionalDependencies: + typescript: 7.0.2 + + '@solana/instruction-plans@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/instructions': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/promises': 8.6.0(typescript@7.0.2) + '@solana/transaction-messages': 8.6.0(typescript@7.0.2) + '@solana/transactions': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/instructions@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/keys@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/assertions': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/nominal-types': 8.6.0(typescript@7.0.2) + '@solana/promises': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/accounts': 8.6.0(typescript@7.0.2) + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/functional': 8.6.0(typescript@7.0.2) + '@solana/instruction-plans': 8.6.0(typescript@7.0.2) + '@solana/instructions': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/offchain-messages': 8.6.0(typescript@7.0.2) + '@solana/plugin-core': 8.6.0(typescript@7.0.2) + '@solana/plugin-interfaces': 8.6.0(typescript@7.0.2) + '@solana/program-client-core': 8.6.0(typescript@7.0.2) + '@solana/programs': 8.6.0(typescript@7.0.2) + '@solana/promises': 8.6.0(typescript@7.0.2) + '@solana/rpc': 8.6.0(typescript@7.0.2) + '@solana/rpc-api': 8.6.0(typescript@7.0.2) + '@solana/rpc-parsed-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-subscriptions': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + '@solana/signers': 8.6.0(typescript@7.0.2) + '@solana/subscribable': 8.6.0(typescript@7.0.2) + '@solana/sysvars': 8.6.0(typescript@7.0.2) + '@solana/transaction-confirmation': 8.6.0(typescript@7.0.2) + '@solana/transaction-introspection': 8.6.0(typescript@7.0.2) + '@solana/transaction-messages': 8.6.0(typescript@7.0.2) + '@solana/transactions': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/nominal-types@8.6.0(typescript@7.0.2)': + optionalDependencies: + typescript: 7.0.2 + + '@solana/offchain-messages@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-data-structures': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/nominal-types': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/options@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-data-structures': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/plugin-core@8.6.0(typescript@7.0.2)': + optionalDependencies: + typescript: 7.0.2 + + '@solana/plugin-interfaces@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/accounts': 8.6.0(typescript@7.0.2) + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/instruction-plans': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec': 8.6.0(typescript@7.0.2) + '@solana/rpc-subscriptions-spec': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + '@solana/signers': 8.6.0(typescript@7.0.2) + '@solana/transactions': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/program-client-core@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/accounts': 8.6.0(typescript@7.0.2) + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/instruction-plans': 8.6.0(typescript@7.0.2) + '@solana/instructions': 8.6.0(typescript@7.0.2) + '@solana/plugin-interfaces': 8.6.0(typescript@7.0.2) + '@solana/rpc-api': 8.6.0(typescript@7.0.2) + '@solana/signers': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/programs@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/promises@8.6.0(typescript@7.0.2)': + optionalDependencies: + typescript: 7.0.2 + + '@solana/rpc-api@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/rpc-parsed-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec': 8.6.0(typescript@7.0.2) + '@solana/rpc-transformers': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + '@solana/transaction-messages': 8.6.0(typescript@7.0.2) + '@solana/transactions': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-parsed-types@8.6.0(typescript@7.0.2)': + optionalDependencies: + typescript: 7.0.2 + + '@solana/rpc-spec-types@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/rpc-spec@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec-types': 8.6.0(typescript@7.0.2) + '@solana/subscribable': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/rpc-subscriptions-api@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/rpc-subscriptions-spec': 8.6.0(typescript@7.0.2) + '@solana/rpc-transformers': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + '@solana/transaction-messages': 8.6.0(typescript@7.0.2) + '@solana/transactions': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-subscriptions-channel-websocket@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/functional': 8.6.0(typescript@7.0.2) + '@solana/rpc-subscriptions-spec': 8.6.0(typescript@7.0.2) + '@solana/subscribable': 8.6.0(typescript@7.0.2) + ws: 8.21.3 + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@solana/rpc-subscriptions-spec@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/promises': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec-types': 8.6.0(typescript@7.0.2) + '@solana/subscribable': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/rpc-subscriptions@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/fast-stable-stringify': 8.6.0(typescript@7.0.2) + '@solana/functional': 8.6.0(typescript@7.0.2) + '@solana/promises': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-subscriptions-api': 8.6.0(typescript@7.0.2) + '@solana/rpc-subscriptions-channel-websocket': 8.6.0(typescript@7.0.2) + '@solana/rpc-subscriptions-spec': 8.6.0(typescript@7.0.2) + '@solana/rpc-transformers': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + '@solana/subscribable': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/rpc-transformers@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/functional': 8.6.0(typescript@7.0.2) + '@solana/nominal-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-transport-http@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec-types': 8.6.0(typescript@7.0.2) + undici-types: 8.12.3 + optionalDependencies: + typescript: 7.0.2 + + '@solana/rpc-types@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/fixed-points': 8.6.0(typescript@7.0.2) + '@solana/nominal-types': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/fast-stable-stringify': 8.6.0(typescript@7.0.2) + '@solana/functional': 8.6.0(typescript@7.0.2) + '@solana/rpc-api': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec': 8.6.0(typescript@7.0.2) + '@solana/rpc-spec-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-transformers': 8.6.0(typescript@7.0.2) + '@solana/rpc-transport-http': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/signers@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/instruction-plans': 8.6.0(typescript@7.0.2) + '@solana/instructions': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/nominal-types': 8.6.0(typescript@7.0.2) + '@solana/offchain-messages': 8.6.0(typescript@7.0.2) + '@solana/transaction-messages': 8.6.0(typescript@7.0.2) + '@solana/transactions': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/subscribable@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/promises': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + + '@solana/sysvars@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/accounts': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-data-structures': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-confirmation@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/promises': 8.6.0(typescript@7.0.2) + '@solana/rpc': 8.6.0(typescript@7.0.2) + '@solana/rpc-subscriptions': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + '@solana/transaction-messages': 8.6.0(typescript@7.0.2) + '@solana/transactions': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/transaction-introspection@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/instructions': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + '@solana/transaction-messages': 8.6.0(typescript@7.0.2) + '@solana/transactions': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-messages@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-data-structures': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/functional': 8.6.0(typescript@7.0.2) + '@solana/instructions': 8.6.0(typescript@7.0.2) + '@solana/nominal-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transactions@8.6.0(typescript@7.0.2)': + dependencies: + '@solana/addresses': 8.6.0(typescript@7.0.2) + '@solana/codecs-core': 8.6.0(typescript@7.0.2) + '@solana/codecs-data-structures': 8.6.0(typescript@7.0.2) + '@solana/codecs-numbers': 8.6.0(typescript@7.0.2) + '@solana/codecs-strings': 8.6.0(typescript@7.0.2) + '@solana/errors': 8.6.0(typescript@7.0.2) + '@solana/functional': 8.6.0(typescript@7.0.2) + '@solana/instructions': 8.6.0(typescript@7.0.2) + '@solana/keys': 8.6.0(typescript@7.0.2) + '@solana/nominal-types': 8.6.0(typescript@7.0.2) + '@solana/rpc-types': 8.6.0(typescript@7.0.2) + '@solana/transaction-messages': 8.6.0(typescript@7.0.2) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/mocha@10.0.10': {} + + '@types/node@26.6.6': + dependencies: + undici-types: 8.9.0 + + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + argparse@3.0.4: {} + + assertion-error@2.0.1: {} + + balanced-match@4.0.4: {} + + brace-expansion@5.0.12: + dependencies: + balanced-match: 4.0.4 + + browser-stdout@1.3.1: {} + + chai@6.3.0: {} + + chalk@5.6.2: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + commander@15.0.0: {} + + debug@4.4.3(supports-color@8.1.1): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 + + diff@9.0.0: {} + + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + + find-up-simple@1.0.1: {} + + fsevents@2.3.3: + optional: true + + glob@14.0.3: + dependencies: + minimatch: 11.0.4 + minipass: 7.1.3 + path-scurry: 3.0.0 + + has-flag@4.0.0: {} + + is-path-inside@4.0.0: {} + + is-unicode-supported@0.1.0: {} + + js-yaml@5.5.0: + dependencies: + argparse: 3.0.4 + + litesvm-darwin-arm64@1.6.2: + optional: true + + litesvm-darwin-x64@1.6.2: + optional: true + + litesvm-linux-arm64-gnu@1.6.2: + optional: true + + litesvm-linux-arm64-musl@1.6.2: + optional: true + + litesvm-linux-x64-gnu@1.6.2: + optional: true + + litesvm-linux-x64-musl@1.6.2: + optional: true + + litesvm@1.6.2(typescript@7.0.2): + dependencies: + '@solana-program/system': 0.14.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana-program/token': 0.16.0(@solana/kit@8.6.0(typescript@7.0.2)) + '@solana/kit': 8.6.0(typescript@7.0.2) + optionalDependencies: + litesvm-darwin-arm64: 1.6.2 + litesvm-darwin-x64: 1.6.2 + litesvm-linux-arm64-gnu: 1.6.2 + litesvm-linux-arm64-musl: 1.6.2 + litesvm-linux-x64-gnu: 1.6.2 + litesvm-linux-x64-musl: 1.6.2 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + + lru-cache@11.5.3: {} + + minimatch@11.0.4: + dependencies: + '@isaacs/nonrecursive-glob-match': 1.0.3 + brace-expansion: 5.0.12 + + minipass@7.1.3: {} + + mocha@12.0.3: + dependencies: + browser-stdout: 1.3.1 + chokidar: 5.0.0 + debug: 4.4.3(supports-color@8.1.1) + diff: 9.0.0 + find-up-simple: 1.0.1 + glob: 14.0.3 + is-path-inside: 4.0.0 + is-unicode-supported: 0.1.0 + js-yaml: 5.5.0 + minimatch: 11.0.4 + ms: 2.1.3 + picocolors: 1.1.1 + serialize-javascript: 7.1.4 + strip-json-comments: 5.0.3 + supports-color: 8.1.1 + workerpool: 10.0.3 + + ms@2.1.3: {} + + path-scurry@3.0.0: + dependencies: + lru-cache: 11.5.3 + minipass: 7.1.3 + + picocolors@1.1.1: {} + + readdirp@5.1.1: {} + + serialize-javascript@7.1.4: {} + + strip-json-comments@5.0.3: {} + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + tsx@4.23.15: + dependencies: + esbuild: 0.28.2 + optionalDependencies: + fsevents: 2.3.3 + + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + undici-types@8.12.3: {} + + undici-types@8.9.0: {} + + workerpool@10.0.3: {} + + ws@8.21.3: {} diff --git a/tokens/token-2022/cpi-guard/pinocchio/pnpm-workspace.yaml b/tokens/token-2022/cpi-guard/pinocchio/pnpm-workspace.yaml new file mode 100644 index 000000000..da56139bb --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +overrides: + glob@>=9.0.0 <=14.0.1: '>=14.0.2' + minimatch@<11.0.1: '>=11.0.1' diff --git a/tokens/token-2022/cpi-guard/pinocchio/program/Cargo.toml b/tokens/token-2022/cpi-guard/pinocchio/program/Cargo.toml new file mode 100644 index 000000000..b73098ce5 --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/program/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "token-2022-cpi-guard-pinocchio-program" +version = "0.1.0" +edition = "2021" + +[dependencies] +pinocchio.workspace = true +pinocchio-log.workspace = true +pinocchio-system.workspace = true + +[lib] +crate-type = ["cdylib", "lib"] + +[features] +custom-heap = [] +custom-panic = [] + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(target_os, values("solana"))'] } diff --git a/tokens/token-2022/cpi-guard/pinocchio/program/src/instructions/cpi_transfer.rs b/tokens/token-2022/cpi-guard/pinocchio/program/src/instructions/cpi_transfer.rs new file mode 100644 index 000000000..2a2788f15 --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/program/src/instructions/cpi_transfer.rs @@ -0,0 +1,76 @@ +use pinocchio::{ + cpi::invoke, + error::ProgramError, + instruction::{InstructionAccount, InstructionView}, + AccountView, ProgramResult, +}; +use pinocchio_log::log; + +use crate::instructions::TOKEN_2022_PROGRAM_ID; + +/// Token-2022 `TransferChecked` instruction discriminator (variant 12). +const TRANSFER_CHECKED: u8 = 12; +/// The `decimals` field of a base mint lives at byte offset 44: a +/// `COption` mint authority (4-byte tag + 32) followed by an 8-byte +/// `u64` supply. +const MINT_DECIMALS_OFFSET: usize = 44; +/// The example transfers a single base unit; the point is the CPI, not the +/// amount. +const TRANSFER_AMOUNT: u64 = 1; + +/// Transfers tokens from `source` to `destination` via a Token-2022 +/// `TransferChecked` CPI, signed by the source account's owner. +/// +/// This is used to demonstrate the `CpiGuard` extension: when CpiGuard is +/// enabled on the source account, Token-2022 rejects this owner-authorized +/// transfer *because it happens through a CPI*. With CpiGuard disabled, the same +/// transfer succeeds. (CpiGuard itself cannot be enabled or disabled through a +/// CPI, so that is done off-chain in the test, not by this program.) +/// +/// Accounts: +/// 0. `[writable]` source token account (owned by `authority`) +/// 1. `[]` mint account (owned by Token-2022; its `decimals` are read here) +/// 2. `[writable]` destination token account +/// 3. `[signer]` authority (the source account's owner) +/// 4. `[]` Token-2022 program +pub fn cpi_transfer(accounts: &mut [AccountView]) -> ProgramResult { + // `token_program` is unused directly, but must be supplied so it is present + // in the transaction for the CPI below. + let [source, mint, destination, authority, _token_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + // Only trust the mint's bytes once Token-2022 is known to own the account; + // any program can create an account whose data looks like a mint. + if !mint.owned_by(&TOKEN_2022_PROGRAM_ID) { + return Err(ProgramError::InvalidAccountOwner); + } + + // `TransferChecked` requires the decimals to match the mint, so read them + // straight from the mint account's data. + let decimals = { + let mint_data = mint.try_borrow()?; + *mint_data.get(MINT_DECIMALS_OFFSET).ok_or(ProgramError::InvalidAccountData)? + }; + + // Layout: `[12] amount: u64 decimals: u8` (little-endian). + let mut data = [0u8; 10]; + data[0] = TRANSFER_CHECKED; + data[1..9].copy_from_slice(&TRANSFER_AMOUNT.to_le_bytes()); + data[9] = decimals; + + log!("Transferring via CPI"); + let transfer_accounts = [ + InstructionAccount::writable(source.address()), + InstructionAccount::readonly(mint.address()), + InstructionAccount::writable(destination.address()), + InstructionAccount::readonly_signer(authority.address()), + ]; + invoke( + &InstructionView { program_id: &TOKEN_2022_PROGRAM_ID, accounts: &transfer_accounts, data: &data }, + &[*source, *mint, *destination, *authority], + )?; + + log!("Transfer complete"); + Ok(()) +} diff --git a/tokens/token-2022/cpi-guard/pinocchio/program/src/instructions/mod.rs b/tokens/token-2022/cpi-guard/pinocchio/program/src/instructions/mod.rs new file mode 100644 index 000000000..257bf209c --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/program/src/instructions/mod.rs @@ -0,0 +1,12 @@ +mod cpi_transfer; + +pub use cpi_transfer::*; + +/// The SPL Token-2022 program ID +/// (`TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`). +/// +/// The Token-2022 instruction is built by hand below, to show its byte layout, +/// and CPI'd into this program. The `pinocchio-token-2022` crate provides +/// ready-made builders if you'd rather not. +pub const TOKEN_2022_PROGRAM_ID: pinocchio::Address = + pinocchio::Address::from_str_const("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"); diff --git a/tokens/token-2022/cpi-guard/pinocchio/program/src/lib.rs b/tokens/token-2022/cpi-guard/pinocchio/program/src/lib.rs new file mode 100644 index 000000000..18082bcc1 --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/program/src/lib.rs @@ -0,0 +1,9 @@ +#![no_std] + +pub mod instructions; +pub mod processor; + +use pinocchio::{entrypoint, nostd_panic_handler}; + +entrypoint!(processor::process_instruction); +nostd_panic_handler!(); diff --git a/tokens/token-2022/cpi-guard/pinocchio/program/src/processor.rs b/tokens/token-2022/cpi-guard/pinocchio/program/src/processor.rs new file mode 100644 index 000000000..dd6c7bd0e --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/program/src/processor.rs @@ -0,0 +1,19 @@ +use pinocchio::{AccountView, Address, ProgramResult}; +use pinocchio_log::log; + +use crate::instructions::cpi_transfer; + +/// Entrypoint for the program. +/// +/// This example exposes a single instruction (transferring tokens via CPI to +/// demonstrate the `CpiGuard` extension), so there is no leading discriminator +/// byte and the instruction carries no data — the amount is fixed at 1 token and +/// the decimals are read from the mint (see `cpi_transfer`). +pub fn process_instruction( + _program_id: &Address, + accounts: &mut [AccountView], + _instruction_data: &[u8], +) -> ProgramResult { + log!("Instruction: CpiTransfer"); + cpi_transfer(accounts) +} diff --git a/tokens/token-2022/cpi-guard/pinocchio/tests/test.ts b/tokens/token-2022/cpi-guard/pinocchio/tests/test.ts new file mode 100644 index 000000000..b8850ce59 --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/tests/test.ts @@ -0,0 +1,288 @@ +import * as path from 'node:path'; +import { + AccountRole, + type Address, + appendTransactionMessageInstruction, + appendTransactionMessageInstructions, + createTransactionMessage, + generateKeyPairSigner, + type KeyPairSigner, + lamports, + pipe, + setTransactionMessageFeePayerSigner, + signTransactionMessageWithSigners, +} from '@solana/kit'; +import { getCreateAccountInstruction, SYSTEM_PROGRAM_ADDRESS } from '@solana-program/system'; +import { + getDisableCpiGuardInstruction, + getEnableCpiGuardInstruction, + getInitializeAccount3Instruction, + getInitializeMint2Instruction, + getMintToInstruction, + getTokenDecoder, + TOKEN_2022_PROGRAM_ADDRESS, +} from '@solana-program/token-2022'; +import { assert } from 'chai'; +import { FailedTransactionMetadata, LiteSVM } from 'litesvm'; + +// A bare SPL Token-2022 mint (no extensions) is 82 bytes; a bare token account is 165. +const MINT_SIZE = 82n; +const TOKEN_ACCOUNT_SIZE = 165n; +// A token account with the CpiGuard extension: +// base account length (165) + account-type byte (1) + CpiGuard TLV (5) = 171 +// The CpiGuard value is a single `bool` (`lock_cpi`). +const CPI_GUARD_ACCOUNT_SIZE = 171n; + +// The compiled program artifact, produced by `build-and-test` into ./fixtures. +// The npm scripts always run from the package root, so resolve from the cwd. +const PROGRAM_SO = path.join(process.cwd(), 'tests', 'fixtures', 'token_2022_cpi_guard_pinocchio_program.so'); + +describe('Token-2022 CPI Guard (Pinocchio)', () => { + let svm: LiteSVM; + let programId: Address; + + before(async () => { + svm = new LiteSVM(); + // The program never asserts its own id, so any address works; a generated + // one keeps the test self-contained. + programId = (await generateKeyPairSigner()).address; + svm.addProgramFromFile(programId, PROGRAM_SO); + }); + + // Creates a plain (no-extension) Token-2022 mint whose authority is the payer. + async function createMint(payer: KeyPairSigner, decimals: number): Promise { + const mint = await generateKeyPairSigner(); + const tx = pipe( + createTransactionMessage({ version: 0 }), + m => setTransactionMessageFeePayerSigner(payer, m), + m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + m => + appendTransactionMessageInstructions( + [ + getCreateAccountInstruction({ + payer, + newAccount: mint, + lamports: svm.minimumBalanceForRentExemption(MINT_SIZE), + space: MINT_SIZE, + programAddress: TOKEN_2022_PROGRAM_ADDRESS, + }), + getInitializeMint2Instruction({ + mint: mint.address, + decimals, + mintAuthority: payer.address, + freezeAuthority: null, + }), + ], + m, + ), + ); + send(await signTransactionMessageWithSigners(tx), 'mint setup'); + return mint; + } + + // Sends a signed transaction and throws with context on failure. + function send(signedTx: Parameters[0], label: string) { + const result = svm.sendTransaction(signedTx); + if (result instanceof FailedTransactionMetadata) { + throw new Error(`${label} failed: ${result.err()}`); + } + } + + // Invokes the example program's cpi_transfer (a TransferChecked CPI) from + // `source` to `destination`, signed by the payer (the source's owner). + function cpiTransferIx(payer: KeyPairSigner, source: Address, mint: Address, destination: Address) { + return { + programAddress: programId, + accounts: [ + { address: source, role: AccountRole.WRITABLE }, // source token account + { address: mint, role: AccountRole.READONLY }, // mint account + { address: destination, role: AccountRole.WRITABLE }, // destination token account + { address: payer.address, role: AccountRole.READONLY_SIGNER as const, signer: payer }, // authority (owner) + { address: TOKEN_2022_PROGRAM_ADDRESS, role: AccountRole.READONLY }, // Token-2022 program + ], + }; + } + + it('Blocks a CPI transfer while CpiGuard is enabled and allows it once disabled', async () => { + const payer = await generateKeyPairSigner(); + svm.airdrop(payer.address, lamports(1_000_000_000n)); + const decimals = 2; + + const mint = await createMint(payer, decimals); + + // Source account with CpiGuard enabled, funded with some tokens. + const source = await generateKeyPairSigner(); + const sourceTx = pipe( + createTransactionMessage({ version: 0 }), + m => setTransactionMessageFeePayerSigner(payer, m), + m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + m => + appendTransactionMessageInstructions( + [ + getCreateAccountInstruction({ + payer, + newAccount: source, + lamports: svm.minimumBalanceForRentExemption(CPI_GUARD_ACCOUNT_SIZE), + space: CPI_GUARD_ACCOUNT_SIZE, + programAddress: TOKEN_2022_PROGRAM_ADDRESS, + }), + getInitializeAccount3Instruction({ + account: source.address, + mint: mint.address, + owner: payer.address, + }), + getMintToInstruction({ + mint: mint.address, + token: source.address, + mintAuthority: payer, + amount: 100n, + }), + getEnableCpiGuardInstruction({ token: source.address, owner: payer }), + ], + m, + ), + ); + send(await signTransactionMessageWithSigners(sourceTx), 'source setup'); + + // Plain destination account. + const destination = await generateKeyPairSigner(); + const destTx = pipe( + createTransactionMessage({ version: 0 }), + m => setTransactionMessageFeePayerSigner(payer, m), + m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + m => + appendTransactionMessageInstructions( + [ + getCreateAccountInstruction({ + payer, + newAccount: destination, + lamports: svm.minimumBalanceForRentExemption(TOKEN_ACCOUNT_SIZE), + space: TOKEN_ACCOUNT_SIZE, + programAddress: TOKEN_2022_PROGRAM_ADDRESS, + }), + getInitializeAccount3Instruction({ + account: destination.address, + mint: mint.address, + owner: payer.address, + }), + ], + m, + ), + ); + send(await signTransactionMessageWithSigners(destTx), 'destination setup'); + + const transferIx = cpiTransferIx(payer, source.address, mint.address, destination.address); + + // While CpiGuard is enabled, the owner-authorized transfer via CPI is rejected. + const blockedTx = pipe( + createTransactionMessage({ version: 0 }), + m => setTransactionMessageFeePayerSigner(payer, m), + m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + m => appendTransactionMessageInstruction(transferIx, m), + ); + const blockedResult = svm.sendTransaction(await signTransactionMessageWithSigners(blockedTx)); + assert.instanceOf(blockedResult, FailedTransactionMetadata, 'expected the guarded CPI transfer to be rejected'); + + // Disable CpiGuard, then the same CPI transfer succeeds. + const disableTx = pipe( + createTransactionMessage({ version: 0 }), + m => setTransactionMessageFeePayerSigner(payer, m), + m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + m => + appendTransactionMessageInstruction( + getDisableCpiGuardInstruction({ token: source.address, owner: payer }), + m, + ), + ); + send(await signTransactionMessageWithSigners(disableTx), 'disable CpiGuard'); + + // The retried transfer is otherwise byte-identical to the blocked one, so + // advance the blockhash to give it a distinct signature. + svm.expireBlockhash(); + const allowedTx = pipe( + createTransactionMessage({ version: 0 }), + m => setTransactionMessageFeePayerSigner(payer, m), + m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + m => appendTransactionMessageInstruction(transferIx, m), + ); + send(await signTransactionMessageWithSigners(allowedTx), 'unguarded CPI transfer'); + + const destAccount = svm.getAccount(destination.address); + if (!destAccount?.exists) throw new Error('Destination account not found'); + const destState = getTokenDecoder().decode(destAccount.data); + assert.equal(destState.amount, 1n); + + console.log('Source (CpiGuard) account:', source.address); + }); + + // Creates a plain (no-extension) Token-2022 token account owned by the payer, + // optionally minting `amount` tokens into it. + async function createTokenAccount(payer: KeyPairSigner, mint: Address, amount = 0n): Promise
{ + const account = await generateKeyPairSigner(); + const tx = pipe( + createTransactionMessage({ version: 0 }), + m => setTransactionMessageFeePayerSigner(payer, m), + m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + m => + appendTransactionMessageInstructions( + [ + getCreateAccountInstruction({ + payer, + newAccount: account, + lamports: svm.minimumBalanceForRentExemption(TOKEN_ACCOUNT_SIZE), + space: TOKEN_ACCOUNT_SIZE, + programAddress: TOKEN_2022_PROGRAM_ADDRESS, + }), + getInitializeAccount3Instruction({ account: account.address, mint, owner: payer.address }), + ...(amount > 0n + ? [getMintToInstruction({ mint, token: account.address, mintAuthority: payer, amount })] + : []), + ], + m, + ), + ); + send(await signTransactionMessageWithSigners(tx), 'token account setup'); + return account.address; + } + + it('Rejects a mint that Token-2022 does not own, before any CPI', async () => { + const payer = await generateKeyPairSigner(); + svm.airdrop(payer.address, lamports(1_000_000_000n)); + + const mint = await createMint(payer, 2); + const source = await createTokenAccount(payer, mint.address, 100n); + const destination = await createTokenAccount(payer, mint.address); + + // A byte-for-byte copy of the real mint, but owned by the System Program: + // its decimals byte reads fine, so only the owner check can stop it. + const realMint = svm.getAccount(mint.address); + if (!realMint?.exists) throw new Error('Mint not found'); + const fakeMint = (await generateKeyPairSigner()).address; + svm.setAccount({ ...realMint, address: fakeMint, programAddress: SYSTEM_PROGRAM_ADDRESS }); + + const tx = pipe( + createTransactionMessage({ version: 0 }), + m => setTransactionMessageFeePayerSigner(payer, m), + m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + m => appendTransactionMessageInstruction(cpiTransferIx(payer, source, fakeMint, destination), m), + ); + const result = svm.sendTransaction(await signTransactionMessageWithSigners(tx)); + assert.instanceOf(result, FailedTransactionMetadata, 'expected a non-Token-2022 mint to be rejected'); + + // The program itself rejected it: Token-2022 was never invoked. + const logs = result.meta().logs(); + assert.isTrue( + logs.some(l => l.startsWith(`Program ${programId} failed`)), + `expected the example program to fail; logs: ${logs.join(' | ')}`, + ); + assert.isFalse( + logs.some(l => l.startsWith(`Program ${TOKEN_2022_PROGRAM_ADDRESS} invoke`)), + `expected no Token-2022 CPI; logs: ${logs.join(' | ')}`, + ); + + // Nothing moved. + const destAccount = svm.getAccount(destination); + if (!destAccount?.exists) throw new Error('Destination account not found'); + assert.equal(getTokenDecoder().decode(destAccount.data).amount, 0n); + }); +}); diff --git a/tokens/token-2022/cpi-guard/pinocchio/tsconfig.json b/tokens/token-2022/cpi-guard/pinocchio/tsconfig.json new file mode 100644 index 000000000..c02443141 --- /dev/null +++ b/tokens/token-2022/cpi-guard/pinocchio/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai", "node"], + "typeRoots": ["./node_modules/@types"], + "lib": ["esnext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "resolveJsonModule": true, + "allowImportingTsExtensions": true, + "noEmit": true, + "skipLibCheck": true + } +}