diff --git a/Cargo.lock b/Cargo.lock index d92d1b032..d58915079 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2044,6 +2044,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nft-minter-pinocchio-program" +version = "0.1.0" +dependencies = [ + "pinocchio 0.10.2", + "pinocchio-associated-token-account", + "pinocchio-log", + "pinocchio-system", + "pinocchio-token", +] + [[package]] name = "num" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index aae171e04..061e7a236 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ members = [ # tokens "tokens/escrow/pinocchio/program", + "tokens/nft-minter/pinocchio/program", "tokens/transfer-tokens/pinocchio/program", "tokens/token-2022/mint-close-authority/native/program", "tokens/token-2022/non-transferable/native/program", diff --git a/README.md b/README.md index 0f7048fa8..634fb976b 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ How to store state that changes size in Solana. [Mint an NFT from inside your own onchain program using the Token and Metaplex Token Metadata programs.](./tokens/nft-minter/README.md) Reminder: you don't need your own program just to mint an NFT, see the note at the top of this README. -[anchor](./tokens/nft-minter/anchor) [native](./tokens/nft-minter/native) +[anchor](./tokens/nft-minter/anchor) [native](./tokens/nft-minter/native) [pinocchio](./tokens/nft-minter/pinocchio) ### NFT operations diff --git a/tokens/nft-minter/pinocchio/cicd.sh b/tokens/nft-minter/pinocchio/cicd.sh new file mode 100644 index 000000000..b2407c75f --- /dev/null +++ b/tokens/nft-minter/pinocchio/cicd.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This script is for quick building & deploying of the program. +# It also serves as a reference for the commands used for building & deploying Solana programs. +# Run this bad boy with "bash cicd.sh" or "./cicd.sh" + +cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so +solana program deploy ./program/target/so/program.so diff --git a/tokens/nft-minter/pinocchio/package.json b/tokens/nft-minter/pinocchio/package.json new file mode 100644 index 000000000..d484fa2da --- /dev/null +++ b/tokens/nft-minter/pinocchio/package.json @@ -0,0 +1,26 @@ +{ + "type": "module", + "scripts": { + "postinstall": "node prepare.mjs", + "test": "pnpm ts-mocha -p ./tsconfig.json -t 1000000 ./tests/test.ts", + "build-and-test": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./tests/fixtures && pnpm test", + "build": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so", + "deploy": "solana program deploy ./program/target/so/program.so" + }, + "dependencies": { + "@solana-program/system": "^0.12.2", + "@solana-program/token": "^0.14.0", + "@solana/kit": "^6.10.0", + "borsh": "^2.0.0", + "litesvm": "^1.3.0" + }, + "devDependencies": { + "@types/chai": "^4.3.1", + "@types/mocha": "^9.1.1", + "@types/node": "^20.0.0", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "ts-mocha": "^10.0.0", + "typescript": "^5.6.0" + } +} diff --git a/tokens/nft-minter/pinocchio/pnpm-lock.yaml b/tokens/nft-minter/pinocchio/pnpm-lock.yaml new file mode 100644 index 000000000..b95201dea --- /dev/null +++ b/tokens/nft-minter/pinocchio/pnpm-lock.yaml @@ -0,0 +1,1880 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@solana-program/system': + specifier: ^0.12.2 + version: 0.12.2(@solana/kit@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)) + '@solana-program/token': + specifier: ^0.14.0 + version: 0.14.0(@solana/kit@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)) + '@solana/kit': + specifier: ^6.10.0 + version: 6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + borsh: + specifier: ^2.0.0 + version: 2.0.0 + litesvm: + specifier: ^1.3.0 + version: 1.3.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + devDependencies: + '@types/chai': + specifier: ^4.3.1 + version: 4.3.20 + '@types/mocha': + specifier: ^9.1.1 + version: 9.1.1 + '@types/node': + specifier: ^20.0.0 + version: 20.19.43 + chai: + specifier: ^4.3.4 + version: 4.5.0 + mocha: + specifier: ^9.0.3 + version: 9.2.2 + ts-mocha: + specifier: ^10.0.0 + version: 10.1.0(mocha@9.2.2) + typescript: + specifier: ^5.6.0 + version: 5.9.3 + +packages: + + '@solana-program/system@0.12.2': + resolution: {integrity: sha512-MaBeOxlvTruQhA7UYkOb3hVTEHPPagOtd+PvTm6a8rGgvEAP0kD4BbC37NceOaR4ABNqdaCmD5OMVRKgrE6KAg==} + peerDependencies: + '@solana/kit': ^6.4.0 + + '@solana-program/token@0.14.0': + resolution: {integrity: sha512-zpLMr6JZndlsQCQvrm0gezfwdr1lmzOGqN6v2WIYXjtDmbF+xg6zh/MAp2UFHRpv3uDmylEdjtQo05pa2OeaYg==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@solana/kit': ^6.5.0 + + '@solana/accounts@6.10.0': + resolution: {integrity: sha512-+FxfDOrnifoPlBkF+fr8eeQdgM6xtIgAg9xKMu3WnIz60oZd4Xnry6+ff6t+ePPoZZp397FSg9ZJet68VCWm5Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/addresses@6.10.0': + resolution: {integrity: sha512-vEoCGBTxG0HCERAn84KXkrJjl+pDaNzOpZ0qbgcPS98fYxP5yzbKB8SNOY2bzrbkRUmmw5Q3hqTRERemUN2Gcw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/assertions@6.10.0': + resolution: {integrity: sha512-lKSAdVo+P/6Lp4vs6shstXmFOpvxrABwn4o1462tb7sKkNapk6o9pPFVPGw4DUgPS3WqWRs1j2tmpuVjhQRntg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-core@6.10.0': + resolution: {integrity: sha512-nfAl9OMGo4HanIMxGsQoVB7BxMoqBCYEUxl8oEAZZ09pDxnaXQZkTRXEwPPccag37XfW1ciPd1vWPKwB2b0HHQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-data-structures@6.10.0': + resolution: {integrity: sha512-CNasJW3bq5u+632Zt5aJ8rOjAjv2HyenpV8o9kAIqdmV4CBpjCCoBnKn8LkuR/sbeREZxJYfhKTXO/9ruAkw7A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-numbers@6.10.0': + resolution: {integrity: sha512-CcM+wX4zOiA9zkh8A7t1787A0Ehgmu5+6Z2tKoHew6cNw/dkaUTPa8JnNHbvfsLC8dfHC1BhAEJl86sKmRsfkQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-strings@6.10.0': + resolution: {integrity: sha512-zlaqkg7K6F6IN4V/Ec8TWkTn054gxv7ZLagvGkuEyAdPQ6BzzsehOm2TqCuyXgJJTCGPLY1bEk6yH9NxANe0kA==} + engines: {node: '>=20.18.0'} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.4.0' + peerDependenciesMeta: + fastestsmallesttextencoderdecoder: + optional: true + typescript: + optional: true + + '@solana/codecs@6.10.0': + resolution: {integrity: sha512-lLVuxod4ChWp9i7OvpgIykYG8Q9OGPVXKnHM9VlzDDLylsx7Y1FoQL00sHa7PqFkJVmkBufaA6dcGbQ7FU+lAQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/errors@6.10.0': + resolution: {integrity: sha512-KBLAxCtAXr357JNhCyIDQXWbuSj5vN6w+28FSfcYY6OOSiphmXLAV3V58jgV0C6iNbIzFJFi6yatFyDTdeJsNg==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/fast-stable-stringify@6.10.0': + resolution: {integrity: sha512-iCNed27wk6PKSS3QUtHovRfMWF/jbVWogs2vB4tukKUCsqG4rDfDInIwZ6ur/nY6XTrgi2gMMdZq9GAUlWsbfw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/fixed-points@6.10.0': + resolution: {integrity: sha512-ZkKL0alXH3L7/wMiVG8YUuG8qBKunlM810+YBD7nUPRhifiGsX1zwADViHLYNqLr/jUk0mTYFUcKznTpB/K+Gg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/functional@6.10.0': + resolution: {integrity: sha512-P8cevu4mAqHTXC37h1TVoOh8zhWB2tlOI/R9vWjYPpcLwcyWf8p2qq4LEGHl5kY+1C+4PNX39HsmCocXOPCDkQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/instruction-plans@6.10.0': + resolution: {integrity: sha512-YG7mo4zykzdc6ZTV0BuN6pveK9qeBySzlYYerq578A4eQu3xcypMAYRGAvhMZtWTanjjmD6CKtM0M7kVp0TNxg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/instructions@6.10.0': + resolution: {integrity: sha512-0TToYF+8LXQ3ofPMx+yF6yaM9l4YJvcAPMy0qV5JsrBUFlWXBSANRuudKBQLHMvb+a3OiUTq5X7omuorKMBB3A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/keys@6.10.0': + resolution: {integrity: sha512-26IRfdm/hTUCmM7MeEeX0ULSbCM6OzkZTkfkrPircqmRM7xyNqP4hq7u0P7wjb9dl7NfgyG6K7cdvUxrj2e3mA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/kit@6.10.0': + resolution: {integrity: sha512-/WnnQp3uARh2JCFSfAakejTAqwmXVuMVTcRn5r2yDwY2yzZ4R6mt/Cl59VPimVLNSoTyN/KsEwhv9omr3ERazQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/nominal-types@6.10.0': + resolution: {integrity: sha512-9ykyBBvnkInH7fCacjJi7zu2PJyd+OCt+VTjIISv070fHzKIMFqZqJJ/dJ0SRH2aHwfB3n86iVsmtBtuxi4KKA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/offchain-messages@6.10.0': + resolution: {integrity: sha512-RiEgAueeMkFMC1suOXBIcmCZgtXRxy24yk0DldPB37bB4zwOF1SAaRjNRPjIkGK8RhCYrEpPosnzLyavw9ueRg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/options@6.10.0': + resolution: {integrity: sha512-RO9UT3UYD8/Cu2uM6ZXbKvLeMnVD42+g9JRds7Pfs4AhiOyg4R4TJrQUAppTgavPTO3PBRlWtWOC05ZH/yAIbg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/plugin-core@6.10.0': + resolution: {integrity: sha512-JE70YTQOfFACVFGvoJon4Scc/eHUWjMu8Ovo35CcV2kHTAHYMCd4UkBd2gmlhK0vRMMomsQi1ZLPlAlTq0OoUQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/plugin-interfaces@6.10.0': + resolution: {integrity: sha512-vr0/l9wcM4orwGr8cjkFWaJ9A4HvzuAv00jMFNMg0Spd0GZqnwnpW+D/fXa1lIJnTRaF3EeEjLh4VjKU037T0Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/program-client-core@6.10.0': + resolution: {integrity: sha512-4PPbTLdC1ylHIuvhOFDP8RnSkXPCFjNFWGslzc+UFKnoR4ajzBcByX94jmaruDMk5ncxgj7tr9pzJTvfGHIaMA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/programs@6.10.0': + resolution: {integrity: sha512-qn/HeLP5KGUJXVub3fyGe69/rWaLX4jzwm6V/1pNxJDbdF+MBdgn18hP6F+VmhfdNmwK0lue3J/1HQ1UTMuQeQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/promises@6.10.0': + resolution: {integrity: sha512-oJSIn+VBBMWDo8oqw7RV3tI6Jih+Ieup6FcQLYLDUriaeo7+8l1Zdezl8zh7SIfeU4lOfAbRg6mR0huaS/Lltg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-api@6.10.0': + resolution: {integrity: sha512-RjPIVsAb/85P1ptoO3WpC0x7QG6gG/e4q/3lo6gbSznUZOcoM+8sSBnCX7BwP1ZkCDS6NK/ClXLnhhhYZx+OGg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-parsed-types@6.10.0': + resolution: {integrity: sha512-5275mvSV1mxhwvrMVa+K7BU/nAetpHfcb+8Ql9rtA8RRf6DyiimFQFZUukE4Ez6XJihEpCHNy98yhkgai9wytQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-spec-types@6.10.0': + resolution: {integrity: sha512-NDZrKyZrJk4HaMFhTE/lAiMB824cWAodKqDHyKi0UteHU9pyRmil3BN1jt7e+j08mwMWwfklSgyrTaq52g6DIQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-spec@6.10.0': + resolution: {integrity: sha512-yQdbWw5mZEWrwsunHR9NHkuhMXIB9sPOObwm18D53v5tAJnxTB0IcHvO647XqFDLTK/yQ4AdDtlYD1vsY07AMQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-api@6.10.0': + resolution: {integrity: sha512-CRPQoTtT1cOwOQUsqS7jgo7wYdAj7jB5ab/UmMPWVpecf2FNMhWhgvxP2s82M7VkDGTGl13qaQ0WySmi7Egrlg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-channel-websocket@6.10.0': + resolution: {integrity: sha512-KkqP1186HELPlJftA88SNAT2znR8knCVzsUipXVzY4zfW8sN3LOa0ePMzh9VZ/V+J+raTt55laR87ovAO0n+zw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-spec@6.10.0': + resolution: {integrity: sha512-nWMwGaG4ulzeX2sskY5TywXF3cwEd8FDmUpLe2JBWxE8XDAOGOKcsYPYFcBgb8ee9KqfPT2PTNdcz9jOhJf34w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions@6.10.0': + resolution: {integrity: sha512-6mfuHp/K7unFKCOTCCBC9ziEGnxe2tyJ74EbR51QUnBeCUdYD7Hhdpxic1WRSJ3UeNW/mG4OzFM6z8Wi64Eh9Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-transformers@6.10.0': + resolution: {integrity: sha512-2nFUrVTiE720pJOY4XKx3HuYmishw0of/4oScu76YGm6O8wsmvFvPNAkrEinmieWXQkfpBfRvLZmpl8PaAy+ug==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-transport-http@6.10.0': + resolution: {integrity: sha512-JrdNuYi0nBbD3X8JUtgX1dQJwIwz/WJvmigDdELysXfGB2bTJpfjqGDLhCLOz2sRl66FASIEqgG/LVa2C9VXcA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-types@6.10.0': + resolution: {integrity: sha512-zaSecTfCPvz/vcoAmKD6XoRstGHTr1EKJBD8T9UcpEFFB6CtF6DxerDB+wrzkamuT6msmnR2DWXMrYOGDAsgIg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc@6.10.0': + resolution: {integrity: sha512-EwxsqoD+NXV+m+iobnWNtATD93gTgaNsOiQOzYB1/2e+8S6fl6obdNPB55yfXgtl4jt6GV6/ae4xuPhLv76vvg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/signers@6.10.0': + resolution: {integrity: sha512-+vtCc+mT1FpGxrA5oL2aaMxSHiMJ2hH5PcDIfjo2XJkHz2klZiCZyT5F9+zpltc9vdi1QTElQq59Sfplmtd33A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/subscribable@6.10.0': + resolution: {integrity: sha512-VsR6XMwkiDBkZJUcoGkEOhf397pOV75gKCL9Bx8bpi2T3Bbs0CxUpMn4yaUgAnRba3eXmjbXMNCXjttfa6sKbw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/sysvars@6.10.0': + resolution: {integrity: sha512-cG13p1+onxz+20iWjwWQr1Z1jQwPm0fnjoW75fqZq7p4rVCie3L2sXvaJsYPjWKrUvpOzOIEHnqZGkG05rCpjg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transaction-confirmation@6.10.0': + resolution: {integrity: sha512-ULvtg65qfenh4T/GYcIlKSUv5EqDcng9UN0dxbHU4kuZdR2e0B8HN2xDC4WhcFQVeFJSbTZmaYFkeTY/Y4gfGQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transaction-messages@6.10.0': + resolution: {integrity: sha512-s7v8G3BTxGlKYIj3eWCG0g1296v+1LBt16mVnlRH5FuyaJ5AdhlhtRho5HUDpdwE8EXun+y1c48V6uhcZ8wdbQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transactions@6.10.0': + resolution: {integrity: sha512-VADSqP9OTYmhrox4pcgDd4+RjVmednXSE0+8Y7SPK4PN1pK5Az2RJ0nSsy0xcTnaOr8mF/crwFktqPrRQwSbQA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@types/chai@4.3.20': + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/mocha@9.1.1': + resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} + + '@types/node@20.19.43': + resolution: {integrity: sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==} + + '@ungap/promise-all-settled@1.1.2': + resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + borsh@2.0.0: + resolution: {integrity: sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg==} + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bufferutil@4.1.0: + resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} + engines: {node: '>=6.14.2'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@15.0.0: + resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==} + engines: {node: '>=22.12.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + debug@4.3.3: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + diff@3.5.1: + resolution: {integrity: sha512-Z3u54A8qGyqFOSr2pk0ijYs8mOE9Qz8kTvtKeBI+upoG9j04Sq+oI7W8zAJiQybDcESET8/uIdHzs0p3k4fZlw==} + engines: {node: '>=0.3.1'} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + litesvm-darwin-arm64@1.3.0: + resolution: {integrity: sha512-fj6cV/ofjMXdl5CwjyyLTQnZObfVH5HYDScQ6O44iRqxASmgEyEh4sC8a7M0YZ1rcli9nu2cWl5ARGura89I7Q==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + litesvm-darwin-x64@1.3.0: + resolution: {integrity: sha512-ZYEddnc+tAn8sVYpzvww0oHFiekbCSv+0OZiA6eUDtcSx9uzeRDmPPQ9eI6vgyews2LefBDSENmUb70GHY6Cqg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + litesvm-linux-arm64-gnu@1.3.0: + resolution: {integrity: sha512-kmmKeef96pJI4AJGCvjzMCW6QHuzFrMF1i6dE6OcrtWHaz0Ag+TFaKOU35H1bjH/fDBwoJUV9UbaIbdWht81tA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + litesvm-linux-arm64-musl@1.3.0: + resolution: {integrity: sha512-FO9p6rx+/3h7R3CU7lkOebL+jy8UEDngSrENHu7pj9EOr78QVyE3Fm0O+WMnwXpMoCSgW0XLhu1cI9NHAbzCTA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + litesvm-linux-x64-gnu@1.3.0: + resolution: {integrity: sha512-yXC8ZAdIei9JQ2xw5/BocOTu/7EqZuFPyhgENQ1mYDhjNpoyUbIuGCWnqtria14mDda0aV9yVev8plGUrUpjUw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + litesvm-linux-x64-musl@1.3.0: + resolution: {integrity: sha512-oedromp1gTjShXmKmxZ1FYtnfM824vRcrPSPvGM0CrqJqKK61m1+tFwNRAVsDlpmWKvO/zsz90ctbgAUo/3TXg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + litesvm@1.3.0: + resolution: {integrity: sha512-tMu9sBIqSbF1gQluXEUtGmXPfZlMc10tOoBVeDokgK77nl/CcuC506sEoFKM5Rq58Dkb070lBMVBLc43TbMUzQ==} + engines: {node: '>= 20'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@4.2.1: + resolution: {integrity: sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==} + engines: {node: '>=10'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mocha@9.2.2: + resolution: {integrity: sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==} + engines: {node: '>= 12.0.0'} + hasBin: true + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.1: + resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-mocha@10.1.0: + resolution: {integrity: sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA==} + engines: {node: '>= 6.X.X'} + hasBin: true + peerDependencies: + mocha: ^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X + + ts-node@7.0.1: + resolution: {integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==} + engines: {node: '>=4.2.0'} + hasBin: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@8.8.0: + resolution: {integrity: sha512-nNSnIK0VcEoNWrYwxCz9DFT1W7ASyBRWX7Hju/p9RAfVDcHoH07hkMg/na9U/2S04fhkPc4pDUK5NblZoaCvwg==} + + utf-8-validate@6.0.6: + resolution: {integrity: sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==} + engines: {node: '>=6.14.2'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + workerpool@6.2.0: + resolution: {integrity: sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yn@2.0.0: + resolution: {integrity: sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==} + engines: {node: '>=4'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@solana-program/system@0.12.2(@solana/kit@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6))': + dependencies: + '@solana/kit': 6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + + '@solana-program/token@0.14.0(@solana/kit@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6))': + dependencies: + '@solana-program/system': 0.12.2(@solana/kit@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)) + '@solana/kit': 6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + + '@solana/accounts@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/addresses@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/assertions': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/nominal-types': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/assertions@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-core@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-data-structures@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-numbers@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-strings@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/fixed-points': 6.10.0(typescript@5.9.3) + '@solana/options': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@6.10.0(typescript@5.9.3)': + dependencies: + chalk: 5.6.2 + commander: 15.0.0 + optionalDependencies: + typescript: 5.9.3 + + '@solana/fast-stable-stringify@6.10.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/fixed-points@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/functional@6.10.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/instruction-plans@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/instructions': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/promises': 6.10.0(typescript@5.9.3) + '@solana/transaction-messages': 6.10.0(typescript@5.9.3) + '@solana/transactions': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/instructions@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/keys@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/assertions': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/nominal-types': 6.10.0(typescript@5.9.3) + '@solana/promises': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': + dependencies: + '@solana/accounts': 6.10.0(typescript@5.9.3) + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/functional': 6.10.0(typescript@5.9.3) + '@solana/instruction-plans': 6.10.0(typescript@5.9.3) + '@solana/instructions': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/offchain-messages': 6.10.0(typescript@5.9.3) + '@solana/plugin-core': 6.10.0(typescript@5.9.3) + '@solana/plugin-interfaces': 6.10.0(typescript@5.9.3) + '@solana/program-client-core': 6.10.0(typescript@5.9.3) + '@solana/programs': 6.10.0(typescript@5.9.3) + '@solana/rpc': 6.10.0(typescript@5.9.3) + '@solana/rpc-api': 6.10.0(typescript@5.9.3) + '@solana/rpc-parsed-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-subscriptions': 6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + '@solana/signers': 6.10.0(typescript@5.9.3) + '@solana/subscribable': 6.10.0(typescript@5.9.3) + '@solana/sysvars': 6.10.0(typescript@5.9.3) + '@solana/transaction-confirmation': 6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@solana/transaction-messages': 6.10.0(typescript@5.9.3) + '@solana/transactions': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/nominal-types@6.10.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/offchain-messages@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/nominal-types': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/options@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/plugin-core@6.10.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/plugin-interfaces@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/instruction-plans': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec': 6.10.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + '@solana/signers': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/program-client-core@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/accounts': 6.10.0(typescript@5.9.3) + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/instruction-plans': 6.10.0(typescript@5.9.3) + '@solana/instructions': 6.10.0(typescript@5.9.3) + '@solana/plugin-interfaces': 6.10.0(typescript@5.9.3) + '@solana/rpc-api': 6.10.0(typescript@5.9.3) + '@solana/signers': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/programs@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/promises@6.10.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-api@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/rpc-parsed-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec': 6.10.0(typescript@5.9.3) + '@solana/rpc-transformers': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + '@solana/transaction-messages': 6.10.0(typescript@5.9.3) + '@solana/transactions': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-parsed-types@6.10.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-spec-types@6.10.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-spec@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.10.0(typescript@5.9.3) + '@solana/subscribable': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-subscriptions-api@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 6.10.0(typescript@5.9.3) + '@solana/rpc-transformers': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + '@solana/transaction-messages': 6.10.0(typescript@5.9.3) + '@solana/transactions': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-subscriptions-channel-websocket@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/functional': 6.10.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 6.10.0(typescript@5.9.3) + '@solana/subscribable': 6.10.0(typescript@5.9.3) + ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@solana/rpc-subscriptions-spec@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/promises': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.10.0(typescript@5.9.3) + '@solana/subscribable': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-subscriptions@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 6.10.0(typescript@5.9.3) + '@solana/functional': 6.10.0(typescript@5.9.3) + '@solana/promises': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 6.10.0(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@solana/rpc-subscriptions-spec': 6.10.0(typescript@5.9.3) + '@solana/rpc-transformers': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + '@solana/subscribable': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/rpc-transformers@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/functional': 6.10.0(typescript@5.9.3) + '@solana/nominal-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-transport-http@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.10.0(typescript@5.9.3) + undici-types: 8.8.0 + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-types@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/fixed-points': 6.10.0(typescript@5.9.3) + '@solana/nominal-types': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 6.10.0(typescript@5.9.3) + '@solana/functional': 6.10.0(typescript@5.9.3) + '@solana/rpc-api': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec': 6.10.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-transformers': 6.10.0(typescript@5.9.3) + '@solana/rpc-transport-http': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/signers@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/instructions': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/nominal-types': 6.10.0(typescript@5.9.3) + '@solana/offchain-messages': 6.10.0(typescript@5.9.3) + '@solana/transaction-messages': 6.10.0(typescript@5.9.3) + '@solana/transactions': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/subscribable@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/promises': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/sysvars@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/accounts': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-confirmation@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/promises': 6.10.0(typescript@5.9.3) + '@solana/rpc': 6.10.0(typescript@5.9.3) + '@solana/rpc-subscriptions': 6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + '@solana/transaction-messages': 6.10.0(typescript@5.9.3) + '@solana/transactions': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/transaction-messages@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/functional': 6.10.0(typescript@5.9.3) + '@solana/instructions': 6.10.0(typescript@5.9.3) + '@solana/nominal-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transactions@6.10.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.10.0(typescript@5.9.3) + '@solana/codecs-core': 6.10.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.10.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.10.0(typescript@5.9.3) + '@solana/codecs-strings': 6.10.0(typescript@5.9.3) + '@solana/errors': 6.10.0(typescript@5.9.3) + '@solana/functional': 6.10.0(typescript@5.9.3) + '@solana/instructions': 6.10.0(typescript@5.9.3) + '@solana/keys': 6.10.0(typescript@5.9.3) + '@solana/nominal-types': 6.10.0(typescript@5.9.3) + '@solana/rpc-types': 6.10.0(typescript@5.9.3) + '@solana/transaction-messages': 6.10.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@types/chai@4.3.20': {} + + '@types/json5@0.0.29': + optional: true + + '@types/mocha@9.1.1': {} + + '@types/node@20.19.43': + dependencies: + undici-types: 6.21.0 + + '@ungap/promise-all-settled@1.1.2': {} + + ansi-colors@4.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + argparse@2.0.1: {} + + arrify@1.0.1: {} + + assertion-error@1.1.0: {} + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + borsh@2.0.0: {} + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browser-stdout@1.3.1: {} + + buffer-from@1.1.2: {} + + bufferutil@4.1.0: + dependencies: + node-gyp-build: 4.8.4 + optional: true + + camelcase@6.3.0: {} + + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@15.0.0: {} + + concat-map@0.0.1: {} + + debug@4.3.3(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + decamelize@4.0.0: {} + + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + + diff@3.5.1: {} + + diff@5.0.0: {} + + emoji-regex@8.0.0: {} + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat@5.0.2: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + get-caller-file@2.0.5: {} + + get-func-name@2.0.2: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + growl@1.10.5: {} + + has-flag@4.0.0: {} + + he@1.2.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-plain-obj@2.1.0: {} + + is-unicode-supported@0.1.0: {} + + isexe@2.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + optional: true + + litesvm-darwin-arm64@1.3.0: + optional: true + + litesvm-darwin-x64@1.3.0: + optional: true + + litesvm-linux-arm64-gnu@1.3.0: + optional: true + + litesvm-linux-arm64-musl@1.3.0: + optional: true + + litesvm-linux-x64-gnu@1.3.0: + optional: true + + litesvm-linux-x64-musl@1.3.0: + optional: true + + litesvm@1.3.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6): + dependencies: + '@solana-program/system': 0.12.2(@solana/kit@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)) + '@solana-program/token': 0.14.0(@solana/kit@6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)) + '@solana/kit': 6.10.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + optionalDependencies: + litesvm-darwin-arm64: 1.3.0 + litesvm-darwin-x64: 1.3.0 + litesvm-linux-arm64-gnu: 1.3.0 + litesvm-linux-arm64-musl: 1.3.0 + litesvm-linux-x64-gnu: 1.3.0 + litesvm-linux-x64-musl: 1.3.0 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + make-error@1.3.6: {} + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + + minimatch@4.2.1: + dependencies: + brace-expansion: 1.1.14 + + minimist@1.2.8: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mocha@9.2.2: + dependencies: + '@ungap/promise-all-settled': 1.1.2 + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.3(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + growl: 1.10.5 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 4.2.1 + ms: 2.1.3 + nanoid: 3.3.1 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + which: 2.0.2 + workerpool: 6.2.0 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + + ms@2.1.2: {} + + ms@2.1.3: {} + + nanoid@3.3.1: {} + + node-gyp-build@4.8.4: + optional: true + + normalize-path@3.0.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + pathval@1.1.1: {} + + picomatch@2.3.2: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + require-directory@2.1.1: {} + + safe-buffer@5.2.1: {} + + serialize-javascript@6.0.0: + dependencies: + randombytes: 2.1.0 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: + optional: true + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-mocha@10.1.0(mocha@9.2.2): + dependencies: + mocha: 9.2.2 + ts-node: 7.0.1 + optionalDependencies: + tsconfig-paths: 3.15.0 + + ts-node@7.0.1: + dependencies: + arrify: 1.0.1 + buffer-from: 1.1.2 + diff: 3.5.1 + make-error: 1.3.6 + minimist: 1.2.8 + mkdirp: 0.5.6 + source-map-support: 0.5.21 + yn: 2.0.0 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + optional: true + + type-detect@4.1.0: {} + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + undici-types@8.8.0: {} + + utf-8-validate@6.0.6: + dependencies: + node-gyp-build: 4.8.4 + optional: true + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + workerpool@6.2.0: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 + + y18n@5.0.8: {} + + yargs-parser@20.2.4: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + + yn@2.0.0: {} + + yocto-queue@0.1.0: {} diff --git a/tokens/nft-minter/pinocchio/prepare.mjs b/tokens/nft-minter/pinocchio/prepare.mjs new file mode 100644 index 000000000..3ffe52750 --- /dev/null +++ b/tokens/nft-minter/pinocchio/prepare.mjs @@ -0,0 +1,35 @@ +// Dumps the Metaplex Token Metadata program from mainnet into the bankrun +// fixtures directory so the test can load it into the local test validator. +// Runs automatically via the `postinstall` script. +// +// Uses only the Node.js standard library (no extra dependencies). Errors are +// logged but not fatal — a missing fixture will surface as a clear test failure +// when bankrun can't find `token_metadata.so`. + +import { execSync } from "node:child_process"; +import { mkdirSync, rmSync } from "node:fs"; +import { join } from "node:path"; + +const programs = [ + { + id: "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s", + name: "token_metadata.so", + }, +]; + +const outputDir = "tests/fixtures"; + +try { + mkdirSync(outputDir, { recursive: true }); + // Point the Solana CLI at mainnet, where the canonical program lives. + execSync("solana config set -um", { stdio: "inherit" }); + + for (const { id, name } of programs) { + const outputFile = join(outputDir, name); + rmSync(outputFile, { force: true }); + execSync(`solana program dump ${id} ${outputFile}`, { stdio: "inherit" }); + console.log(`Dumped ${id} -> ${outputFile}`); + } +} catch (error) { + console.error(`Failed to prepare program fixtures: ${error.message}`); +} diff --git a/tokens/nft-minter/pinocchio/program/Cargo.toml b/tokens/nft-minter/pinocchio/program/Cargo.toml new file mode 100644 index 000000000..1b88d3fba --- /dev/null +++ b/tokens/nft-minter/pinocchio/program/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "nft-minter-pinocchio-program" +version = "0.1.0" +edition = "2021" + +[dependencies] +pinocchio.workspace = true +pinocchio-log.workspace = true +pinocchio-system.workspace = true +pinocchio-token.workspace = true +pinocchio-associated-token-account.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/nft-minter/pinocchio/program/src/instructions/create.rs b/tokens/nft-minter/pinocchio/program/src/instructions/create.rs new file mode 100644 index 000000000..33e2d0cf0 --- /dev/null +++ b/tokens/nft-minter/pinocchio/program/src/instructions/create.rs @@ -0,0 +1,133 @@ +use alloc::vec::Vec; + +use pinocchio::{ + cpi::invoke, + error::ProgramError, + instruction::{InstructionAccount, InstructionView}, + sysvars::{rent::Rent, Sysvar}, + AccountView, ProgramResult, +}; +use pinocchio_log::log; +use pinocchio_system::instructions::CreateAccount; +use pinocchio_token::instructions::InitializeMint2; + +use crate::instructions::{CreateTokenArgs, MINT_SIZE, TOKEN_DECIMALS, TOKEN_METADATA_PROGRAM_ID}; + +/// Discriminator of the Metaplex `CreateMetadataAccountV3` instruction (variant +/// 33 of the Token Metadata program's instruction enum). +const CREATE_METADATA_ACCOUNT_V3: u8 = 33; + +/// Creates a new SPL Token mint (with 0 decimals, the NFT standard) and attaches +/// an on-chain Metaplex metadata account to it (name, symbol, URI). +/// +/// Accounts: +/// 0. `[signer, writable]` mint account (a fresh keypair to initialize) +/// 1. `[]` mint authority (also recorded as metadata update authority) +/// 2. `[writable]` metadata account (the Metaplex metadata PDA) +/// 3. `[signer, writable]` payer (funds the new accounts) +/// 4. `[]` system program +/// 5. `[]` token program +/// 6. `[]` token metadata program +/// +/// Instruction data: Borsh `[name: string, symbol: string, uri: string]`. +/// +/// The mint authority is passed as a non-signer; the metadata CPI requires it to +/// sign, which is satisfied by passing the payer's address for it (the payer +/// signs the transaction). This mirrors the `native` example. +pub fn create_token(accounts: &[AccountView], data: &[u8]) -> ProgramResult { + // `token_program` and `token_metadata_program` are unused directly, but must + // be supplied so they are present in the transaction for the CPIs below. + let [mint_account, mint_authority, metadata_account, payer, system_program, _token_program, _token_metadata_program] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + let args = CreateTokenArgs::parse(data)?; + + // Fund the mint account with enough lamports to stay rent-exempt, read from + // the Rent sysvar. + let rent = Rent::get()?; + let lamports = rent.try_minimum_balance(MINT_SIZE)?; + + log!("Creating mint account"); + CreateAccount { + from: payer, + to: mint_account, + lamports, + space: MINT_SIZE as u64, + owner: &pinocchio_token::ID, + } + .invoke()?; + + log!("Initializing mint account"); + InitializeMint2 { + mint: mint_account, + decimals: TOKEN_DECIMALS, + mint_authority: mint_authority.address(), + freeze_authority: Some(mint_authority.address()), + } + .invoke()?; + + log!("Creating metadata account"); + let metadata_data = build_metadata_data(&args); + let metadata_accounts = [ + InstructionAccount::writable(metadata_account.address()), + InstructionAccount::readonly(mint_account.address()), + InstructionAccount::readonly_signer(mint_authority.address()), + InstructionAccount::writable_signer(payer.address()), + // Update authority — recorded only, not required to sign for V3. + InstructionAccount::readonly(mint_authority.address()), + InstructionAccount::readonly(system_program.address()), + ]; + let instruction = InstructionView { + program_id: &TOKEN_METADATA_PROGRAM_ID, + accounts: &metadata_accounts, + data: &metadata_data, + }; + invoke( + &instruction, + &[ + metadata_account, + mint_account, + mint_authority, + payer, + mint_authority, + system_program, + ], + )?; + + log!("NFT mint created successfully"); + Ok(()) +} + +/// Serializes the data for a Metaplex `CreateMetadataAccountV3` instruction. +/// +/// Layout: `[33] DataV2 is_mutable:bool collection_details:Option`, where +/// `DataV2` is `name:string symbol:string uri:string seller_fee:u16 +/// creators:Option collection:Option uses:Option`. Mirrors the values used by +/// the `anchor` and `native` examples (no royalties, no creators, immutable). +fn build_metadata_data(args: &CreateTokenArgs) -> Vec { + let mut data = Vec::new(); + data.push(CREATE_METADATA_ACCOUNT_V3); + + // DataV2 + push_borsh_string(&mut data, args.name); + push_borsh_string(&mut data, args.symbol); + push_borsh_string(&mut data, args.uri); + data.extend_from_slice(&0u16.to_le_bytes()); // seller_fee_basis_points + data.push(0); // creators: None + data.push(0); // collection: None + data.push(0); // uses: None + + data.push(0); // is_mutable: false + data.push(0); // collection_details: None + + data +} + +/// Appends a Borsh `string` (4-byte little-endian length prefix + UTF-8 bytes). +fn push_borsh_string(buffer: &mut Vec, value: &[u8]) { + buffer.extend_from_slice(&(value.len() as u32).to_le_bytes()); + buffer.extend_from_slice(value); +} diff --git a/tokens/nft-minter/pinocchio/program/src/instructions/mint.rs b/tokens/nft-minter/pinocchio/program/src/instructions/mint.rs new file mode 100644 index 000000000..092adef90 --- /dev/null +++ b/tokens/nft-minter/pinocchio/program/src/instructions/mint.rs @@ -0,0 +1,119 @@ +use alloc::vec::Vec; + +use pinocchio::{ + cpi::invoke, + error::ProgramError, + instruction::{InstructionAccount, InstructionView}, + AccountView, ProgramResult, +}; +use pinocchio_associated_token_account::instructions::CreateIdempotent; +use pinocchio_log::log; +use pinocchio_token::instructions::MintTo; + +use crate::instructions::TOKEN_METADATA_PROGRAM_ID; + +/// Discriminator of the Metaplex `CreateMasterEditionV3` instruction (variant 17 +/// of the Token Metadata program's instruction enum). +const CREATE_MASTER_EDITION_V3: u8 = 17; + +/// Mints the single NFT token to the payer's associated token account and then +/// creates its master edition account. Creating the master edition transfers the +/// mint and freeze authorities to the edition PDA, capping the supply at one and +/// making this a true non-fungible token. +/// +/// Accounts: +/// 0. `[writable]` mint account +/// 1. `[writable]` metadata account +/// 2. `[writable]` master edition account (the edition PDA) +/// 3. `[]` mint authority (also the metadata update authority) +/// 4. `[writable]` payer's associated token account (the destination) +/// 5. `[signer, writable]` payer (funds the accounts and owns the NFT) +/// 6. `[]` system program +/// 7. `[]` token program +/// 8. `[]` associated token program +/// 9. `[]` token metadata program +/// +/// Instruction data: none. +/// +/// The mint authority is passed as a non-signer; the `MintTo` and master edition +/// CPIs require it to sign, which is satisfied by passing the payer's address for +/// it (the payer signs the transaction). This mirrors the `native` example. +pub fn mint_to(accounts: &[AccountView]) -> ProgramResult { + // `associated_token_program` and `token_metadata_program` are unused + // directly, but must be supplied so they are present for the CPIs below. + let [mint_account, metadata_account, edition_account, mint_authority, associated_token_account, payer, system_program, token_program, _associated_token_program, _token_metadata_program] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + log!("Creating associated token account if needed"); + CreateIdempotent { + funding_account: payer, + account: associated_token_account, + wallet: payer, + mint: mint_account, + system_program, + token_program, + } + .invoke()?; + + log!("Minting NFT to associated token account"); + MintTo { + mint: mint_account, + account: associated_token_account, + mint_authority, + amount: 1, + } + .invoke()?; + + // Create the master edition. This is what makes the token a real NFT: the + // Token Metadata program takes over the mint and freeze authorities, so no + // further tokens can ever be minted from this mint. + log!("Creating master edition account"); + let edition_data = build_master_edition_data(); + let edition_accounts = [ + InstructionAccount::writable(edition_account.address()), + InstructionAccount::writable(mint_account.address()), + // Update authority and mint authority are the same key here. + InstructionAccount::readonly_signer(mint_authority.address()), + InstructionAccount::readonly_signer(mint_authority.address()), + InstructionAccount::writable_signer(payer.address()), + InstructionAccount::writable(metadata_account.address()), + InstructionAccount::readonly(token_program.address()), + InstructionAccount::readonly(system_program.address()), + ]; + let instruction = InstructionView { + program_id: &TOKEN_METADATA_PROGRAM_ID, + accounts: &edition_accounts, + data: &edition_data, + }; + invoke( + &instruction, + &[ + edition_account, + mint_account, + mint_authority, + mint_authority, + payer, + metadata_account, + token_program, + system_program, + ], + )?; + + log!("NFT minted successfully"); + Ok(()) +} + +/// Serializes the data for a Metaplex `CreateMasterEditionV3` instruction. +/// +/// Layout: `[17] max_supply:Option`. A `max_supply` of `Some(1)` caps the +/// number of printable editions, mirroring the `native` example. +fn build_master_edition_data() -> Vec { + let mut data = Vec::new(); + data.push(CREATE_MASTER_EDITION_V3); + data.push(1); // max_supply: Some + data.extend_from_slice(&1u64.to_le_bytes()); // max_supply value + data +} diff --git a/tokens/nft-minter/pinocchio/program/src/instructions/mod.rs b/tokens/nft-minter/pinocchio/program/src/instructions/mod.rs new file mode 100644 index 000000000..6f86e0a8b --- /dev/null +++ b/tokens/nft-minter/pinocchio/program/src/instructions/mod.rs @@ -0,0 +1,57 @@ +use pinocchio::error::ProgramError; + +mod create; +mod mint; + +pub use create::*; +pub use mint::*; + +/// Size (in bytes) of an SPL Token mint account. +pub const MINT_SIZE: usize = 82; + +/// Decimals for the minted token. NFTs use 0 decimals (the mint has a supply of +/// exactly one indivisible token). +pub const TOKEN_DECIMALS: u8 = 0; + +/// The Metaplex Token Metadata program ID +/// (`metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s`). +pub const TOKEN_METADATA_PROGRAM_ID: pinocchio::Address = + pinocchio::Address::from_str_const("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); + +/// Borsh-encoded arguments for the `Create` instruction. +/// +/// Field order matches the `native` example's `CreateTokenArgs`. +pub struct CreateTokenArgs<'a> { + pub name: &'a [u8], + pub symbol: &'a [u8], + pub uri: &'a [u8], +} + +impl<'a> CreateTokenArgs<'a> { + /// Parses the instruction data: three Borsh strings (title, symbol, uri). + pub fn parse(data: &'a [u8]) -> Result { + let mut offset = 0; + let name = read_borsh_string(data, &mut offset)?; + let symbol = read_borsh_string(data, &mut offset)?; + let uri = read_borsh_string(data, &mut offset)?; + Ok(Self { name, symbol, uri }) + } +} + +/// Reads a Borsh `string` (a 4-byte little-endian length prefix followed by that +/// many UTF-8 bytes) starting at `*offset`, advancing `offset` past it. +fn read_borsh_string<'a>(data: &'a [u8], offset: &mut usize) -> Result<&'a [u8], ProgramError> { + let len_bytes: [u8; 4] = data + .get(*offset..*offset + 4) + .ok_or(ProgramError::InvalidInstructionData)? + .try_into() + .map_err(|_| ProgramError::InvalidInstructionData)?; + let len = u32::from_le_bytes(len_bytes) as usize; + *offset += 4; + + let bytes = data + .get(*offset..*offset + len) + .ok_or(ProgramError::InvalidInstructionData)?; + *offset += len; + Ok(bytes) +} diff --git a/tokens/nft-minter/pinocchio/program/src/lib.rs b/tokens/nft-minter/pinocchio/program/src/lib.rs new file mode 100644 index 000000000..2e923127d --- /dev/null +++ b/tokens/nft-minter/pinocchio/program/src/lib.rs @@ -0,0 +1,14 @@ +#![no_std] + +// The `entrypoint!` macro installs the default (bump) global allocator, so the +// `alloc` crate is available — we use it to build the variable-length Metaplex +// instruction data at runtime. +extern crate alloc; + +pub mod instructions; +pub mod processor; + +use pinocchio::{entrypoint, nostd_panic_handler}; + +entrypoint!(processor::process_instruction); +nostd_panic_handler!(); diff --git a/tokens/nft-minter/pinocchio/program/src/processor.rs b/tokens/nft-minter/pinocchio/program/src/processor.rs new file mode 100644 index 000000000..a5245cd71 --- /dev/null +++ b/tokens/nft-minter/pinocchio/program/src/processor.rs @@ -0,0 +1,32 @@ +use pinocchio::{error::ProgramError, AccountView, Address, ProgramResult}; +use pinocchio_log::log; + +use crate::instructions::{create_token, mint_to}; + +/// Dispatches an instruction based on its leading discriminator byte. +/// +/// The discriminator is the Borsh enum variant index, matching the `native` +/// example's `NftMinterInstruction`: +/// - `0` -> Create (args: `[title: string, symbol: string, uri: string]`) +/// - `1` -> Mint (no args) +pub fn process_instruction( + _program_id: &Address, + accounts: &[AccountView], + instruction_data: &[u8], +) -> ProgramResult { + let (discriminator, args) = instruction_data + .split_first() + .ok_or(ProgramError::InvalidInstructionData)?; + + match *discriminator { + 0 => { + log!("Instruction: Create"); + create_token(accounts, args) + } + 1 => { + log!("Instruction: Mint"); + mint_to(accounts) + } + _ => Err(ProgramError::InvalidInstructionData), + } +} diff --git a/tokens/nft-minter/pinocchio/tests/test.ts b/tokens/nft-minter/pinocchio/tests/test.ts new file mode 100644 index 000000000..8cde1f2eb --- /dev/null +++ b/tokens/nft-minter/pinocchio/tests/test.ts @@ -0,0 +1,187 @@ +import { Buffer } from "node:buffer"; +import * as path from "node:path"; +import { + AccountRole, + address, + appendTransactionMessageInstruction, + createTransactionMessage, + generateKeyPairSigner, + getAddressEncoder, + getProgramDerivedAddress, + lamports, + pipe, + setTransactionMessageFeePayerSigner, + signTransactionMessageWithSigners, +} from "@solana/kit"; +import { SYSTEM_PROGRAM_ADDRESS } from "@solana-program/system"; +import { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, getTokenDecoder, TOKEN_PROGRAM_ADDRESS } from "@solana-program/token"; +import * as borsh from "borsh"; +import { assert } from "chai"; +import { FailedTransactionMetadata, LiteSVM } from "litesvm"; + +// The legacy SPL Token and Associated Token Account programs are bundled with +// LiteSVM's standard runtime, and their ids come from the official +// @solana-program/token client. The Metaplex Token Metadata program is not +// bundled and has no official @solana-program client, so its id stays +// hand-rolled and it is dumped from mainnet into tests/fixtures by prepare.mjs. +const TOKEN_METADATA_PROGRAM_ID = address("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); + +// Instruction discriminators (the Borsh enum variant index). +const CREATE = 0; +const MINT = 1; + +// Borsh schema for the Create instruction data, matching the program's +// `CreateTokenArgs` (and the native example's wire format). +const CreateTokenArgsSchema: borsh.Schema = { + struct: { + instruction: "u8", + nft_title: "string", + nft_symbol: "string", + nft_uri: "string", + }, +}; + +// The compiled program artifacts live in ./fixtures: the pinocchio program is +// built there by `build-and-test`, and token_metadata.so is dumped from mainnet +// by prepare.mjs. The npm scripts always run from the package root. +const FIXTURES = path.join(process.cwd(), "tests", "fixtures"); +const PROGRAM_SO = path.join(FIXTURES, "nft_minter_pinocchio_program.so"); +const TOKEN_METADATA_SO = path.join(FIXTURES, "token_metadata.so"); + +const addressEncoder = getAddressEncoder(); + +async function getMetadataAddress(mint: ReturnType) { + const [metadata] = await getProgramDerivedAddress({ + programAddress: TOKEN_METADATA_PROGRAM_ID, + seeds: ["metadata", addressEncoder.encode(TOKEN_METADATA_PROGRAM_ID), addressEncoder.encode(mint)], + }); + return metadata; +} + +async function getMasterEditionAddress(mint: ReturnType) { + const [edition] = await getProgramDerivedAddress({ + programAddress: TOKEN_METADATA_PROGRAM_ID, + seeds: ["metadata", addressEncoder.encode(TOKEN_METADATA_PROGRAM_ID), addressEncoder.encode(mint), "edition"], + }); + return edition; +} + +async function getAssociatedTokenAddress(mint: ReturnType, owner: ReturnType) { + const [ata] = await getProgramDerivedAddress({ + programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS, + seeds: [addressEncoder.encode(owner), addressEncoder.encode(TOKEN_PROGRAM_ADDRESS), addressEncoder.encode(mint)], + }); + return ata; +} + +describe("NFT Minter (Pinocchio)", () => { + let svm: LiteSVM; + let programId: ReturnType; + let payer: Awaited>; + let mint: Awaited>; + + 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); + svm.addProgramFromFile(TOKEN_METADATA_PROGRAM_ID, TOKEN_METADATA_SO); + + payer = await generateKeyPairSigner(); + svm.airdrop(payer.address, lamports(10_000_000_000n)); + // The mint is created in the first test and reused (as a non-signer) by the + // second, so it is generated once for the whole suite. + mint = await generateKeyPairSigner(); + }); + + async function send[0]>( + ix: TInstruction, + ) { + const transactionMessage = pipe( + createTransactionMessage({ version: 0 }), + (m) => setTransactionMessageFeePayerSigner(payer, m), + (m) => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + (m) => appendTransactionMessageInstruction(ix, m), + ); + const signedTx = await signTransactionMessageWithSigners(transactionMessage); + const result = svm.sendTransaction(signedTx); + if (result instanceof FailedTransactionMetadata) { + throw new Error(`Transaction failed: ${result.err()}`); + } + } + + it("Create an NFT!", async () => { + const metadataAddress = await getMetadataAddress(mint.address); + + const data = Buffer.from( + borsh.serialize(CreateTokenArgsSchema, { + instruction: CREATE, + nft_title: "Homer NFT", + nft_symbol: "HOMR", + nft_uri: + "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json", + }), + ); + + await send({ + programAddress: programId, + accounts: [ + { address: mint.address, role: AccountRole.WRITABLE_SIGNER, signer: mint }, // mint account + { address: payer.address, role: AccountRole.READONLY }, // mint authority + { address: metadataAddress, role: AccountRole.WRITABLE }, // metadata account + { address: payer.address, role: AccountRole.WRITABLE_SIGNER, signer: payer }, // payer + { address: SYSTEM_PROGRAM_ADDRESS, role: AccountRole.READONLY }, // system program + { address: TOKEN_PROGRAM_ADDRESS, role: AccountRole.READONLY }, // token program + { address: TOKEN_METADATA_PROGRAM_ID, role: AccountRole.READONLY }, // token metadata program + ], + data: new Uint8Array(data), + }); + + const mintAccount = svm.getAccount(mint.address); + if (!mintAccount?.exists) throw new Error("Mint account not found"); + assert.equal(mintAccount.programAddress, TOKEN_PROGRAM_ADDRESS); + + const metadataAccount = svm.getAccount(metadataAddress); + if (!metadataAccount?.exists) throw new Error("Metadata account not found"); + assert.equal(metadataAccount.programAddress, TOKEN_METADATA_PROGRAM_ID); + assert.isTrue(Buffer.from(metadataAccount.data).toString("utf-8").includes("Homer NFT")); + }); + + it("Mint the NFT to your wallet!", async () => { + const metadataAddress = await getMetadataAddress(mint.address); + const editionAddress = await getMasterEditionAddress(mint.address); + const ata = await getAssociatedTokenAddress(mint.address, payer.address); + + await send({ + programAddress: programId, + accounts: [ + { address: mint.address, role: AccountRole.WRITABLE }, // mint account + { address: metadataAddress, role: AccountRole.WRITABLE }, // metadata account + { address: editionAddress, role: AccountRole.WRITABLE }, // master edition account + { address: payer.address, role: AccountRole.READONLY }, // mint authority + { address: ata, role: AccountRole.WRITABLE }, // associated token account + { address: payer.address, role: AccountRole.WRITABLE_SIGNER, signer: payer }, // payer + { address: SYSTEM_PROGRAM_ADDRESS, role: AccountRole.READONLY }, // system program + { address: TOKEN_PROGRAM_ADDRESS, role: AccountRole.READONLY }, // token program + { address: ASSOCIATED_TOKEN_PROGRAM_ADDRESS, role: AccountRole.READONLY }, // associated token program + { address: TOKEN_METADATA_PROGRAM_ID, role: AccountRole.READONLY }, // token metadata program + ], + data: new Uint8Array([MINT]), + }); + + // The NFT (a single token) landed in the payer's associated token account. + const ataAccount = svm.getAccount(ata); + if (!ataAccount?.exists) throw new Error("Associated token account not found"); + // Decode the token account with the official codec instead of reading the + // `amount` field from a raw byte offset by hand. + const amount = getTokenDecoder().decode(ataAccount.data).amount; + assert.equal(amount, 1n); + + // The master edition account exists and is owned by the Token Metadata + // program — proof the CreateMasterEditionV3 CPI succeeded. + const editionAccount = svm.getAccount(editionAddress); + if (!editionAccount?.exists) throw new Error("Master edition account not found"); + assert.equal(editionAccount.programAddress, TOKEN_METADATA_PROGRAM_ID); + }); +}); diff --git a/tokens/nft-minter/pinocchio/tsconfig.json b/tokens/nft-minter/pinocchio/tsconfig.json new file mode 100644 index 000000000..237de9f97 --- /dev/null +++ b/tokens/nft-minter/pinocchio/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai", "node"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2022", "dom"], + "module": "preserve", + "moduleResolution": "bundler", + "target": "es2022", + "esModuleInterop": true + } +}