diff --git a/Anchor.toml b/Anchor.toml index 33b37858..150a4335 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -1,3 +1,15 @@ +[scripts] +test = "npx mocha --import=tsx tests/main.test.ts" +propose = "yarn run ts-node scripts/initializeProposal.ts" +initialize-dao = "yarn run ts-node scripts/initializeDao.ts" +finalize = "yarn run ts-node scripts/finalizeProposal.ts" +metadata = "yarn run ts-node scripts/uploadMetadata.ts" +send-tokens = "yarn run ts-node scripts/sendTokens.ts" +crank = "yarn run ts-node scripts/crankTwap.ts" +attach-metadata = "yarn run ts-node scripts/attachMetadata.ts" +reclaim-tokens = "yarn run ts-node scripts/reclaimTokens.ts" +merge-tokens = "yarn run ts-node scripts/mergeTokens.ts" + [toolchain] [features] @@ -18,17 +30,6 @@ url = "https://api.apr.dev" cluster = "Localnet" wallet = "~/.config/solana/id.json" -[scripts] -propose = "yarn run ts-node scripts/initializeProposal.ts" -initialize-dao = "yarn run ts-node scripts/initializeDao.ts" -finalize = "yarn run ts-node scripts/finalizeProposal.ts" -metadata = "yarn run ts-node scripts/uploadMetadata.ts" -send-tokens = "yarn run ts-node scripts/sendTokens.ts" -crank = "yarn run ts-node scripts/crankTwap.ts" -attach-metadata = "yarn run ts-node scripts/attachMetadata.ts" -reclaim-tokens = "yarn run ts-node scripts/reclaimTokens.ts" -merge-tokens = "yarn run ts-node scripts/mergeTokens.ts" -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/*.ts" [test] startup_wait = 5000 diff --git a/Cargo.lock b/Cargo.lock index a6c8f2ae..1d6e03fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -687,7 +687,7 @@ dependencies = [ [[package]] name = "conditional_vault" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anchor-lang", "anchor-spl", diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..6aa2c8b6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5615 @@ +{ + "name": "futarchy", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@coral-xyz/anchor": "0.28.0", + "@metadaoproject/futarchy": "0.3.0-alpha.12", + "@metaplex-foundation/mpl-token-metadata": "^3.2.0", + "@metaplex-foundation/umi": "^0.9.1", + "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", + "@metaplex-foundation/umi-uploader-bundlr": "^0.9.1", + "@solana/spl-token": "^0.3.7", + "@solana/web3.js": "^1.90.0", + "anchor-bankrun": "^0.3.0", + "solana-bankrun": "^0.2.0", + "spl-token-bankrun": "0.2.6" + }, + "devDependencies": { + "@solana/spl-memo": "^0.2.3", + "@solana/spl-token-registry": "^0.2.4574", + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.0", + "@types/mocha": "^9.0.0", + "@types/node": "^20.8.6", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "prettier": "^2.6.2", + "ts-mocha": "^10.0.0", + "tsx": "^4.7.1", + "typescript": "^4.3.5" + } + }, + "node_modules/@babel/runtime": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bundlr-network/client": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@bundlr-network/client/-/client-0.8.9.tgz", + "integrity": "sha512-SJ7BAt/KhONeFQ0+nbqrw2DUWrsev6y6cmlXt+3x7fPCkw7OJwudtxV/h2nBteZd65NXjqw8yzkmLiLfZ7CCRA==", + "license": "Apache-2.0", + "dependencies": { + "@solana/wallet-adapter-base": "^0.9.2", + "@solana/web3.js": "^1.36.0", + "@supercharge/promise-pool": "^2.1.0", + "algosdk": "^1.13.1", + "arbundles": "^0.6.21", + "arweave": "^1.11.4", + "async-retry": "^1.3.3", + "axios": "^0.25.0", + "base64url": "^3.0.1", + "bignumber.js": "^9.0.1", + "bs58": "^4.0.1", + "commander": "^8.2.0", + "csv": "^6.0.5", + "ethers": "^5.5.1", + "inquirer": "^8.2.0", + "js-sha256": "^0.9.0", + "mime-types": "^2.1.34", + "near-api-js": "^0.44.2", + "near-seed-phrase": "^0.2.0" + }, + "bin": { + "bundlr": "build/node/cli.js" + } + }, + "node_modules/@coral-xyz/anchor": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.28.0.tgz", + "integrity": "sha512-kQ02Hv2ZqxtWP30WN1d4xxT4QqlOXYDxmEd3k/bbneqhV3X5QMO4LAtoUFs7otxyivOgoqam5Il5qx81FuI4vw==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@coral-xyz/borsh": "^0.28.0", + "@solana/web3.js": "^1.68.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^6.3.0", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@coral-xyz/borsh": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.28.0.tgz", + "integrity": "sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.68.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@metadaoproject/futarchy": { + "resolved": "sdk", + "link": true + }, + "node_modules/@metaplex-foundation/mpl-token-metadata": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-3.2.1.tgz", + "integrity": "sha512-26W1NhQwDWmLOg/pBRYut7x/vEs/5kFS2sWVEY5/X0f2jJOLhnd4NaZQcq+5u+XZsXvm1jq2AtrRGPNK43oqWQ==", + "license": "Apache-2.0", + "dependencies": { + "@metaplex-foundation/mpl-toolbox": "^0.9.4" + }, + "peerDependencies": { + "@metaplex-foundation/umi": ">= 0.8.2 < 1" + } + }, + "node_modules/@metaplex-foundation/mpl-toolbox": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/mpl-toolbox/-/mpl-toolbox-0.9.4.tgz", + "integrity": "sha512-fd6JxfoLbj/MM8FG2x91KYVy1U6AjBQw4qjt7+Da3trzQaWnSaYHDcYRG/53xqfvZ9qofY1T2t53GXPlD87lnQ==", + "license": "Apache-2.0", + "peerDependencies": { + "@metaplex-foundation/umi": ">= 0.8.2 < 1" + } + }, + "node_modules/@metaplex-foundation/umi": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi/-/umi-0.9.1.tgz", + "integrity": "sha512-IhHoOvp4vfO/++YL+78+iVuLM53+FDwUOZDYgH6lx0jYXyQ27BeaieeR5i+q3A9dz4KxQo5Nzc5aCA1109QGCQ==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-options": "^0.8.9", + "@metaplex-foundation/umi-public-keys": "^0.8.9", + "@metaplex-foundation/umi-serializers": "^0.9.0" + } + }, + "node_modules/@metaplex-foundation/umi-bundle-defaults": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-bundle-defaults/-/umi-bundle-defaults-0.9.1.tgz", + "integrity": "sha512-QBaCLrb2D5uhY6pbWdxGPdD3LNKOAZ/Wfp7gEzhAipWmEV75KO7ya3AzaU4JZPHaf9juwdU4wO50WEPRb7YyQg==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-downloader-http": "^0.9.1", + "@metaplex-foundation/umi-eddsa-web3js": "^0.9.1", + "@metaplex-foundation/umi-http-fetch": "^0.9.1", + "@metaplex-foundation/umi-program-repository": "^0.9.1", + "@metaplex-foundation/umi-rpc-chunk-get-accounts": "^0.9.1", + "@metaplex-foundation/umi-rpc-web3js": "^0.9.1", + "@metaplex-foundation/umi-serializer-data-view": "^0.9.1", + "@metaplex-foundation/umi-transaction-factory-web3js": "^0.9.1" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@metaplex-foundation/umi-downloader-http": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-downloader-http/-/umi-downloader-http-0.9.1.tgz", + "integrity": "sha512-T/t9YtkDxovIz5hG0SEBolzet0nTd77hZJSSGCNfrhhgJJtNeIHz+/0K+o7U+ubLddFmtPNxF4KBfmh1jCYCQQ==", + "license": "MIT", + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1" + } + }, + "node_modules/@metaplex-foundation/umi-eddsa-web3js": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-eddsa-web3js/-/umi-eddsa-web3js-0.9.1.tgz", + "integrity": "sha512-D+ZP8jOEzfr1ncF18zRdxfE820xjTf6AIBZd926TRj8dlOFIDfu1J0FGS7pC+52CAC9BRNrRvYQyc1TPORkfTQ==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", + "@noble/curves": "^1.0.0" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@metaplex-foundation/umi-http-fetch": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-http-fetch/-/umi-http-fetch-0.9.1.tgz", + "integrity": "sha512-Flh5wSbiYmeDg4V6IE9BNX1BH3eewcIzHxZ1RT1sagU0PlDwy37dm0gcU+svYM/usDvnbk4hwOMGcZkhQLN1QQ==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.7" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1" + } + }, + "node_modules/@metaplex-foundation/umi-options": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-options/-/umi-options-0.8.9.tgz", + "integrity": "sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==", + "license": "MIT" + }, + "node_modules/@metaplex-foundation/umi-program-repository": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-program-repository/-/umi-program-repository-0.9.1.tgz", + "integrity": "sha512-6SawFMO4IZdk4y+D/+o8CyYnfmy8kcOqhQsX3fUMqIXSzz0vzMT2/dDTMfLsuTVyULnaW/VYm26cmYBjVqZTlw==", + "license": "MIT", + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1" + } + }, + "node_modules/@metaplex-foundation/umi-public-keys": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-public-keys/-/umi-public-keys-0.8.9.tgz", + "integrity": "sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-serializers-encodings": "^0.8.9" + } + }, + "node_modules/@metaplex-foundation/umi-rpc-chunk-get-accounts": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-chunk-get-accounts/-/umi-rpc-chunk-get-accounts-0.9.1.tgz", + "integrity": "sha512-WxF4DxSBJXzrGfmJ+X4DjF4rk9as/0EnkpGo0DdtHTZNqIfRY9mqi8OPRe/JhSjYzWFCC0ngjanqShhcEetB4A==", + "license": "MIT", + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1" + } + }, + "node_modules/@metaplex-foundation/umi-rpc-web3js": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-web3js/-/umi-rpc-web3js-0.9.1.tgz", + "integrity": "sha512-kOJEc9IWMX+H7dI5zZZimww1w0A6yd2V/fsQHKB/kHddja7JoPK4Au68n45Pi0vb3HY7riCQN9XMqOOPD5tcxA==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-web3js-adapters": "^0.9.1" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@metaplex-foundation/umi-serializer-data-view": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializer-data-view/-/umi-serializer-data-view-0.9.1.tgz", + "integrity": "sha512-teilMc3abBrdLtgQ0PqnNXvmdsjNFPk4sVbM/flxoh9edyRQCAJmyK7DEA7cXCYfhBVX0jwSJIEcqTDa+r+jdw==", + "license": "MIT", + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1" + } + }, + "node_modules/@metaplex-foundation/umi-serializers": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializers/-/umi-serializers-0.9.0.tgz", + "integrity": "sha512-hAOW9Djl4w4ioKeR4erDZl5IG4iJdP0xA19ZomdaCbMhYAAmG/FEs5khh0uT2mq53/MnzWcXSUPoO8WBN4Q+Vg==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-options": "^0.8.9", + "@metaplex-foundation/umi-public-keys": "^0.8.9", + "@metaplex-foundation/umi-serializers-core": "^0.8.9", + "@metaplex-foundation/umi-serializers-encodings": "^0.8.9", + "@metaplex-foundation/umi-serializers-numbers": "^0.8.9" + } + }, + "node_modules/@metaplex-foundation/umi-serializers-core": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-core/-/umi-serializers-core-0.8.9.tgz", + "integrity": "sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==", + "license": "MIT" + }, + "node_modules/@metaplex-foundation/umi-serializers-encodings": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-encodings/-/umi-serializers-encodings-0.8.9.tgz", + "integrity": "sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-serializers-core": "^0.8.9" + } + }, + "node_modules/@metaplex-foundation/umi-serializers-numbers": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-numbers/-/umi-serializers-numbers-0.8.9.tgz", + "integrity": "sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-serializers-core": "^0.8.9" + } + }, + "node_modules/@metaplex-foundation/umi-transaction-factory-web3js": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-transaction-factory-web3js/-/umi-transaction-factory-web3js-0.9.1.tgz", + "integrity": "sha512-DBBvaMpR6pR3ZpyaRD/0QSTjS+3lxHIUZYAqZi0JYsTyYqNTNsdKVbeu6uLjbeyoJbmqgKVZ0nZgcokEKx49eg==", + "license": "MIT", + "dependencies": { + "@metaplex-foundation/umi-web3js-adapters": "^0.9.1" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@metaplex-foundation/umi-uploader-bundlr": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-uploader-bundlr/-/umi-uploader-bundlr-0.9.1.tgz", + "integrity": "sha512-R2apPj0lWSem1zI0Tqk1MAi+nPK3JVcnppwzvczoUs2n+vuQdk6cQSLE+sbHiba7Gq1bx/Y7DwLLayhLwY8GcA==", + "license": "MIT", + "dependencies": { + "@bundlr-network/client": "^0.8.8", + "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", + "bignumber.js": "^9.0.2", + "buffer": "^6.0.3" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@metaplex-foundation/umi-web3js-adapters": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-web3js-adapters/-/umi-web3js-adapters-0.9.1.tgz", + "integrity": "sha512-O6lQGJFebRM8P67ajvUpuctJ/J39Lylp4wyg8E1tHmFxUsdBC7M9qBixi/WmCiNKgSfVrq6MmiYaba3OSrtqwg==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.1", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.5.0.tgz", + "integrity": "sha512-J5EKamIHnKPyClwVrzmaf5wSdQXgdHcPZIZLu3bwnbeCx8/7NPK5q2ZBWF+5FvYGByjiQQsJYX6jfgB2wDPn3A==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/ed25519": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", + "integrity": "sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@randlabs/communication-bridge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@randlabs/communication-bridge/-/communication-bridge-1.0.1.tgz", + "integrity": "sha512-CzS0U8IFfXNK7QaJFE4pjbxDGfPjbXBEsEaCn9FN15F+ouSAEUQkva3Gl66hrkBZOGexKFEWMwUHIDKpZ2hfVg==", + "license": "Apache-2.0" + }, + "node_modules/@randlabs/myalgo-connect": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@randlabs/myalgo-connect/-/myalgo-connect-1.4.2.tgz", + "integrity": "sha512-K9hEyUi7G8tqOp7kWIALJLVbGCByhilcy6123WfcorxWwiE1sbQupPyIU5f3YdQK6wMjBsyTWiLW52ZBMp7sXA==", + "license": "Apache-2.0", + "dependencies": { + "@randlabs/communication-bridge": "1.0.1" + } + }, + "node_modules/@solana/buffer-layout": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", + "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", + "license": "MIT", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "license": "Apache-2.0", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/codecs": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-preview.2.tgz", + "integrity": "sha512-4HHzCD5+pOSmSB71X6w9ptweV48Zj1Vqhe732+pcAQ2cMNnN0gMPMdDq7j3YwaZDZ7yrILVV/3+HTnfT77t2yA==", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/codecs-data-structures": "2.0.0-preview.2", + "@solana/codecs-numbers": "2.0.0-preview.2", + "@solana/codecs-strings": "2.0.0-preview.2", + "@solana/options": "2.0.0-preview.2" + } + }, + "node_modules/@solana/codecs-core": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-preview.2.tgz", + "integrity": "sha512-gLhCJXieSCrAU7acUJjbXl+IbGnqovvxQLlimztPoGgfLQ1wFYu+XJswrEVQqknZYK1pgxpxH3rZ+OKFs0ndQg==", + "dependencies": { + "@solana/errors": "2.0.0-preview.2" + } + }, + "node_modules/@solana/codecs-data-structures": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-preview.2.tgz", + "integrity": "sha512-Xf5vIfromOZo94Q8HbR04TbgTwzigqrKII0GjYr21K7rb3nba4hUW2ir8kguY7HWFBcjHGlU5x3MevKBOLp3Zg==", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/codecs-numbers": "2.0.0-preview.2", + "@solana/errors": "2.0.0-preview.2" + } + }, + "node_modules/@solana/codecs-numbers": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-preview.2.tgz", + "integrity": "sha512-aLZnDTf43z4qOnpTcDsUVy1Ci9im1Md8thWipSWbE+WM9ojZAx528oAql+Cv8M8N+6ALKwgVRhPZkto6E59ARw==", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/errors": "2.0.0-preview.2" + } + }, + "node_modules/@solana/codecs-strings": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-preview.2.tgz", + "integrity": "sha512-EgBwY+lIaHHgMJIqVOGHfIfpdmmUDNoNO/GAUGeFPf+q0dF+DtwhJPEMShhzh64X2MeCZcmSO6Kinx0Bvmmz2g==", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/codecs-numbers": "2.0.0-preview.2", + "@solana/errors": "2.0.0-preview.2" + }, + "peerDependencies": { + "fastestsmallesttextencoderdecoder": "^1.0.22" + } + }, + "node_modules/@solana/errors": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-preview.2.tgz", + "integrity": "sha512-H2DZ1l3iYF5Rp5pPbJpmmtCauWeQXRJapkDg8epQ8BJ7cA2Ut/QEtC3CMmw/iMTcuS6uemFNLcWvlOfoQhvQuA==", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.0.0" + }, + "bin": { + "errors": "bin/cli.js" + } + }, + "node_modules/@solana/errors/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@solana/errors/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@solana/options": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-preview.2.tgz", + "integrity": "sha512-FAHqEeH0cVsUOTzjl5OfUBw2cyT8d5Oekx4xcn5hn+NyPAfQJgM3CEThzgRD6Q/4mM5pVUnND3oK/Mt1RzSE/w==", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/codecs-numbers": "2.0.0-preview.2" + } + }, + "node_modules/@solana/spl-memo": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@solana/spl-memo/-/spl-memo-0.2.3.tgz", + "integrity": "sha512-CNsKSsl85ebuVoeGq1LDYi5M/PMs1Pxv2/UsyTgS6b30qrYqZOXha5ouZzgGKtJtZ3C3dxfOAEw6caJPN1N63w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.20.0" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.11.tgz", + "integrity": "sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==", + "license": "Apache-2.0", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "@solana/spl-token-metadata": "^0.1.2", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.88.0" + } + }, + "node_modules/@solana/spl-token-metadata": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.4.tgz", + "integrity": "sha512-N3gZ8DlW6NWDV28+vCCDJoTqaCZiF/jDUnk3o8GRkAFzHObiR60Bs1gXHBa8zCPdvOwiG6Z3dg5pg7+RW6XNsQ==", + "dependencies": { + "@solana/codecs": "2.0.0-preview.2", + "@solana/spl-type-length-value": "0.1.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.91.6" + } + }, + "node_modules/@solana/spl-token-registry": { + "version": "0.2.4574", + "resolved": "https://registry.npmjs.org/@solana/spl-token-registry/-/spl-token-registry-0.2.4574.tgz", + "integrity": "sha512-JzlfZmke8Rxug20VT/VpI2XsXlsqMlcORIUivF+Yucj7tFi7A0dXG7h+2UnD0WaZJw8BrUz2ABNkUnv89vbv1A==", + "dev": true, + "license": "Apache", + "dependencies": { + "cross-fetch": "3.0.6" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@solana/spl-token-registry/node_modules/cross-fetch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz", + "integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "2.6.1" + } + }, + "node_modules/@solana/spl-token-registry/node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@solana/spl-type-length-value": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@solana/spl-type-length-value/-/spl-type-length-value-0.1.0.tgz", + "integrity": "sha512-JBMGB0oR4lPttOZ5XiUGyvylwLQjt1CPJa6qQ5oM+MBCndfjz2TKKkw0eATlLLcYmq1jBVsNlJ2cD6ns2GR7lA==", + "license": "Apache-2.0", + "dependencies": { + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@solana/wallet-adapter-base": { + "version": "0.9.23", + "resolved": "https://registry.npmjs.org/@solana/wallet-adapter-base/-/wallet-adapter-base-0.9.23.tgz", + "integrity": "sha512-apqMuYwFp1jFi55NxDfvXUX2x1T0Zh07MxhZ/nCCTGys5raSfYUh82zen2BLv8BSDj/JxZ2P/s7jrQZGrX8uAw==", + "license": "Apache-2.0", + "dependencies": { + "@solana/wallet-standard-features": "^1.1.0", + "@wallet-standard/base": "^1.0.1", + "@wallet-standard/features": "^1.0.3", + "eventemitter3": "^4.0.7" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.77.3" + } + }, + "node_modules/@solana/wallet-standard-features": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@solana/wallet-standard-features/-/wallet-standard-features-1.2.0.tgz", + "integrity": "sha512-tUd9srDLkRpe1BYg7we+c4UhRQkq+XQWswsr/L1xfGmoRDF47BPSXf4zE7ZU2GRBGvxtGt7lwJVAufQyQYhxTQ==", + "license": "Apache-2.0", + "dependencies": { + "@wallet-standard/base": "^1.0.1", + "@wallet-standard/features": "^1.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.95.3", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.3.tgz", + "integrity": "sha512-O6rPUN0w2fkNqx/Z3QJMB9L225Ex10PRDH8bTaIUPZXMPV0QP8ZpPvjQnXK+upUczlRgzHzd6SjKIha1p+I6og==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@noble/curves": "^1.4.2", + "@noble/hashes": "^1.4.0", + "@solana/buffer-layout": "^4.0.1", + "agentkeepalive": "^4.5.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.2.1", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.3", + "fast-stable-stringify": "^1.0.0", + "jayson": "^4.1.1", + "node-fetch": "^2.7.0", + "rpc-websockets": "^9.0.2", + "superstruct": "^2.0.2" + } + }, + "node_modules/@solana/web3.js/node_modules/superstruct": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz", + "integrity": "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@supercharge/promise-pool": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@supercharge/promise-pool/-/promise-pool-2.4.0.tgz", + "integrity": "sha512-O9CMipBlq5OObdt1uKJGIzm9cdjpPWfj+a+Zw9EgWKxaMNHKC7EU7X9taj3H0EGQNLOSq2jAcOa3EzxlfHsD6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.12.tgz", + "integrity": "sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.17", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.17.tgz", + "integrity": "sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==", + "dev": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.16.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.1.tgz", + "integrity": "sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/@wallet-standard/base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@wallet-standard/base/-/base-1.0.1.tgz", + "integrity": "sha512-1To3ekMfzhYxe0Yhkpri+Fedq0SYcfrOfJi3vbLjMwF2qiKPjTGLwZkf2C9ftdQmxES+hmxhBzTwF4KgcOwf8w==", + "license": "Apache-2.0", + "engines": { + "node": ">=16" + } + }, + "node_modules/@wallet-standard/features": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@wallet-standard/features/-/features-1.0.3.tgz", + "integrity": "sha512-m8475I6W5LTatTZuUz5JJNK42wFRgkJTB0I9tkruMwfqBF2UN2eomkYNVf9RbrsROelCRzSFmugqjKZBFaubsA==", + "license": "Apache-2.0", + "dependencies": { + "@wallet-standard/base": "^1.0.1" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "license": "MIT" + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/algo-msgpack-with-bigint": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", + "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/algosdk": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.24.1.tgz", + "integrity": "sha512-9moZxdqeJ6GdE4N6fA/GlUP4LrbLZMYcYkt141J4Ss68OfEgH9qW0wBuZ3ZOKEx/xjc5bg7mLP2Gjg7nwrkmww==", + "license": "MIT", + "dependencies": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.2", + "cross-fetch": "^3.1.5", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "tweetnacl": "^1.0.3", + "vlq": "^2.0.4" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/anchor-bankrun": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/anchor-bankrun/-/anchor-bankrun-0.3.0.tgz", + "integrity": "sha512-PYBW5fWX+iGicIS5MIM/omhk1tQPUc0ELAnI/IkLKQJ6d75De/CQRh8MF2bU/TgGyFi6zEel80wUe3uRol9RrQ==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "@coral-xyz/anchor": "^0.28.0", + "@solana/web3.js": "^1.78.4", + "solana-bankrun": "^0.2.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arbundles": { + "version": "0.6.23", + "resolved": "https://registry.npmjs.org/arbundles/-/arbundles-0.6.23.tgz", + "integrity": "sha512-+gr93F3fivN+6dhiImT6BQNaXz4oECPn2GYjCZjS2yEoq7hM78FRvVp6kQyjEdhnuBFQr/q4oS/nkjnQlHdj9Q==", + "license": "Apache-2.0", + "dependencies": { + "@noble/ed25519": "^1.6.1", + "@randlabs/myalgo-connect": "^1.1.2", + "@solana/wallet-adapter-base": "^0.9.2", + "algosdk": "^1.13.1", + "arweave": "^1.11.4", + "arweave-stream-tx": "^1.1.0", + "avsc": "https://github.com/Irys-xyz/avsc#csp-fixes", + "axios": "^0.21.3", + "base64url": "^3.0.1", + "bs58": "^4.0.1", + "ethers": "^5.5.1", + "keccak": "^3.0.2", + "multistream": "^4.1.0", + "process": "^0.11.10", + "secp256k1": "^4.0.2", + "tmp-promise": "^3.0.2" + } + }, + "node_modules/arbundles/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/arconnect": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/arconnect/-/arconnect-0.4.2.tgz", + "integrity": "sha512-Jkpd4QL3TVqnd3U683gzXmZUVqBUy17DdJDuL/3D9rkysLgX6ymJ2e+sR+xyZF5Rh42CBqDXWNMmCjBXeP7Gbw==", + "license": "MIT", + "dependencies": { + "arweave": "^1.10.13" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arweave": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/arweave/-/arweave-1.14.4.tgz", + "integrity": "sha512-tmqU9fug8XAmFETYwgUhLaD3WKav5DaM4p1vgJpEj/Px2ORPPMikwnSySlFymmL2qgRh2ZBcZsg11+RXPPGLsA==", + "license": "MIT", + "dependencies": { + "arconnect": "^0.4.2", + "asn1.js": "^5.4.1", + "base64-js": "^1.5.1", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=16.15.0" + } + }, + "node_modules/arweave-stream-tx": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/arweave-stream-tx/-/arweave-stream-tx-1.2.2.tgz", + "integrity": "sha512-bNt9rj0hbAEzoUZEF2s6WJbIz8nasZlZpxIw03Xm8fzb9gRiiZlZGW3lxQLjfc9Z0VRUWDzwtqoYeEoB/JDToQ==", + "dependencies": { + "exponential-backoff": "^3.1.0" + }, + "peerDependencies": { + "arweave": "^1.10.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "license": "MIT" + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/avsc": { + "version": "5.4.7", + "resolved": "git+ssh://git@github.com/Irys-xyz/avsc.git#a730cc8018b79e114b6a3381bbb57760a24c6cef", + "license": "MIT", + "engines": { + "node": ">=0.11" + } + }, + "node_modules/axios": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.7" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "license": "MIT" + }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bip39": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", + "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", + "license": "ISC", + "dependencies": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + } + }, + "node_modules/bip39-light": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/bip39-light/-/bip39-light-1.0.7.tgz", + "integrity": "sha512-WDTmLRQUsiioBdTs9BmSEmkJza+8xfJmptsNJjxnoq3EydSa/ZBXT6rm66KoT3PJIRYMnhSKNR7S9YL1l7R40Q==", + "license": "ISC", + "dependencies": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9" + } + }, + "node_modules/bip39/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==", + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "license": "MIT" + }, + "node_modules/borsh": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "license": "MIT" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", + "license": "MIT", + "engines": { + "node": ">=4.5" + } + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/capability": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/capability/-/capability-0.2.5.tgz", + "integrity": "sha512-rsJZYVCgXd08sPqwmaIqjAd5SUTfonV0z/gDJ8D6cN8wQphky1kkAYEqQ+hmDxTw7UihvBfjUVUSY+DBEe44jg==", + "license": "MIT" + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "license": "MIT" + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/crypto-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", + "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/csv": { + "version": "6.3.8", + "resolved": "https://registry.npmjs.org/csv/-/csv-6.3.8.tgz", + "integrity": "sha512-gRh3yiT9bHBA5ka2yOpyFqAVu/ZpwWzajMUR/es0ljevAE88WyHBuMUy7jzd2o5j6LYQesEO/AyhbQ9BhbDXUA==", + "license": "MIT", + "dependencies": { + "csv-generate": "^4.4.0", + "csv-parse": "^5.5.5", + "csv-stringify": "^6.4.6", + "stream-transform": "^3.3.1" + }, + "engines": { + "node": ">= 0.1.90" + } + }, + "node_modules/csv-generate": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-4.4.0.tgz", + "integrity": "sha512-geM01acNPZ0wr4/9sKev5fCzFG/tsc/NbuFWrhLc47M1zQyUdEJH65+cxTLIVafEwhBjIYwQ7fdOL9roBqVltQ==", + "license": "MIT" + }, + "node_modules/csv-parse": { + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.5.tgz", + "integrity": "sha512-erCk7tyU3yLWAhk6wvKxnyPtftuy/6Ak622gOO7BCJ05+TYffnPCJF905wmOQm+BpkX54OdAl8pveJwUdpnCXQ==", + "license": "MIT" + }, + "node_modules/csv-stringify": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.4.6.tgz", + "integrity": "sha512-h2V2XZ3uOTLilF5dPIptgUfN/o2ia/80Ie0Lly18LAnw5s8Eb7kt8rfxSUy24AztJZas9f6DPZpVlzDUtFt/ag==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/error-polyfill": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/error-polyfill/-/error-polyfill-0.1.3.tgz", + "integrity": "sha512-XHJk60ufE+TG/ydwp4lilOog549iiQF2OAPhkk9DdiYWMrltz5yhDz/xnKuenNwP7gy3dsibssO5QpVhkrSzzg==", + "license": "MIT", + "dependencies": { + "capability": "^0.2.5", + "o3": "^1.0.3", + "u3": "^0.1.1" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/esbuild": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "license": "Apache-2.0" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", + "license": "MIT" + }, + "node_modules/fastestsmallesttextencoderdecoder": { + "version": "1.0.22", + "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", + "peer": true + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hi-base32": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==", + "license": "MIT" + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jayson": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.2.tgz", + "integrity": "sha512-5nzMWDHy6f+koZOuYsArh2AXs73NfWYVlFyJJuCedr93GpY+Ku8qq10ropSXVfHK+H0T6paA88ww+/dV+1fBNA==", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "uuid": "^8.3.2", + "ws": "^7.5.10" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, + "node_modules/jayson/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/jayson/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", + "license": "MIT" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "license": "MIT" + }, + "node_modules/js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "license": "MIT", + "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", + "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" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multistream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", + "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "once": "^1.4.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" + }, + "node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/near-api-js": { + "version": "0.44.2", + "resolved": "https://registry.npmjs.org/near-api-js/-/near-api-js-0.44.2.tgz", + "integrity": "sha512-eMnc4V+geggapEUa3nU2p8HSHn/njtloI4P2mceHQWO8vDE1NGpnAw8FuTBrLmXSgIv9m6oocgFc9t3VNf5zwg==", + "license": "(MIT AND Apache-2.0)", + "dependencies": { + "bn.js": "5.2.0", + "borsh": "^0.6.0", + "bs58": "^4.0.0", + "depd": "^2.0.0", + "error-polyfill": "^0.1.3", + "http-errors": "^1.7.2", + "js-sha256": "^0.9.0", + "mustache": "^4.0.0", + "node-fetch": "^2.6.1", + "text-encoding-utf-8": "^1.0.2", + "tweetnacl": "^1.0.1" + } + }, + "node_modules/near-api-js/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "license": "MIT" + }, + "node_modules/near-api-js/node_modules/borsh": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.6.0.tgz", + "integrity": "sha512-sl5k89ViqsThXQpYa9XDtz1sBl3l1lI313cFUY1HKr+wvMILnb+58xpkqTNrYbelh99dY7K8usxoCusQmqix9Q==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/near-hd-key": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/near-hd-key/-/near-hd-key-1.2.1.tgz", + "integrity": "sha512-SIrthcL5Wc0sps+2e1xGj3zceEa68TgNZDLuCx0daxmfTP7sFTB3/mtE2pYhlFsCxWoMn+JfID5E1NlzvvbRJg==", + "license": "MIT", + "dependencies": { + "bip39": "3.0.2", + "create-hmac": "1.1.7", + "tweetnacl": "1.0.3" + } + }, + "node_modules/near-seed-phrase": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/near-seed-phrase/-/near-seed-phrase-0.2.0.tgz", + "integrity": "sha512-NpmrnejpY1AdlRpDZ0schJQJtfBaoUheRfiYtQpcq9TkwPgqKZCRULV5L3hHmLc0ep7KRtikbPQ9R2ztN/3cyQ==", + "license": "MIT", + "dependencies": { + "bip39-light": "^1.0.7", + "bs58": "^4.0.1", + "near-hd-key": "^1.2.1", + "tweetnacl": "^1.0.2" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/o3": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/o3/-/o3-1.0.3.tgz", + "integrity": "sha512-f+4n+vC6s4ysy7YO7O2gslWZBUu8Qj2i2OUJOvjRxQva7jVjYjB29jrr9NCjmxZQR0gzrOcv1RnqoYOeMs5VRQ==", + "license": "MIT", + "dependencies": { + "capability": "^0.2.5" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rpc-websockets": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.0.2.tgz", + "integrity": "sha512-YzggvfItxMY3Lwuax5rC18inhbjJv9Py7JXRHxTIi94JOLrqBsSsUUc5bbl5W6c11tXhdfpDPK0KzBhoGe8jjw==", + "dependencies": { + "@swc/helpers": "^0.5.11", + "@types/uuid": "^8.3.4", + "@types/ws": "^8.2.2", + "buffer": "^6.0.3", + "eventemitter3": "^5.0.1", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/rpc-websockets/node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/rpc-websockets/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/rpc-websockets/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "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 + } + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/solana-bankrun": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/solana-bankrun/-/solana-bankrun-0.2.0.tgz", + "integrity": "sha512-TS6vYoO/9YJZng7oiLOVyuz8V7yLow5Hp4SLYWW71XM3702v+z9f1fvUBKudRfa4dfpta4tRNufApSiBIALxJQ==", + "license": "MIT", + "dependencies": { + "@solana/web3.js": "^1.68.0", + "bs58": "^4.0.1" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "solana-bankrun-darwin-arm64": "0.2.0", + "solana-bankrun-darwin-universal": "0.2.0", + "solana-bankrun-darwin-x64": "0.2.0", + "solana-bankrun-linux-x64-gnu": "0.2.0", + "solana-bankrun-linux-x64-musl": "0.2.0" + } + }, + "node_modules/solana-bankrun-darwin-arm64": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-darwin-arm64/-/solana-bankrun-darwin-arm64-0.2.0.tgz", + "integrity": "sha512-ENQ5Z/CYeY8ZVWIc2VutY/gMlBaHi93/kDw9w0iVwewoV+/YpQmP2irwrshIKu6ggRPTF3Ehlh2V6fGVIYWcXw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/solana-bankrun-darwin-universal": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-darwin-universal/-/solana-bankrun-darwin-universal-0.2.0.tgz", + "integrity": "sha512-HE45TvZXzBipm1fMn87+fkHeIuQ/KFAi5G/S29y/TLuBYt4RDI935RkWiT0rEQ7KwnwO6Y1aTsOaQXldY5R7uQ==", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/solana-bankrun-darwin-x64": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-darwin-x64/-/solana-bankrun-darwin-x64-0.2.0.tgz", + "integrity": "sha512-42UsVrnac2Oo4UaIDo60zfI3Xn1i8W6fmcc9ixJQZNTtdO8o2/sY4mFxcJx9lhLMhda5FPHrQbGYgYdIs0kK0g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/solana-bankrun-linux-x64-gnu": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-linux-x64-gnu/-/solana-bankrun-linux-x64-gnu-0.2.0.tgz", + "integrity": "sha512-WnqQjfBBdcI0ZLysjvRStI8gX7vm1c3CI6CC03lgkUztH+Chcq9C4LI9m2M8mXza8Xkn9ryeKAmX36Bx/yoVzg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/solana-bankrun-linux-x64-musl": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-linux-x64-musl/-/solana-bankrun-linux-x64-musl-0.2.0.tgz", + "integrity": "sha512-8mtf14ZBoah30+MIJBUwb5BlGLRZyK5cZhCkYnC/ROqaIDN8RxMM44NL63gTUIaNHsFwWGA9xR0KSeljeh3PKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spl-token-bankrun": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/spl-token-bankrun/-/spl-token-bankrun-0.2.6.tgz", + "integrity": "sha512-tD4qpg7s4bagnjlWiDKaY158TcYq9odecM2rwqlKFjKzeVyjYnyoQq54BxwofghWD9Q+gOR/0BbWYK2KW2VbJQ==", + "license": "GPL-3.0-or-later", + "dependencies": { + "@solana/spl-token": "^0.3.8", + "solana-bankrun": "^0.3.0" + } + }, + "node_modules/spl-token-bankrun/node_modules/solana-bankrun": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/solana-bankrun/-/solana-bankrun-0.3.0.tgz", + "integrity": "sha512-YkH7sa8TB/AoRPzG17CXJtYsRIQHEkEqGLz1Vwc13taXhDBkjO7z6NI5JYw7n0ybRymDHwMYTc7sd+5J40TyVQ==", + "license": "MIT", + "dependencies": { + "@solana/web3.js": "^1.68.0", + "bs58": "^4.0.1" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "solana-bankrun-darwin-arm64": "0.3.0", + "solana-bankrun-darwin-universal": "0.3.0", + "solana-bankrun-darwin-x64": "0.3.0", + "solana-bankrun-linux-x64-gnu": "0.3.0", + "solana-bankrun-linux-x64-musl": "0.3.0" + } + }, + "node_modules/spl-token-bankrun/node_modules/solana-bankrun-darwin-arm64": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-darwin-arm64/-/solana-bankrun-darwin-arm64-0.3.0.tgz", + "integrity": "sha512-+NbDncf0U6l3knuacRBiqpjZ2DSp+5lZaAU518gH7/x6qubbui/d000STaIBK+uNTPBS/AL/bCN+7PkXqmA3lA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/spl-token-bankrun/node_modules/solana-bankrun-darwin-universal": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-darwin-universal/-/solana-bankrun-darwin-universal-0.3.0.tgz", + "integrity": "sha512-1/F0xdMa4qvc5o6z16FCCbZ5jbdvKvxpx5kyPcMWRiRPwyvi+zltMxciPAYMlg3wslQqGz88uFhrBEzq2eTumQ==", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/spl-token-bankrun/node_modules/solana-bankrun-darwin-x64": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-darwin-x64/-/solana-bankrun-darwin-x64-0.3.0.tgz", + "integrity": "sha512-U6CANjkmMl+lgNA7UH0GKs5V7LtVIUDzJBZefGGqLfqUNv3EjA/PrrToM0hAOWJgkxSwdz6zW+p5sw5FmnbXtg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/spl-token-bankrun/node_modules/solana-bankrun-linux-x64-gnu": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-linux-x64-gnu/-/solana-bankrun-linux-x64-gnu-0.3.0.tgz", + "integrity": "sha512-qJSkCFs0k2n4XtTnyxGMiZsuqO2TiqTYgWjQ+3mZhGNUAMys/Vq8bd7/SyBm6RR7EfVuRXRxZvh+F8oKZ77V4w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/spl-token-bankrun/node_modules/solana-bankrun-linux-x64-musl": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/solana-bankrun-linux-x64-musl/-/solana-bankrun-linux-x64-musl-0.3.0.tgz", + "integrity": "sha512-xsS2CS2xb1Sw4ivNXM0gPz/qpW9BX0neSvt/pnok5L330Nu9xlTnKAY8FhzzqOP9P9sJlGRM787Y6d0yYwt6xQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-transform": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-3.3.1.tgz", + "integrity": "sha512-BL8pv9QL8Ikd11oZwlRDp1qYMhGR0i50zI9ltoijKGc4ubQWal/Rc4p6SYJp1TBOGpE0uAGchwbxOZ1ycwTuqQ==", + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superstruct": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.15.5.tgz", + "integrity": "sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/tmp-promise/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/ts-mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.0.0.tgz", + "integrity": "sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-node": "7.0.1" + }, + "bin": { + "ts-mocha": "bin/ts-mocha" + }, + "engines": { + "node": ">= 6.X.X" + }, + "optionalDependencies": { + "tsconfig-paths": "^3.5.0" + }, + "peerDependencies": { + "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" + } + }, + "node_modules/ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/tsx": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz", + "integrity": "sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.19.10", + "get-tsconfig": "^4.7.2" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/u3": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/u3/-/u3-0.1.1.tgz", + "integrity": "sha512-+J5D5ir763y+Am/QY6hXNRlwljIeRMZMGs0cT6qqZVVzzT3X3nFPXVyPOFRMOR4kupB0T8JnCdpWdp6Q/iXn3w==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vlq": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", + "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==", + "license": "MIT" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "sdk": { + "name": "@metadaoproject/futarchy", + "version": "0.3.0-alpha.12", + "dependencies": { + "@coral-xyz/anchor": "^0.29.0", + "@noble/hashes": "^1.4.0", + "@solana/spl-token": "^0.3.7", + "@solana/web3.js": "^1.74.0", + "bn.js": "^5.2.1", + "decimal.js": "^10.4.3", + "esbuild": "^0.17.15" + }, + "devDependencies": { + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.0", + "@types/mocha": "^9.0.0", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "prettier": "^2.6.2", + "solana-bankrun": "^0.2.0", + "spl-token-bankrun": "0.2.3", + "ts-mocha": "^10.0.0", + "typescript": "^4.3.5" + } + }, + "sdk/node_modules/@coral-xyz/anchor": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz", + "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@coral-xyz/borsh": "^0.29.0", + "@noble/hashes": "^1.3.1", + "@solana/web3.js": "^1.68.0", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^6.3.0", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "sdk/node_modules/@coral-xyz/borsh": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", + "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.68.0" + } + }, + "sdk/node_modules/spl-token-bankrun": { + "version": "0.2.3", + "dev": true, + "license": "GPL-3.0-or-later", + "dependencies": { + "@solana/spl-token": "^0.3.8", + "solana-bankrun": "^0.2.0" + } + } + } +} diff --git a/package.json b/package.json index 584dbe98..250696d6 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,31 @@ { + "type": "module", "scripts": { "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" }, "dependencies": { "@coral-xyz/anchor": "0.29.0", + "@metadaoproject/futarchy": "0.4.0-alpha.1", "@metaplex-foundation/mpl-token-metadata": "^3.2.0", "@metaplex-foundation/umi": "^0.9.1", "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", "@metaplex-foundation/umi-uploader-bundlr": "^0.9.1", "@noble/ed25519": "^2.0.0", "@noble/secp256k1": "^2.0.0", - "@openbook-dex/openbook-v2": "0.1.7", "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.90.0", - "@sqds/multisig": "^2.0.0", "anchor-bankrun": "^0.3.0", "arweave": "^1.14.4", "solana-bankrun": "^0.3.0", - "spl-token-bankrun": "0.2.5", - "@metadaoproject/futarchy": "0.3.0-alpha.8" + "spl-token-bankrun": "0.2.6" }, "devDependencies": { - "@mercurial-finance/dynamic-amm-sdk": "^0.4.19", "@solana/spl-memo": "^0.2.3", "@solana/spl-token-registry": "^0.2.4574", "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", + "@types/mocha": "^10.0.7", "@types/node": "^20.8.6", "chai": "^4.3.4", "mocha": "^9.0.3", diff --git a/programs/amm/src/error.rs b/programs/amm/src/error.rs index 193867e4..f584cfda 100644 --- a/programs/amm/src/error.rs +++ b/programs/amm/src/error.rs @@ -2,6 +2,8 @@ use anchor_lang::prelude::*; #[error_code] pub enum AmmError { + #[msg("An assertion failed")] + AssertFailed, #[msg("Can't get a TWAP before some observations have been stored")] NoSlotsPassed, #[msg("Can't swap through a pool without token reserves on either side")] diff --git a/programs/amm/src/instructions/add_liquidity.rs b/programs/amm/src/instructions/add_liquidity.rs index c0bc8c39..00b1e461 100644 --- a/programs/amm/src/instructions/add_liquidity.rs +++ b/programs/amm/src/instructions/add_liquidity.rs @@ -46,7 +46,7 @@ impl AddOrRemoveLiquidity<'_> { AmmError::InsufficientBalance ); - amm.update_twap(Clock::get()?.slot); + amm.update_twap(Clock::get()?.slot)?; // airlifted from uniswap v1: // https://github.com/Uniswap/v1-contracts/blob/c10c08d81d6114f694baa8bd32f555a40f6264da/contracts/uniswap_exchange.vy#L48 diff --git a/programs/amm/src/instructions/crank_that_twap.rs b/programs/amm/src/instructions/crank_that_twap.rs index 8a8b10d1..3e4b4f39 100644 --- a/programs/amm/src/instructions/crank_that_twap.rs +++ b/programs/amm/src/instructions/crank_that_twap.rs @@ -12,7 +12,7 @@ impl CrankThatTwap<'_> { pub fn handle(ctx: Context) -> Result<()> { let CrankThatTwap { amm } = ctx.accounts; - amm.update_twap(Clock::get()?.slot); + amm.update_twap(Clock::get()?.slot)?; Ok(()) } diff --git a/programs/amm/src/instructions/remove_liquidity.rs b/programs/amm/src/instructions/remove_liquidity.rs index b7e04e90..20d3209e 100644 --- a/programs/amm/src/instructions/remove_liquidity.rs +++ b/programs/amm/src/instructions/remove_liquidity.rs @@ -41,13 +41,13 @@ impl AddOrRemoveLiquidity<'_> { require!(lp_tokens_to_burn > 0, AmmError::ZeroLiquidityRemove); - amm.update_twap(Clock::get()?.slot); + amm.update_twap(Clock::get()?.slot)?; // airlifted from uniswap v1: // https://github.com/Uniswap/v1-contracts/blob/c10c08d81d6114f694baa8bd32f555a40f6264da/contracts/uniswap_exchange.vy#L83 let total_liquidity = lp_mint.supply; - assert!(total_liquidity > 0); + require_gt!(total_liquidity, 0, AmmError::AssertFailed); let (base_to_withdraw, quote_to_withdraw) = amm.get_base_and_quote_withdrawable(lp_tokens_to_burn, total_liquidity); diff --git a/programs/amm/src/instructions/swap.rs b/programs/amm/src/instructions/swap.rs index b978ee41..a3bdec4f 100644 --- a/programs/amm/src/instructions/swap.rs +++ b/programs/amm/src/instructions/swap.rs @@ -78,7 +78,7 @@ impl Swap<'_> { require!(input_amount > 0, AmmError::ZeroSwapAmount); - amm.update_twap(Clock::get()?.slot); + amm.update_twap(Clock::get()?.slot)?; let output_amount = amm.swap(input_amount, swap_type)?; diff --git a/programs/amm/src/state/amm.rs b/programs/amm/src/state/amm.rs index 25a9624b..e7221bbd 100644 --- a/programs/amm/src/state/amm.rs +++ b/programs/amm/src/state/amm.rs @@ -166,7 +166,7 @@ impl Amm { let slots_passed = (self.oracle.last_updated_slot - self.created_at_slot) as u128; require_neq!(slots_passed, 0, AmmError::NoSlotsPassed); - assert!(self.oracle.aggregator != 0); + require!(self.oracle.aggregator != 0, AmmError::AssertFailed); Ok(self.oracle.aggregator / slots_passed) } @@ -175,7 +175,7 @@ impl Amm { /// have been made. /// /// Returns an observation if one was recorded. - pub fn update_twap(&mut self, current_slot: Slot) -> Option { + pub fn update_twap(&mut self, current_slot: Slot) -> Result> { let oracle = &mut self.oracle; // a manipulator is likely to be "bursty" with their usage, such as a // validator who abuses their slots to manipulate the TWAP. @@ -196,11 +196,11 @@ impl Amm { // that trades near $1500 and you allow $25 updates per minute, it can double // over an hour. if current_slot < oracle.last_updated_slot + ONE_MINUTE_IN_SLOTS { - return None; + return Ok(None); } if self.base_amount == 0 || self.quote_amount == 0 { - return None; + return Ok(None); } // we store prices as quote units / base units scaled by 1e12. @@ -244,32 +244,32 @@ impl Amm { initial_observation: oracle.initial_observation, }; - assert!(new_oracle.last_updated_slot > oracle.last_updated_slot); + require!(new_oracle.last_updated_slot > oracle.last_updated_slot, AmmError::AssertFailed); // assert that the new observation is between price and last observation match price.cmp(&oracle.last_observation) { Ordering::Greater => { - assert!(new_observation > oracle.last_observation); - assert!(new_observation <= price); + require!(new_observation > oracle.last_observation, AmmError::AssertFailed); + require!(new_observation <= price, AmmError::AssertFailed); } Ordering::Equal => { - assert!(new_observation == price); + require!(new_observation == price, AmmError::AssertFailed); } Ordering::Less => { - assert!(new_observation < oracle.last_observation); - assert!(new_observation >= price); + require!(new_observation < oracle.last_observation, AmmError::AssertFailed); + require!(new_observation >= price, AmmError::AssertFailed); } } *oracle = new_oracle; - Some(new_observation) + Ok(Some(new_observation)) } pub fn invariant(&self) -> Result<()> { let oracle = &self.oracle; - assert!(oracle.last_price <= MAX_PRICE); - assert!(oracle.last_observation <= MAX_PRICE); + require!(oracle.last_price <= MAX_PRICE, AmmError::AssertFailed); + require!(oracle.last_observation <= MAX_PRICE, AmmError::AssertFailed); Ok(()) } @@ -359,7 +359,7 @@ mod simple_amm_tests { let slots_until_overflow = u128::MAX / (u64::MAX as u128 * PRICE_SCALE); amm.update_twap(slots_until_overflow as u64); - assert!(amm.oracle.aggregator > MAX_PRICE * 18_400_000); + require!(amm.oracle.aggregator > MAX_PRICE * 18_400_000); assert_ne!(amm.oracle.aggregator, u128::MAX); amm_clone.update_twap(slots_until_overflow as u64 + 1); diff --git a/programs/autocrat/src/instructions/finalize_proposal.rs b/programs/autocrat/src/instructions/finalize_proposal.rs index 659642fc..94190296 100644 --- a/programs/autocrat/src/instructions/finalize_proposal.rs +++ b/programs/autocrat/src/instructions/finalize_proposal.rs @@ -1,10 +1,12 @@ +use conditional_vault::{cpi::accounts::ResolveQuestion, ResolveQuestionArgs}; + use super::*; #[derive(Accounts)] pub struct FinalizeProposal<'info> { #[account(mut, - has_one = base_vault, - has_one = quote_vault, + // has_one = base_vault, + // has_one = quote_vault, has_one = pass_amm, has_one = fail_amm, has_one = dao, @@ -15,9 +17,11 @@ pub struct FinalizeProposal<'info> { #[account(has_one = treasury)] pub dao: Box>, #[account(mut)] - pub base_vault: Box>, - #[account(mut)] - pub quote_vault: Box>, + pub question: Account<'info, Question>, + // #[account(mut)] + // pub base_vault: Box>, + // #[account(mut)] + // pub quote_vault: Box>, /// CHECK: never read pub treasury: UncheckedAccount<'info>, #[account( @@ -71,8 +75,9 @@ impl FinalizeProposal<'_> { pass_amm, fail_amm, dao, - base_vault, - quote_vault, + question, + // base_vault, + // quote_vault, treasury, pass_lp_user_account, fail_lp_user_account, @@ -147,38 +152,41 @@ impl FinalizeProposal<'_> { .saturating_mul(MAX_BPS.saturating_add(dao.pass_threshold_bps).into()) / MAX_BPS as u128; - let (new_proposal_state, new_vault_state) = if pass_market_twap > threshold { - (ProposalState::Passed, VaultStatus::Finalized) + let (new_proposal_state, payout_numerators) = if pass_market_twap > threshold { + (ProposalState::Passed, vec![0, 1]) } else { - (ProposalState::Failed, VaultStatus::Reverted) + (ProposalState::Failed, vec![1, 0]) }; proposal.state = new_proposal_state; - for vault in [base_vault.to_account_info(), quote_vault.to_account_info()] { - let vault_program = vault_program.to_account_info(); - let cpi_accounts = SettleConditionalVault { - settlement_authority: proposal.to_account_info(), - vault, - }; - let cpi_ctx = CpiContext::new(vault_program, cpi_accounts).with_signer(proposal_signer); - conditional_vault::cpi::settle_conditional_vault(cpi_ctx, new_vault_state)?; - } - - base_vault.reload()?; - quote_vault.reload()?; - - match new_proposal_state { - ProposalState::Passed => { - assert!(base_vault.status == VaultStatus::Finalized); - assert!(quote_vault.status == VaultStatus::Finalized); - } - ProposalState::Failed => { - assert!(base_vault.status == VaultStatus::Reverted); - assert!(quote_vault.status == VaultStatus::Reverted); - } - _ => unreachable!("Encountered an unexpected proposal state"), - } + // for vault in [base_vault.to_account_info(), quote_vault.to_account_info()] { + let vault_program = vault_program.to_account_info(); + let cpi_accounts = ResolveQuestion { + question: question.to_account_info(), + oracle: proposal.to_account_info(), + }; + let cpi_ctx = CpiContext::new(vault_program, cpi_accounts).with_signer(proposal_signer); + conditional_vault::cpi::resolve_question( + cpi_ctx, + ResolveQuestionArgs { payout_numerators }, + )?; + // } + + // base_vault.reload()?; + // quote_vault.reload()?; + + // match new_proposal_state { + // ProposalState::Passed => { + // require!(base_vault.status == VaultStatus::Finalized); + // require!(quote_vault.status == VaultStatus::Finalized); + // } + // ProposalState::Failed => { + // require!(base_vault.status == VaultStatus::Reverted); + // require!(quote_vault.status == VaultStatus::Reverted); + // } + // _ => unreachable!("Encountered an unexpected proposal state"), + // } Ok(()) } diff --git a/programs/autocrat/src/instructions/initialize_proposal.rs b/programs/autocrat/src/instructions/initialize_proposal.rs index 4c57dd05..c7951422 100644 --- a/programs/autocrat/src/instructions/initialize_proposal.rs +++ b/programs/autocrat/src/instructions/initialize_proposal.rs @@ -25,19 +25,25 @@ pub struct InitializeProposal<'info> { pub proposal: Box>, #[account(mut)] pub dao: Box>, + #[account( + constraint = question.oracle == proposal.key() + )] + pub question: Box>, #[account( constraint = quote_vault.underlying_token_mint == dao.usdc_mint, - constraint = quote_vault.settlement_authority == proposal.key() @ AutocratError::InvalidSettlementAuthority, + has_one = question, + // constraint = quote_vault.settlement_authority == proposal.key() @ AutocratError::InvalidSettlementAuthority, )] pub quote_vault: Account<'info, ConditionalVaultAccount>, #[account( constraint = base_vault.underlying_token_mint == dao.token_mint, - constraint = base_vault.settlement_authority == proposal.key() @ AutocratError::InvalidSettlementAuthority, + has_one = question, + // constraint = base_vault.settlement_authority == proposal.key() @ AutocratError::InvalidSettlementAuthority, )] pub base_vault: Account<'info, ConditionalVaultAccount>, #[account( - constraint = pass_amm.base_mint == base_vault.conditional_on_finalize_token_mint, - constraint = pass_amm.quote_mint == quote_vault.conditional_on_finalize_token_mint, + constraint = pass_amm.base_mint == base_vault.conditional_token_mints[1], + constraint = pass_amm.quote_mint == quote_vault.conditional_token_mints[1], )] pub pass_amm: Box>, #[account(constraint = pass_amm.lp_mint == pass_lp_mint.key())] @@ -45,8 +51,8 @@ pub struct InitializeProposal<'info> { #[account(constraint = fail_amm.lp_mint == fail_lp_mint.key())] pub fail_lp_mint: Account<'info, Mint>, #[account( - constraint = fail_amm.base_mint == base_vault.conditional_on_revert_token_mint, - constraint = fail_amm.quote_mint == quote_vault.conditional_on_revert_token_mint, + constraint = fail_amm.base_mint == base_vault.conditional_token_mints[0], + constraint = fail_amm.quote_mint == quote_vault.conditional_token_mints[0], )] pub fail_amm: Box>, #[account( @@ -110,6 +116,7 @@ impl InitializeProposal<'_> { let Self { base_vault, quote_vault, + question, proposal, dao, pass_amm, @@ -210,6 +217,7 @@ impl InitializeProposal<'_> { fail_lp_tokens_locked: fail_lp_tokens_to_lock, nonce, pda_bump: ctx.bumps.proposal, + question: question.key(), }); Ok(()) diff --git a/programs/autocrat/src/lib.rs b/programs/autocrat/src/lib.rs index 60d0ac21..2fcc6c74 100644 --- a/programs/autocrat/src/lib.rs +++ b/programs/autocrat/src/lib.rs @@ -26,10 +26,11 @@ use anchor_lang::prelude::*; use anchor_lang::solana_program; use anchor_spl::token::{self, Mint, Token, TokenAccount, Transfer}; -use conditional_vault::cpi::accounts::SettleConditionalVault; +// use conditional_vault::cpi::accounts::SettleConditionalVault; use conditional_vault::program::ConditionalVault as ConditionalVaultProgram; use conditional_vault::ConditionalVault as ConditionalVaultAccount; -use conditional_vault::VaultStatus; +use conditional_vault::Question; +// use conditional_vault::VaultStatus; pub mod error; pub mod instructions; diff --git a/programs/autocrat/src/state/proposal.rs b/programs/autocrat/src/state/proposal.rs index 27d7e5a0..f3438df5 100644 --- a/programs/autocrat/src/state/proposal.rs +++ b/programs/autocrat/src/state/proposal.rs @@ -43,6 +43,7 @@ pub struct Proposal { /// the math :D pub nonce: u64, pub pda_bump: u8, + pub question: Pubkey, } impl From<&ProposalInstruction> for Instruction { diff --git a/programs/conditional_vault/Cargo.toml b/programs/conditional_vault/Cargo.toml index 95da9691..4e66ebe1 100644 --- a/programs/conditional_vault/Cargo.toml +++ b/programs/conditional_vault/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "conditional_vault" -version = "0.3.0" +version = "0.4.0" description = "SVM-based program for minting conditional tokens" edition = "2021" diff --git a/programs/conditional_vault/src/error.rs b/programs/conditional_vault/src/error.rs index 44e47245..2c810f4d 100644 --- a/programs/conditional_vault/src/error.rs +++ b/programs/conditional_vault/src/error.rs @@ -2,14 +2,34 @@ use super::*; #[error_code] pub enum VaultError { + #[msg("An assertion failed")] + AssertFailed, #[msg("Insufficient underlying token balance to mint this amount of conditional tokens")] InsufficientUnderlyingTokens, + #[msg("Insufficient conditional token balance to merge this `amount`")] + InsufficientConditionalTokens, #[msg("This `vault_underlying_token_account` is not this vault's `underlying_token_account`")] InvalidVaultUnderlyingTokenAccount, #[msg("This conditional token mint is not this vault's conditional token mint")] InvalidConditionalTokenMint, - #[msg("Vault needs to be settled as finalized before users can redeem conditional tokens for underlying tokens")] + #[msg("Question needs to be resolved before users can redeem conditional tokens for underlying tokens")] CantRedeemConditionalTokens, - #[msg("Once a vault has been settled, its status as either finalized or reverted cannot be changed")] - VaultAlreadySettled, + #[msg("Questions need 2 or more conditions")] + InsufficientNumConditions, + #[msg("Invalid number of payout numerators")] + InvalidNumPayoutNumerators, + #[msg("Client needs to pass in the list of conditional mints for a vault followed by the user's token accounts for those tokens")] + InvalidConditionals, + #[msg("Conditional mint not in vault")] + ConditionalMintMismatch, + #[msg("Unable to deserialize a conditional token mint")] + BadConditionalMint, + #[msg("Unable to deserialize a conditional token account")] + BadConditionalTokenAccount, + #[msg("User conditional token account mint does not match conditional mint")] + ConditionalTokenMintMismatch, + #[msg("Payouts must sum to 1 or more")] + PayoutZero, + #[msg("Conditional token metadata already set")] + ConditionalTokenMetadataAlreadySet, } diff --git a/programs/conditional_vault/src/instructions/add_metadata_to_conditional_tokens.rs b/programs/conditional_vault/src/instructions/add_metadata_to_conditional_tokens.rs index 3b40008d..0f2f50d5 100644 --- a/programs/conditional_vault/src/instructions/add_metadata_to_conditional_tokens.rs +++ b/programs/conditional_vault/src/instructions/add_metadata_to_conditional_tokens.rs @@ -8,43 +8,26 @@ pub mod proph3t_deployer { #[derive(AnchorSerialize, AnchorDeserialize)] pub struct AddMetadataToConditionalTokensArgs { - pub proposal_number: u64, - pub on_finalize_uri: String, - pub on_revert_uri: String, + pub name: String, + pub symbol: String, + pub uri: String, } #[derive(Accounts)] pub struct AddMetadataToConditionalTokens<'info> { #[account(mut)] pub payer: Signer<'info>, - #[account( - mut, - has_one = underlying_token_mint, - )] - pub vault: Account<'info, ConditionalVault>, #[account(mut)] - pub underlying_token_mint: Account<'info, Mint>, - pub underlying_token_metadata: Account<'info, MetadataAccount>, - #[account( - mut, - mint::authority = vault, - mint::freeze_authority = vault, - mint::decimals = underlying_token_mint.decimals - )] - pub conditional_on_finalize_token_mint: Account<'info, Mint>, + pub vault: Account<'info, ConditionalVault>, + // pub underlying_token_metadata: Account<'info, MetadataAccount>, #[account( mut, mint::authority = vault, - mint::freeze_authority = vault, - mint::decimals = underlying_token_mint.decimals )] - pub conditional_on_revert_token_mint: Account<'info, Mint>, - /// CHECK: verified via cpi into token metadata - #[account(mut)] - pub conditional_on_finalize_token_metadata: AccountInfo<'info>, + pub conditional_token_mint: Account<'info, Mint>, /// CHECK: verified via cpi into token metadata #[account(mut)] - pub conditional_on_revert_token_metadata: AccountInfo<'info>, + pub conditional_token_metadata: AccountInfo<'info>, pub token_metadata_program: Program<'info, Metadata>, pub system_program: Program<'info, System>, pub rent: Sysvar<'info, Rent>, @@ -52,9 +35,14 @@ pub struct AddMetadataToConditionalTokens<'info> { impl AddMetadataToConditionalTokens<'_> { pub fn validate(&self) -> Result<()> { + // require!( + // self.vault.status == VaultStatus::Active, + // VaultError::VaultAlreadySettled + // ); + require!( - self.vault.status == VaultStatus::Active, - VaultError::VaultAlreadySettled + self.conditional_token_metadata.data_is_empty(), + VaultError::ConditionalTokenMetadataAlreadySet ); #[cfg(feature = "production")] @@ -69,55 +57,36 @@ impl AddMetadataToConditionalTokens<'_> { let seeds = generate_vault_seeds!(ctx.accounts.vault); let signer_seeds = &[&seeds[..]]; - // there are null bytes we must trim from string, otherwise string value is longer than we want - let underlying_token_symbol_raw = ctx.accounts.underlying_token_metadata.symbol.clone(); - let underlying_token_symbol = underlying_token_symbol_raw.trim_matches(char::from(0)); - - let on_finalize_token_symbol = format!("p{}", underlying_token_symbol); - let on_revert_token_symbol = format!("f{}", underlying_token_symbol); + // let underlying_token_symbol_raw = ctx.accounts.underlying_token_metadata.symbol.clone(); + // let underlying_token_symbol = underlying_token_symbol_raw.trim_matches(char::from(0)); - for (symbol, uri, metadata, mint) in [ - ( - on_finalize_token_symbol, - args.on_finalize_uri, - &ctx.accounts.conditional_on_finalize_token_metadata, - &ctx.accounts.conditional_on_finalize_token_mint, - ), - ( - on_revert_token_symbol, - args.on_revert_uri, - &ctx.accounts.conditional_on_revert_token_metadata, - &ctx.accounts.conditional_on_revert_token_mint, - ), - ] { - let cpi_program = ctx.accounts.token_metadata_program.to_account_info(); + let cpi_program = ctx.accounts.token_metadata_program.to_account_info(); - let cpi_accounts = CreateMetadataAccountsV3 { - metadata: metadata.to_account_info(), - mint: mint.to_account_info(), - mint_authority: ctx.accounts.vault.to_account_info(), - payer: ctx.accounts.payer.to_account_info(), - update_authority: ctx.accounts.vault.to_account_info(), - system_program: ctx.accounts.system_program.to_account_info(), - rent: ctx.accounts.rent.to_account_info(), - }; + let cpi_accounts = CreateMetadataAccountsV3 { + metadata: ctx.accounts.conditional_token_metadata.to_account_info(), + mint: ctx.accounts.conditional_token_mint.to_account_info(), + mint_authority: ctx.accounts.vault.to_account_info(), + payer: ctx.accounts.payer.to_account_info(), + update_authority: ctx.accounts.vault.to_account_info(), + system_program: ctx.accounts.system_program.to_account_info(), + rent: ctx.accounts.rent.to_account_info(), + }; - create_metadata_accounts_v3( - CpiContext::new(cpi_program, cpi_accounts).with_signer(signer_seeds), - DataV2 { - name: format!("Proposal {}: {}", args.proposal_number, symbol), - symbol, - uri, - seller_fee_basis_points: 0, - creators: None, - collection: None, - uses: None, - }, - false, - true, - None, - )?; - } + create_metadata_accounts_v3( + CpiContext::new(cpi_program, cpi_accounts).with_signer(signer_seeds), + DataV2 { + name: args.name, + symbol: args.symbol, + uri: args.uri, + seller_fee_basis_points: 0, + creators: None, + collection: None, + uses: None, + }, + false, + true, + None, + )?; Ok(()) } diff --git a/programs/conditional_vault/src/instructions/common.rs b/programs/conditional_vault/src/instructions/common.rs index ec979880..f6b71c78 100644 --- a/programs/conditional_vault/src/instructions/common.rs +++ b/programs/conditional_vault/src/instructions/common.rs @@ -2,33 +2,15 @@ use super::*; #[derive(Accounts)] pub struct InteractWithVault<'info> { - #[account( - has_one = conditional_on_finalize_token_mint @ VaultError::InvalidConditionalTokenMint, - has_one = conditional_on_revert_token_mint @ VaultError::InvalidConditionalTokenMint, - )] + pub question: Account<'info, Question>, + #[account(has_one = question)] pub vault: Account<'info, ConditionalVault>, - #[account(mut)] - pub conditional_on_finalize_token_mint: Account<'info, Mint>, - #[account(mut)] - pub conditional_on_revert_token_mint: Account<'info, Mint>, #[account( mut, constraint = vault_underlying_token_account.key() == vault.underlying_token_account @ VaultError::InvalidVaultUnderlyingTokenAccount )] pub vault_underlying_token_account: Account<'info, TokenAccount>, pub authority: Signer<'info>, - #[account( - mut, - token::authority = authority, - token::mint = conditional_on_finalize_token_mint - )] - pub user_conditional_on_finalize_token_account: Account<'info, TokenAccount>, - #[account( - mut, - token::authority = authority, - token::mint = conditional_on_revert_token_mint - )] - pub user_conditional_on_revert_token_account: Account<'info, TokenAccount>, #[account( mut, token::authority = authority, @@ -37,3 +19,56 @@ pub struct InteractWithVault<'info> { pub user_underlying_token_account: Account<'info, TokenAccount>, pub token_program: Program<'info, Token>, } + +impl<'info, 'c: 'info> InteractWithVault<'info> { + pub fn get_mints_and_user_token_accounts( + ctx: &Context<'_, '_, 'c, 'info, Self>, + ) -> Result<(Vec>, Vec>)> { + // msg!("HelloWorld"); + let remaining_accs = &mut ctx.remaining_accounts.iter(); + // msg!("{:?}", remaining_accs); + + let expected_num_conditional_tokens = ctx.accounts.question.num_outcomes(); + require_eq!( + remaining_accs.len(), + expected_num_conditional_tokens * 2, + VaultError::InvalidConditionals + ); + + let mut conditional_token_mints = vec![]; + let mut user_conditional_token_accounts = vec![]; + + for i in 0..expected_num_conditional_tokens { + let conditional_token_mint = next_account_info(remaining_accs)?; + require_eq!( + ctx.accounts.vault.conditional_token_mints[i], + conditional_token_mint.key(), + VaultError::ConditionalMintMismatch + ); + + // really, this should never fail because we initialize mints when we initialize the vault + conditional_token_mints.push( + Account::::try_from(conditional_token_mint) + .or(Err(VaultError::BadConditionalMint))?, + ); + } + + for i in 0..expected_num_conditional_tokens { + let user_conditional_token_account = next_account_info(remaining_accs)?; + + let user_conditional_token_account = + Account::::try_from(user_conditional_token_account) + .or(Err(VaultError::BadConditionalTokenAccount))?; + + require_eq!( + user_conditional_token_account.mint, + conditional_token_mints[i].key(), + VaultError::ConditionalTokenMintMismatch + ); + + user_conditional_token_accounts.push(user_conditional_token_account); + } + + Ok((conditional_token_mints, user_conditional_token_accounts)) + } +} diff --git a/programs/conditional_vault/src/instructions/initialize_conditional_vault.rs b/programs/conditional_vault/src/instructions/initialize_conditional_vault.rs index 2ed0c5d5..f5a0f9e4 100644 --- a/programs/conditional_vault/src/instructions/initialize_conditional_vault.rs +++ b/programs/conditional_vault/src/instructions/initialize_conditional_vault.rs @@ -1,46 +1,24 @@ use super::*; -#[derive(AnchorSerialize, AnchorDeserialize)] -pub struct InitializeConditionalVaultArgs { - pub settlement_authority: Pubkey, -} +use anchor_lang::system_program; +use anchor_spl::token; #[derive(Accounts)] -#[instruction(args: InitializeConditionalVaultArgs)] pub struct InitializeConditionalVault<'info> { #[account( init, payer = payer, - space = 8 + std::mem::size_of::(), + space = 8 + std::mem::size_of::() + (32 * question.num_outcomes()), seeds = [ b"conditional_vault", - args.settlement_authority.key().as_ref(), + question.key().as_ref(), underlying_token_mint.key().as_ref(), ], bump )] pub vault: Box>, + pub question: Account<'info, Question>, pub underlying_token_mint: Account<'info, Mint>, - #[account( - init, - payer = payer, - seeds = [b"conditional_on_finalize_mint", vault.key().as_ref()], - bump, - mint::authority = vault, - mint::freeze_authority = vault, - mint::decimals = underlying_token_mint.decimals - )] - pub conditional_on_finalize_token_mint: Box>, - #[account( - init, - payer = payer, - seeds = [b"conditional_on_revert_mint", vault.key().as_ref()], - bump, - mint::authority = vault, - mint::freeze_authority = vault, - mint::decimals = underlying_token_mint.decimals - )] - pub conditional_on_revert_token_mint: Box>, #[account( associated_token::authority = vault, associated_token::mint = underlying_token_mint @@ -53,26 +31,67 @@ pub struct InitializeConditionalVault<'info> { pub system_program: Program<'info, System>, } -impl InitializeConditionalVault<'_> { - pub fn handle(ctx: Context, args: InitializeConditionalVaultArgs) -> Result<()> { +impl<'info, 'c: 'info> InitializeConditionalVault<'info> { + pub fn handle(ctx: Context<'_, '_, 'c, 'info, Self>) -> Result<()> { let vault = &mut ctx.accounts.vault; - let InitializeConditionalVaultArgs { - settlement_authority, - } = args; + let decimals = ctx.accounts.underlying_token_mint.decimals; + + let remaining_accs = &mut ctx.remaining_accounts.iter(); + + let expected_num_conditional_tokens = ctx.accounts.question.num_outcomes(); + let mut conditional_token_mints = vec![]; + + let mint_lamports = Rent::get()?.minimum_balance(Mint::LEN); + for i in 0..expected_num_conditional_tokens { + let (conditional_token_mint_address, pda_bump) = Pubkey::find_program_address( + &[b"conditional_token", vault.key().as_ref(), &[i as u8]], + ctx.program_id, + ); + + let conditional_token_mint = next_account_info(remaining_accs)?; + require_eq!(conditional_token_mint.key(), conditional_token_mint_address); + + conditional_token_mints.push(conditional_token_mint_address); + + let cpi_program = ctx.accounts.system_program.to_account_info(); + let cpi_accounts = system_program::CreateAccount { + from: ctx.accounts.payer.to_account_info(), + to: conditional_token_mint.to_account_info(), + }; + let vault_key = vault.key(); + let seeds = &[ + b"conditional_token", + vault_key.as_ref(), + &[i as u8], + &[pda_bump], + ]; + let signer = &[&seeds[..]]; + let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer); + + system_program::create_account( + cpi_ctx, + mint_lamports, + Mint::LEN as u64, + ctx.accounts.token_program.key, + )?; + + let cpi_program = ctx.accounts.token_program.to_account_info(); + let cpi_accounts = token::InitializeMint2 { + mint: conditional_token_mint.to_account_info(), + }; + let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts); + + token::initialize_mint2(cpi_ctx, decimals, &vault.key(), None)?; + } vault.set_inner(ConditionalVault { - status: VaultStatus::Active, - settlement_authority, + question: ctx.accounts.question.key(), underlying_token_mint: ctx.accounts.underlying_token_mint.key(), underlying_token_account: ctx.accounts.vault_underlying_token_account.key(), - conditional_on_finalize_token_mint: ctx - .accounts - .conditional_on_finalize_token_mint - .key(), - conditional_on_revert_token_mint: ctx.accounts.conditional_on_revert_token_mint.key(), + conditional_token_mints, pda_bump: ctx.bumps.vault, - decimals: ctx.accounts.underlying_token_mint.decimals, + decimals, }); Ok(()) diff --git a/programs/conditional_vault/src/instructions/initialize_question.rs b/programs/conditional_vault/src/instructions/initialize_question.rs new file mode 100644 index 00000000..760fca22 --- /dev/null +++ b/programs/conditional_vault/src/instructions/initialize_question.rs @@ -0,0 +1,56 @@ +use super::*; + +#[derive(AnchorSerialize, AnchorDeserialize)] +pub struct InitializeQuestionArgs { + pub question_id: [u8; 32], + pub oracle: Pubkey, + pub num_conditions: u8, +} + +#[derive(Accounts)] +#[instruction(args: InitializeQuestionArgs)] +pub struct InitializeQuestion<'info> { + #[account( + init, + payer = payer, + space = 8 + 32 + 32 + 1 + 4 + (args.num_conditions as usize * 4) + 4, + seeds = [ + b"question", + args.question_id.as_ref(), + args.oracle.key().as_ref(), + &[args.num_conditions], + ], + bump + )] + pub question: Box>, + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, +} + +impl InitializeQuestion<'_> { + pub fn handle(ctx: Context, args: InitializeQuestionArgs) -> Result<()> { + require_gte!( + args.num_conditions, + 2, + VaultError::InsufficientNumConditions + ); + + let question = &mut ctx.accounts.question; + + let InitializeQuestionArgs { + question_id, + oracle, + num_conditions, + } = args; + + question.set_inner(Question { + question_id, + oracle, + payout_numerators: vec![0; num_conditions as usize], + payout_denominator: 0, + }); + + Ok(()) + } +} diff --git a/programs/conditional_vault/src/instructions/merge_conditional_tokens.rs b/programs/conditional_vault/src/instructions/merge_conditional_tokens.rs deleted file mode 100644 index e8c16919..00000000 --- a/programs/conditional_vault/src/instructions/merge_conditional_tokens.rs +++ /dev/null @@ -1,114 +0,0 @@ -use super::*; - -impl InteractWithVault<'_> { - pub fn validate_merge_conditional_tokens(&self) -> Result<()> { - require!( - self.vault.status == VaultStatus::Active, - VaultError::VaultAlreadySettled - ); - - Ok(()) - } - - pub fn handle_merge_conditional_tokens(ctx: Context, amount: u64) -> Result<()> { - let accs = &ctx.accounts; - - let vault = &accs.vault; - - // Store Pre-operation Balances - let pre_user_conditional_on_finalize_balance = ctx - .accounts - .user_conditional_on_finalize_token_account - .amount; - let pre_user_conditional_on_revert_balance = - ctx.accounts.user_conditional_on_revert_token_account.amount; - let pre_vault_underlying_balance = ctx.accounts.vault_underlying_token_account.amount; - let pre_finalize_mint_supply = ctx.accounts.conditional_on_finalize_token_mint.supply; - let pre_revert_mint_supply = ctx.accounts.conditional_on_revert_token_mint.supply; - - let seeds = generate_vault_seeds!(vault); - let signer = &[&seeds[..]]; - - // burn `amount` from both token accounts - for (conditional_mint, user_conditional_token_account) in [ - ( - &accs.conditional_on_finalize_token_mint, - &accs.user_conditional_on_finalize_token_account, - ), - ( - &accs.conditional_on_revert_token_mint, - &accs.user_conditional_on_revert_token_account, - ), - ] { - token::burn( - CpiContext::new( - accs.token_program.to_account_info(), - Burn { - mint: conditional_mint.to_account_info(), - from: user_conditional_token_account.to_account_info(), - authority: accs.authority.to_account_info(), - }, - ), - amount, - )?; - } - - // Transfer `amount` from vault to user - token::transfer( - CpiContext::new_with_signer( - accs.token_program.to_account_info(), - Transfer { - from: accs.vault_underlying_token_account.to_account_info(), - to: accs.user_underlying_token_account.to_account_info(), - authority: accs.vault.to_account_info(), - }, - signer, - ), - amount, - )?; - - // Reload Accounts to Reflect Changes - ctx.accounts - .user_conditional_on_finalize_token_account - .reload()?; - ctx.accounts - .user_conditional_on_revert_token_account - .reload()?; - ctx.accounts.vault_underlying_token_account.reload()?; - ctx.accounts.conditional_on_finalize_token_mint.reload()?; - ctx.accounts.conditional_on_revert_token_mint.reload()?; - - // Check post-operation balances - let post_user_conditional_on_finalize_balance = ctx - .accounts - .user_conditional_on_finalize_token_account - .amount; - let post_user_conditional_on_revert_balance = - ctx.accounts.user_conditional_on_revert_token_account.amount; - let post_vault_underlying_balance = ctx.accounts.vault_underlying_token_account.amount; - let post_finalize_mint_supply = ctx.accounts.conditional_on_finalize_token_mint.supply; - let post_revert_mint_supply = ctx.accounts.conditional_on_revert_token_mint.supply; - - // Check that the user's conditional token balances are unchanged (since we're not necessarily burning all tokens) - require_eq!( - post_user_conditional_on_finalize_balance, - pre_user_conditional_on_finalize_balance - amount - ); - require_eq!( - post_user_conditional_on_revert_balance, - pre_user_conditional_on_revert_balance - amount - ); - - // Check that the mint supplies have been reduced by the burned amounts - require_eq!(post_finalize_mint_supply, pre_finalize_mint_supply - amount); - require_eq!(post_revert_mint_supply, pre_revert_mint_supply - amount); - - // Check that the vault's underlying balance has been reduced by the transferred amount - require_eq!( - post_vault_underlying_balance, - pre_vault_underlying_balance - amount - ); - - Ok(()) - } -} diff --git a/programs/conditional_vault/src/instructions/merge_tokens.rs b/programs/conditional_vault/src/instructions/merge_tokens.rs new file mode 100644 index 00000000..8d48b0fa --- /dev/null +++ b/programs/conditional_vault/src/instructions/merge_tokens.rs @@ -0,0 +1,106 @@ +use super::*; + +impl<'info, 'c: 'info> InteractWithVault<'info> { + pub fn handle_merge_tokens(ctx: Context<'_, '_, 'c, 'info, Self>, amount: u64) -> Result<()> { + let accs = &ctx.accounts; + + let (mut conditional_token_mints, mut user_conditional_token_accounts) = + Self::get_mints_and_user_token_accounts(&ctx)?; + + for conditional_token_account in user_conditional_token_accounts.iter() { + require!( + conditional_token_account.amount >= amount, + VaultError::InsufficientConditionalTokens + ); + } + + let vault = &accs.vault; + + let pre_user_underlying_balance = accs.user_underlying_token_account.amount; + let pre_vault_underlying_balance = accs.vault_underlying_token_account.amount; + + let expected_future_balances: Vec = user_conditional_token_accounts + .iter() + .map(|account| account.amount - amount) + .collect(); + let expected_future_supplies: Vec = conditional_token_mints + .iter() + .map(|mint| mint.supply - amount) + .collect(); + + let seeds = generate_vault_seeds!(vault); + let signer = &[&seeds[..]]; + + for (conditional_mint, user_conditional_token_account) in conditional_token_mints + .iter() + .zip(user_conditional_token_accounts.iter()) + { + token::burn( + CpiContext::new( + accs.token_program.to_account_info(), + Burn { + mint: conditional_mint.to_account_info(), + from: user_conditional_token_account.to_account_info(), + authority: accs.authority.to_account_info(), + }, + ), + amount, + )?; + } + + // Transfer `amount` from vault to user + token::transfer( + CpiContext::new_with_signer( + accs.token_program.to_account_info(), + Transfer { + from: accs.vault_underlying_token_account.to_account_info(), + to: accs.user_underlying_token_account.to_account_info(), + authority: accs.vault.to_account_info(), + }, + signer, + ), + amount, + )?; + + ctx.accounts.user_underlying_token_account.reload()?; + ctx.accounts.vault_underlying_token_account.reload()?; + + require_eq!( + ctx.accounts.user_underlying_token_account.amount, + pre_user_underlying_balance + amount, + VaultError::AssertFailed + ); + require_eq!( + ctx.accounts.vault_underlying_token_account.amount, + pre_vault_underlying_balance - amount, + VaultError::AssertFailed + ); + + for (mint, expected_supply) in conditional_token_mints + .iter_mut() + .zip(expected_future_supplies.iter()) + { + mint.reload()?; + require_eq!(mint.supply, *expected_supply, VaultError::AssertFailed); + } + + for (account, expected_balance) in user_conditional_token_accounts + .iter_mut() + .zip(expected_future_balances.iter()) + { + account.reload()?; + require_eq!(account.amount, *expected_balance, VaultError::AssertFailed); + } + + ctx.accounts.vault.invariant( + &ctx.accounts.question, + conditional_token_mints + .iter() + .map(|mint| mint.supply) + .collect::>(), + ctx.accounts.vault_underlying_token_account.amount, + )?; + + Ok(()) + } +} diff --git a/programs/conditional_vault/src/instructions/mint_conditional_tokens.rs b/programs/conditional_vault/src/instructions/mint_conditional_tokens.rs deleted file mode 100644 index 35c64e39..00000000 --- a/programs/conditional_vault/src/instructions/mint_conditional_tokens.rs +++ /dev/null @@ -1,96 +0,0 @@ -use super::*; - -impl InteractWithVault<'_> { - pub fn handle_mint_conditional_tokens(ctx: Context, amount: u64) -> Result<()> { - let accs = &ctx.accounts; - - let pre_vault_underlying_balance = accs.vault_underlying_token_account.amount; - let pre_user_conditional_on_finalize_balance = - accs.user_conditional_on_finalize_token_account.amount; - let pre_user_conditional_on_revert_balance = - accs.user_conditional_on_revert_token_account.amount; - let pre_finalize_mint_supply = accs.conditional_on_finalize_token_mint.supply; - let pre_revert_mint_supply = accs.conditional_on_revert_token_mint.supply; - - require!( - accs.user_underlying_token_account.amount >= amount, - VaultError::InsufficientUnderlyingTokens - ); - - let vault = &accs.vault; - - let seeds = generate_vault_seeds!(vault); - let signer = &[&seeds[..]]; - - token::transfer( - CpiContext::new( - accs.token_program.to_account_info(), - Transfer { - from: accs.user_underlying_token_account.to_account_info(), - to: accs.vault_underlying_token_account.to_account_info(), - authority: accs.authority.to_account_info(), - }, - ), - amount, - )?; - - for (conditional_mint, user_conditional_token_account) in [ - ( - &accs.conditional_on_finalize_token_mint, - &accs.user_conditional_on_finalize_token_account, - ), - ( - &accs.conditional_on_revert_token_mint, - &accs.user_conditional_on_revert_token_account, - ), - ] { - token::mint_to( - CpiContext::new_with_signer( - accs.token_program.to_account_info(), - MintTo { - mint: conditional_mint.to_account_info(), - to: user_conditional_token_account.to_account_info(), - authority: accs.vault.to_account_info(), - }, - signer, - ), - amount, - )?; - } - - ctx.accounts - .user_conditional_on_finalize_token_account - .reload()?; - ctx.accounts - .user_conditional_on_revert_token_account - .reload()?; - ctx.accounts.vault_underlying_token_account.reload()?; - ctx.accounts.conditional_on_finalize_token_mint.reload()?; - ctx.accounts.conditional_on_revert_token_mint.reload()?; - - let post_user_conditional_on_finalize_balance = ctx - .accounts - .user_conditional_on_finalize_token_account - .amount; - let post_user_conditional_on_revert_balance = - ctx.accounts.user_conditional_on_revert_token_account.amount; - let post_vault_underlying_balance = ctx.accounts.vault_underlying_token_account.amount; - let post_finalize_mint_supply = ctx.accounts.conditional_on_finalize_token_mint.supply; - let post_revert_mint_supply = ctx.accounts.conditional_on_revert_token_mint.supply; - - // Only the paranoid survive ;) - assert!(post_vault_underlying_balance == pre_vault_underlying_balance + amount); - assert!( - post_user_conditional_on_finalize_balance - == pre_user_conditional_on_finalize_balance + amount - ); - assert!( - post_user_conditional_on_revert_balance - == pre_user_conditional_on_revert_balance + amount - ); - assert!(post_finalize_mint_supply == pre_finalize_mint_supply + amount); - assert!(post_revert_mint_supply == pre_revert_mint_supply + amount); - - Ok(()) - } -} diff --git a/programs/conditional_vault/src/instructions/mod.rs b/programs/conditional_vault/src/instructions/mod.rs index 13626b8c..a8ba7368 100644 --- a/programs/conditional_vault/src/instructions/mod.rs +++ b/programs/conditional_vault/src/instructions/mod.rs @@ -3,13 +3,17 @@ use super::*; pub mod add_metadata_to_conditional_tokens; pub mod common; pub mod initialize_conditional_vault; -pub mod merge_conditional_tokens; -pub mod mint_conditional_tokens; -pub mod redeem_conditional_tokens_for_underlying_tokens; -pub mod settle_conditional_vault; +pub mod initialize_question; +pub mod merge_tokens; +pub mod redeem_tokens; +pub mod resolve_question; +pub mod split_tokens; +pub use initialize_question::*; pub use add_metadata_to_conditional_tokens::*; pub use common::*; pub use initialize_conditional_vault::*; - -pub use settle_conditional_vault::*; +pub use resolve_question::*; +// pub use split_tokens::*; +// pub use merge_tokens::*; +// pub use redeem_tokens::*; diff --git a/programs/conditional_vault/src/instructions/redeem_conditional_tokens_for_underlying_tokens.rs b/programs/conditional_vault/src/instructions/redeem_conditional_tokens_for_underlying_tokens.rs deleted file mode 100644 index a7e55c01..00000000 --- a/programs/conditional_vault/src/instructions/redeem_conditional_tokens_for_underlying_tokens.rs +++ /dev/null @@ -1,122 +0,0 @@ -use super::*; - -impl InteractWithVault<'_> { - pub fn validate_redeem_conditional_tokens(&self) -> Result<()> { - require!( - self.vault.status != VaultStatus::Active, - VaultError::CantRedeemConditionalTokens - ); - - Ok(()) - } - - pub fn handle_redeem_conditional_tokens(ctx: Context) -> Result<()> { - let accs = &ctx.accounts; - let vault = &accs.vault; - let vault_status = vault.status; - - // storing some numbers for later invariant checks - let pre_vault_underlying_balance = accs.vault_underlying_token_account.amount; - let pre_finalize_mint_supply = accs.conditional_on_finalize_token_mint.supply; - let pre_revert_mint_supply = accs.conditional_on_revert_token_mint.supply; - - let pre_conditional_on_finalize_balance = - accs.user_conditional_on_finalize_token_account.amount; - let pre_conditional_on_revert_balance = - accs.user_conditional_on_revert_token_account.amount; - - let seeds = generate_vault_seeds!(vault); - let signer = &[&seeds[..]]; - - // burn from both accounts even though we technically only need to burn from one - for (conditional_mint, user_conditional_token_account) in [ - ( - &accs.conditional_on_finalize_token_mint, - &accs.user_conditional_on_finalize_token_account, - ), - ( - &accs.conditional_on_revert_token_mint, - &accs.user_conditional_on_revert_token_account, - ), - ] { - token::burn( - CpiContext::new( - accs.token_program.to_account_info(), - Burn { - mint: conditional_mint.to_account_info(), - from: user_conditional_token_account.to_account_info(), - authority: accs.authority.to_account_info(), - }, - ), - user_conditional_token_account.amount, - )?; - } - - let redeemable = match vault_status { - VaultStatus::Finalized => pre_conditional_on_finalize_balance, - VaultStatus::Reverted => pre_conditional_on_revert_balance, - _ => unreachable!(), - }; - - token::transfer( - CpiContext::new_with_signer( - accs.token_program.to_account_info(), - Transfer { - from: accs.vault_underlying_token_account.to_account_info(), - to: accs.user_underlying_token_account.to_account_info(), - authority: accs.vault.to_account_info(), - }, - signer, - ), - redeemable, - )?; - - ctx.accounts - .user_conditional_on_finalize_token_account - .reload()?; - ctx.accounts - .user_conditional_on_revert_token_account - .reload()?; - ctx.accounts.vault_underlying_token_account.reload()?; - ctx.accounts.conditional_on_finalize_token_mint.reload()?; - ctx.accounts.conditional_on_revert_token_mint.reload()?; - - let post_user_conditional_on_finalize_balance = ctx - .accounts - .user_conditional_on_finalize_token_account - .amount; - let post_user_conditional_on_revert_balance = - ctx.accounts.user_conditional_on_revert_token_account.amount; - let post_vault_underlying_balance = ctx.accounts.vault_underlying_token_account.amount; - let post_finalize_mint_supply = ctx.accounts.conditional_on_finalize_token_mint.supply; - let post_revert_mint_supply = ctx.accounts.conditional_on_revert_token_mint.supply; - - assert!(post_user_conditional_on_finalize_balance == 0); - assert!(post_user_conditional_on_revert_balance == 0); - assert!( - post_finalize_mint_supply - == pre_finalize_mint_supply - pre_conditional_on_finalize_balance - ); - assert!( - post_revert_mint_supply == pre_revert_mint_supply - pre_conditional_on_revert_balance - ); - match vault_status { - VaultStatus::Finalized => { - assert!( - post_vault_underlying_balance - == pre_vault_underlying_balance - pre_conditional_on_finalize_balance - ); - } - VaultStatus::Reverted => { - assert!(vault_status == VaultStatus::Reverted); - assert!( - post_vault_underlying_balance - == pre_vault_underlying_balance - pre_conditional_on_revert_balance - ); - } - _ => unreachable!(), - } - - Ok(()) - } -} diff --git a/programs/conditional_vault/src/instructions/redeem_tokens.rs b/programs/conditional_vault/src/instructions/redeem_tokens.rs new file mode 100644 index 00000000..dd1c300b --- /dev/null +++ b/programs/conditional_vault/src/instructions/redeem_tokens.rs @@ -0,0 +1,127 @@ +use super::*; + +impl<'info, 'c: 'info> InteractWithVault<'info> { + pub fn validate_redeem_tokens(&self) -> Result<()> { + require!( + self.question.is_resolved(), + VaultError::CantRedeemConditionalTokens + ); + + Ok(()) + } + + pub fn handle_redeem_tokens(ctx: Context<'_, '_, 'c, 'info, Self>) -> Result<()> { + let accs = &ctx.accounts; + + let (mut conditional_token_mints, mut user_conditional_token_accounts) = + Self::get_mints_and_user_token_accounts(&ctx)?; + + // calculate the expected future supplies of the conditional token mints + // as current supply - user balance + let expected_future_supplies: Vec = conditional_token_mints + .iter() + .zip(user_conditional_token_accounts.iter()) + .map(|(mint, account)| mint.supply - account.amount) + .collect(); + + let vault = &accs.vault; + let question = &accs.question; + + let seeds = generate_vault_seeds!(vault); + let signer = &[&seeds[..]]; + + let user_underlying_balance_before = accs.user_underlying_token_account.amount; + let vault_underlying_balance_before = accs.vault_underlying_token_account.amount; + // safe because there is always at least two conditional tokens and thus + // at least two user conditional token accounts + let max_redeemable = user_conditional_token_accounts + .iter() + .map(|account| account.amount) + .max() + .unwrap(); + + let mut total_redeemable = 0; + + for (conditional_mint, user_conditional_token_account) in conditional_token_mints + .iter() + .zip(user_conditional_token_accounts.iter()) + { + // this is safe because we check that every conditional mint is a part of the vault + let payout_index = vault + .conditional_token_mints + .iter() + .position(|mint| mint == &conditional_mint.key()) + .unwrap(); + + total_redeemable += ((user_conditional_token_account.amount as u128 + * question.payout_numerators[payout_index] as u128) + / question.payout_denominator as u128) as u64; + + token::burn( + CpiContext::new( + accs.token_program.to_account_info(), + Burn { + mint: conditional_mint.to_account_info(), + from: user_conditional_token_account.to_account_info(), + authority: accs.authority.to_account_info(), + }, + ), + user_conditional_token_account.amount, + )?; + } + + token::transfer( + CpiContext::new_with_signer( + accs.token_program.to_account_info(), + Transfer { + from: accs.vault_underlying_token_account.to_account_info(), + to: accs.user_underlying_token_account.to_account_info(), + authority: accs.vault.to_account_info(), + }, + signer, + ), + total_redeemable, + )?; + + require_gte!(max_redeemable, total_redeemable, VaultError::AssertFailed); + + ctx.accounts.user_underlying_token_account.reload()?; + ctx.accounts.vault_underlying_token_account.reload()?; + + require_eq!( + ctx.accounts.user_underlying_token_account.amount, + user_underlying_balance_before + total_redeemable, + VaultError::AssertFailed + ); + + require_eq!( + ctx.accounts.vault_underlying_token_account.amount, + vault_underlying_balance_before - total_redeemable, + VaultError::AssertFailed + ); + + for acc in user_conditional_token_accounts.iter_mut() { + acc.reload()?; + require_eq!(acc.amount, 0, VaultError::AssertFailed); + } + + for (mint, expected_supply) in conditional_token_mints + .iter_mut() + .zip(expected_future_supplies.iter()) + { + mint.reload()?; + require_eq!(mint.supply, *expected_supply, VaultError::AssertFailed); + } + + ctx.accounts.vault.invariant( + &ctx.accounts.question, + conditional_token_mints + .iter() + .map(|mint| mint.supply) + .collect::>(), + ctx.accounts.vault_underlying_token_account.amount, + )?; + + Ok(()) + } +} diff --git a/programs/conditional_vault/src/instructions/resolve_question.rs b/programs/conditional_vault/src/instructions/resolve_question.rs new file mode 100644 index 00000000..e6c84d0e --- /dev/null +++ b/programs/conditional_vault/src/instructions/resolve_question.rs @@ -0,0 +1,33 @@ +use super::*; + +#[derive(AnchorSerialize, AnchorDeserialize)] +pub struct ResolveQuestionArgs { + pub payout_numerators: Vec, +} + +#[derive(Accounts)] +#[instruction(args: ResolveQuestionArgs)] +pub struct ResolveQuestion<'info> { + #[account(mut, has_one = oracle)] + pub question: Account<'info, Question>, + pub oracle: Signer<'info>, +} + +impl ResolveQuestion<'_> { + pub fn handle(ctx: Context, args: ResolveQuestionArgs) -> Result<()> { + let question = &mut ctx.accounts.question; + + require_eq!( + args.payout_numerators.len(), + question.num_outcomes(), + VaultError::InvalidNumPayoutNumerators + ); + + question.payout_denominator = args.payout_numerators.iter().sum(); + question.payout_numerators = args.payout_numerators; + + require_gt!(question.payout_denominator, 0, VaultError::PayoutZero); + + Ok(()) + } +} diff --git a/programs/conditional_vault/src/instructions/settle_conditional_vault.rs b/programs/conditional_vault/src/instructions/settle_conditional_vault.rs deleted file mode 100644 index 0fb51e75..00000000 --- a/programs/conditional_vault/src/instructions/settle_conditional_vault.rs +++ /dev/null @@ -1,30 +0,0 @@ -use super::*; - -#[derive(Accounts)] -pub struct SettleConditionalVault<'info> { - pub settlement_authority: Signer<'info>, - #[account( - mut, - has_one = settlement_authority, - )] - pub vault: Account<'info, ConditionalVault>, -} - -impl SettleConditionalVault<'_> { - pub fn validate(&self) -> Result<()> { - require!( - self.vault.status == VaultStatus::Active, - VaultError::VaultAlreadySettled - ); - - Ok(()) - } - - pub fn handle(ctx: Context, new_status: VaultStatus) -> Result<()> { - let vault = &mut ctx.accounts.vault; - - vault.status = new_status; - - Ok(()) - } -} diff --git a/programs/conditional_vault/src/instructions/split_tokens.rs b/programs/conditional_vault/src/instructions/split_tokens.rs new file mode 100644 index 00000000..b3592121 --- /dev/null +++ b/programs/conditional_vault/src/instructions/split_tokens.rs @@ -0,0 +1,88 @@ +use super::*; + +impl<'info, 'c: 'info> InteractWithVault<'info> { + pub fn handle_split_tokens(ctx: Context<'_, '_, 'c, 'info, Self>, amount: u64) -> Result<()> { + let accs = &ctx.accounts; + + let (mut conditional_token_mints, mut user_conditional_token_accounts) = + Self::get_mints_and_user_token_accounts(&ctx)?; + + let pre_vault_underlying_balance = accs.vault_underlying_token_account.amount; + let pre_conditional_user_balances = user_conditional_token_accounts + .iter() + .map(|acc| acc.amount) + .collect::>(); + let pre_conditional_mint_supplies = conditional_token_mints + .iter() + .map(|mint| mint.supply) + .collect::>(); + + require!( + accs.user_underlying_token_account.amount >= amount, + VaultError::InsufficientUnderlyingTokens + ); + + let vault = &accs.vault; + + let seeds = generate_vault_seeds!(vault); + let signer = &[&seeds[..]]; + + token::transfer( + CpiContext::new( + accs.token_program.to_account_info(), + Transfer { + from: accs.user_underlying_token_account.to_account_info(), + to: accs.vault_underlying_token_account.to_account_info(), + authority: accs.authority.to_account_info(), + }, + ), + amount, + )?; + + for (conditional_mint, user_conditional_token_account) in conditional_token_mints + .iter() + .zip(user_conditional_token_accounts.iter()) + { + token::mint_to( + CpiContext::new_with_signer( + accs.token_program.to_account_info(), + MintTo { + mint: conditional_mint.to_account_info(), + to: user_conditional_token_account.to_account_info(), + authority: accs.vault.to_account_info(), + }, + signer, + ), + amount, + )?; + } + + ctx.accounts.vault_underlying_token_account.reload()?; + require_eq!( + ctx.accounts.vault_underlying_token_account.amount, + pre_vault_underlying_balance + amount, + VaultError::AssertFailed + ); + + for (i, mint) in conditional_token_mints.iter_mut().enumerate() { + mint.reload()?; + require_eq!(mint.supply, pre_conditional_mint_supplies[i] + amount, VaultError::AssertFailed); + } + + for (i, acc) in user_conditional_token_accounts.iter_mut().enumerate() { + acc.reload()?; + require_eq!(acc.amount, pre_conditional_user_balances[i] + amount, VaultError::AssertFailed); + } + + ctx.accounts.vault.invariant( + &ctx.accounts.question, + conditional_token_mints + .iter() + .map(|mint| mint.supply) + .collect::>(), + ctx.accounts.vault_underlying_token_account.amount, + )?; + + Ok(()) + } +} diff --git a/programs/conditional_vault/src/lib.rs b/programs/conditional_vault/src/lib.rs index ed86fcac..818ca252 100644 --- a/programs/conditional_vault/src/lib.rs +++ b/programs/conditional_vault/src/lib.rs @@ -1,13 +1,12 @@ use anchor_lang::prelude::*; use anchor_spl::metadata::{ create_metadata_accounts_v3, mpl_token_metadata::types::DataV2, CreateMetadataAccountsV3, - Metadata, MetadataAccount, + Metadata, }; use anchor_spl::{ associated_token::AssociatedToken, token::{self, Burn, Mint, MintTo, Token, TokenAccount, Transfer}, }; -// use mpl_token_metadata::state::DataV2; pub mod error; pub mod instructions; @@ -27,8 +26,8 @@ security_txt! { contacts: "email:metaproph3t@protonmail.com", policy: "The market will decide whether we pay a bug bounty.", source_code: "https://github.com/metaDAOproject/futarchy", - source_release: "v0.3", - auditors: "Neodyme", + source_release: "v0.4", + auditors: "Neodyme (v0.3)", acknowledgements: "DCF = (CF1 / (1 + r)^1) + (CF2 / (1 + r)^2) + ... (CFn / (1 + r)^n)" } @@ -38,45 +37,52 @@ declare_id!("VAU1T7S5UuEHmMvXtXMVmpEoQtZ2ya7eRb7gcN47wDp"); pub mod conditional_vault { use super::*; - pub fn initialize_conditional_vault( - ctx: Context, - args: InitializeConditionalVaultArgs, + pub fn initialize_question( + ctx: Context, + args: InitializeQuestionArgs, ) -> Result<()> { - InitializeConditionalVault::handle(ctx, args) + InitializeQuestion::handle(ctx, args) } - #[access_control(ctx.accounts.validate())] - pub fn add_metadata_to_conditional_tokens( - ctx: Context, - args: AddMetadataToConditionalTokensArgs, + pub fn resolve_question( + ctx: Context, + args: ResolveQuestionArgs, ) -> Result<()> { - AddMetadataToConditionalTokens::handle(ctx, args) + ResolveQuestion::handle(ctx, args) } - #[access_control(ctx.accounts.validate())] - pub fn settle_conditional_vault( - ctx: Context, - new_status: VaultStatus, + pub fn initialize_conditional_vault<'c: 'info, 'info>( + ctx: Context<'_, '_, 'c, 'info, InitializeConditionalVault<'info>>, + ) -> Result<()> { + InitializeConditionalVault::handle(ctx) + } + + pub fn split_tokens<'c: 'info, 'info>( + ctx: Context<'_, '_, 'c, 'info, InteractWithVault<'info>>, + amount: u64, ) -> Result<()> { - SettleConditionalVault::handle(ctx, new_status) + InteractWithVault::handle_split_tokens(ctx, amount) } - #[access_control(ctx.accounts.validate_merge_conditional_tokens())] - pub fn merge_conditional_tokens_for_underlying_tokens( - ctx: Context, + pub fn merge_tokens<'c: 'info, 'info>( + ctx: Context<'_, '_, 'c, 'info, InteractWithVault<'info>>, amount: u64, ) -> Result<()> { - InteractWithVault::handle_merge_conditional_tokens(ctx, amount) + InteractWithVault::handle_merge_tokens(ctx, amount) } - pub fn mint_conditional_tokens(ctx: Context, amount: u64) -> Result<()> { - InteractWithVault::handle_mint_conditional_tokens(ctx, amount) + #[access_control(ctx.accounts.validate_redeem_tokens())] + pub fn redeem_tokens<'c: 'info, 'info>( + ctx: Context<'_, '_, 'c, 'info, InteractWithVault<'info>>, + ) -> Result<()> { + InteractWithVault::handle_redeem_tokens(ctx) } - #[access_control(ctx.accounts.validate_redeem_conditional_tokens())] - pub fn redeem_conditional_tokens_for_underlying_tokens( - ctx: Context, + #[access_control(ctx.accounts.validate())] + pub fn add_metadata_to_conditional_tokens( + ctx: Context, + args: AddMetadataToConditionalTokensArgs, ) -> Result<()> { - InteractWithVault::handle_redeem_conditional_tokens(ctx) + AddMetadataToConditionalTokens::handle(ctx, args) } } diff --git a/programs/conditional_vault/src/state/conditional_vault.rs b/programs/conditional_vault/src/state/conditional_vault.rs index 9637885c..994c171d 100644 --- a/programs/conditional_vault/src/state/conditional_vault.rs +++ b/programs/conditional_vault/src/state/conditional_vault.rs @@ -9,27 +9,60 @@ pub enum VaultStatus { #[account] pub struct ConditionalVault { - pub status: VaultStatus, - /// The account that can either finalize the vault to make conditional tokens - /// redeemable for underlying tokens or revert the vault to make deposit - /// slips redeemable for underlying tokens. - pub settlement_authority: Pubkey, - /// The mint of the tokens that are deposited into the vault. + pub question: Pubkey, pub underlying_token_mint: Pubkey, - /// The vault's storage account for deposited funds. pub underlying_token_account: Pubkey, - pub conditional_on_finalize_token_mint: Pubkey, - pub conditional_on_revert_token_mint: Pubkey, + pub conditional_token_mints: Vec, pub pda_bump: u8, pub decimals: u8, } +impl ConditionalVault { + /// Checks that the vault's assets are always greater than its potential + /// liabilities. Should be called anytime you mint or burn conditional + /// tokens. + /// + /// `conditional_token_supplies` should be in the same order as + /// `vault.conditional_token_mints`. + pub fn invariant( + &self, + question: &Question, + conditional_token_supplies: Vec, + vault_underlying_balance: u64, + ) -> Result<()> { + // if the question isn't resolved, the vault should have more underlying + // tokens than ANY conditional token mint's supply + + // if the question is resolved, the vault should have more underlying + // tokens than the sum of the conditional token mint's supplies multiplied + // by their respective payouts + + let max_possible_liability = if !question.is_resolved() { + // safe because conditional_token_supplies is non-empty + *conditional_token_supplies.iter().max().unwrap() + } else { + conditional_token_supplies + .iter() + .enumerate() + .map(|(i, supply)| { + *supply * question.payout_numerators[i] as u64 + / question.payout_denominator as u64 + }) + .sum::() + }; + + require_gte!(vault_underlying_balance, max_possible_liability, VaultError::AssertFailed); + + Ok(()) + } +} + #[macro_export] macro_rules! generate_vault_seeds { ($vault:expr) => {{ &[ b"conditional_vault", - $vault.settlement_authority.as_ref(), + $vault.question.as_ref(), $vault.underlying_token_mint.as_ref(), &[$vault.pda_bump], ] diff --git a/programs/conditional_vault/src/state/mod.rs b/programs/conditional_vault/src/state/mod.rs index 49d3a06b..33af445d 100644 --- a/programs/conditional_vault/src/state/mod.rs +++ b/programs/conditional_vault/src/state/mod.rs @@ -1,5 +1,7 @@ use super::*; pub mod conditional_vault; +pub mod question; pub use conditional_vault::*; +pub use question::*; diff --git a/programs/conditional_vault/src/state/question.rs b/programs/conditional_vault/src/state/question.rs new file mode 100644 index 00000000..c5d68173 --- /dev/null +++ b/programs/conditional_vault/src/state/question.rs @@ -0,0 +1,39 @@ +use super::*; + +/// Questions represent statements about future events. +/// +/// These statements include: +/// - "Will this proposal pass?" +/// - "Who, if anyone, will be hired?" +/// - "How effective will the grant committee deem this grant?" +/// +/// Questions have 2 or more possible outcomes. For a question like "will this +/// proposal pass," the outcomes are "yes" and "no." For a question like "who +/// will be hired," the outcomes could be "Alice," "Bob," and "neither." +/// +/// Outcomes resolve to a number between 0 and 1. Binary questions like "will +/// this proposal pass" have outcomes that resolve to exactly 0 or 1. You can +/// also have questions with scalar outcomes. For example, the question "how +/// effective will the grant committee deem this grant" could have two outcomes: +/// "ineffective" and "effective." If the grant committee deems the grant 70% +/// effective, the "effective" outcome would resolve to 0.7 and the "ineffective" +/// outcome would resolve to 0.3. +/// +/// Once resolved, the sum of all outcome resolutions is exactly 1. +#[account] +pub struct Question { + pub question_id: [u8; 32], + pub oracle: Pubkey, + pub payout_numerators: Vec, + pub payout_denominator: u32, +} + +impl Question { + pub fn num_outcomes(&self) -> usize { + self.payout_numerators.len() + } + + pub fn is_resolved(&self) -> bool { + self.payout_denominator != 0 + } +} diff --git a/programs/optimistic_timelock/src/lib.rs b/programs/optimistic_timelock/src/lib.rs index 2bfc1c28..a068207a 100644 --- a/programs/optimistic_timelock/src/lib.rs +++ b/programs/optimistic_timelock/src/lib.rs @@ -38,7 +38,11 @@ impl Timelock { pub fn check_authority(&self, authority: Pubkey) -> Result { if authority == self.authority { Ok(AuthorityType::TimelockAuthority) - } else if self.optimistic_proposers.iter().any(|proposer| proposer.pubkey == authority) { + } else if self + .optimistic_proposers + .iter() + .any(|proposer| proposer.pubkey == authority) + { Ok(AuthorityType::OptimisticProposer) } else { Err(TimelockError::NoAuthority.into()) @@ -136,7 +140,10 @@ pub mod optimistic_timelock { Ok(()) } - pub fn set_optimistic_proposer_cooldown_slots(ctx: Context, cooldown_slots: u64) -> Result<()> { + pub fn set_optimistic_proposer_cooldown_slots( + ctx: Context, + cooldown_slots: u64, + ) -> Result<()> { let timelock = &mut ctx.accounts.timelock; timelock.optimistic_proposer_cooldown_slots = cooldown_slots; @@ -148,7 +155,11 @@ pub mod optimistic_timelock { let timelock = &mut ctx.accounts.timelock; // idempotent - if timelock.optimistic_proposers.iter().any(|enq| enq.pubkey == enqueuer) { + if timelock + .optimistic_proposers + .iter() + .any(|enq| enq.pubkey == enqueuer) + { return Ok(()); } @@ -160,7 +171,10 @@ pub mod optimistic_timelock { Ok(()) } - pub fn remove_optimistic_proposer(ctx: Context, optimistic_proposer: Pubkey) -> Result<()> { + pub fn remove_optimistic_proposer( + ctx: Context, + optimistic_proposer: Pubkey, + ) -> Result<()> { let timelock = &mut ctx.accounts.timelock; let index = timelock @@ -455,7 +469,9 @@ pub enum TimelockError { CannotExecuteTransactions, #[msg("The signer is neither the timelock authority nor an optimistic proposer")] NoAuthority, - #[msg("Optimistic proposers can't cancel transaction batches enqueued by the timelock authority")] + #[msg( + "Optimistic proposers can't cancel transaction batches enqueued by the timelock authority" + )] InsufficientPermissions, #[msg("This optimistic proposer is still in its cooldown period")] OptimisticProposerCooldown, diff --git a/test.sh b/run.sh similarity index 71% rename from test.sh rename to run.sh index c7188e9f..325dea79 100755 --- a/test.sh +++ b/run.sh @@ -1,7 +1,25 @@ #!/bin/sh +build() { + find programs | entr -sc 'anchor build' +} + test() { - find programs tests sdk | entr -sc '(cd sdk && yarn build) && RUST_LOG= anchor test' + find programs tests sdk | entr -sc 'anchor build && (cd sdk && yarn build) && RUST_LOG= anchor test --skip-build' +} + +build_vault() { + find programs | entr -sc 'anchor build -p conditional_vault' +} + +test_vault() { + # anchor doesn't let you past test files, so we do this weird thing where we + # modify the Anchor.toml and then put it back + #sed -i '2s/\(\(\S\+\s\+\)\{9\}\)\S\+/\1tests\/conditionalVault.ts"/' Anchor.toml + #sleep 10 && sed -i '2s/\(\(\S\+\s\+\)\{9\}\)\S\+/\1tests\/*.ts"/' Anchor.toml & + # find programs tests sdk | entr -sc \ + # "anchor build -p conditional_vault && (cd sdk && yarn build) && sed -i '2s/\(\(\S\+\s\+\)\{10\}\)\S\+/\1tests\/conditionalVault\/*.ts\"/' Anchor.toml && (sleep 3 && sed -i '2s/\(\(\S\+\s\+\)\{10\}\)\S\+/\1tests\/\**\/*.ts\"/' Anchor.toml) & RUST_LOG= anchor test --skip-build" + find programs tests sdk | entr -sc 'anchor build -p conditional_vault && (cd sdk && yarn build) && RUST_LOG= anchor test --skip-build' } test_no_build() { @@ -46,10 +64,6 @@ test_amm_logs() { find programs tests | entr -csr 'anchor build -p amm && yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/amm.ts' } -# requires solana-test-validator to be running in the background -bankrun_vault() { - (find programs && find tests) | entr -csr 'anchor build -p conditional_vault && RUST_LOG= yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/conditionalVault.ts' -} bankrun_migrator() { (find programs && find tests) | entr -csr 'anchor build -p autocrat_migrator && RUST_LOG= yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/migrator.ts' @@ -68,7 +82,10 @@ bankrun_logs() { } case "$1" in + build) build ;; test) test ;; + vault) test_vault ;; + build_vault) build_vault ;; test_no_build) test_no_build ;; build_verifiable) build_verifiable "$2" ;; deploy) deploy "$2" "$3" ;; @@ -83,4 +100,4 @@ case "$1" in bankrun_vault_logs) bankrun_vault_logs ;; bankrun_logs) bankrun_logs ;; *) echo "Unknown command: $1" ;; -esac \ No newline at end of file +esac diff --git a/scripts/mergeTokens.ts b/scripts/mergeTokens.ts index 1a74347e..8d257e8c 100644 --- a/scripts/mergeTokens.ts +++ b/scripts/mergeTokens.ts @@ -55,14 +55,39 @@ async function main() { DAO ); - const basePassBalance = (await token.getOrCreateAssociatedTokenAccount(provider.connection, payer, passBaseMint, payer.publicKey)).amount; - const quotePassBalance = (await token.getOrCreateAssociatedTokenAccount(provider.connection, payer, passQuoteMint, payer.publicKey)).amount; + const basePassBalance = ( + await token.getOrCreateAssociatedTokenAccount( + provider.connection, + payer, + passBaseMint, + payer.publicKey + ) + ).amount; + const quotePassBalance = ( + await token.getOrCreateAssociatedTokenAccount( + provider.connection, + payer, + passQuoteMint, + payer.publicKey + ) + ).amount; - await vaultClient.mergeConditionalTokensIx(baseVault, storedDao.tokenMint, new BN(basePassBalance.toString())) + await vaultClient + .mergeConditionalTokensIx( + baseVault, + storedDao.tokenMint, + new BN(basePassBalance.toString()) + ) .preInstructions([ - ComputeBudgetProgram.setComputeUnitLimit({ units: 150_000 }), - ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 100 }), - await vaultClient.mergeConditionalTokensIx(quoteVault, storedDao.usdcMint, new BN(quotePassBalance.toString())).instruction(), + ComputeBudgetProgram.setComputeUnitLimit({ units: 150_000 }), + ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 100 }), + await vaultClient + .mergeConditionalTokensIx( + quoteVault, + storedDao.usdcMint, + new BN(quotePassBalance.toString()) + ) + .instruction(), ]) .rpc(); } diff --git a/sdk/package.json b/sdk/package.json index bcb7122f..f74e86e4 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,18 +1,26 @@ { "name": "@metadaoproject/futarchy", - "version": "0.3.0-alpha.9", + "version": "0.4.0-alpha.1", + "type": "module", "main": "dist/index.js", + "module": "dist/index.js", "types": "dist/index.d.ts", "files": [ "/dist" ], + "exports": { + ".": "./dist/index.js", + "./v0.3": "./dist/v0.3/index.js", + "./v0.4": "./dist/v0.4/index.js" + }, "scripts": { "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check", - "build": "rm -rf ./dist && cp ../target/types/* ./src/types && yarn lint:fix && yarn tsc" + "build": "rm -rf ./dist && cp ../target/types/* ./src/v0.4/types && yarn lint:fix && yarn tsc" }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", + "@noble/hashes": "^1.4.0", "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.74.0", "bn.js": "^5.2.1", @@ -20,16 +28,15 @@ "esbuild": "^0.17.15" }, "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "prettier": "^2.6.2", "solana-bankrun": "^0.2.0", "spl-token-bankrun": "0.2.3", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - }, - "packageManager": "yarn@3.3.1" + "ts-mocha": "^10.0.0", + "typescript": "^4.9.5" + } } diff --git a/sdk/src/InstructionHandler.ts b/sdk/src/InstructionHandler.ts deleted file mode 100644 index 243d07bf..00000000 --- a/sdk/src/InstructionHandler.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { - AddressLookupTableAccount, - Blockhash, - ConfirmOptions, - Keypair, - Signer, - Transaction, - TransactionInstruction, - TransactionMessage, - VersionedTransaction, -} from "@solana/web3.js"; -import { BanksClient } from "solana-bankrun"; -import { addComputeUnits, addPriorityFee } from "./utils"; -import { AmmClient } from "./AmmClient"; -import { AnchorProvider, Program } from "@coral-xyz/anchor"; - -export type SignerOrKeypair = Signer | Keypair; - -interface Client { - provider: AnchorProvider; - program: ProgramType; - luts: AddressLookupTableAccount[]; -} - -export class InstructionHandler< - ProgramType, - Type extends Client = Client -> { - public instructions: TransactionInstruction[]; - public signers: Set; - public client: Type; - - public computeUnits = 200_000; - public microLamportsPerComputeUnit = 0; - - public preInstructions: TransactionInstruction[]; - public postInstructions: TransactionInstruction[]; - - constructor( - instructions: TransactionInstruction[], - signers: SignerOrKeypair[], - client: Type - ) { - this.instructions = instructions; - - this.signers = new Set(); - signers.forEach((s) => this.signers.add(s)); - - this.client = client; - - this.preInstructions = []; - this.postInstructions = []; - } - - addPreInstructions( - instructions: TransactionInstruction[], - signers: SignerOrKeypair[] = [] - ): InstructionHandler { - this.preInstructions = [...instructions, ...this.preInstructions]; - signers.forEach((s) => this.signers.add(s)); - return this; - } - - addPostInstructions( - instructions: TransactionInstruction[], - signers: SignerOrKeypair[] = [] - ): InstructionHandler { - this.postInstructions = [...instructions, ...this.postInstructions]; - signers.forEach((s) => this.signers.add(s)); - return this; - } - - async getVersionedTransaction(blockhash: Blockhash) { - this.instructions = [ - ...this.preInstructions, - ...this.instructions, - ...this.postInstructions, - ]; - - if (this.microLamportsPerComputeUnit != 0) { - this.instructions = [ - addPriorityFee(this.microLamportsPerComputeUnit), - ...this.instructions, - ]; - } - - if (this.computeUnits != 200_000) { - this.instructions = [ - addComputeUnits(this.computeUnits), - ...this.instructions, - ]; - } - - const message = new TransactionMessage({ - payerKey: this.client.provider.wallet.publicKey, - recentBlockhash: blockhash, - instructions: this.instructions, - }).compileToV0Message(this.client.luts); - - let tx = new VersionedTransaction(message); - - let signersArray = Array.from(this.signers); - if (this.signers.size) { - tx.sign(signersArray); - } - - return tx; - } - - setComputeUnits(computeUnits: number): InstructionHandler { - this.computeUnits = computeUnits; - return this; - } - - setPriorityFee( - microLamportsPerComputeUnit: number - ): InstructionHandler { - this.microLamportsPerComputeUnit = microLamportsPerComputeUnit; - return this; - } - - async bankrun(banksClient: BanksClient) { - try { - let [blockhash] = (await banksClient.getLatestBlockhash())!; - const tx = await this.getVersionedTransaction(blockhash); - return await banksClient.processTransaction(tx); - } catch (e) { - console.log(e); - throw e; - } - } - - async rpc(opts: ConfirmOptions = { skipPreflight: true }) { - try { - let blockhash = ( - await this.client.provider.connection.getLatestBlockhash() - ).blockhash; - let tx = await this.getVersionedTransaction(blockhash); - tx = await this.client.provider.wallet.signTransaction(tx); - return await this.client.provider.connection.sendRawTransaction( - tx.serialize(), - opts - ); - } catch (e) { - console.log(e); - throw e; - } - } -} diff --git a/sdk/src/index.ts b/sdk/src/index.ts index 20730eed..bfa636c7 100644 --- a/sdk/src/index.ts +++ b/sdk/src/index.ts @@ -1,6 +1 @@ -export * from "./types"; -export * from "./utils"; -export * from "./constants"; -export * from "./AmmClient"; -export * from "./AutocratClient"; -export * from "./ConditionalVaultClient"; +export { sha256 } from "@noble/hashes/sha256"; diff --git a/sdk/src/AmmClient.ts b/sdk/src/v0.3/AmmClient.ts similarity index 100% rename from sdk/src/AmmClient.ts rename to sdk/src/v0.3/AmmClient.ts diff --git a/sdk/src/AutocratClient.ts b/sdk/src/v0.3/AutocratClient.ts similarity index 100% rename from sdk/src/AutocratClient.ts rename to sdk/src/v0.3/AutocratClient.ts diff --git a/sdk/src/ConditionalVaultClient.ts b/sdk/src/v0.3/ConditionalVaultClient.ts similarity index 100% rename from sdk/src/ConditionalVaultClient.ts rename to sdk/src/v0.3/ConditionalVaultClient.ts diff --git a/sdk/src/constants.ts b/sdk/src/v0.3/constants.ts similarity index 100% rename from sdk/src/constants.ts rename to sdk/src/v0.3/constants.ts diff --git a/sdk/src/v0.3/index.ts b/sdk/src/v0.3/index.ts new file mode 100644 index 00000000..20730eed --- /dev/null +++ b/sdk/src/v0.3/index.ts @@ -0,0 +1,6 @@ +export * from "./types"; +export * from "./utils"; +export * from "./constants"; +export * from "./AmmClient"; +export * from "./AutocratClient"; +export * from "./ConditionalVaultClient"; diff --git a/sdk/src/types/amm.ts b/sdk/src/v0.3/types/amm.ts similarity index 100% rename from sdk/src/types/amm.ts rename to sdk/src/v0.3/types/amm.ts diff --git a/sdk/src/types/autocrat.ts b/sdk/src/v0.3/types/autocrat.ts similarity index 100% rename from sdk/src/types/autocrat.ts rename to sdk/src/v0.3/types/autocrat.ts diff --git a/sdk/src/types/autocrat_migrator.ts b/sdk/src/v0.3/types/autocrat_migrator.ts similarity index 100% rename from sdk/src/types/autocrat_migrator.ts rename to sdk/src/v0.3/types/autocrat_migrator.ts diff --git a/sdk/src/types/conditional_vault.ts b/sdk/src/v0.3/types/conditional_vault.ts similarity index 100% rename from sdk/src/types/conditional_vault.ts rename to sdk/src/v0.3/types/conditional_vault.ts diff --git a/sdk/src/types/index.ts b/sdk/src/v0.3/types/index.ts similarity index 100% rename from sdk/src/types/index.ts rename to sdk/src/v0.3/types/index.ts diff --git a/sdk/src/types/optimistic_timelock.ts b/sdk/src/v0.3/types/optimistic_timelock.ts similarity index 100% rename from sdk/src/types/optimistic_timelock.ts rename to sdk/src/v0.3/types/optimistic_timelock.ts diff --git a/sdk/src/types/utils.ts b/sdk/src/v0.3/types/utils.ts similarity index 100% rename from sdk/src/types/utils.ts rename to sdk/src/v0.3/types/utils.ts diff --git a/sdk/src/utils/cu.ts b/sdk/src/v0.3/utils/cu.ts similarity index 100% rename from sdk/src/utils/cu.ts rename to sdk/src/v0.3/utils/cu.ts diff --git a/sdk/src/utils/filters.ts b/sdk/src/v0.3/utils/filters.ts similarity index 100% rename from sdk/src/utils/filters.ts rename to sdk/src/v0.3/utils/filters.ts diff --git a/sdk/src/utils/index.ts b/sdk/src/v0.3/utils/index.ts similarity index 100% rename from sdk/src/utils/index.ts rename to sdk/src/v0.3/utils/index.ts diff --git a/sdk/src/utils/instruction.ts b/sdk/src/v0.3/utils/instruction.ts similarity index 100% rename from sdk/src/utils/instruction.ts rename to sdk/src/v0.3/utils/instruction.ts diff --git a/sdk/src/utils/metadata.ts b/sdk/src/v0.3/utils/metadata.ts similarity index 100% rename from sdk/src/utils/metadata.ts rename to sdk/src/v0.3/utils/metadata.ts diff --git a/sdk/src/utils/pda.ts b/sdk/src/v0.3/utils/pda.ts similarity index 100% rename from sdk/src/utils/pda.ts rename to sdk/src/v0.3/utils/pda.ts diff --git a/sdk/src/utils/priceMath.ts b/sdk/src/v0.3/utils/priceMath.ts similarity index 100% rename from sdk/src/utils/priceMath.ts rename to sdk/src/v0.3/utils/priceMath.ts diff --git a/sdk/src/v0.4/AmmClient.ts b/sdk/src/v0.4/AmmClient.ts new file mode 100644 index 00000000..c6db19ec --- /dev/null +++ b/sdk/src/v0.4/AmmClient.ts @@ -0,0 +1,526 @@ +import { AnchorProvider, IdlTypes, Program } from "@coral-xyz/anchor"; +import { AddressLookupTableAccount, Keypair, PublicKey } from "@solana/web3.js"; + +import { Amm as AmmIDLType, IDL as AmmIDL } from "./types/amm.js"; + +import BN from "bn.js"; +import { AMM_PROGRAM_ID } from "./constants.js"; +import { AmmAccount, LowercaseKeys } from "./types/index.js"; +import { getAmmLpMintAddr, getAmmAddr } from "./utils/pda.js"; +// import { MethodsBuilder } from "@coral-xyz/anchor/dist/cjs/program/namespace/methods"; +import { + MintLayout, + unpackMint, + getAssociatedTokenAddressSync, + createAssociatedTokenAccountIdempotentInstruction, +} from "@solana/spl-token"; +import { PriceMath } from "./utils/priceMath.js"; + +export type SwapType = LowercaseKeys["SwapType"]>; + +export type CreateAmmClientParams = { + provider: AnchorProvider; + ammProgramId?: PublicKey; +}; + +export type AddLiquiditySimulation = { + baseAmount: BN; + quoteAmount: BN; + expectedLpTokens: BN; + minLpTokens?: BN; + maxBaseAmount?: BN; +}; + +export type SwapSimulation = { + expectedOut: BN; + newBaseReserves: BN; + newQuoteReserves: BN; + minExpectedOut?: BN; +}; + +export type RemoveLiquiditySimulation = { + expectedBaseOut: BN; + expectedQuoteOut: BN; + minBaseOut?: BN; + minQuoteOut?: BN; +}; + +export class AmmClient { + public readonly provider: AnchorProvider; + public readonly program: Program; + public readonly luts: AddressLookupTableAccount[]; + + constructor( + provider: AnchorProvider, + ammProgramId: PublicKey, + luts: AddressLookupTableAccount[] + ) { + this.provider = provider; + this.program = new Program(AmmIDL, ammProgramId, provider); + this.luts = luts; + } + + public static createClient( + createAutocratClientParams: CreateAmmClientParams + ): AmmClient { + let { provider, ammProgramId: programId } = createAutocratClientParams; + + const luts: AddressLookupTableAccount[] = []; + + return new AmmClient(provider, programId || AMM_PROGRAM_ID, luts); + } + + getProgramId(): PublicKey { + return this.program.programId; + } + + async createAmm( + proposal: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + twapInitialObservation: number, + twapMaxObservationChangePerUpdate?: number + ): Promise { + if (!twapMaxObservationChangePerUpdate) { + twapMaxObservationChangePerUpdate = twapInitialObservation * 0.02; + } + let [amm] = getAmmAddr(this.getProgramId(), baseMint, quoteMint); + + let baseDecimals = unpackMint( + baseMint, + await this.provider.connection.getAccountInfo(baseMint) + ).decimals; + let quoteDecimals = unpackMint( + quoteMint, + await this.provider.connection.getAccountInfo(quoteMint) + ).decimals; + + let [twapFirstObservationScaled, twapMaxObservationChangePerUpdateScaled] = + PriceMath.getAmmPrices( + baseDecimals, + quoteDecimals, + twapInitialObservation, + twapMaxObservationChangePerUpdate + ); + + await this.createAmmIx( + baseMint, + quoteMint, + twapFirstObservationScaled, + twapMaxObservationChangePerUpdateScaled + ).rpc(); + + return amm; + } + + // both twap values need to be scaled beforehand + createAmmIx( + baseMint: PublicKey, + quoteMint: PublicKey, + twapInitialObservation: BN, + twapMaxObservationChangePerUpdate: BN + ) { + let [amm] = getAmmAddr(this.getProgramId(), baseMint, quoteMint); + let [lpMint] = getAmmLpMintAddr(this.getProgramId(), amm); + + let vaultAtaBase = getAssociatedTokenAddressSync(baseMint, amm, true); + let vaultAtaQuote = getAssociatedTokenAddressSync(quoteMint, amm, true); + + return this.program.methods + .createAmm({ + twapInitialObservation, + twapMaxObservationChangePerUpdate, + }) + .accounts({ + user: this.provider.publicKey, + amm, + lpMint, + baseMint, + quoteMint, + vaultAtaBase, + vaultAtaQuote, + }); + } + + async addLiquidity( + amm: PublicKey, + quoteAmount?: number, + baseAmount?: number + ) { + let storedAmm = await this.getAmm(amm); + + let lpMintSupply = unpackMint( + storedAmm.lpMint, + await this.provider.connection.getAccountInfo(storedAmm.lpMint) + ).supply; + + let quoteAmountCasted: BN | undefined; + let baseAmountCasted: BN | undefined; + + if (quoteAmount != undefined) { + let quoteDecimals = unpackMint( + storedAmm.quoteMint, + await this.provider.connection.getAccountInfo(storedAmm.quoteMint) + ).decimals; + quoteAmountCasted = new BN(quoteAmount).mul( + new BN(10).pow(new BN(quoteDecimals)) + ); + } + + if (baseAmount != undefined) { + let baseDecimals = unpackMint( + storedAmm.baseMint, + await this.provider.connection.getAccountInfo(storedAmm.baseMint) + ).decimals; + baseAmountCasted = new BN(baseAmount).mul( + new BN(10).pow(new BN(baseDecimals)) + ); + } + + if (lpMintSupply == 0n) { + if (quoteAmount == undefined || baseAmount == undefined) { + throw new Error( + "No pool created yet, you need to specify both base and quote" + ); + } + + // console.log(quoteAmountCasted?.toString()); + // console.log(baseAmountCasted?.toString()) + + return await this.addLiquidityIx( + amm, + storedAmm.baseMint, + storedAmm.quoteMint, + quoteAmountCasted as BN, + baseAmountCasted as BN, + new BN(0) + ).rpc(); + } + + // quoteAmount == undefined ? undefined : new BN(quoteAmount); + // let baseAmountCasted: BN | undefined = + // baseAmount == undefined ? undefined : new BN(baseAmount); + + let sim = this.simulateAddLiquidity( + storedAmm.baseAmount, + storedAmm.quoteAmount, + Number(lpMintSupply), + baseAmountCasted, + quoteAmountCasted + ); + + await this.addLiquidityIx( + amm, + storedAmm.baseMint, + storedAmm.quoteMint, + sim.quoteAmount, + sim.baseAmount, + sim.expectedLpTokens + ).rpc(); + } + + addLiquidityIx( + amm: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + quoteAmount: BN, + maxBaseAmount: BN, + minLpTokens: BN, + user: PublicKey = this.provider.publicKey + ) { + const [lpMint] = getAmmLpMintAddr(this.program.programId, amm); + + const userLpAccount = getAssociatedTokenAddressSync(lpMint, user); + + return this.program.methods + .addLiquidity({ + quoteAmount, + maxBaseAmount, + minLpTokens, + }) + .accounts({ + user, + amm, + lpMint, + userLpAccount, + userBaseAccount: getAssociatedTokenAddressSync(baseMint, user), + userQuoteAccount: getAssociatedTokenAddressSync(quoteMint, user), + vaultAtaBase: getAssociatedTokenAddressSync(baseMint, amm, true), + vaultAtaQuote: getAssociatedTokenAddressSync(quoteMint, amm, true), + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + userLpAccount, + this.provider.publicKey, + lpMint + ), + ]); + } + + removeLiquidityIx( + ammAddr: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + lpTokensToBurn: BN, + minBaseAmount: BN, + minQuoteAmount: BN + ) { + const [lpMint] = getAmmLpMintAddr(this.program.programId, ammAddr); + + return this.program.methods + .removeLiquidity({ + lpTokensToBurn, + minBaseAmount, + minQuoteAmount, + }) + .accounts({ + user: this.provider.publicKey, + amm: ammAddr, + lpMint, + userLpAccount: getAssociatedTokenAddressSync( + lpMint, + this.provider.publicKey + ), + userBaseAccount: getAssociatedTokenAddressSync( + baseMint, + this.provider.publicKey + ), + userQuoteAccount: getAssociatedTokenAddressSync( + quoteMint, + this.provider.publicKey + ), + vaultAtaBase: getAssociatedTokenAddressSync(baseMint, ammAddr, true), + vaultAtaQuote: getAssociatedTokenAddressSync(quoteMint, ammAddr, true), + }); + } + + async swap( + amm: PublicKey, + swapType: SwapType, + inputAmount: number, + outputAmountMin: number + ) { + const storedAmm = await this.getAmm(amm); + + let quoteDecimals = await this.getDecimals(storedAmm.quoteMint); + let baseDecimals = await this.getDecimals(storedAmm.baseMint); + + let inputAmountScaled: BN; + let outputAmountMinScaled: BN; + if (swapType.buy) { + inputAmountScaled = PriceMath.scale(inputAmount, quoteDecimals); + outputAmountMinScaled = PriceMath.scale(outputAmountMin, baseDecimals); + } else { + inputAmountScaled = PriceMath.scale(inputAmount, baseDecimals); + outputAmountMinScaled = PriceMath.scale(outputAmountMin, quoteDecimals); + } + + return await this.swapIx( + amm, + storedAmm.baseMint, + storedAmm.quoteMint, + swapType, + inputAmountScaled, + outputAmountMinScaled + ).rpc(); + } + + swapIx( + amm: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + swapType: SwapType, + inputAmount: BN, + outputAmountMin: BN + ) { + const receivingToken = swapType.buy ? baseMint : quoteMint; + + return this.program.methods + .swap({ + swapType, + inputAmount, + outputAmountMin, + }) + .accounts({ + user: this.provider.publicKey, + amm, + userBaseAccount: getAssociatedTokenAddressSync( + baseMint, + this.provider.publicKey, + true + ), + userQuoteAccount: getAssociatedTokenAddressSync( + quoteMint, + this.provider.publicKey, + true + ), + vaultAtaBase: getAssociatedTokenAddressSync(baseMint, amm, true), + vaultAtaQuote: getAssociatedTokenAddressSync(quoteMint, amm, true), + }) + .preInstructions([ + // create the receiving token account if it doesn't exist + createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + getAssociatedTokenAddressSync( + receivingToken, + this.provider.publicKey + ), + this.provider.publicKey, + receivingToken + ), + ]); + } + + async crankThatTwap(amm: PublicKey) { + return this.crankThatTwapIx(amm).rpc(); + } + + crankThatTwapIx(amm: PublicKey) { + return this.program.methods.crankThatTwap().accounts({ + amm, + }); + } + + // getter functions + + // async getLTWAP(ammAddr: PublicKey): Promise { + // const amm = await this.program.account.amm.fetch(ammAddr); + // return amm.twapLastObservationUq64X32 + // .div(new BN(2).pow(new BN(32))) + // .toNumber(); + // } + + async getAmm(amm: PublicKey): Promise { + return await this.program.account.amm.fetch(amm); + } + + getTwap(amm: AmmAccount): BN { + return amm.oracle.aggregator.div( + amm.oracle.lastUpdatedSlot.sub(amm.createdAtSlot) + ); + } + + simulateAddLiquidity( + baseReserves: BN, + quoteReserves: BN, + lpMintSupply: number, + baseAmount?: BN, + quoteAmount?: BN, + slippageBps?: BN + ): AddLiquiditySimulation { + if (lpMintSupply == 0) { + throw new Error( + "This AMM doesn't have existing liquidity so we can't fill in the blanks" + ); + } + + if (baseAmount == undefined && quoteAmount == undefined) { + throw new Error("Must specify either a base amount or a quote amount"); + } + + let expectedLpTokens: BN; + + if (quoteAmount == undefined) { + quoteAmount = baseAmount?.mul(quoteReserves).div(baseReserves); + } + baseAmount = quoteAmount?.mul(baseReserves).div(quoteReserves).addn(1); + + expectedLpTokens = quoteAmount + ?.mul(new BN(lpMintSupply)) + .div(quoteReserves) as BN; + + let minLpTokens, maxBaseAmount; + if (slippageBps) { + minLpTokens = PriceMath.subtractSlippage(expectedLpTokens, slippageBps); + maxBaseAmount = PriceMath.addSlippage(baseAmount as BN, slippageBps); + } + + return { + quoteAmount: quoteAmount as BN, + baseAmount: baseAmount as BN, + expectedLpTokens, + minLpTokens, + maxBaseAmount, + }; + } + + simulateSwap( + inputAmount: BN, + swapType: SwapType, + baseReserves: BN, + quoteReserves: BN, + slippageBps?: BN + ): SwapSimulation { + if (baseReserves.eqn(0) || quoteReserves.eqn(0)) { + throw new Error("reserves must be non-zero"); + } + + let inputReserves, outputReserves: BN; + if (swapType.buy) { + inputReserves = quoteReserves; + outputReserves = baseReserves; + } else { + inputReserves = baseReserves; + outputReserves = quoteReserves; + } + + let inputAmountWithFee: BN = inputAmount.muln(990); + + let numerator: BN = inputAmountWithFee.mul(outputReserves); + let denominator: BN = inputReserves.muln(1000).add(inputAmountWithFee); + + let expectedOut = numerator.div(denominator); + let minExpectedOut; + if (slippageBps) { + minExpectedOut = PriceMath.subtractSlippage(expectedOut, slippageBps); + } + + let newBaseReserves, newQuoteReserves: BN; + if (swapType.buy) { + newBaseReserves = baseReserves.sub(expectedOut); + newQuoteReserves = quoteReserves.add(inputAmount); + } else { + newBaseReserves = baseReserves.add(inputAmount); + newQuoteReserves = quoteReserves.sub(expectedOut); + } + + return { + expectedOut, + newBaseReserves, + newQuoteReserves, + minExpectedOut, + }; + } + + simulateRemoveLiquidity( + lpTokensToBurn: BN, + baseReserves: BN, + quoteReserves: BN, + lpTotalSupply: BN, + slippageBps?: BN + ): RemoveLiquiditySimulation { + const expectedBaseOut = lpTokensToBurn.mul(baseReserves).div(lpTotalSupply); + const expectedQuoteOut = lpTokensToBurn + .mul(quoteReserves) + .div(lpTotalSupply); + + let minBaseOut, minQuoteOut; + if (slippageBps) { + minBaseOut = PriceMath.subtractSlippage(expectedBaseOut, slippageBps); + minQuoteOut = PriceMath.subtractSlippage(expectedQuoteOut, slippageBps); + } + + return { + expectedBaseOut, + expectedQuoteOut, + minBaseOut, + minQuoteOut, + }; + } + + async getDecimals(mint: PublicKey): Promise { + return unpackMint(mint, await this.provider.connection.getAccountInfo(mint)) + .decimals; + } +} diff --git a/sdk/src/v0.4/AutocratClient.ts b/sdk/src/v0.4/AutocratClient.ts new file mode 100644 index 00000000..eeef249e --- /dev/null +++ b/sdk/src/v0.4/AutocratClient.ts @@ -0,0 +1,769 @@ +import { AnchorProvider, IdlTypes, Program } from "@coral-xyz/anchor"; +import { + AccountMeta, + AddressLookupTableAccount, + ComputeBudgetProgram, + Connection, + Keypair, + PublicKey, + Transaction, + TransactionInstruction, +} from "@solana/web3.js"; +import { PriceMath } from "./utils/priceMath.js"; +import { ProposalInstruction, InitializeDaoParams } from "./types/index.js"; + +import { Autocrat, IDL as AutocratIDL } from "./types/autocrat.js"; +import { + ConditionalVault, + IDL as ConditionalVaultIDL, +} from "./types/conditional_vault.js"; + +import BN from "bn.js"; +import { + AMM_PROGRAM_ID, + AUTOCRAT_PROGRAM_ID, + CONDITIONAL_VAULT_PROGRAM_ID, + MAINNET_USDC, + USDC_DECIMALS, +} from "./constants.js"; +import { + DEFAULT_CU_PRICE, + InstructionUtils, + MaxCUs, + getAmmAddr, + getAmmLpMintAddr, + getConditionalTokenMintAddr, + getDaoTreasuryAddr, + getProposalAddr, + getQuestionAddr, + getVaultAddr, + getVaultFinalizeMintAddr, + getVaultRevertMintAddr, +} from "./utils/index.js"; +import { ConditionalVaultClient } from "./ConditionalVaultClient.js"; +import { AmmClient } from "./AmmClient.js"; +import { + createAssociatedTokenAccountIdempotentInstruction, + getAssociatedTokenAddressSync, + unpackMint, +} from "@solana/spl-token"; +import { sha256 } from "@noble/hashes/sha256"; +import { Dao, Proposal } from "./types/index.js"; + +export type CreateClientParams = { + provider: AnchorProvider; + autocratProgramId?: PublicKey; + conditionalVaultProgramId?: PublicKey; + ammProgramId?: PublicKey; +}; + +export type ProposalVaults = { + baseVault: PublicKey; + quoteVault: PublicKey; +}; + +export class AutocratClient { + public readonly provider: AnchorProvider; + public readonly autocrat: Program; + public readonly vaultClient: ConditionalVaultClient; + public readonly ammClient: AmmClient; + public readonly luts: AddressLookupTableAccount[]; + + constructor( + provider: AnchorProvider, + autocratProgramId: PublicKey, + conditionalVaultProgramId: PublicKey, + ammProgramId: PublicKey, + luts: AddressLookupTableAccount[] + ) { + this.provider = provider; + this.autocrat = new Program( + AutocratIDL, + autocratProgramId, + provider + ); + this.vaultClient = ConditionalVaultClient.createClient({ + provider, + conditionalVaultProgramId, + }); + this.ammClient = AmmClient.createClient({ provider, ammProgramId }); + this.luts = luts; + } + + public static createClient( + createAutocratClientParams: CreateClientParams + ): AutocratClient { + let { + provider, + autocratProgramId, + conditionalVaultProgramId, + ammProgramId, + } = createAutocratClientParams; + + const luts: AddressLookupTableAccount[] = []; + + return new AutocratClient( + provider, + autocratProgramId || AUTOCRAT_PROGRAM_ID, + conditionalVaultProgramId || CONDITIONAL_VAULT_PROGRAM_ID, + ammProgramId || AMM_PROGRAM_ID, + luts + ); + } + + async getProposal(proposal: PublicKey): Promise { + return this.autocrat.account.proposal.fetch(proposal); + } + + async getDao(dao: PublicKey): Promise { + return this.autocrat.account.dao.fetch(dao); + } + + getProposalPdas( + proposal: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + dao: PublicKey + ): { + question: PublicKey; + baseVault: PublicKey; + quoteVault: PublicKey; + passBaseMint: PublicKey; + passQuoteMint: PublicKey; + failBaseMint: PublicKey; + failQuoteMint: PublicKey; + passAmm: PublicKey; + failAmm: PublicKey; + passLp: PublicKey; + failLp: PublicKey; + } { + let vaultProgramId = this.vaultClient.vaultProgram.programId; + const [question] = getQuestionAddr( + vaultProgramId, + sha256(`Will ${proposal} pass?/FAIL/PASS`), + proposal, + 2 + ); + const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); + const [baseVault] = getVaultAddr( + this.vaultClient.vaultProgram.programId, + question, + baseMint + ); + const [quoteVault] = getVaultAddr( + this.vaultClient.vaultProgram.programId, + question, + quoteMint + ); + + const [failBaseMint] = getConditionalTokenMintAddr( + vaultProgramId, + baseVault, + 0 + ); + const [failQuoteMint] = getConditionalTokenMintAddr( + vaultProgramId, + quoteVault, + 0 + ); + + const [passBaseMint] = getConditionalTokenMintAddr( + vaultProgramId, + baseVault, + 1 + ); + const [passQuoteMint] = getConditionalTokenMintAddr( + vaultProgramId, + quoteVault, + 1 + ); + + const [passAmm] = getAmmAddr( + this.ammClient.program.programId, + passBaseMint, + passQuoteMint + ); + const [failAmm] = getAmmAddr( + this.ammClient.program.programId, + failBaseMint, + failQuoteMint + ); + + const [passLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + passAmm + ); + const [failLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + failAmm + ); + + return { + question, + baseVault, + quoteVault, + passBaseMint, + passQuoteMint, + failBaseMint, + failQuoteMint, + passAmm, + failAmm, + passLp, + failLp, + }; + } + + async initializeDao( + tokenMint: PublicKey, + tokenPriceUiAmount: number, + minBaseFutarchicLiquidity: number, + minQuoteFutarchicLiquidity: number, + usdcMint: PublicKey = MAINNET_USDC, + daoKeypair: Keypair = Keypair.generate() + ): Promise { + let tokenDecimals = unpackMint( + tokenMint, + await this.provider.connection.getAccountInfo(tokenMint) + ).decimals; + + let scaledPrice = PriceMath.getAmmPrice( + tokenPriceUiAmount, + tokenDecimals, + USDC_DECIMALS + ); + + console.log( + PriceMath.getHumanPrice(scaledPrice, tokenDecimals, USDC_DECIMALS) + ); + + await this.initializeDaoIx( + daoKeypair, + tokenMint, + { + twapInitialObservation: scaledPrice, + twapMaxObservationChangePerUpdate: scaledPrice.divn(50), + minQuoteFutarchicLiquidity: new BN(minQuoteFutarchicLiquidity).mul( + new BN(10).pow(new BN(USDC_DECIMALS)) + ), + minBaseFutarchicLiquidity: new BN(minBaseFutarchicLiquidity).mul( + new BN(10).pow(new BN(tokenDecimals)) + ), + passThresholdBps: null, + slotsPerProposal: null, + }, + usdcMint + ) + .postInstructions([ + ComputeBudgetProgram.setComputeUnitLimit({ + units: MaxCUs.initializeDao, + }), + ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: DEFAULT_CU_PRICE, + }), + ]) + .rpc({ maxRetries: 5 }); + + return daoKeypair.publicKey; + } + + initializeDaoIx( + daoKeypair: Keypair, + tokenMint: PublicKey, + params: InitializeDaoParams, + usdcMint: PublicKey = MAINNET_USDC + ) { + return this.autocrat.methods + .initializeDao(params) + .accounts({ + dao: daoKeypair.publicKey, + tokenMint, + usdcMint, + }) + .signers([daoKeypair]); + } + + async initializeProposal( + dao: PublicKey, + descriptionUrl: string, + instruction: ProposalInstruction, + baseTokensToLP: BN, + quoteTokensToLP: BN + ): Promise { + const storedDao = await this.getDao(dao); + + const nonce = new BN(Math.random() * 2 ** 50); + + let [proposal] = getProposalAddr( + this.autocrat.programId, + this.provider.publicKey, + nonce + ); + + await this.vaultClient.initializeQuestion( + sha256(`Will ${proposal} pass?/FAIL/PASS`), + proposal, + 2 + ); + + const { + baseVault, + quoteVault, + passAmm, + failAmm, + passBaseMint, + passQuoteMint, + failBaseMint, + failQuoteMint, + question, + } = this.getProposalPdas( + proposal, + storedDao.tokenMint, + storedDao.usdcMint, + dao + ); + + // it's important that these happen in a single atomic transaction + await this.vaultClient + .initializeVaultIx(question, storedDao.tokenMint, 2) + .postInstructions( + await InstructionUtils.getInstructions( + this.vaultClient.initializeVaultIx(question, storedDao.usdcMint, 2), + this.ammClient.createAmmIx( + passBaseMint, + passQuoteMint, + storedDao.twapInitialObservation, + storedDao.twapMaxObservationChangePerUpdate + ), + this.ammClient.createAmmIx( + failBaseMint, + failQuoteMint, + storedDao.twapInitialObservation, + storedDao.twapMaxObservationChangePerUpdate + ) + ) + ) + .rpc(); + + await this.vaultClient + .splitTokensIx( + question, + baseVault, + storedDao.tokenMint, + baseTokensToLP, + 2 + ) + .postInstructions( + await InstructionUtils.getInstructions( + this.vaultClient.splitTokensIx( + question, + quoteVault, + storedDao.usdcMint, + quoteTokensToLP, + 2 + ) + ) + ) + .rpc(); + + await this.ammClient + .addLiquidityIx( + passAmm, + passBaseMint, + passQuoteMint, + quoteTokensToLP, + baseTokensToLP, + new BN(0) + ) + .postInstructions( + await InstructionUtils.getInstructions( + this.ammClient.addLiquidityIx( + failAmm, + failBaseMint, + failQuoteMint, + quoteTokensToLP, + baseTokensToLP, + new BN(0) + ) + ) + ) + .rpc(); + + // this is how many original tokens are created + const lpTokens = quoteTokensToLP; + + await this.initializeProposalIx( + descriptionUrl, + instruction, + dao, + storedDao.tokenMint, + storedDao.usdcMint, + lpTokens, + lpTokens, + nonce, + question + ).rpc(); + + return proposal; + } + + // async createProposalTxAndPDAs( + // dao: PublicKey, + // descriptionUrl: string, + // instruction: ProposalInstruction, + // baseTokensToLP: BN, + // quoteTokensToLP: BN + // ): Promise< + // [ + // Transaction[], + // { + // proposalAcct: PublicKey; + // baseCondVaultAcct: PublicKey; + // quoteCondVaultAcct: PublicKey; + // passMarketAcct: PublicKey; + // failMarketAcct: PublicKey; + // } + // ] + // > { + // const storedDao = await this.getDao(dao); + + // const nonce = new BN(Math.random() * 2 ** 50); + + // let [proposal] = getProposalAddr( + // this.autocrat.programId, + // this.provider.publicKey, + // nonce + // ); + + // const { + // baseVault, + // quoteVault, + // passAmm, + // failAmm, + // passBaseMint, + // passQuoteMint, + // failBaseMint, + // failQuoteMint, + // } = this.getProposalPdas( + // proposal, + // storedDao.tokenMint, + // storedDao.usdcMint, + // dao + // ); + + // // it's important that these happen in a single atomic transaction + // const initVaultTx = await this.vaultClient + // .initializeVaultIx(proposal, storedDao.tokenMint) + // .postInstructions( + // await InstructionUtils.getInstructions( + // this.vaultClient.initializeVaultIx(proposal, storedDao.usdcMint), + // this.ammClient.createAmmIx( + // passBaseMint, + // passQuoteMint, + // storedDao.twapInitialObservation, + // storedDao.twapMaxObservationChangePerUpdate + // ), + // this.ammClient.createAmmIx( + // failBaseMint, + // failQuoteMint, + // storedDao.twapInitialObservation, + // storedDao.twapMaxObservationChangePerUpdate + // ) + // ) + // ) + // .transaction(); + + // const mintConditionalTokensTx = await this.vaultClient + // .mintConditionalTokensIx(baseVault, storedDao.tokenMint, baseTokensToLP) + // .postInstructions( + // await InstructionUtils.getInstructions( + // this.vaultClient.mintConditionalTokensIx( + // quoteVault, + // storedDao.usdcMint, + // quoteTokensToLP + // ) + // ) + // ) + // .transaction(); + + // const addLiquidityTx = await this.ammClient + // .addLiquidityIx( + // passAmm, + // passBaseMint, + // passQuoteMint, + // quoteTokensToLP, + // baseTokensToLP, + // new BN(0) + // ) + // .postInstructions( + // await InstructionUtils.getInstructions( + // this.ammClient.addLiquidityIx( + // failAmm, + // failBaseMint, + // failQuoteMint, + // quoteTokensToLP, + // baseTokensToLP, + // new BN(0) + // ) + // ) + // ) + // .transaction(); + + // // this is how many original tokens are created + // const lpTokens = quoteTokensToLP; + + // const initTx = await this.initializeProposalIx( + // descriptionUrl, + // instruction, + // dao, + // storedDao.tokenMint, + // storedDao.usdcMint, + // lpTokens, + // lpTokens, + // nonce, + // question + // ).transaction(); + + // return [ + // [initVaultTx, mintConditionalTokensTx, addLiquidityTx, initTx], + // { + // baseCondVaultAcct: baseVault, + // quoteCondVaultAcct: quoteVault, + // failMarketAcct: failAmm, + // passMarketAcct: passAmm, + // proposalAcct: proposal, + // }, + // ]; + // } + + initializeProposalIx( + descriptionUrl: string, + instruction: ProposalInstruction, + dao: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + passLpTokensToLock: BN, + failLpTokensToLock: BN, + nonce: BN, + question: PublicKey + ) { + let [proposal] = getProposalAddr( + this.autocrat.programId, + this.provider.publicKey, + nonce + ); + const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); + const { baseVault, quoteVault, passAmm, failAmm } = this.getProposalPdas( + proposal, + baseMint, + quoteMint, + dao + ); + + const [passLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + passAmm + ); + const [failLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + failAmm + ); + + const passLpVaultAccount = getAssociatedTokenAddressSync( + passLp, + daoTreasury, + true + ); + const failLpVaultAccount = getAssociatedTokenAddressSync( + failLp, + daoTreasury, + true + ); + + return this.autocrat.methods + .initializeProposal({ + descriptionUrl, + instruction, + passLpTokensToLock, + failLpTokensToLock, + nonce, + }) + .accounts({ + question, + proposal, + dao, + baseVault, + quoteVault, + passAmm, + failAmm, + passLpMint: passLp, + failLpMint: failLp, + passLpUserAccount: getAssociatedTokenAddressSync( + passLp, + this.provider.publicKey + ), + failLpUserAccount: getAssociatedTokenAddressSync( + failLp, + this.provider.publicKey + ), + passLpVaultAccount, + failLpVaultAccount, + proposer: this.provider.publicKey, + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + passLpVaultAccount, + daoTreasury, + passLp + ), + createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + failLpVaultAccount, + daoTreasury, + failLp + ), + ]); + } + + async finalizeProposal(proposal: PublicKey) { + let storedProposal = await this.getProposal(proposal); + let storedDao = await this.getDao(storedProposal.dao); + + return this.finalizeProposalIx( + proposal, + storedProposal.instruction, + storedProposal.dao, + storedDao.tokenMint, + storedDao.usdcMint, + storedProposal.proposer + ).rpc(); + } + + finalizeProposalIx( + proposal: PublicKey, + instruction: any, + dao: PublicKey, + daoToken: PublicKey, + usdc: PublicKey, + proposer: PublicKey + ) { + let vaultProgramId = this.vaultClient.vaultProgram.programId; + + const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); + const { question, passAmm, failAmm } = this.getProposalPdas( + proposal, + daoToken, + usdc, + dao + ); + + const [passLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + passAmm + ); + const [failLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + failAmm + ); + + return this.autocrat.methods.finalizeProposal().accounts({ + proposal, + passAmm, + failAmm, + dao, + question, + // baseVault, + // quoteVault, + passLpUserAccount: getAssociatedTokenAddressSync(passLp, proposer), + failLpUserAccount: getAssociatedTokenAddressSync(failLp, proposer), + passLpVaultAccount: getAssociatedTokenAddressSync( + passLp, + daoTreasury, + true + ), + failLpVaultAccount: getAssociatedTokenAddressSync( + failLp, + daoTreasury, + true + ), + vaultProgram: this.vaultClient.vaultProgram.programId, + treasury: daoTreasury, + }); + } + + async executeProposal(proposal: PublicKey) { + let storedProposal = await this.getProposal(proposal); + + return this.executeProposalIx( + proposal, + storedProposal.dao, + storedProposal.instruction + ).rpc(); + } + + executeProposalIx(proposal: PublicKey, dao: PublicKey, instruction: any) { + const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); + return this.autocrat.methods + .executeProposal() + .accounts({ + proposal, + dao, + // daoTreasury, + }) + .remainingAccounts( + instruction.accounts + .concat({ + pubkey: instruction.programId, + isWritable: false, + isSigner: false, + }) + .map((meta: AccountMeta) => + meta.pubkey.equals(daoTreasury) + ? { ...meta, isSigner: false } + : meta + ) + ); + } + + // cranks the TWAPs of multiple proposals' markets. there's a limit on the + // number of proposals you can pass in, which I can't determine rn because + // there aren't enough proposals on devnet + async crankProposalMarkets( + proposals: PublicKey[], + priorityFeeMicroLamports: number + ) { + const amms: PublicKey[] = []; + + for (const proposal of proposals) { + const storedProposal = await this.getProposal(proposal); + amms.push(storedProposal.passAmm); + amms.push(storedProposal.failAmm); + } + + while (true) { + let ixs: TransactionInstruction[] = []; + + for (const amm of amms) { + ixs.push(await this.ammClient.crankThatTwapIx(amm).instruction()); + } + + let tx = new Transaction(); + tx.add( + ComputeBudgetProgram.setComputeUnitLimit({ units: 4_000 * ixs.length }) + ); + tx.add( + ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: priorityFeeMicroLamports, + }) + ); + tx.add(...ixs); + try { + await this.provider.sendAndConfirm(tx); + } catch (err) { + console.log("err", err); + } + + await new Promise((resolve) => setTimeout(resolve, 65 * 1000)); // 65,000 milliseconds = 1 minute and 5 seconds + } + } +} diff --git a/sdk/src/v0.4/ConditionalVaultClient.ts b/sdk/src/v0.4/ConditionalVaultClient.ts new file mode 100644 index 00000000..c480b545 --- /dev/null +++ b/sdk/src/v0.4/ConditionalVaultClient.ts @@ -0,0 +1,470 @@ +import { AnchorProvider, Program, utils } from "@coral-xyz/anchor"; +import { + AddressLookupTableAccount, + Keypair, + PublicKey, + SystemProgram, +} from "@solana/web3.js"; + +import { + ConditionalVault, + IDL as ConditionalVaultIDL, +} from "./types/conditional_vault.js"; + +import BN from "bn.js"; +import { + CONDITIONAL_VAULT_PROGRAM_ID, + MPL_TOKEN_METADATA_PROGRAM_ID, +} from "./constants.js"; +import { + getQuestionAddr, + getMetadataAddr, + getVaultAddr, + getVaultFinalizeMintAddr, + getVaultRevertMintAddr, + getConditionalTokenMintAddr, +} from "./utils/index.js"; +import { + createAssociatedTokenAccountIdempotentInstruction, + createAssociatedTokenAccountInstruction, + getAssociatedTokenAddressSync, + TOKEN_PROGRAM_ID, +} from "@solana/spl-token"; + +export type CreateVaultClientParams = { + provider: AnchorProvider; + conditionalVaultProgramId?: PublicKey; +}; + +export class ConditionalVaultClient { + public readonly provider: AnchorProvider; + public readonly vaultProgram: Program; + + constructor(provider: AnchorProvider, conditionalVaultProgramId: PublicKey) { + this.provider = provider; + this.vaultProgram = new Program( + ConditionalVaultIDL, + conditionalVaultProgramId, + provider + ); + } + + public static createClient( + createVaultClientParams: CreateVaultClientParams + ): ConditionalVaultClient { + let { provider, conditionalVaultProgramId } = createVaultClientParams; + + return new ConditionalVaultClient( + provider, + conditionalVaultProgramId || CONDITIONAL_VAULT_PROGRAM_ID + ); + } + + async fetchQuestion(question: PublicKey) { + return this.vaultProgram.account.question.fetch(question); + } + + async fetchVault(vault: PublicKey) { + return this.vaultProgram.account.conditionalVault.fetch(vault); + } + + async getVault(vault: PublicKey) { + return this.vaultProgram.account.conditionalVault.fetch(vault); + } + + initializeQuestionIx( + questionId: Uint8Array, + oracle: PublicKey, + numConditions: number + ) { + const [question] = getQuestionAddr( + this.vaultProgram.programId, + questionId, + oracle, + numConditions + ); + + return this.vaultProgram.methods + .initializeQuestion({ + questionId: Array.from(questionId), + oracle, + numConditions, + }) + .accounts({ + question, + }); + } + + async initializeQuestion( + questionId: Uint8Array, + oracle: PublicKey, + numConditions: number + ): Promise { + const [question] = getQuestionAddr( + this.vaultProgram.programId, + questionId, + oracle, + numConditions + ); + + await this.initializeQuestionIx(questionId, oracle, numConditions).rpc(); + + return question; + } + + initializeVaultIx( + question: PublicKey, + underlyingTokenMint: PublicKey, + numOutcomes: number + ) { + const [vault] = getVaultAddr( + this.vaultProgram.programId, + question, + underlyingTokenMint + ); + + let conditionalTokenMintAddrs = []; + for (let i = 0; i < numOutcomes; i++) { + const [conditionalTokenMint] = getConditionalTokenMintAddr( + this.vaultProgram.programId, + vault, + i + ); + conditionalTokenMintAddrs.push(conditionalTokenMint); + } + + const vaultUnderlyingTokenAccount = getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ); + + return this.vaultProgram.methods + .initializeConditionalVault() + .accounts({ + vault, + question, + underlyingTokenMint, + vaultUnderlyingTokenAccount, + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + vaultUnderlyingTokenAccount, + vault, + underlyingTokenMint + ), + ]) + .remainingAccounts( + conditionalTokenMintAddrs.map((conditionalTokenMint) => { + return { + pubkey: conditionalTokenMint, + isWritable: true, + isSigner: false, + }; + }) + ); + } + + async initializeVault( + question: PublicKey, + underlyingTokenMint: PublicKey, + numOutcomes: number + ): Promise { + const [vault] = getVaultAddr( + this.vaultProgram.programId, + question, + underlyingTokenMint + ); + + await this.initializeVaultIx( + question, + underlyingTokenMint, + numOutcomes + ).rpc(); + + return vault; + } + + resolveQuestionIx( + question: PublicKey, + oracle: Keypair, + payoutNumerators: number[] + ) { + return this.vaultProgram.methods + .resolveQuestion({ + payoutNumerators, + }) + .accounts({ + question, + oracle: oracle.publicKey, + }) + .signers([oracle]); + } + + getConditionalTokenMints(vault: PublicKey, numOutcomes: number): PublicKey[] { + let conditionalTokenMintAddrs = []; + for (let i = 0; i < numOutcomes; i++) { + const [conditionalTokenMint] = getConditionalTokenMintAddr( + this.vaultProgram.programId, + vault, + i + ); + conditionalTokenMintAddrs.push(conditionalTokenMint); + } + return conditionalTokenMintAddrs; + } + + getRemainingAccounts( + conditionalTokenMints: PublicKey[], + userConditionalAccounts: PublicKey[] + ) { + return conditionalTokenMints + .concat(userConditionalAccounts) + .map((account) => ({ + pubkey: account, + isWritable: true, + isSigner: false, + })); + } + + // Helper method to get conditional token accounts and instructions + getConditionalTokenAccountsAndInstructions( + vault: PublicKey, + numOutcomes: number, + user: PublicKey + ) { + const conditionalTokenMintAddrs = this.getConditionalTokenMints( + vault, + numOutcomes + ); + const userConditionalAccounts = conditionalTokenMintAddrs.map((mint) => + getAssociatedTokenAddressSync(mint, user, true) + ); + + const preInstructions = conditionalTokenMintAddrs.map((mint) => + createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + getAssociatedTokenAddressSync(mint, user), + user, + mint + ) + ); + + const remainingAccounts = this.getRemainingAccounts( + conditionalTokenMintAddrs, + userConditionalAccounts + ); + + return { userConditionalAccounts, preInstructions, remainingAccounts }; + } + + splitTokensIx( + question: PublicKey, + vault: PublicKey, + underlyingTokenMint: PublicKey, + amount: BN, + numOutcomes: number, + user: PublicKey = this.provider.publicKey + ) { + const { preInstructions, remainingAccounts } = + this.getConditionalTokenAccountsAndInstructions(vault, numOutcomes, user); + + return this.vaultProgram.methods + .splitTokens(amount) + .accounts({ + question, + authority: user, + vault, + vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + user, + true + ), + }) + .preInstructions(preInstructions) + .remainingAccounts(remainingAccounts); + } + + mergeTokensIx( + question: PublicKey, + vault: PublicKey, + underlyingTokenMint: PublicKey, + amount: BN, + numOutcomes: number, + user: PublicKey = this.provider.publicKey + ) { + let conditionalTokenMintAddrs = this.getConditionalTokenMints( + vault, + numOutcomes + ); + + let userConditionalAccounts = []; + for (let conditionalTokenMint of conditionalTokenMintAddrs) { + userConditionalAccounts.push( + getAssociatedTokenAddressSync(conditionalTokenMint, user, true) + ); + } + + let ix = this.vaultProgram.methods + .mergeTokens(amount) + .accounts({ + question, + authority: user, + vault, + vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + user, + true + ), + }) + .preInstructions( + conditionalTokenMintAddrs.map((conditionalTokenMint) => { + return createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + getAssociatedTokenAddressSync(conditionalTokenMint, user), + user, + conditionalTokenMint + ); + }) + ) + .remainingAccounts( + conditionalTokenMintAddrs + .concat(userConditionalAccounts) + .map((conditionalTokenMint) => { + return { + pubkey: conditionalTokenMint, + isWritable: true, + isSigner: false, + }; + }) + ); + + return ix; + } + + redeemTokensIx( + question: PublicKey, + vault: PublicKey, + underlyingTokenMint: PublicKey, + numOutcomes: number, + user: PublicKey = this.provider.publicKey + ) { + let conditionalTokenMintAddrs = []; + for (let i = 0; i < numOutcomes; i++) { + const [conditionalTokenMint] = getConditionalTokenMintAddr( + this.vaultProgram.programId, + vault, + i + ); + conditionalTokenMintAddrs.push(conditionalTokenMint); + } + + let userConditionalAccounts = []; + for (let conditionalTokenMint of conditionalTokenMintAddrs) { + userConditionalAccounts.push( + getAssociatedTokenAddressSync(conditionalTokenMint, user, true) + ); + } + + let ix = this.vaultProgram.methods + .redeemTokens() + .accounts({ + question, + authority: user, + vault, + vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + user, + true + ), + }) + .preInstructions( + conditionalTokenMintAddrs.map((conditionalTokenMint) => { + return createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + getAssociatedTokenAddressSync(conditionalTokenMint, user), + user, + conditionalTokenMint + ); + }) + ) + .remainingAccounts( + conditionalTokenMintAddrs + .concat(userConditionalAccounts) + .map((conditionalTokenMint) => { + return { + pubkey: conditionalTokenMint, + isWritable: true, + isSigner: false, + }; + }) + ); + + return ix; + } + + addMetadataToConditionalTokensIx( + vault: PublicKey, + index: number, + name: string, + symbol: string, + uri: string + // underlyingTokenMint: PublicKey, + // proposalNumber: number, + // onFinalizeUri: string, + // onRevertUri: string + ) { + // const [underlyingTokenMetadata] = getMetadataAddr(underlyingTokenMint); + + const [conditionalTokenMint] = getConditionalTokenMintAddr( + this.vaultProgram.programId, + vault, + index + ); + + // const [conditionalOnFinalizeTokenMint] = getVaultFinalizeMintAddr( + // this.vaultProgram.programId, + // vault + // ); + // const [conditionalOnRevertTokenMint] = getVaultRevertMintAddr( + // this.vaultProgram.programId, + // vault + // ); + + const [conditionalTokenMetadata] = getMetadataAddr(conditionalTokenMint); + + // const [conditionalOnRevertTokenMetadata] = getMetadataAddr( + // conditionalOnRevertTokenMint + // ); + + return this.vaultProgram.methods + .addMetadataToConditionalTokens({ + name, + symbol, + uri, + }) + .accounts({ + payer: this.provider.publicKey, + vault, + conditionalTokenMint, + conditionalTokenMetadata, + tokenMetadataProgram: MPL_TOKEN_METADATA_PROGRAM_ID, + }); + } +} diff --git a/sdk/src/v0.4/constants.ts b/sdk/src/v0.4/constants.ts new file mode 100644 index 00000000..66ef1523 --- /dev/null +++ b/sdk/src/v0.4/constants.ts @@ -0,0 +1,26 @@ +import { PublicKey } from "@solana/web3.js"; + +export const AUTOCRAT_PROGRAM_ID = new PublicKey( + "autoQP9RmUNkzzKRXsMkWicDVZ3h29vvyMDcAYjCxxg" +); +export const AMM_PROGRAM_ID = new PublicKey( + "AMM5G2nxuKUwCLRYTW7qqEwuoqCtNSjtbipwEmm2g8bH" +); +export const CONDITIONAL_VAULT_PROGRAM_ID = new PublicKey( + "VAU1T7S5UuEHmMvXtXMVmpEoQtZ2ya7eRb7gcN47wDp" +); + +export const MPL_TOKEN_METADATA_PROGRAM_ID = new PublicKey( + "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" +); + +export const META_MINT = new PublicKey( + "3gN1WVEJwSHNWjo7hr87DgZp6zkf8kWgAJD29DmfE2Gr" +); +export const MAINNET_USDC = new PublicKey( + "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" +); + +export const USDC_DECIMALS = 6; + +export const AUTOCRAT_LUTS: PublicKey[] = []; diff --git a/sdk/src/v0.4/index.ts b/sdk/src/v0.4/index.ts new file mode 100644 index 00000000..1aa39fe5 --- /dev/null +++ b/sdk/src/v0.4/index.ts @@ -0,0 +1,6 @@ +export * from "./types/index.js"; +export * from "./utils/index.js"; +export * from "./constants.js"; +export * from "./AmmClient.js"; +export * from "./AutocratClient.js"; +export * from "./ConditionalVaultClient.js"; diff --git a/sdk/src/v0.4/types/amm.ts b/sdk/src/v0.4/types/amm.ts new file mode 100644 index 00000000..0a7d6669 --- /dev/null +++ b/sdk/src/v0.4/types/amm.ts @@ -0,0 +1,1083 @@ +export type Amm = { + version: "0.3.0"; + name: "amm"; + instructions: [ + { + name: "createAmm"; + accounts: [ + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "lpMint"; + isMut: true; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "quoteMint"; + isMut: false; + isSigner: false; + }, + { + name: "vaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "CreateAmmArgs"; + }; + } + ]; + }, + { + name: "addLiquidity"; + accounts: [ + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "lpMint"; + isMut: true; + isSigner: false; + }, + { + name: "userLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userBaseAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userQuoteAccount"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "AddLiquidityArgs"; + }; + } + ]; + }, + { + name: "removeLiquidity"; + accounts: [ + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "lpMint"; + isMut: true; + isSigner: false; + }, + { + name: "userLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userBaseAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userQuoteAccount"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "RemoveLiquidityArgs"; + }; + } + ]; + }, + { + name: "swap"; + accounts: [ + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "userBaseAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userQuoteAccount"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "SwapArgs"; + }; + } + ]; + }, + { + name: "crankThatTwap"; + accounts: [ + { + name: "amm"; + isMut: true; + isSigner: false; + } + ]; + args: []; + } + ]; + accounts: [ + { + name: "amm"; + type: { + kind: "struct"; + fields: [ + { + name: "bump"; + type: "u8"; + }, + { + name: "createdAtSlot"; + type: "u64"; + }, + { + name: "lpMint"; + type: "publicKey"; + }, + { + name: "baseMint"; + type: "publicKey"; + }, + { + name: "quoteMint"; + type: "publicKey"; + }, + { + name: "baseMintDecimals"; + type: "u8"; + }, + { + name: "quoteMintDecimals"; + type: "u8"; + }, + { + name: "baseAmount"; + type: "u64"; + }, + { + name: "quoteAmount"; + type: "u64"; + }, + { + name: "oracle"; + type: { + defined: "TwapOracle"; + }; + } + ]; + }; + } + ]; + types: [ + { + name: "AddLiquidityArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "quoteAmount"; + docs: ["How much quote token you will deposit to the pool"]; + type: "u64"; + }, + { + name: "maxBaseAmount"; + docs: ["The maximum base token you will deposit to the pool"]; + type: "u64"; + }, + { + name: "minLpTokens"; + docs: ["The minimum LP token you will get back"]; + type: "u64"; + } + ]; + }; + }, + { + name: "CreateAmmArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "twapInitialObservation"; + type: "u128"; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + } + ]; + }; + }, + { + name: "RemoveLiquidityArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "lpTokensToBurn"; + type: "u64"; + }, + { + name: "minQuoteAmount"; + type: "u64"; + }, + { + name: "minBaseAmount"; + type: "u64"; + } + ]; + }; + }, + { + name: "SwapArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "swapType"; + type: { + defined: "SwapType"; + }; + }, + { + name: "inputAmount"; + type: "u64"; + }, + { + name: "outputAmountMin"; + type: "u64"; + } + ]; + }; + }, + { + name: "TwapOracle"; + type: { + kind: "struct"; + fields: [ + { + name: "lastUpdatedSlot"; + type: "u64"; + }, + { + name: "lastPrice"; + docs: [ + "A price is the number of quote units per base unit multiplied by 1e12.", + "You cannot simply divide by 1e12 to get a price you can display in the UI", + "because the base and quote decimals may be different. Instead, do:", + "ui_price = (price * (10**(base_decimals - quote_decimals))) / 1e12" + ]; + type: "u128"; + }, + { + name: "lastObservation"; + docs: [ + "If we did a raw TWAP over prices, someone could push the TWAP heavily with", + "a few extremely large outliers. So we use observations, which can only move", + "by `max_observation_change_per_update` per update." + ]; + type: "u128"; + }, + { + name: "aggregator"; + docs: [ + "Running sum of slots_per_last_update * last_observation.", + "", + "Assuming latest observations are as big as possible (u64::MAX * 1e12),", + "we can store 18 million slots worth of observations, which turns out to", + "be ~85 days worth of slots.", + "", + "Assuming that latest observations are 100x smaller than they could theoretically", + "be, we can store 8500 days (23 years) worth of them. Even this is a very", + "very conservative assumption - META/USDC prices should be between 1e9 and", + "1e15, which would overflow after 1e15 years worth of slots.", + "", + "So in the case of an overflow, the aggregator rolls back to 0. It's the", + "client's responsibility to sanity check the assets or to handle an", + "aggregator at t2 being smaller than an aggregator at t1." + ]; + type: "u128"; + }, + { + name: "maxObservationChangePerUpdate"; + docs: ["The most that an observation can change per update."]; + type: "u128"; + }, + { + name: "initialObservation"; + docs: ["What the initial `latest_observation` is set to."]; + type: "u128"; + } + ]; + }; + }, + { + name: "SwapType"; + type: { + kind: "enum"; + variants: [ + { + name: "Buy"; + }, + { + name: "Sell"; + } + ]; + }; + } + ]; + errors: [ + { + code: 6000; + name: "NoSlotsPassed"; + msg: "Can't get a TWAP before some observations have been stored"; + }, + { + code: 6001; + name: "NoReserves"; + msg: "Can't swap through a pool without token reserves on either side"; + }, + { + code: 6002; + name: "InputAmountOverflow"; + msg: "Input token amount is too large for a swap, causes overflow"; + }, + { + code: 6003; + name: "AddLiquidityCalculationError"; + msg: "Add liquidity calculation error"; + }, + { + code: 6004; + name: "DecimalScaleError"; + msg: "Error in decimal scale conversion"; + }, + { + code: 6005; + name: "SameTokenMints"; + msg: "You can't create an AMM pool where the token mints are the same"; + }, + { + code: 6006; + name: "SwapSlippageExceeded"; + msg: "A user wouldn't have gotten back their `output_amount_min`, reverting"; + }, + { + code: 6007; + name: "InsufficientBalance"; + msg: "The user had insufficient balance to do this"; + }, + { + code: 6008; + name: "ZeroLiquidityRemove"; + msg: "Must remove a non-zero amount of liquidity"; + }, + { + code: 6009; + name: "ZeroLiquidityToAdd"; + msg: "Cannot add liquidity with 0 tokens on either side"; + }, + { + code: 6010; + name: "ZeroMinLpTokens"; + msg: "Must specify a non-zero `min_lp_tokens` when adding to an existing pool"; + }, + { + code: 6011; + name: "AddLiquiditySlippageExceeded"; + msg: "LP wouldn't have gotten back `lp_token_min`"; + }, + { + code: 6012; + name: "AddLiquidityMaxBaseExceeded"; + msg: "LP would have spent more than `max_base_amount`"; + }, + { + code: 6013; + name: "InsufficientQuoteAmount"; + msg: "`quote_amount` must be greater than 100000000 when initializing a pool"; + }, + { + code: 6014; + name: "ZeroSwapAmount"; + msg: "Users must swap a non-zero amount"; + }, + { + code: 6015; + name: "ConstantProductInvariantFailed"; + msg: "K should always be increasing"; + }, + { + code: 6016; + name: "CastingOverflow"; + msg: "Casting has caused an overflow"; + } + ]; +}; + +export const IDL: Amm = { + version: "0.3.0", + name: "amm", + instructions: [ + { + name: "createAmm", + accounts: [ + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "lpMint", + isMut: true, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "quoteMint", + isMut: false, + isSigner: false, + }, + { + name: "vaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "CreateAmmArgs", + }, + }, + ], + }, + { + name: "addLiquidity", + accounts: [ + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "lpMint", + isMut: true, + isSigner: false, + }, + { + name: "userLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "userBaseAccount", + isMut: true, + isSigner: false, + }, + { + name: "userQuoteAccount", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "AddLiquidityArgs", + }, + }, + ], + }, + { + name: "removeLiquidity", + accounts: [ + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "lpMint", + isMut: true, + isSigner: false, + }, + { + name: "userLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "userBaseAccount", + isMut: true, + isSigner: false, + }, + { + name: "userQuoteAccount", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "RemoveLiquidityArgs", + }, + }, + ], + }, + { + name: "swap", + accounts: [ + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "userBaseAccount", + isMut: true, + isSigner: false, + }, + { + name: "userQuoteAccount", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "SwapArgs", + }, + }, + ], + }, + { + name: "crankThatTwap", + accounts: [ + { + name: "amm", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + ], + accounts: [ + { + name: "amm", + type: { + kind: "struct", + fields: [ + { + name: "bump", + type: "u8", + }, + { + name: "createdAtSlot", + type: "u64", + }, + { + name: "lpMint", + type: "publicKey", + }, + { + name: "baseMint", + type: "publicKey", + }, + { + name: "quoteMint", + type: "publicKey", + }, + { + name: "baseMintDecimals", + type: "u8", + }, + { + name: "quoteMintDecimals", + type: "u8", + }, + { + name: "baseAmount", + type: "u64", + }, + { + name: "quoteAmount", + type: "u64", + }, + { + name: "oracle", + type: { + defined: "TwapOracle", + }, + }, + ], + }, + }, + ], + types: [ + { + name: "AddLiquidityArgs", + type: { + kind: "struct", + fields: [ + { + name: "quoteAmount", + docs: ["How much quote token you will deposit to the pool"], + type: "u64", + }, + { + name: "maxBaseAmount", + docs: ["The maximum base token you will deposit to the pool"], + type: "u64", + }, + { + name: "minLpTokens", + docs: ["The minimum LP token you will get back"], + type: "u64", + }, + ], + }, + }, + { + name: "CreateAmmArgs", + type: { + kind: "struct", + fields: [ + { + name: "twapInitialObservation", + type: "u128", + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + }, + ], + }, + }, + { + name: "RemoveLiquidityArgs", + type: { + kind: "struct", + fields: [ + { + name: "lpTokensToBurn", + type: "u64", + }, + { + name: "minQuoteAmount", + type: "u64", + }, + { + name: "minBaseAmount", + type: "u64", + }, + ], + }, + }, + { + name: "SwapArgs", + type: { + kind: "struct", + fields: [ + { + name: "swapType", + type: { + defined: "SwapType", + }, + }, + { + name: "inputAmount", + type: "u64", + }, + { + name: "outputAmountMin", + type: "u64", + }, + ], + }, + }, + { + name: "TwapOracle", + type: { + kind: "struct", + fields: [ + { + name: "lastUpdatedSlot", + type: "u64", + }, + { + name: "lastPrice", + docs: [ + "A price is the number of quote units per base unit multiplied by 1e12.", + "You cannot simply divide by 1e12 to get a price you can display in the UI", + "because the base and quote decimals may be different. Instead, do:", + "ui_price = (price * (10**(base_decimals - quote_decimals))) / 1e12", + ], + type: "u128", + }, + { + name: "lastObservation", + docs: [ + "If we did a raw TWAP over prices, someone could push the TWAP heavily with", + "a few extremely large outliers. So we use observations, which can only move", + "by `max_observation_change_per_update` per update.", + ], + type: "u128", + }, + { + name: "aggregator", + docs: [ + "Running sum of slots_per_last_update * last_observation.", + "", + "Assuming latest observations are as big as possible (u64::MAX * 1e12),", + "we can store 18 million slots worth of observations, which turns out to", + "be ~85 days worth of slots.", + "", + "Assuming that latest observations are 100x smaller than they could theoretically", + "be, we can store 8500 days (23 years) worth of them. Even this is a very", + "very conservative assumption - META/USDC prices should be between 1e9 and", + "1e15, which would overflow after 1e15 years worth of slots.", + "", + "So in the case of an overflow, the aggregator rolls back to 0. It's the", + "client's responsibility to sanity check the assets or to handle an", + "aggregator at t2 being smaller than an aggregator at t1.", + ], + type: "u128", + }, + { + name: "maxObservationChangePerUpdate", + docs: ["The most that an observation can change per update."], + type: "u128", + }, + { + name: "initialObservation", + docs: ["What the initial `latest_observation` is set to."], + type: "u128", + }, + ], + }, + }, + { + name: "SwapType", + type: { + kind: "enum", + variants: [ + { + name: "Buy", + }, + { + name: "Sell", + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: "NoSlotsPassed", + msg: "Can't get a TWAP before some observations have been stored", + }, + { + code: 6001, + name: "NoReserves", + msg: "Can't swap through a pool without token reserves on either side", + }, + { + code: 6002, + name: "InputAmountOverflow", + msg: "Input token amount is too large for a swap, causes overflow", + }, + { + code: 6003, + name: "AddLiquidityCalculationError", + msg: "Add liquidity calculation error", + }, + { + code: 6004, + name: "DecimalScaleError", + msg: "Error in decimal scale conversion", + }, + { + code: 6005, + name: "SameTokenMints", + msg: "You can't create an AMM pool where the token mints are the same", + }, + { + code: 6006, + name: "SwapSlippageExceeded", + msg: "A user wouldn't have gotten back their `output_amount_min`, reverting", + }, + { + code: 6007, + name: "InsufficientBalance", + msg: "The user had insufficient balance to do this", + }, + { + code: 6008, + name: "ZeroLiquidityRemove", + msg: "Must remove a non-zero amount of liquidity", + }, + { + code: 6009, + name: "ZeroLiquidityToAdd", + msg: "Cannot add liquidity with 0 tokens on either side", + }, + { + code: 6010, + name: "ZeroMinLpTokens", + msg: "Must specify a non-zero `min_lp_tokens` when adding to an existing pool", + }, + { + code: 6011, + name: "AddLiquiditySlippageExceeded", + msg: "LP wouldn't have gotten back `lp_token_min`", + }, + { + code: 6012, + name: "AddLiquidityMaxBaseExceeded", + msg: "LP would have spent more than `max_base_amount`", + }, + { + code: 6013, + name: "InsufficientQuoteAmount", + msg: "`quote_amount` must be greater than 100000000 when initializing a pool", + }, + { + code: 6014, + name: "ZeroSwapAmount", + msg: "Users must swap a non-zero amount", + }, + { + code: 6015, + name: "ConstantProductInvariantFailed", + msg: "K should always be increasing", + }, + { + code: 6016, + name: "CastingOverflow", + msg: "Casting has caused an overflow", + }, + ], +}; diff --git a/sdk/src/v0.4/types/autocrat.ts b/sdk/src/v0.4/types/autocrat.ts new file mode 100644 index 00000000..3825b3ef --- /dev/null +++ b/sdk/src/v0.4/types/autocrat.ts @@ -0,0 +1,1271 @@ +export type Autocrat = { + version: "0.3.0"; + name: "autocrat"; + instructions: [ + { + name: "initializeDao"; + accounts: [ + { + name: "dao"; + isMut: true; + isSigner: true; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenMint"; + isMut: false; + isSigner: false; + }, + { + name: "usdcMint"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "InitializeDaoParams"; + }; + } + ]; + }, + { + name: "initializeProposal"; + accounts: [ + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "dao"; + isMut: true; + isSigner: false; + }, + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "quoteVault"; + isMut: false; + isSigner: false; + }, + { + name: "baseVault"; + isMut: false; + isSigner: false; + }, + { + name: "passAmm"; + isMut: false; + isSigner: false; + }, + { + name: "passLpMint"; + isMut: false; + isSigner: false; + }, + { + name: "failLpMint"; + isMut: false; + isSigner: false; + }, + { + name: "failAmm"; + isMut: false; + isSigner: false; + }, + { + name: "passLpUserAccount"; + isMut: true; + isSigner: false; + }, + { + name: "failLpUserAccount"; + isMut: true; + isSigner: false; + }, + { + name: "passLpVaultAccount"; + isMut: true; + isSigner: false; + }, + { + name: "failLpVaultAccount"; + isMut: true; + isSigner: false; + }, + { + name: "proposer"; + isMut: true; + isSigner: true; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "InitializeProposalParams"; + }; + } + ]; + }, + { + name: "finalizeProposal"; + accounts: [ + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "passAmm"; + isMut: false; + isSigner: false; + }, + { + name: "failAmm"; + isMut: false; + isSigner: false; + }, + { + name: "dao"; + isMut: false; + isSigner: false; + }, + { + name: "question"; + isMut: true; + isSigner: false; + }, + { + name: "treasury"; + isMut: false; + isSigner: false; + }, + { + name: "passLpUserAccount"; + isMut: true; + isSigner: false; + }, + { + name: "failLpUserAccount"; + isMut: true; + isSigner: false; + }, + { + name: "passLpVaultAccount"; + isMut: true; + isSigner: false; + }, + { + name: "failLpVaultAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "vaultProgram"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "executeProposal"; + accounts: [ + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "dao"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "updateDao"; + accounts: [ + { + name: "dao"; + isMut: true; + isSigner: false; + }, + { + name: "treasury"; + isMut: false; + isSigner: true; + } + ]; + args: [ + { + name: "daoParams"; + type: { + defined: "UpdateDaoParams"; + }; + } + ]; + } + ]; + accounts: [ + { + name: "dao"; + type: { + kind: "struct"; + fields: [ + { + name: "treasuryPdaBump"; + type: "u8"; + }, + { + name: "treasury"; + type: "publicKey"; + }, + { + name: "tokenMint"; + type: "publicKey"; + }, + { + name: "usdcMint"; + type: "publicKey"; + }, + { + name: "proposalCount"; + type: "u32"; + }, + { + name: "passThresholdBps"; + type: "u16"; + }, + { + name: "slotsPerProposal"; + type: "u64"; + }, + { + name: "twapInitialObservation"; + docs: [ + "For manipulation-resistance the TWAP is a time-weighted average observation,", + "where observation tries to approximate price but can only move by", + "`twap_max_observation_change_per_update` per update. Because it can only move", + "a little bit per update, you need to check that it has a good initial observation.", + "Otherwise, an attacker could create a very high initial observation in the pass", + "market and a very low one in the fail market to force the proposal to pass.", + "", + "We recommend setting an initial observation around the spot price of the token,", + "and max observation change per update around 2% the spot price of the token.", + "For example, if the spot price of META is $400, we'd recommend setting an initial", + "observation of 400 (converted into the AMM prices) and a max observation change per", + "update of 8 (also converted into the AMM prices). Observations can be updated once", + "a minute, so 2% allows the proposal market to reach double the spot price or 0", + "in 50 minutes." + ]; + type: "u128"; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + }, + { + name: "minQuoteFutarchicLiquidity"; + docs: [ + "As an anti-spam measure and to help liquidity, you need to lock up some liquidity", + "in both futarchic markets in order to create a proposal.", + "", + "For example, for META, we can use a `min_quote_futarchic_liquidity` of", + "5000 * 1_000_000 (5000 USDC) and a `min_base_futarchic_liquidity` of", + "10 * 1_000_000_000 (10 META)." + ]; + type: "u64"; + }, + { + name: "minBaseFutarchicLiquidity"; + type: "u64"; + } + ]; + }; + }, + { + name: "proposal"; + type: { + kind: "struct"; + fields: [ + { + name: "number"; + type: "u32"; + }, + { + name: "proposer"; + type: "publicKey"; + }, + { + name: "descriptionUrl"; + type: "string"; + }, + { + name: "slotEnqueued"; + type: "u64"; + }, + { + name: "state"; + type: { + defined: "ProposalState"; + }; + }, + { + name: "instruction"; + type: { + defined: "ProposalInstruction"; + }; + }, + { + name: "passAmm"; + type: "publicKey"; + }, + { + name: "failAmm"; + type: "publicKey"; + }, + { + name: "baseVault"; + type: "publicKey"; + }, + { + name: "quoteVault"; + type: "publicKey"; + }, + { + name: "dao"; + type: "publicKey"; + }, + { + name: "passLpTokensLocked"; + type: "u64"; + }, + { + name: "failLpTokensLocked"; + type: "u64"; + }, + { + name: "nonce"; + docs: [ + "We need to include a per-proposer nonce to prevent some weird proposal", + "front-running edge cases. Using a `u64` means that proposers are unlikely", + "to run into collisions, even if they generate nonces randomly - I've run", + "the math :D" + ]; + type: "u64"; + }, + { + name: "pdaBump"; + type: "u8"; + }, + { + name: "question"; + type: "publicKey"; + } + ]; + }; + } + ]; + types: [ + { + name: "InitializeDaoParams"; + type: { + kind: "struct"; + fields: [ + { + name: "twapInitialObservation"; + type: "u128"; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + }, + { + name: "minQuoteFutarchicLiquidity"; + type: "u64"; + }, + { + name: "minBaseFutarchicLiquidity"; + type: "u64"; + }, + { + name: "passThresholdBps"; + type: { + option: "u16"; + }; + }, + { + name: "slotsPerProposal"; + type: { + option: "u64"; + }; + } + ]; + }; + }, + { + name: "InitializeProposalParams"; + type: { + kind: "struct"; + fields: [ + { + name: "descriptionUrl"; + type: "string"; + }, + { + name: "instruction"; + type: { + defined: "ProposalInstruction"; + }; + }, + { + name: "passLpTokensToLock"; + type: "u64"; + }, + { + name: "failLpTokensToLock"; + type: "u64"; + }, + { + name: "nonce"; + type: "u64"; + } + ]; + }; + }, + { + name: "UpdateDaoParams"; + type: { + kind: "struct"; + fields: [ + { + name: "passThresholdBps"; + type: { + option: "u16"; + }; + }, + { + name: "slotsPerProposal"; + type: { + option: "u64"; + }; + }, + { + name: "twapInitialObservation"; + type: { + option: "u128"; + }; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: { + option: "u128"; + }; + }, + { + name: "minQuoteFutarchicLiquidity"; + type: { + option: "u64"; + }; + }, + { + name: "minBaseFutarchicLiquidity"; + type: { + option: "u64"; + }; + } + ]; + }; + }, + { + name: "ProposalAccount"; + type: { + kind: "struct"; + fields: [ + { + name: "pubkey"; + type: "publicKey"; + }, + { + name: "isSigner"; + type: "bool"; + }, + { + name: "isWritable"; + type: "bool"; + } + ]; + }; + }, + { + name: "ProposalInstruction"; + type: { + kind: "struct"; + fields: [ + { + name: "programId"; + type: "publicKey"; + }, + { + name: "accounts"; + type: { + vec: { + defined: "ProposalAccount"; + }; + }; + }, + { + name: "data"; + type: "bytes"; + } + ]; + }; + }, + { + name: "ProposalState"; + type: { + kind: "enum"; + variants: [ + { + name: "Pending"; + }, + { + name: "Passed"; + }, + { + name: "Failed"; + }, + { + name: "Executed"; + } + ]; + }; + } + ]; + errors: [ + { + code: 6000; + name: "AmmTooOld"; + msg: "Amms must have been created within 5 minutes (counted in slots) of proposal initialization"; + }, + { + code: 6001; + name: "InvalidInitialObservation"; + msg: "An amm has an `initial_observation` that doesn't match the `dao`'s config"; + }, + { + code: 6002; + name: "InvalidMaxObservationChange"; + msg: "An amm has a `max_observation_change_per_update` that doesn't match the `dao`'s config"; + }, + { + code: 6003; + name: "InvalidSettlementAuthority"; + msg: "One of the vaults has an invalid `settlement_authority`"; + }, + { + code: 6004; + name: "ProposalTooYoung"; + msg: "Proposal is too young to be executed or rejected"; + }, + { + code: 6005; + name: "MarketsTooYoung"; + msg: "Markets too young for proposal to be finalized. TWAP might need to be cranked"; + }, + { + code: 6006; + name: "ProposalAlreadyFinalized"; + msg: "This proposal has already been finalized"; + }, + { + code: 6007; + name: "InvalidVaultNonce"; + msg: "A conditional vault has an invalid nonce. A nonce should encode the proposal number"; + }, + { + code: 6008; + name: "ProposalNotPassed"; + msg: "This proposal can't be executed because it isn't in the passed state"; + }, + { + code: 6009; + name: "InsufficientLpTokenBalance"; + msg: "The proposer has fewer pass or fail LP tokens than they requested to lock"; + }, + { + code: 6010; + name: "InsufficientLpTokenLock"; + msg: "The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`"; + } + ]; +}; + +export const IDL: Autocrat = { + version: "0.3.0", + name: "autocrat", + instructions: [ + { + name: "initializeDao", + accounts: [ + { + name: "dao", + isMut: true, + isSigner: true, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenMint", + isMut: false, + isSigner: false, + }, + { + name: "usdcMint", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "InitializeDaoParams", + }, + }, + ], + }, + { + name: "initializeProposal", + accounts: [ + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "dao", + isMut: true, + isSigner: false, + }, + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "quoteVault", + isMut: false, + isSigner: false, + }, + { + name: "baseVault", + isMut: false, + isSigner: false, + }, + { + name: "passAmm", + isMut: false, + isSigner: false, + }, + { + name: "passLpMint", + isMut: false, + isSigner: false, + }, + { + name: "failLpMint", + isMut: false, + isSigner: false, + }, + { + name: "failAmm", + isMut: false, + isSigner: false, + }, + { + name: "passLpUserAccount", + isMut: true, + isSigner: false, + }, + { + name: "failLpUserAccount", + isMut: true, + isSigner: false, + }, + { + name: "passLpVaultAccount", + isMut: true, + isSigner: false, + }, + { + name: "failLpVaultAccount", + isMut: true, + isSigner: false, + }, + { + name: "proposer", + isMut: true, + isSigner: true, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "InitializeProposalParams", + }, + }, + ], + }, + { + name: "finalizeProposal", + accounts: [ + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "passAmm", + isMut: false, + isSigner: false, + }, + { + name: "failAmm", + isMut: false, + isSigner: false, + }, + { + name: "dao", + isMut: false, + isSigner: false, + }, + { + name: "question", + isMut: true, + isSigner: false, + }, + { + name: "treasury", + isMut: false, + isSigner: false, + }, + { + name: "passLpUserAccount", + isMut: true, + isSigner: false, + }, + { + name: "failLpUserAccount", + isMut: true, + isSigner: false, + }, + { + name: "passLpVaultAccount", + isMut: true, + isSigner: false, + }, + { + name: "failLpVaultAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "vaultProgram", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "executeProposal", + accounts: [ + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "dao", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "updateDao", + accounts: [ + { + name: "dao", + isMut: true, + isSigner: false, + }, + { + name: "treasury", + isMut: false, + isSigner: true, + }, + ], + args: [ + { + name: "daoParams", + type: { + defined: "UpdateDaoParams", + }, + }, + ], + }, + ], + accounts: [ + { + name: "dao", + type: { + kind: "struct", + fields: [ + { + name: "treasuryPdaBump", + type: "u8", + }, + { + name: "treasury", + type: "publicKey", + }, + { + name: "tokenMint", + type: "publicKey", + }, + { + name: "usdcMint", + type: "publicKey", + }, + { + name: "proposalCount", + type: "u32", + }, + { + name: "passThresholdBps", + type: "u16", + }, + { + name: "slotsPerProposal", + type: "u64", + }, + { + name: "twapInitialObservation", + docs: [ + "For manipulation-resistance the TWAP is a time-weighted average observation,", + "where observation tries to approximate price but can only move by", + "`twap_max_observation_change_per_update` per update. Because it can only move", + "a little bit per update, you need to check that it has a good initial observation.", + "Otherwise, an attacker could create a very high initial observation in the pass", + "market and a very low one in the fail market to force the proposal to pass.", + "", + "We recommend setting an initial observation around the spot price of the token,", + "and max observation change per update around 2% the spot price of the token.", + "For example, if the spot price of META is $400, we'd recommend setting an initial", + "observation of 400 (converted into the AMM prices) and a max observation change per", + "update of 8 (also converted into the AMM prices). Observations can be updated once", + "a minute, so 2% allows the proposal market to reach double the spot price or 0", + "in 50 minutes.", + ], + type: "u128", + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + }, + { + name: "minQuoteFutarchicLiquidity", + docs: [ + "As an anti-spam measure and to help liquidity, you need to lock up some liquidity", + "in both futarchic markets in order to create a proposal.", + "", + "For example, for META, we can use a `min_quote_futarchic_liquidity` of", + "5000 * 1_000_000 (5000 USDC) and a `min_base_futarchic_liquidity` of", + "10 * 1_000_000_000 (10 META).", + ], + type: "u64", + }, + { + name: "minBaseFutarchicLiquidity", + type: "u64", + }, + ], + }, + }, + { + name: "proposal", + type: { + kind: "struct", + fields: [ + { + name: "number", + type: "u32", + }, + { + name: "proposer", + type: "publicKey", + }, + { + name: "descriptionUrl", + type: "string", + }, + { + name: "slotEnqueued", + type: "u64", + }, + { + name: "state", + type: { + defined: "ProposalState", + }, + }, + { + name: "instruction", + type: { + defined: "ProposalInstruction", + }, + }, + { + name: "passAmm", + type: "publicKey", + }, + { + name: "failAmm", + type: "publicKey", + }, + { + name: "baseVault", + type: "publicKey", + }, + { + name: "quoteVault", + type: "publicKey", + }, + { + name: "dao", + type: "publicKey", + }, + { + name: "passLpTokensLocked", + type: "u64", + }, + { + name: "failLpTokensLocked", + type: "u64", + }, + { + name: "nonce", + docs: [ + "We need to include a per-proposer nonce to prevent some weird proposal", + "front-running edge cases. Using a `u64` means that proposers are unlikely", + "to run into collisions, even if they generate nonces randomly - I've run", + "the math :D", + ], + type: "u64", + }, + { + name: "pdaBump", + type: "u8", + }, + { + name: "question", + type: "publicKey", + }, + ], + }, + }, + ], + types: [ + { + name: "InitializeDaoParams", + type: { + kind: "struct", + fields: [ + { + name: "twapInitialObservation", + type: "u128", + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + }, + { + name: "minQuoteFutarchicLiquidity", + type: "u64", + }, + { + name: "minBaseFutarchicLiquidity", + type: "u64", + }, + { + name: "passThresholdBps", + type: { + option: "u16", + }, + }, + { + name: "slotsPerProposal", + type: { + option: "u64", + }, + }, + ], + }, + }, + { + name: "InitializeProposalParams", + type: { + kind: "struct", + fields: [ + { + name: "descriptionUrl", + type: "string", + }, + { + name: "instruction", + type: { + defined: "ProposalInstruction", + }, + }, + { + name: "passLpTokensToLock", + type: "u64", + }, + { + name: "failLpTokensToLock", + type: "u64", + }, + { + name: "nonce", + type: "u64", + }, + ], + }, + }, + { + name: "UpdateDaoParams", + type: { + kind: "struct", + fields: [ + { + name: "passThresholdBps", + type: { + option: "u16", + }, + }, + { + name: "slotsPerProposal", + type: { + option: "u64", + }, + }, + { + name: "twapInitialObservation", + type: { + option: "u128", + }, + }, + { + name: "twapMaxObservationChangePerUpdate", + type: { + option: "u128", + }, + }, + { + name: "minQuoteFutarchicLiquidity", + type: { + option: "u64", + }, + }, + { + name: "minBaseFutarchicLiquidity", + type: { + option: "u64", + }, + }, + ], + }, + }, + { + name: "ProposalAccount", + type: { + kind: "struct", + fields: [ + { + name: "pubkey", + type: "publicKey", + }, + { + name: "isSigner", + type: "bool", + }, + { + name: "isWritable", + type: "bool", + }, + ], + }, + }, + { + name: "ProposalInstruction", + type: { + kind: "struct", + fields: [ + { + name: "programId", + type: "publicKey", + }, + { + name: "accounts", + type: { + vec: { + defined: "ProposalAccount", + }, + }, + }, + { + name: "data", + type: "bytes", + }, + ], + }, + }, + { + name: "ProposalState", + type: { + kind: "enum", + variants: [ + { + name: "Pending", + }, + { + name: "Passed", + }, + { + name: "Failed", + }, + { + name: "Executed", + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: "AmmTooOld", + msg: "Amms must have been created within 5 minutes (counted in slots) of proposal initialization", + }, + { + code: 6001, + name: "InvalidInitialObservation", + msg: "An amm has an `initial_observation` that doesn't match the `dao`'s config", + }, + { + code: 6002, + name: "InvalidMaxObservationChange", + msg: "An amm has a `max_observation_change_per_update` that doesn't match the `dao`'s config", + }, + { + code: 6003, + name: "InvalidSettlementAuthority", + msg: "One of the vaults has an invalid `settlement_authority`", + }, + { + code: 6004, + name: "ProposalTooYoung", + msg: "Proposal is too young to be executed or rejected", + }, + { + code: 6005, + name: "MarketsTooYoung", + msg: "Markets too young for proposal to be finalized. TWAP might need to be cranked", + }, + { + code: 6006, + name: "ProposalAlreadyFinalized", + msg: "This proposal has already been finalized", + }, + { + code: 6007, + name: "InvalidVaultNonce", + msg: "A conditional vault has an invalid nonce. A nonce should encode the proposal number", + }, + { + code: 6008, + name: "ProposalNotPassed", + msg: "This proposal can't be executed because it isn't in the passed state", + }, + { + code: 6009, + name: "InsufficientLpTokenBalance", + msg: "The proposer has fewer pass or fail LP tokens than they requested to lock", + }, + { + code: 6010, + name: "InsufficientLpTokenLock", + msg: "The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`", + }, + ], +}; diff --git a/sdk/src/v0.4/types/autocrat_migrator.ts b/sdk/src/v0.4/types/autocrat_migrator.ts new file mode 100644 index 00000000..05f5d3fc --- /dev/null +++ b/sdk/src/v0.4/types/autocrat_migrator.ts @@ -0,0 +1,237 @@ +export type AutocratMigrator = { + version: "0.1.0"; + name: "autocrat_migrator"; + instructions: [ + { + name: "multiTransfer2"; + accounts: [ + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "authority"; + isMut: true; + isSigner: true; + }, + { + name: "from0"; + isMut: true; + isSigner: false; + }, + { + name: "to0"; + isMut: true; + isSigner: false; + }, + { + name: "from1"; + isMut: true; + isSigner: false; + }, + { + name: "to1"; + isMut: true; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "lamportReceiver"; + isMut: true; + isSigner: false; + } + ]; + args: []; + }, + { + name: "multiTransfer4"; + accounts: [ + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "authority"; + isMut: true; + isSigner: true; + }, + { + name: "from0"; + isMut: true; + isSigner: false; + }, + { + name: "to0"; + isMut: true; + isSigner: false; + }, + { + name: "from1"; + isMut: true; + isSigner: false; + }, + { + name: "to1"; + isMut: true; + isSigner: false; + }, + { + name: "from2"; + isMut: true; + isSigner: false; + }, + { + name: "to2"; + isMut: true; + isSigner: false; + }, + { + name: "from3"; + isMut: true; + isSigner: false; + }, + { + name: "to3"; + isMut: true; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "lamportReceiver"; + isMut: true; + isSigner: false; + } + ]; + args: []; + } + ]; +}; + +export const IDL: AutocratMigrator = { + version: "0.1.0", + name: "autocrat_migrator", + instructions: [ + { + name: "multiTransfer2", + accounts: [ + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "authority", + isMut: true, + isSigner: true, + }, + { + name: "from0", + isMut: true, + isSigner: false, + }, + { + name: "to0", + isMut: true, + isSigner: false, + }, + { + name: "from1", + isMut: true, + isSigner: false, + }, + { + name: "to1", + isMut: true, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "lamportReceiver", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + { + name: "multiTransfer4", + accounts: [ + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "authority", + isMut: true, + isSigner: true, + }, + { + name: "from0", + isMut: true, + isSigner: false, + }, + { + name: "to0", + isMut: true, + isSigner: false, + }, + { + name: "from1", + isMut: true, + isSigner: false, + }, + { + name: "to1", + isMut: true, + isSigner: false, + }, + { + name: "from2", + isMut: true, + isSigner: false, + }, + { + name: "to2", + isMut: true, + isSigner: false, + }, + { + name: "from3", + isMut: true, + isSigner: false, + }, + { + name: "to3", + isMut: true, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "lamportReceiver", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + ], +}; diff --git a/sdk/src/v0.4/types/conditional_vault.ts b/sdk/src/v0.4/types/conditional_vault.ts new file mode 100644 index 00000000..7acfbc7e --- /dev/null +++ b/sdk/src/v0.4/types/conditional_vault.ts @@ -0,0 +1,1005 @@ +export type ConditionalVault = { + version: "0.4.0"; + name: "conditional_vault"; + instructions: [ + { + name: "initializeQuestion"; + accounts: [ + { + name: "question"; + isMut: true; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "InitializeQuestionArgs"; + }; + } + ]; + }, + { + name: "resolveQuestion"; + accounts: [ + { + name: "question"; + isMut: true; + isSigner: false; + }, + { + name: "oracle"; + isMut: false; + isSigner: true; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "ResolveQuestionArgs"; + }; + } + ]; + }, + { + name: "initializeConditionalVault"; + accounts: [ + { + name: "vault"; + isMut: true; + isSigner: false; + }, + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "underlyingTokenMint"; + isMut: false; + isSigner: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + isMut: false; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "splitTokens"; + accounts: [ + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "vault"; + isMut: false; + isSigner: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "userUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "amount"; + type: "u64"; + } + ]; + }, + { + name: "mergeTokens"; + accounts: [ + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "vault"; + isMut: false; + isSigner: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "userUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "amount"; + type: "u64"; + } + ]; + }, + { + name: "redeemTokens"; + accounts: [ + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "vault"; + isMut: false; + isSigner: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "userUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "addMetadataToConditionalTokens"; + accounts: [ + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "vault"; + isMut: true; + isSigner: false; + }, + { + name: "conditionalTokenMint"; + isMut: true; + isSigner: false; + }, + { + name: "conditionalTokenMetadata"; + isMut: true; + isSigner: false; + }, + { + name: "tokenMetadataProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "rent"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "AddMetadataToConditionalTokensArgs"; + }; + } + ]; + } + ]; + accounts: [ + { + name: "conditionalVault"; + type: { + kind: "struct"; + fields: [ + { + name: "question"; + type: "publicKey"; + }, + { + name: "underlyingTokenMint"; + type: "publicKey"; + }, + { + name: "underlyingTokenAccount"; + type: "publicKey"; + }, + { + name: "conditionalTokenMints"; + type: { + vec: "publicKey"; + }; + }, + { + name: "pdaBump"; + type: "u8"; + }, + { + name: "decimals"; + type: "u8"; + } + ]; + }; + }, + { + name: "question"; + docs: [ + "Questions represent statements about future events.", + "", + "These statements include:", + '- "Will this proposal pass?"', + '- "Who, if anyone, will be hired?"', + '- "How effective will the grant committee deem this grant?"', + "", + 'Questions have 2 or more possible outcomes. For a question like "will this', + 'proposal pass," the outcomes are "yes" and "no." For a question like "who', + 'will be hired," the outcomes could be "Alice," "Bob," and "neither."', + "", + 'Outcomes resolve to a number between 0 and 1. Binary questions like "will', + 'this proposal pass" have outcomes that resolve to exactly 0 or 1. You can', + 'also have questions with scalar outcomes. For example, the question "how', + 'effective will the grant committee deem this grant" could have two outcomes:', + '"ineffective" and "effective." If the grant committee deems the grant 70%', + 'effective, the "effective" outcome would resolve to 0.7 and the "ineffective"', + "outcome would resolve to 0.3.", + "", + "Once resolved, the sum of all outcome resolutions is exactly 1." + ]; + type: { + kind: "struct"; + fields: [ + { + name: "questionId"; + type: { + array: ["u8", 32]; + }; + }, + { + name: "oracle"; + type: "publicKey"; + }, + { + name: "payoutNumerators"; + type: { + vec: "u32"; + }; + }, + { + name: "payoutDenominator"; + type: "u32"; + } + ]; + }; + } + ]; + types: [ + { + name: "AddMetadataToConditionalTokensArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "name"; + type: "string"; + }, + { + name: "symbol"; + type: "string"; + }, + { + name: "uri"; + type: "string"; + } + ]; + }; + }, + { + name: "InitializeQuestionArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "questionId"; + type: { + array: ["u8", 32]; + }; + }, + { + name: "oracle"; + type: "publicKey"; + }, + { + name: "numConditions"; + type: "u8"; + } + ]; + }; + }, + { + name: "ResolveQuestionArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "payoutNumerators"; + type: { + vec: "u32"; + }; + } + ]; + }; + }, + { + name: "VaultStatus"; + type: { + kind: "enum"; + variants: [ + { + name: "Active"; + }, + { + name: "Finalized"; + }, + { + name: "Reverted"; + } + ]; + }; + } + ]; + errors: [ + { + code: 6000; + name: "InsufficientUnderlyingTokens"; + msg: "Insufficient underlying token balance to mint this amount of conditional tokens"; + }, + { + code: 6001; + name: "InsufficientConditionalTokens"; + msg: "Insufficient conditional token balance to merge this `amount`"; + }, + { + code: 6002; + name: "InvalidVaultUnderlyingTokenAccount"; + msg: "This `vault_underlying_token_account` is not this vault's `underlying_token_account`"; + }, + { + code: 6003; + name: "InvalidConditionalTokenMint"; + msg: "This conditional token mint is not this vault's conditional token mint"; + }, + { + code: 6004; + name: "CantRedeemConditionalTokens"; + msg: "Question needs to be resolved before users can redeem conditional tokens for underlying tokens"; + }, + { + code: 6005; + name: "InsufficientNumConditions"; + msg: "Questions need 2 or more conditions"; + }, + { + code: 6006; + name: "InvalidNumPayoutNumerators"; + msg: "Invalid number of payout numerators"; + }, + { + code: 6007; + name: "InvalidConditionals"; + msg: "Client needs to pass in the list of conditional mints for a vault followed by the user's token accounts for those tokens"; + }, + { + code: 6008; + name: "ConditionalMintMismatch"; + msg: "Conditional mint not in vault"; + }, + { + code: 6009; + name: "BadConditionalMint"; + msg: "Unable to deserialize a conditional token mint"; + }, + { + code: 6010; + name: "BadConditionalTokenAccount"; + msg: "Unable to deserialize a conditional token account"; + }, + { + code: 6011; + name: "ConditionalTokenMintMismatch"; + msg: "User conditional token account mint does not match conditional mint"; + }, + { + code: 6012; + name: "PayoutZero"; + msg: "Payouts must sum to 1 or more"; + }, + { + code: 6013; + name: "ConditionalTokenMetadataAlreadySet"; + msg: "Conditional token metadata already set"; + } + ]; +}; + +export const IDL: ConditionalVault = { + version: "0.4.0", + name: "conditional_vault", + instructions: [ + { + name: "initializeQuestion", + accounts: [ + { + name: "question", + isMut: true, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "InitializeQuestionArgs", + }, + }, + ], + }, + { + name: "resolveQuestion", + accounts: [ + { + name: "question", + isMut: true, + isSigner: false, + }, + { + name: "oracle", + isMut: false, + isSigner: true, + }, + ], + args: [ + { + name: "args", + type: { + defined: "ResolveQuestionArgs", + }, + }, + ], + }, + { + name: "initializeConditionalVault", + accounts: [ + { + name: "vault", + isMut: true, + isSigner: false, + }, + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "underlyingTokenMint", + isMut: false, + isSigner: false, + }, + { + name: "vaultUnderlyingTokenAccount", + isMut: false, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "splitTokens", + accounts: [ + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "vault", + isMut: false, + isSigner: false, + }, + { + name: "vaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "userUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "amount", + type: "u64", + }, + ], + }, + { + name: "mergeTokens", + accounts: [ + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "vault", + isMut: false, + isSigner: false, + }, + { + name: "vaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "userUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "amount", + type: "u64", + }, + ], + }, + { + name: "redeemTokens", + accounts: [ + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "vault", + isMut: false, + isSigner: false, + }, + { + name: "vaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "userUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "addMetadataToConditionalTokens", + accounts: [ + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "vault", + isMut: true, + isSigner: false, + }, + { + name: "conditionalTokenMint", + isMut: true, + isSigner: false, + }, + { + name: "conditionalTokenMetadata", + isMut: true, + isSigner: false, + }, + { + name: "tokenMetadataProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "rent", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "AddMetadataToConditionalTokensArgs", + }, + }, + ], + }, + ], + accounts: [ + { + name: "conditionalVault", + type: { + kind: "struct", + fields: [ + { + name: "question", + type: "publicKey", + }, + { + name: "underlyingTokenMint", + type: "publicKey", + }, + { + name: "underlyingTokenAccount", + type: "publicKey", + }, + { + name: "conditionalTokenMints", + type: { + vec: "publicKey", + }, + }, + { + name: "pdaBump", + type: "u8", + }, + { + name: "decimals", + type: "u8", + }, + ], + }, + }, + { + name: "question", + docs: [ + "Questions represent statements about future events.", + "", + "These statements include:", + '- "Will this proposal pass?"', + '- "Who, if anyone, will be hired?"', + '- "How effective will the grant committee deem this grant?"', + "", + 'Questions have 2 or more possible outcomes. For a question like "will this', + 'proposal pass," the outcomes are "yes" and "no." For a question like "who', + 'will be hired," the outcomes could be "Alice," "Bob," and "neither."', + "", + 'Outcomes resolve to a number between 0 and 1. Binary questions like "will', + 'this proposal pass" have outcomes that resolve to exactly 0 or 1. You can', + 'also have questions with scalar outcomes. For example, the question "how', + 'effective will the grant committee deem this grant" could have two outcomes:', + '"ineffective" and "effective." If the grant committee deems the grant 70%', + 'effective, the "effective" outcome would resolve to 0.7 and the "ineffective"', + "outcome would resolve to 0.3.", + "", + "Once resolved, the sum of all outcome resolutions is exactly 1.", + ], + type: { + kind: "struct", + fields: [ + { + name: "questionId", + type: { + array: ["u8", 32], + }, + }, + { + name: "oracle", + type: "publicKey", + }, + { + name: "payoutNumerators", + type: { + vec: "u32", + }, + }, + { + name: "payoutDenominator", + type: "u32", + }, + ], + }, + }, + ], + types: [ + { + name: "AddMetadataToConditionalTokensArgs", + type: { + kind: "struct", + fields: [ + { + name: "name", + type: "string", + }, + { + name: "symbol", + type: "string", + }, + { + name: "uri", + type: "string", + }, + ], + }, + }, + { + name: "InitializeQuestionArgs", + type: { + kind: "struct", + fields: [ + { + name: "questionId", + type: { + array: ["u8", 32], + }, + }, + { + name: "oracle", + type: "publicKey", + }, + { + name: "numConditions", + type: "u8", + }, + ], + }, + }, + { + name: "ResolveQuestionArgs", + type: { + kind: "struct", + fields: [ + { + name: "payoutNumerators", + type: { + vec: "u32", + }, + }, + ], + }, + }, + { + name: "VaultStatus", + type: { + kind: "enum", + variants: [ + { + name: "Active", + }, + { + name: "Finalized", + }, + { + name: "Reverted", + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: "InsufficientUnderlyingTokens", + msg: "Insufficient underlying token balance to mint this amount of conditional tokens", + }, + { + code: 6001, + name: "InsufficientConditionalTokens", + msg: "Insufficient conditional token balance to merge this `amount`", + }, + { + code: 6002, + name: "InvalidVaultUnderlyingTokenAccount", + msg: "This `vault_underlying_token_account` is not this vault's `underlying_token_account`", + }, + { + code: 6003, + name: "InvalidConditionalTokenMint", + msg: "This conditional token mint is not this vault's conditional token mint", + }, + { + code: 6004, + name: "CantRedeemConditionalTokens", + msg: "Question needs to be resolved before users can redeem conditional tokens for underlying tokens", + }, + { + code: 6005, + name: "InsufficientNumConditions", + msg: "Questions need 2 or more conditions", + }, + { + code: 6006, + name: "InvalidNumPayoutNumerators", + msg: "Invalid number of payout numerators", + }, + { + code: 6007, + name: "InvalidConditionals", + msg: "Client needs to pass in the list of conditional mints for a vault followed by the user's token accounts for those tokens", + }, + { + code: 6008, + name: "ConditionalMintMismatch", + msg: "Conditional mint not in vault", + }, + { + code: 6009, + name: "BadConditionalMint", + msg: "Unable to deserialize a conditional token mint", + }, + { + code: 6010, + name: "BadConditionalTokenAccount", + msg: "Unable to deserialize a conditional token account", + }, + { + code: 6011, + name: "ConditionalTokenMintMismatch", + msg: "User conditional token account mint does not match conditional mint", + }, + { + code: 6012, + name: "PayoutZero", + msg: "Payouts must sum to 1 or more", + }, + { + code: 6013, + name: "ConditionalTokenMetadataAlreadySet", + msg: "Conditional token metadata already set", + }, + ], +}; diff --git a/sdk/src/v0.4/types/index.ts b/sdk/src/v0.4/types/index.ts new file mode 100644 index 00000000..472e02bf --- /dev/null +++ b/sdk/src/v0.4/types/index.ts @@ -0,0 +1,34 @@ +import { Autocrat } from "./autocrat.js"; +export { Autocrat, IDL as AutocratIDL } from "./autocrat.js"; + +import { Amm } from "./amm.js"; +export { Amm, IDL as AmmIDL } from "./amm.js"; + +import { ConditionalVault } from "./conditional_vault.js"; +export { + ConditionalVault, + IDL as ConditionalVaultIDL, +} from "./conditional_vault.js"; + +export { LowercaseKeys } from "./utils.js"; + +import type { IdlAccounts, IdlTypes } from "@coral-xyz/anchor"; +import { PublicKey } from "@solana/web3.js"; + +export type InitializeDaoParams = IdlTypes["InitializeDaoParams"]; +export type UpdateDaoParams = IdlTypes["UpdateDaoParams"]; +export type ProposalInstruction = IdlTypes["ProposalInstruction"]; + +export type Proposal = IdlAccounts["proposal"]; +export type ProposalWrapper = { + account: Proposal; + publicKey: PublicKey; +}; + +export type Dao = IdlAccounts["dao"]; +export type ProposalAccount = IdlAccounts["proposal"]; + +export type AmmAccount = IdlAccounts["amm"]; + +export type ConditionalVaultAccount = + IdlAccounts["conditionalVault"]; diff --git a/sdk/src/v0.4/types/optimistic_timelock.ts b/sdk/src/v0.4/types/optimistic_timelock.ts new file mode 100644 index 00000000..dda1fa46 --- /dev/null +++ b/sdk/src/v0.4/types/optimistic_timelock.ts @@ -0,0 +1,1023 @@ +export type OptimisticTimelock = { + version: "0.3.0"; + name: "optimistic_timelock"; + instructions: [ + { + name: "createTimelock"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: false; + }, + { + name: "timelock"; + isMut: true; + isSigner: true; + } + ]; + args: [ + { + name: "authority"; + type: "publicKey"; + }, + { + name: "delayInSlots"; + type: "u64"; + }, + { + name: "enqueuers"; + type: { + vec: "publicKey"; + }; + }, + { + name: "enqueuerCooldownSlots"; + type: "u64"; + } + ]; + }, + { + name: "setDelayInSlots"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "delayInSlots"; + type: "u64"; + } + ]; + }, + { + name: "setAuthority"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "authority"; + type: "publicKey"; + } + ]; + }, + { + name: "setOptimisticProposerCooldownSlots"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "cooldownSlots"; + type: "u64"; + } + ]; + }, + { + name: "addOptimisticProposer"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "enqueuer"; + type: "publicKey"; + } + ]; + }, + { + name: "removeOptimisticProposer"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "optimisticProposer"; + type: "publicKey"; + } + ]; + }, + { + name: "createTransactionBatch"; + accounts: [ + { + name: "transactionBatchAuthority"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: false; + isSigner: false; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: true; + } + ]; + args: []; + }, + { + name: "addTransaction"; + accounts: [ + { + name: "transactionBatchAuthority"; + isMut: false; + isSigner: true; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "programId"; + type: "publicKey"; + }, + { + name: "accounts"; + type: { + vec: { + defined: "TransactionAccount"; + }; + }; + }, + { + name: "data"; + type: "bytes"; + } + ]; + }, + { + name: "sealTransactionBatch"; + accounts: [ + { + name: "transactionBatchAuthority"; + isMut: false; + isSigner: true; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: []; + }, + { + name: "enqueueTransactionBatch"; + accounts: [ + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: []; + }, + { + name: "cancelTransactionBatch"; + accounts: [ + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: []; + }, + { + name: "executeTransactionBatch"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: false; + }, + { + name: "timelock"; + isMut: false; + isSigner: false; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: []; + } + ]; + accounts: [ + { + name: "timelock"; + type: { + kind: "struct"; + fields: [ + { + name: "authority"; + type: "publicKey"; + }, + { + name: "signerBump"; + type: "u8"; + }, + { + name: "delayInSlots"; + type: "u64"; + }, + { + name: "optimisticProposers"; + type: { + vec: { + defined: "OptimisticProposer"; + }; + }; + }, + { + name: "optimisticProposerCooldownSlots"; + docs: [ + "The cooldown period for enqueuers to prevent spamming the timelock." + ]; + type: "u64"; + } + ]; + }; + }, + { + name: "transactionBatch"; + type: { + kind: "struct"; + fields: [ + { + name: "status"; + type: { + defined: "TransactionBatchStatus"; + }; + }, + { + name: "transactions"; + type: { + vec: { + defined: "Transaction"; + }; + }; + }, + { + name: "timelock"; + type: "publicKey"; + }, + { + name: "enqueuedSlot"; + type: "u64"; + }, + { + name: "transactionBatchAuthority"; + type: "publicKey"; + }, + { + name: "enqueuerType"; + type: { + defined: "AuthorityType"; + }; + } + ]; + }; + } + ]; + types: [ + { + name: "OptimisticProposer"; + type: { + kind: "struct"; + fields: [ + { + name: "pubkey"; + type: "publicKey"; + }, + { + name: "lastSlotEnqueued"; + type: "u64"; + } + ]; + }; + }, + { + name: "Transaction"; + type: { + kind: "struct"; + fields: [ + { + name: "programId"; + type: "publicKey"; + }, + { + name: "accounts"; + type: { + vec: { + defined: "TransactionAccount"; + }; + }; + }, + { + name: "data"; + type: "bytes"; + }, + { + name: "didExecute"; + type: "bool"; + } + ]; + }; + }, + { + name: "TransactionAccount"; + type: { + kind: "struct"; + fields: [ + { + name: "pubkey"; + type: "publicKey"; + }, + { + name: "isSigner"; + type: "bool"; + }, + { + name: "isWritable"; + type: "bool"; + } + ]; + }; + }, + { + name: "AuthorityType"; + type: { + kind: "enum"; + variants: [ + { + name: "OptimisticProposer"; + }, + { + name: "TimelockAuthority"; + } + ]; + }; + }, + { + name: "TransactionBatchStatus"; + type: { + kind: "enum"; + variants: [ + { + name: "Created"; + }, + { + name: "Sealed"; + }, + { + name: "Enqueued"; + }, + { + name: "Cancelled"; + }, + { + name: "Executed"; + } + ]; + }; + } + ]; + errors: [ + { + code: 6000; + name: "NotReady"; + msg: "This transaction is not yet ready to be executed"; + }, + { + code: 6001; + name: "CannotAddTransactions"; + msg: "Can only add instructions when transaction batch status is `Created`"; + }, + { + code: 6002; + name: "CannotSealTransactionBatch"; + msg: "Can only seal the transaction batch when status is `Created`"; + }, + { + code: 6003; + name: "CannotEnqueueTransactionBatch"; + msg: "Can only enqueue the timelock running once the status is `Sealed`"; + }, + { + code: 6004; + name: "CannotCancelTimelock"; + msg: "Can only cancel the transactions if the status `Enqueued`"; + }, + { + code: 6005; + name: "CanOnlyCancelDuringTimelockPeriod"; + msg: "Can only cancel the transactions during the timelock period"; + }, + { + code: 6006; + name: "CannotExecuteTransactions"; + msg: "Can only execute the transactions if the status is `Enqueued`"; + }, + { + code: 6007; + name: "NoAuthority"; + msg: "The signer is neither the timelock authority nor an optimistic proposer"; + }, + { + code: 6008; + name: "InsufficientPermissions"; + msg: "Optimistic proposers can't cancel transaction batches enqueued by the timelock authority"; + }, + { + code: 6009; + name: "OptimisticProposerCooldown"; + msg: "This optimistic proposer is still in its cooldown period"; + } + ]; +}; + +export const IDL: OptimisticTimelock = { + version: "0.3.0", + name: "optimistic_timelock", + instructions: [ + { + name: "createTimelock", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: false, + }, + { + name: "timelock", + isMut: true, + isSigner: true, + }, + ], + args: [ + { + name: "authority", + type: "publicKey", + }, + { + name: "delayInSlots", + type: "u64", + }, + { + name: "enqueuers", + type: { + vec: "publicKey", + }, + }, + { + name: "enqueuerCooldownSlots", + type: "u64", + }, + ], + }, + { + name: "setDelayInSlots", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "delayInSlots", + type: "u64", + }, + ], + }, + { + name: "setAuthority", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "authority", + type: "publicKey", + }, + ], + }, + { + name: "setOptimisticProposerCooldownSlots", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "cooldownSlots", + type: "u64", + }, + ], + }, + { + name: "addOptimisticProposer", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "enqueuer", + type: "publicKey", + }, + ], + }, + { + name: "removeOptimisticProposer", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "optimisticProposer", + type: "publicKey", + }, + ], + }, + { + name: "createTransactionBatch", + accounts: [ + { + name: "transactionBatchAuthority", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: false, + isSigner: false, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: true, + }, + ], + args: [], + }, + { + name: "addTransaction", + accounts: [ + { + name: "transactionBatchAuthority", + isMut: false, + isSigner: true, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "programId", + type: "publicKey", + }, + { + name: "accounts", + type: { + vec: { + defined: "TransactionAccount", + }, + }, + }, + { + name: "data", + type: "bytes", + }, + ], + }, + { + name: "sealTransactionBatch", + accounts: [ + { + name: "transactionBatchAuthority", + isMut: false, + isSigner: true, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + { + name: "enqueueTransactionBatch", + accounts: [ + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + { + name: "cancelTransactionBatch", + accounts: [ + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + { + name: "executeTransactionBatch", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: false, + }, + { + name: "timelock", + isMut: false, + isSigner: false, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + ], + accounts: [ + { + name: "timelock", + type: { + kind: "struct", + fields: [ + { + name: "authority", + type: "publicKey", + }, + { + name: "signerBump", + type: "u8", + }, + { + name: "delayInSlots", + type: "u64", + }, + { + name: "optimisticProposers", + type: { + vec: { + defined: "OptimisticProposer", + }, + }, + }, + { + name: "optimisticProposerCooldownSlots", + docs: [ + "The cooldown period for enqueuers to prevent spamming the timelock.", + ], + type: "u64", + }, + ], + }, + }, + { + name: "transactionBatch", + type: { + kind: "struct", + fields: [ + { + name: "status", + type: { + defined: "TransactionBatchStatus", + }, + }, + { + name: "transactions", + type: { + vec: { + defined: "Transaction", + }, + }, + }, + { + name: "timelock", + type: "publicKey", + }, + { + name: "enqueuedSlot", + type: "u64", + }, + { + name: "transactionBatchAuthority", + type: "publicKey", + }, + { + name: "enqueuerType", + type: { + defined: "AuthorityType", + }, + }, + ], + }, + }, + ], + types: [ + { + name: "OptimisticProposer", + type: { + kind: "struct", + fields: [ + { + name: "pubkey", + type: "publicKey", + }, + { + name: "lastSlotEnqueued", + type: "u64", + }, + ], + }, + }, + { + name: "Transaction", + type: { + kind: "struct", + fields: [ + { + name: "programId", + type: "publicKey", + }, + { + name: "accounts", + type: { + vec: { + defined: "TransactionAccount", + }, + }, + }, + { + name: "data", + type: "bytes", + }, + { + name: "didExecute", + type: "bool", + }, + ], + }, + }, + { + name: "TransactionAccount", + type: { + kind: "struct", + fields: [ + { + name: "pubkey", + type: "publicKey", + }, + { + name: "isSigner", + type: "bool", + }, + { + name: "isWritable", + type: "bool", + }, + ], + }, + }, + { + name: "AuthorityType", + type: { + kind: "enum", + variants: [ + { + name: "OptimisticProposer", + }, + { + name: "TimelockAuthority", + }, + ], + }, + }, + { + name: "TransactionBatchStatus", + type: { + kind: "enum", + variants: [ + { + name: "Created", + }, + { + name: "Sealed", + }, + { + name: "Enqueued", + }, + { + name: "Cancelled", + }, + { + name: "Executed", + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: "NotReady", + msg: "This transaction is not yet ready to be executed", + }, + { + code: 6001, + name: "CannotAddTransactions", + msg: "Can only add instructions when transaction batch status is `Created`", + }, + { + code: 6002, + name: "CannotSealTransactionBatch", + msg: "Can only seal the transaction batch when status is `Created`", + }, + { + code: 6003, + name: "CannotEnqueueTransactionBatch", + msg: "Can only enqueue the timelock running once the status is `Sealed`", + }, + { + code: 6004, + name: "CannotCancelTimelock", + msg: "Can only cancel the transactions if the status `Enqueued`", + }, + { + code: 6005, + name: "CanOnlyCancelDuringTimelockPeriod", + msg: "Can only cancel the transactions during the timelock period", + }, + { + code: 6006, + name: "CannotExecuteTransactions", + msg: "Can only execute the transactions if the status is `Enqueued`", + }, + { + code: 6007, + name: "NoAuthority", + msg: "The signer is neither the timelock authority nor an optimistic proposer", + }, + { + code: 6008, + name: "InsufficientPermissions", + msg: "Optimistic proposers can't cancel transaction batches enqueued by the timelock authority", + }, + { + code: 6009, + name: "OptimisticProposerCooldown", + msg: "This optimistic proposer is still in its cooldown period", + }, + ], +}; diff --git a/sdk/src/v0.4/types/utils.ts b/sdk/src/v0.4/types/utils.ts new file mode 100644 index 00000000..c878debe --- /dev/null +++ b/sdk/src/v0.4/types/utils.ts @@ -0,0 +1,3 @@ +export type LowercaseKeys = { + [K in keyof T as Lowercase]: T[K]; +}; diff --git a/sdk/src/v0.4/utils/cu.ts b/sdk/src/v0.4/utils/cu.ts new file mode 100644 index 00000000..7264b2bc --- /dev/null +++ b/sdk/src/v0.4/utils/cu.ts @@ -0,0 +1,11 @@ +export const MaxCUs = { + initializeDao: 30_000, + createIdempotent: 25_000, + initializeConditionalVault: 45_000, + mintConditionalTokens: 35_000, + initializeAmm: 120_000, + addLiquidity: 120_000, + initializeProposal: 60_000, +}; + +export const DEFAULT_CU_PRICE = 1; diff --git a/sdk/src/v0.4/utils/filters.ts b/sdk/src/v0.4/utils/filters.ts new file mode 100644 index 00000000..945f7731 --- /dev/null +++ b/sdk/src/v0.4/utils/filters.ts @@ -0,0 +1,21 @@ +import { GetProgramAccountsFilter, PublicKey } from "@solana/web3.js"; + +export const filterPositionsByUser = ( + userAddr: PublicKey +): GetProgramAccountsFilter => ({ + memcmp: { + offset: 8, // discriminator + bytes: userAddr.toBase58(), + }, +}); + +export const filterPositionsByAmm = ( + ammAddr: PublicKey +): GetProgramAccountsFilter => ({ + memcmp: { + offset: + 8 + // discriminator + 32, // user address + bytes: ammAddr.toBase58(), + }, +}); diff --git a/sdk/src/v0.4/utils/index.ts b/sdk/src/v0.4/utils/index.ts new file mode 100644 index 00000000..cb5d012e --- /dev/null +++ b/sdk/src/v0.4/utils/index.ts @@ -0,0 +1,40 @@ +export * from "./filters.js"; +export * from "./pda.js"; +export * from "./priceMath.js"; +export * from "./metadata.js"; +export * from "./cu.js"; +export * from "./instruction.js"; + +import { AccountMeta, ComputeBudgetProgram, PublicKey } from "@solana/web3.js"; + +export enum PriorityFeeTier { + NORMAL = 35, + HIGH = 3571, + TURBO = 357142, +} + +export const addComputeUnits = (num_units: number = 1_400_000) => + ComputeBudgetProgram.setComputeUnitLimit({ + units: num_units, + }); + +export const addPriorityFee = (pf: number) => + ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: pf, + }); + +export const pubkeyToAccountInfo = ( + pubkey: PublicKey, + isWritable: boolean, + isSigner = false +): AccountMeta => { + return { + pubkey: pubkey, + isSigner: isSigner, + isWritable: isWritable, + }; +}; + +export async function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/sdk/src/v0.4/utils/instruction.ts b/sdk/src/v0.4/utils/instruction.ts new file mode 100644 index 00000000..f18e4883 --- /dev/null +++ b/sdk/src/v0.4/utils/instruction.ts @@ -0,0 +1,16 @@ +import * as anchor from "@coral-xyz/anchor"; +import { TransactionInstruction } from "@solana/web3.js"; + +export class InstructionUtils { + public static async getInstructions( + ...methodBuilders: any[] + ): Promise { + let instructions: TransactionInstruction[] = []; + + for (const methodBuilder of methodBuilders) { + instructions.push(...(await methodBuilder.transaction()).instructions); + } + + return instructions; + } +} diff --git a/sdk/src/v0.4/utils/metadata.ts b/sdk/src/v0.4/utils/metadata.ts new file mode 100644 index 00000000..922a89f3 --- /dev/null +++ b/sdk/src/v0.4/utils/metadata.ts @@ -0,0 +1,35 @@ +import BN from "bn.js"; +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { Connection } from "@solana/web3.js"; +import { bundlrUploader } from "@metaplex-foundation/umi-uploader-bundlr"; +import { UmiPlugin } from "@metaplex-foundation/umi"; + +export const assetImageMap: Record = { + fMETA: "https://arweave.net/tGxvOjMZw7B0qHsdCcIMO57oH5g5OaItOZdXo3BXKz8", + fUSDC: "https://arweave.net/DpvxeAyVbaoivhIVCLjdf566k2SwVn0YVBL0sTOezWk", + pMETA: "https://arweave.net/iuqi7PRRESdDxj1oRyk2WzR90_zdFcmZsuWicv3XGfs", + pUSDC: "https://arweave.net/e4IO7F59F_RKCiuB--_ABPot7Qh1yFsGkWzVhcXuKDU", +}; + +// Upload some JSON, returning its URL +export const uploadConditionalTokenMetadataJson = async ( + connection: Connection, + identityPlugin: UmiPlugin, + proposalNumber: number, + symbol: string + // proposal: BN, + // conditionalToken: string, + // image: string +): Promise => { + // use bundlr, targeting arweave + const umi = createUmi(connection); + umi.use(bundlrUploader()); + umi.use(identityPlugin); + + return umi.uploader.uploadJson({ + name: `Proposal ${proposalNumber}: ${symbol}`, + image: assetImageMap[symbol], + symbol, + description: "A conditional token for use in futarchy.", + }); +}; diff --git a/sdk/src/v0.4/utils/pda.ts b/sdk/src/v0.4/utils/pda.ts new file mode 100644 index 00000000..13d5a4d5 --- /dev/null +++ b/sdk/src/v0.4/utils/pda.ts @@ -0,0 +1,146 @@ +import { AccountMeta, PublicKey } from "@solana/web3.js"; +import { utils } from "@coral-xyz/anchor"; +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, +} from "@solana/spl-token"; +import BN from "bn.js"; +import { + fromWeb3JsPublicKey, + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { MPL_TOKEN_METADATA_PROGRAM_ID } from "../constants.js"; + +export const getQuestionAddr = ( + programId: PublicKey, + questionId: Uint8Array, + oracle: PublicKey, + numConditions: number +) => { + if (questionId.length != 32) { + throw new Error("questionId must be 32 bytes"); + } + + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("question"), + Buffer.from(questionId), + oracle.toBuffer(), + new BN(numConditions).toBuffer("le", 1), + ], + programId + ); +}; + +export const getVaultAddr = ( + programId: PublicKey, + question: PublicKey, + underlyingTokenMint: PublicKey +) => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("conditional_vault"), + question.toBuffer(), + underlyingTokenMint.toBuffer(), + ], + programId + ); +}; + +export const getConditionalTokenMintAddr = ( + programId: PublicKey, + vault: PublicKey, + index: number +) => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("conditional_token"), + vault.toBuffer(), + new BN(index).toBuffer("le", 1), + ], + programId + ); +}; + +export const getVaultFinalizeMintAddr = ( + programId: PublicKey, + vault: PublicKey +) => { + return getVaultMintAddr(programId, vault, "conditional_on_finalize_mint"); +}; + +export const getMetadataAddr = (mint: PublicKey) => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("metadata"), + MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), + mint.toBuffer(), + ], + MPL_TOKEN_METADATA_PROGRAM_ID + ); +}; + +export const getVaultRevertMintAddr = ( + programId: PublicKey, + vault: PublicKey +) => { + return getVaultMintAddr(programId, vault, "conditional_on_revert_mint"); +}; + +const getVaultMintAddr = ( + programId: PublicKey, + vault: PublicKey, + seed: string +) => { + return PublicKey.findProgramAddressSync( + [utils.bytes.utf8.encode(seed), vault.toBuffer()], + programId + ); +}; + +export const getDaoTreasuryAddr = ( + programId: PublicKey, + dao: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync([dao.toBuffer()], programId); +}; + +export const getProposalAddr = ( + programId: PublicKey, + proposer: PublicKey, + nonce: BN +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("proposal"), + proposer.toBuffer(), + nonce.toArrayLike(Buffer, "le", 8), + ], + programId + ); +}; + +export const getAmmAddr = ( + programId: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("amm__"), + baseMint.toBuffer(), + quoteMint.toBuffer(), + ], + programId + ); +}; + +export const getAmmLpMintAddr = ( + programId: PublicKey, + amm: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [utils.bytes.utf8.encode("amm_lp_mint"), amm.toBuffer()], + programId + ); +}; diff --git a/sdk/src/v0.4/utils/priceMath.ts b/sdk/src/v0.4/utils/priceMath.ts new file mode 100644 index 00000000..305c3375 --- /dev/null +++ b/sdk/src/v0.4/utils/priceMath.ts @@ -0,0 +1,85 @@ +import BN from "bn.js"; + +const BN_TEN = new BN(10); +const PRICE_SCALE = BN_TEN.pow(new BN(12)); +const PRICE_SCALE_NUMBER = 1e12; + +export class PriceMath { + public static getAmmPriceFromReserves( + baseReserves: BN, + quoteReserves: BN + ): BN { + return quoteReserves.mul(PRICE_SCALE).div(baseReserves); + } + + public static getChainAmount(humanAmount: number, decimals: number): BN { + // you have to do it this weird way because BN can't be constructed with + // numbers larger than 2**50 + const [integerPart, fractionalPart = ""] = humanAmount + .toString() + .split("."); + return new BN(integerPart + fractionalPart) + .mul(new BN(10).pow(new BN(decimals))) + .div(new BN(10).pow(new BN(fractionalPart.length))); + } + + public static getHumanAmount(chainAmount: BN, decimals: number): number { + return chainAmount.toNumber() / 10 ** decimals; + } + + public static getHumanPrice( + ammPrice: BN, + baseDecimals: number, + quoteDecimals: number + ): number { + let decimalScalar = BN_TEN.pow(new BN(quoteDecimals - baseDecimals).abs()); + + let price1e12 = + quoteDecimals > baseDecimals + ? ammPrice.div(decimalScalar) + : ammPrice.mul(decimalScalar); + + return price1e12.toNumber() / 1e12; + } + + public static getAmmPrice( + humanPrice: number, + baseDecimals: number, + quoteDecimals: number + ): BN { + let price1e12 = new BN(humanPrice * PRICE_SCALE_NUMBER); + + let decimalScalar = BN_TEN.pow(new BN(quoteDecimals - baseDecimals).abs()); + + let scaledPrice = + quoteDecimals > baseDecimals + ? price1e12.mul(decimalScalar) + : price1e12.div(decimalScalar); + + return scaledPrice; + } + + public static getAmmPrices( + baseDecimals: number, + quoteDecimals: number, + ...prices: number[] + ): BN[] { + // Map through each price, scaling it using the scalePrice method + return prices.map((price) => + this.getAmmPrice(price, baseDecimals, quoteDecimals) + ); + } + + public static scale(number: number, decimals: number): BN { + return new BN(number * 10 ** decimals); + // return new BN(number).mul(new BN(10).pow(new BN(decimals))); + } + + public static addSlippage(chainAmount: BN, slippageBps: BN): BN { + return chainAmount.mul(slippageBps.addn(10_000)).divn(10_000); + } + + public static subtractSlippage(chainAmount: BN, slippageBps: BN): BN { + return chainAmount.mul(new BN(10_000).sub(slippageBps)).divn(10_000); + } +} diff --git a/sdk/tsconfig.json b/sdk/tsconfig.json index ddceb6e9..ba75c571 100644 --- a/sdk/tsconfig.json +++ b/sdk/tsconfig.json @@ -4,17 +4,20 @@ "mocha", "chai" ], + "paths": { + "@metadaoproject/futarchy/v0.4": ["./dist/v0.4/types/index.d.ts"] + }, "typeRoots": [ "./node_modules/@types" ], "lib": [ "esnext" ], - "module": "commonjs", + "module": "NodeNext", "target": "esnext", "esModuleInterop": true, "skipLibCheck": true, - "moduleResolution": "node", + "moduleResolution": "nodenext", "sourceMap": true, "outDir": "dist", "strict": true, @@ -22,6 +25,7 @@ }, "include": [ "src/*", + "src/v0.4/*" ], "exclude": [ "node_modules", diff --git a/sdk/yarn.lock b/sdk/yarn.lock index 030d5a20..159e0282 100644 --- a/sdk/yarn.lock +++ b/sdk/yarn.lock @@ -159,6 +159,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== +"@noble/hashes@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + "@solana/buffer-layout-utils@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca" @@ -1298,7 +1303,7 @@ type-detect@^4.0.0, type-detect@^4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -typescript@^4.3.5: +typescript@^4.9.5: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== diff --git a/tests/amm.ts b/tests/amm/amm.ts similarity index 97% rename from tests/amm.ts rename to tests/amm/amm.ts index 25fe0dd9..db149295 100644 --- a/tests/amm.ts +++ b/tests/amm/amm.ts @@ -26,7 +26,7 @@ import { } from "@metadaoproject/futarchy"; import { Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; -import { expectError, fastForward } from "./utils/utils"; +import { expectError, advanceBySlots } from "../utils"; const META_DECIMALS = 9; const USDC_DECIMALS = 6; @@ -48,12 +48,12 @@ describe("amm", async function () { banksClient = context.banksClient; provider = new BankrunProvider(context); anchor.setProvider(provider); - ammClient = await AmmClient.createClient({ provider }); + ammClient = await AmmClient.createClient({ provider: provider as any }); payer = provider.wallet.payer; }); beforeEach(async function () { - await fastForward(context, 1n); + await advanceBySlots(context, 1n); META = await createMint( banksClient, payer, @@ -88,7 +88,7 @@ describe("amm", async function () { META, userMetaAccount, payer.publicKey, - 10_000 * 10 ** 9 + 100 * 10 ** 9 ); mintTo( banksClient, @@ -96,7 +96,7 @@ describe("amm", async function () { USDC, userUsdcAccount, payer.publicKey, - 1_000_000 * 10 ** 6 + 10_000 * 10 ** 6 ); proposal = Keypair.generate().publicKey; @@ -110,12 +110,7 @@ describe("amm", async function () { let expectedMaxObservationChangePerUpdate = new BN(10_000_000_000); let bump: number; - [amm, bump] = getAmmAddr( - ammClient.program.programId, - META, - USDC, - proposal - ); + [amm, bump] = getAmmAddr(ammClient.program.programId, META, USDC); const ammAcc = await ammClient.getAmm(amm); @@ -160,8 +155,7 @@ describe("amm", async function () { META, META, twapFirstObservationScaled, - twapMaxObservationChangePerUpdateScaled, - proposal + twapMaxObservationChangePerUpdateScaled ) .rpc() .then(callbacks[0], callbacks[1]); @@ -391,7 +385,7 @@ describe("amm", async function () { ) .rpc(); - await fastForward(context, 1n); + await advanceBySlots(context, 1n); const ammMiddle = await ammClient.getAmm(amm); let quoteReceived = @@ -429,7 +423,7 @@ describe("amm", async function () { ) .rpc(); - await fastForward(context, 1n); + await advanceBySlots(context, 1n); const ammMiddle = await ammClient.getAmm(amm); let baseReceived = diff --git a/tests/amm/integration/ammLifecycle.test.ts b/tests/amm/integration/ammLifecycle.test.ts new file mode 100644 index 00000000..d4a9768b --- /dev/null +++ b/tests/amm/integration/ammLifecycle.test.ts @@ -0,0 +1,107 @@ +import { + AmmClient, + getAmmAddr, + getAmmLpMintAddr, +} from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { + createMint, + createAssociatedTokenAccount, + mintTo, + getAccount, + getMint, +} from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import * as token from "@solana/spl-token"; +import { expectError } from "../../utils.js"; +import { BN } from "bn.js"; + +export default async function () { + let ammClient: AmmClient; + let META: PublicKey; + let USDC: PublicKey; + let amm: PublicKey; + + ammClient = this.ammClient; + META = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 9 + ); + USDC = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 6 + ); + + await this.createTokenAccount(META, this.payer.publicKey); + await this.createTokenAccount(USDC, this.payer.publicKey); + + await this.mintTo(META, this.payer.publicKey, this.payer, 100 * 10 ** 9); + await this.mintTo(USDC, this.payer.publicKey, this.payer, 10_000 * 10 ** 6); + + let proposal = Keypair.generate().publicKey; + amm = await ammClient.createAmm(proposal, META, USDC, 500); + + // 1. Initialize AMM + const initialAmm = await ammClient.getAmm(amm); + assert.isTrue(initialAmm.baseAmount.eqn(0)); + assert.isTrue(initialAmm.quoteAmount.eqn(0)); + + // 2. Add initial liquidity + await ammClient.addLiquidity(amm, 1000, 2); + const ammAfterInitialLiquidity = await ammClient.getAmm(amm); + assert.isTrue(ammAfterInitialLiquidity.baseAmount.gt(new BN(0))); + assert.isTrue(ammAfterInitialLiquidity.quoteAmount.gt(new BN(0))); + + // 3. Perform swaps + await ammClient.swap(amm, { buy: {} }, 100, 0.1); + await ammClient.swap(amm, { sell: {} }, 0.1, 50); + + // 4. Add more liquidity + await ammClient.addLiquidity(amm, 500, 1); + + // 5. Remove some liquidity + let userLpAccount = token.getAssociatedTokenAddressSync( + getAmmLpMintAddr(ammClient.program.programId, amm)[0], + this.payer.publicKey + ); + let userLpBalance = (await getAccount(this.banksClient, userLpAccount)) + .amount; + await ammClient + .removeLiquidityIx( + amm, + META, + USDC, + new BN(Number(userLpBalance) / 2), + new BN(0), + new BN(0) + ) + .rpc(); + + // 6. Perform more swaps + await ammClient.swap(amm, { buy: {} }, 200, 0.2); + await ammClient.swap(amm, { sell: {} }, 0.2, 100); + + // 7. Remove all remaining liquidity + userLpBalance = (await getAccount(this.banksClient, userLpAccount)).amount; + await ammClient + .removeLiquidityIx( + amm, + META, + USDC, + new BN(userLpBalance), + new BN(0), + new BN(0) + ) + .rpc(); + + const finalAmm = await ammClient.getAmm(amm); + assert.isTrue(finalAmm.baseAmount.eqn(0)); + assert.isTrue(finalAmm.quoteAmount.eqn(0)); +} diff --git a/tests/amm/main.test.ts b/tests/amm/main.test.ts new file mode 100644 index 00000000..dc87a7fd --- /dev/null +++ b/tests/amm/main.test.ts @@ -0,0 +1,13 @@ +import initializeAmm from "./unit/initializeAmm.test"; +import addLiquidity from "./unit/addLiquidity.test"; +import swap from "./unit/swap.test"; +import removeLiquidity from "./unit/removeLiquidity.test"; +import ammLifecycle from "./integration/ammLifecycle.test"; + +export default function suite() { + describe("#initialize_amm", initializeAmm); + describe("#add_liquidity", addLiquidity); + describe("#swap", swap); + describe("#remove_liquidity", removeLiquidity); + it("AMM lifecycle", ammLifecycle); +} diff --git a/tests/amm/unit/addLiquidity.test.ts b/tests/amm/unit/addLiquidity.test.ts new file mode 100644 index 00000000..c32db1b0 --- /dev/null +++ b/tests/amm/unit/addLiquidity.test.ts @@ -0,0 +1,104 @@ +import { + AmmClient, + getAmmAddr, + getAmmLpMintAddr, +} from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { + createMint, + createAssociatedTokenAccount, + mintTo, + getAccount, +} from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import { expectError } from "../../utils.js"; +import * as token from "@solana/spl-token"; +import { BN } from "bn.js"; + +export default function suite() { + let ammClient: AmmClient; + let META: PublicKey; + let USDC: PublicKey; + let amm: PublicKey; + + beforeEach(async function () { + ammClient = this.ammClient; + META = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 9 + ); + USDC = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 6 + ); + + let proposal = Keypair.generate().publicKey; + amm = await ammClient.createAmm(proposal, META, USDC, 500); + + await this.createTokenAccount(META, this.payer.publicKey); + await this.createTokenAccount(USDC, this.payer.publicKey); + + await this.mintTo(META, this.payer.publicKey, this.payer, 100 * 10 ** 9); + await this.mintTo(USDC, this.payer.publicKey, this.payer, 10_000 * 10 ** 6); + }); + + it("adds initial liquidity to an amm", async function () { + await ammClient + .addLiquidityIx( + amm, + META, + USDC, + new BN(5000 * 10 ** 6), + new BN(6 * 10 ** 9), + new BN(0) + ) + .rpc(); + + const storedAmm = await ammClient.getAmm(amm); + + assert.isTrue(storedAmm.baseAmount.eq(new BN(6 * 10 ** 9))); + assert.isTrue(storedAmm.quoteAmount.eq(new BN(5000 * 10 ** 6))); + + const lpMint = await getAccount( + this.banksClient, + token.getAssociatedTokenAddressSync( + getAmmLpMintAddr(ammClient.program.programId, amm)[0], + this.payer.publicKey + ) + ); + + assert.equal(lpMint.amount.toString(), (5000 * 10 ** 6).toString()); + }); + + it("adds liquidity after it's already been added", async function () { + await ammClient + .addLiquidityIx( + amm, + META, + USDC, + new BN(5000 * 10 ** 6), + new BN(6 * 10 ** 9), + new BN(0) + ) + .rpc(); + + const storedAmm = await ammClient.getAmm(amm); + + assert.isTrue(storedAmm.baseAmount.eq(new BN(6 * 10 ** 9))); + assert.isTrue(storedAmm.quoteAmount.eq(new BN(5000 * 10 ** 6))); + + // const lpMint = await getAccount( + // this.banksClient, + // getAmmLpMintAddr(ammClient.program.programId, amm)[0] + // ); + + // assert.equal(lpMint.amount.toString(), (7500 * 10 ** 6).toString()); + }); +} diff --git a/tests/amm/unit/initializeAmm.test.ts b/tests/amm/unit/initializeAmm.test.ts new file mode 100644 index 00000000..be1dbbfb --- /dev/null +++ b/tests/amm/unit/initializeAmm.test.ts @@ -0,0 +1,90 @@ +import { + AmmClient, + getAmmAddr, + getAmmLpMintAddr, + PriceMath, +} from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { createMint } from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import { expectError } from "../../utils.js"; +import { BN } from "bn.js"; + +export default function suite() { + let ammClient: AmmClient; + let META: PublicKey; + let USDC: PublicKey; + + before(async function () { + ammClient = this.ammClient; + META = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 9 + ); + USDC = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 6 + ); + }); + + it("creates an amm", async function () { + let expectedInitialObservation = new BN(500_000_000_000); + let expectedMaxObservationChangePerUpdate = new BN(10_000_000_000); + + let bump: number; + let amm: PublicKey; + [amm, bump] = getAmmAddr(ammClient.program.programId, META, USDC); + + await ammClient.createAmm(Keypair.generate().publicKey, META, USDC, 500); + + const ammAcc = await ammClient.getAmm(amm); + + assert.equal(ammAcc.bump, bump); + assert.isTrue(ammAcc.createdAtSlot.eq(ammAcc.oracle.lastUpdatedSlot)); + assert.equal(ammAcc.baseMint.toBase58(), META.toBase58()); + assert.equal(ammAcc.quoteMint.toBase58(), USDC.toBase58()); + assert.equal(ammAcc.baseMintDecimals, 9); + assert.equal(ammAcc.quoteMintDecimals, 6); + assert.isTrue(ammAcc.baseAmount.eqn(0)); + assert.isTrue(ammAcc.quoteAmount.eqn(0)); + assert.isTrue(ammAcc.oracle.lastObservation.eq(expectedInitialObservation)); + assert.isTrue(ammAcc.oracle.aggregator.eqn(0)); + assert.isTrue( + ammAcc.oracle.maxObservationChangePerUpdate.eq( + expectedMaxObservationChangePerUpdate + ) + ); + assert.isTrue( + ammAcc.oracle.initialObservation.eq(expectedInitialObservation) + ); + }); + + it("fails to create an amm with two identical mints", async function () { + let [twapFirstObservationScaled, twapMaxObservationChangePerUpdateScaled] = + PriceMath.getAmmPrices(9, 9, 100, 1); + + const callbacks = expectError( + "SameTokenMints", + "create AMM succeeded despite same token mints" + ); + + let proposal = Keypair.generate().publicKey; + + await ammClient + .createAmmIx( + META, + META, + twapFirstObservationScaled, + twapMaxObservationChangePerUpdateScaled + ) + .rpc() + .then(callbacks[0], callbacks[1]); + }); +} diff --git a/tests/amm/unit/removeLiquidity.test.ts b/tests/amm/unit/removeLiquidity.test.ts new file mode 100644 index 00000000..19d7261b --- /dev/null +++ b/tests/amm/unit/removeLiquidity.test.ts @@ -0,0 +1,166 @@ +import { + AmmClient, + getAmmAddr, + getAmmLpMintAddr, +} from "@metadaoproject/futarchy"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { + createMint, + createAssociatedTokenAccount, + mintTo, + getAccount, + getMint, +} from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import * as token from "@solana/spl-token"; +import { expectError } from "../../utils.js"; +import { getAssociatedTokenAddressSync } from "@solana/spl-token"; +import { BN } from "bn.js"; + +export default function suite() { + let ammClient: AmmClient; + let META: PublicKey; + let USDC: PublicKey; + let amm: PublicKey; + + beforeEach(async function () { + ammClient = this.ammClient; + META = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 9 + ); + USDC = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 6 + ); + + await this.createTokenAccount(META, this.payer.publicKey); + await this.createTokenAccount(USDC, this.payer.publicKey); + + await this.mintTo(META, this.payer.publicKey, this.payer, 100 * 10 ** 9); + await this.mintTo(USDC, this.payer.publicKey, this.payer, 10_000 * 10 ** 6); + + let proposal = Keypair.generate().publicKey; + amm = await ammClient.createAmm(proposal, META, USDC, 500); + + await ammClient.addLiquidity(amm, 1000, 2); + }); + + it("can't remove 0 liquidity", async function () { + const callbacks = expectError( + "ZeroLiquidityRemove", + "was able to remove 0 liquidity" + ); + + await ammClient + .removeLiquidityIx( + amm, + META, + USDC, + new BN(0), + new BN(0), + new BN(0) + ) + .rpc() + .then(callbacks[0], callbacks[1]); + }); + + it("remove some liquidity from an amm position", async function () { + const ammStart = await ammClient.getAmm(amm); + + let userLpAccount = getAssociatedTokenAddressSync( + ammStart.lpMint, + this.payer.publicKey + ); + + const userLpAccountStart = await getAccount( + this.banksClient, + userLpAccount + ); + const lpMintStart = await getMint(this.banksClient, ammStart.lpMint); + + await ammClient + .removeLiquidityIx( + amm, + META, + USDC, + new BN(userLpAccountStart.amount.toString()).divn(2), + new BN(0), + new BN(0) + ) + .rpc(); + + const userLpAccountEnd = await getAccount(this.banksClient, userLpAccount); + const lpMintEnd = await getMint(this.banksClient, ammStart.lpMint); + + const ammEnd = await ammClient.getAmm(amm); + + assert.isBelow(Number(lpMintEnd.supply), Number(lpMintStart.supply)); + assert.isBelow( + Number(userLpAccountEnd.amount), + Number(userLpAccountStart.amount) + ); + + assert.isBelow( + ammEnd.baseAmount.toNumber(), + ammStart.baseAmount.toNumber() + ); + assert.isBelow( + ammEnd.quoteAmount.toNumber(), + ammStart.quoteAmount.toNumber() + ); + }); + + it("remove all liquidity from an amm position", async function () { + const ammStart = await ammClient.getAmm(amm); + + let userLpAccount = getAssociatedTokenAddressSync( + ammStart.lpMint, + this.payer.publicKey + ); + + const userLpAccountStart = await getAccount( + this.banksClient, + userLpAccount + ); + const lpMintStart = await getMint(this.banksClient, ammStart.lpMint); + + await ammClient + .removeLiquidityIx( + amm, + META, + USDC, + new BN(userLpAccountStart.amount.toString()), + new BN(1 * 10 ** 9), + new BN(10 * 10 ** 6) + ) + .rpc(); + + const userLpAccountEnd = await getAccount(this.banksClient, userLpAccount); + const lpMintEnd = await getMint(this.banksClient, ammStart.lpMint); + + assert.isBelow(Number(lpMintEnd.supply), Number(lpMintStart.supply)); + assert.isBelow( + Number(userLpAccountEnd.amount), + Number(userLpAccountStart.amount) + ); + + const ammEnd = await ammClient.getAmm(amm); + + assert.isBelow( + ammEnd.baseAmount.toNumber(), + ammStart.baseAmount.toNumber() + ); + assert.isBelow( + ammEnd.quoteAmount.toNumber(), + ammStart.quoteAmount.toNumber() + ); + }); +} diff --git a/tests/amm/unit/swap.test.ts b/tests/amm/unit/swap.test.ts new file mode 100644 index 00000000..5614217d --- /dev/null +++ b/tests/amm/unit/swap.test.ts @@ -0,0 +1,287 @@ +import { + AmmClient, + getAmmAddr, + getAmmLpMintAddr, +} from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { + createMint, + createAssociatedTokenAccount, + mintTo, + getAccount, + getMint, +} from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import { expectError } from "../../utils.js"; +import { advanceBySlots } from "../../utils.js"; +import { BN } from "bn.js"; +import { getAssociatedTokenAddressSync } from "@solana/spl-token"; + +export default function suite() { + let ammClient: AmmClient; + let META: PublicKey; + let USDC: PublicKey; + let amm: PublicKey; + + beforeEach(async function () { + ammClient = this.ammClient; + META = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 9 + ); + USDC = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + this.payer.publicKey, + 6 + ); + + await this.createTokenAccount(META, this.payer.publicKey); + await this.createTokenAccount(USDC, this.payer.publicKey); + + await this.mintTo(META, this.payer.publicKey, this.payer, 100 * 10 ** 9); + await this.mintTo(USDC, this.payer.publicKey, this.payer, 10_000 * 10 ** 6); + + let proposal = Keypair.generate().publicKey; + amm = await ammClient.createAmm(proposal, META, USDC, 500); + + await ammClient + .addLiquidityIx( + amm, + META, + USDC, + new BN(10_000 * 10 ** 6), + new BN(10 * 10 ** 9), + new BN(0) + ) + .rpc(); + }); + + it("fails when you have insufficient balance", async () => { + let callbacks = expectError( + "InsufficientBalance", + "we should have caught a user not having enough balance" + ); + + await ammClient + .swap(amm, { buy: {} }, 10_000_000, 1) + .then(callbacks[0], callbacks[1]); + + await ammClient + .swap(amm, { sell: {} }, 100_000, 1) + .then(callbacks[0], callbacks[1]); + }); + + it("buys", async function () { + const expectedOut = 0.098029507; + + // Ensure user has enough USDC + await this.mintTo(USDC, this.payer.publicKey, this.payer, 200 * 10 ** 6); + + const storedAmm = await ammClient.getAmm(amm); + let sim = ammClient.simulateSwap( + new BN(100 * 10 ** 6), + { buy: {} }, + storedAmm.baseAmount, + storedAmm.quoteAmount + ); + assert.equal( + sim.expectedOut.toString(), + new BN(expectedOut * 10 ** 9).toString() + ); + + let callbacks = expectError( + "SwapSlippageExceeded", + "we got back too many tokens from the AMM" + ); + + await ammClient + .swap(amm, { buy: {} }, 100, expectedOut + 0.000000001) + .then(callbacks[0], callbacks[1]); + + await ammClient.swap(amm, { buy: {} }, 100, expectedOut); + + await validateAmmState({ + banksClient: this.banksClient, + ammClient, + amm, + base: META, + quote: USDC, + expectedBaseAmount: (10 - expectedOut) * 10 ** 9, + expectedQuoteAmount: 10_100 * 10 ** 6, + expectedLpSupply: 10_000 * 10 ** 6, + }); + }); + + it("sells", async function () { + const expectedOut = 900.818926; + + let callbacks = expectError( + "SwapSlippageExceeded", + "we got back too many tokens from the AMM" + ); + + await ammClient + .swap(amm, { sell: {} }, 1, expectedOut + 0.000001) + .then(callbacks[0], callbacks[1]); + + await ammClient.swap(amm, { sell: {} }, 1, expectedOut); + + await validateAmmState({ + banksClient: this.banksClient, + ammClient, + amm, + base: META, + quote: USDC, + expectedBaseAmount: 11 * 10 ** 9, + expectedQuoteAmount: (10_000 - expectedOut) * 10 ** 6, + expectedLpSupply: 10_000 * 10 ** 6, + }); + }); + + it("swap base to quote and back, should not be profitable", async function () { + const permissionlessAmmStart = await ammClient.program.account.amm.fetch( + amm + ); + const ammEnd = await ammClient.getAmm(amm); + + let startingBaseSwapAmount = 1 * 10 ** 9; + + await ammClient + .swapIx( + amm, + META, + USDC, + { sell: {} }, + new BN(startingBaseSwapAmount), + new BN(1) + ) + .rpc(); + + await advanceBySlots(this.context, 1n); + + const ammMiddle = await ammClient.getAmm(amm); + let quoteReceived = + permissionlessAmmStart.quoteAmount.toNumber() - + ammMiddle.quoteAmount.toNumber(); + + await ammClient + .swapIx( + amm, + META, + USDC, + { buy: {} }, + new BN(quoteReceived), + new BN(1) + ) + .rpc(); + + const permissionlessAmmEnd = await ammClient.program.account.amm.fetch(amm); + let baseReceived = + ammMiddle.baseAmount.toNumber() - + permissionlessAmmEnd.baseAmount.toNumber(); + + assert.isBelow(baseReceived, startingBaseSwapAmount); + assert.isAbove(baseReceived, startingBaseSwapAmount * 0.98); + }); + + it("swap quote to base and back, should not be profitable", async function () { + const ammStart = await ammClient.getAmm(amm); + + let startingQuoteSwapAmount = 1 * 10 ** 6; + + // Ensure user has enough USDC + await this.mintTo(USDC, this.payer.publicKey, this.payer, 2 * 10 ** 6); + + await ammClient + .swapIx( + amm, + META, + USDC, + { buy: {} }, + new BN(startingQuoteSwapAmount), + new BN(1) + ) + .rpc(); + + await advanceBySlots(this.context, 1n); + + const ammMiddle = await ammClient.getAmm(amm); + let baseReceived = + ammStart.baseAmount.toNumber() - ammMiddle.baseAmount.toNumber(); + + await ammClient + .swapIx( + amm, + META, + USDC, + { sell: {} }, + new BN(baseReceived), + new BN(1) + ) + .rpc(); + + const ammEnd = await ammClient.getAmm(amm); + let quoteReceived = + ammMiddle.quoteAmount.toNumber() - ammEnd.quoteAmount.toNumber(); + + assert.isBelow(quoteReceived, startingQuoteSwapAmount); + assert.isAbove(quoteReceived, startingQuoteSwapAmount * 0.98); + }); +} + +async function validateAmmState({ + banksClient, + ammClient, + amm, + base, + quote, + expectedBaseAmount, + expectedQuoteAmount, + expectedLpSupply, +}: { + banksClient: any; + ammClient: AmmClient; + amm: PublicKey; + base: PublicKey; + quote: PublicKey; + expectedBaseAmount: number; + expectedQuoteAmount: number; + expectedLpSupply: number; +}) { + const storedAmm = await ammClient.getAmm(amm); + + assert.equal(storedAmm.baseAmount.toString(), expectedBaseAmount.toString()); + assert.equal( + storedAmm.quoteAmount.toString(), + expectedQuoteAmount.toString() + ); + + assert.equal( + ( + await getAccount( + banksClient, + getAssociatedTokenAddressSync(base, amm, true) + ) + ).amount, + BigInt(expectedBaseAmount) + ); + assert.equal( + ( + await getAccount( + banksClient, + getAssociatedTokenAddressSync(quote, amm, true) + ) + ).amount, + BigInt(expectedQuoteAmount) + ); + assert.equal( + (await getMint(banksClient, storedAmm.lpMint)).supply, + BigInt(expectedLpSupply) + ); +} diff --git a/tests/autocrat.ts b/tests/autocrat/autocrat.ts similarity index 86% rename from tests/autocrat.ts rename to tests/autocrat/autocrat.ts index 87e9bfae..3f3ab477 100644 --- a/tests/autocrat.ts +++ b/tests/autocrat/autocrat.ts @@ -1,5 +1,6 @@ import * as anchor from "@coral-xyz/anchor"; -import { BN, Program } from "@coral-xyz/anchor"; +import { Program } from "@coral-xyz/anchor"; +import { BN } from "bn.js"; import * as token from "@solana/spl-token"; import { getAssociatedTokenAddressSync } from "@solana/spl-token"; import { MEMO_PROGRAM_ID } from "@solana/spl-memo"; @@ -20,15 +21,16 @@ import { getAccount, } from "spl-token-bankrun"; +import { advanceBySlots, expectError } from "../utils.js"; +import { Autocrat, IDL as AutocratIDL } from "../../target/types/autocrat.js"; import { - mintConditionalTokens, - redeemConditionalTokens, -} from "./conditionalVault"; - -import { advanceBySlots, expectError } from "./utils/utils"; -import { Autocrat } from "../target/types/autocrat"; -import { ConditionalVault } from "../target/types/conditional_vault"; -import { AutocratMigrator } from "../target/types/autocrat_migrator"; + ConditionalVault, + IDL as ConditionalVaultIDL, +} from "../../target/types/conditional_vault.js"; +import { + AutocratMigrator, + IDL as AutocratMigratorIDL, +} from "../../target/types/autocrat_migrator.js"; const { PublicKey, Keypair } = anchor.web3; @@ -39,9 +41,12 @@ import { getAmmAddr, getAmmLpMintAddr, getVaultAddr, -} from "@metadaoproject/futarchy"; -import { PriceMath } from "@metadaoproject/futarchy"; -import { AutocratClient, ConditionalVaultClient } from "@metadaoproject/futarchy"; +} from "@metadaoproject/futarchy/v0.4"; +import { PriceMath } from "@metadaoproject/futarchy/v0.4"; +import { + AutocratClient, + ConditionalVaultClient, +} from "@metadaoproject/futarchy/v0.4"; import { ComputeBudgetInstruction, ComputeBudgetProgram, @@ -50,9 +55,9 @@ import { TransactionInstruction, } from "@solana/web3.js"; -const AutocratIDL: Autocrat = require("../target/idl/autocrat.json"); -const ConditionalVaultIDL: ConditionalVault = require("../target/idl/conditional_vault.json"); -const AutocratMigratorIDL: AutocratMigrator = require("../target/idl/autocrat_migrator.json"); +// const AutocratIDL: Autocrat = require("../target/idl/autocrat.json"); +// const ConditionalVaultIDL: ConditionalVault = require("../target/idl/conditional_vault.json"); +// const AutocratMigratorIDL: AutocratMigrator = require("../target/idl/autocrat_migrator.json"); export type PublicKey = anchor.web3.PublicKey; export type Signer = anchor.web3.Signer; @@ -69,7 +74,8 @@ const AUTOCRAT_MIGRATOR_PROGRAM_ID = new PublicKey( const ONE_META = new BN(1_000_000_000); const ONE_USDC = new BN(1_000_000); -describe("autocrat", async function () { +// describe("autocrat", async function () { +export default function suite() { let provider, autocrat, payer, @@ -100,7 +106,7 @@ describe("autocrat", async function () { ammClient = AmmClient.createClient({ provider }); vaultClient = ConditionalVaultClient.createClient({ provider }); - autocratClient = await AutocratClient.createClient({ provider }); + autocratClient = AutocratClient.createClient({ provider }); autocrat = new anchor.Program( AutocratIDL, @@ -340,14 +346,24 @@ describe("autocrat", async function () { ONE_USDC.muln(5000) ); - let { baseVault, quoteVault } = autocratClient.getProposalPdas( + let { baseVault, quoteVault, question } = autocratClient.getProposalPdas( proposal, META, USDC, dao ); - await vaultClient.mintConditionalTokens(baseVault, 10); - await vaultClient.mintConditionalTokens(quoteVault, 10_000); + await vaultClient + .splitTokensIx(question, baseVault, META, new BN(10 * 10 ** 9), 2) + .rpc(); + await vaultClient + .splitTokensIx( + question, + quoteVault, + USDC, + new BN(10_000 * 1_000_000), + 2 + ) + .rpc(); }); it("doesn't finalize proposals that are too young", async function () { @@ -373,6 +389,7 @@ describe("autocrat", async function () { quoteVault, passLp, failLp, + question, } = autocratClient.getProposalPdas(proposal, META, USDC, dao); // swap $500 in the pass market, make it pass @@ -450,22 +467,21 @@ describe("autocrat", async function () { console.log(PriceMath.getHumanPrice(passTwap, 9, 6)); console.log(PriceMath.getHumanPrice(failTwap, 9, 6)); - let storedBaseVault = await vaultClient.getVault(baseVault); - let storedQuoteVault = await vaultClient.getVault(quoteVault); + let storedQuestion = await vaultClient.fetchQuestion(question); + + assert.equal(storedQuestion.payoutDenominator, 1); + assert.deepEqual(storedQuestion.payoutNumerators, [0, 1]); + + // let storedBaseVault = await vaultClient.fetchVault(baseVault); + // let storedQuoteVault = await vaultClient.fetchVault(quoteVault); - assert.exists(storedBaseVault.status.finalized); - assert.exists(storedQuoteVault.status.finalized); + // assert.exists(storedBaseVault.status.finalized); + // assert.exists(storedQuoteVault.status.finalized); }); it("rejects proposals when pass price TWAP < fail price TWAP", async function () { - let { - passAmm, - failAmm, - failBaseMint, - failQuoteMint, - baseVault, - quoteVault, - } = autocratClient.getProposalPdas(proposal, META, USDC, dao); + let { passAmm, failAmm, failBaseMint, failQuoteMint, question } = + autocratClient.getProposalPdas(proposal, META, USDC, dao); // swap $500 in the fail market, make it fail await ammClient @@ -513,16 +529,21 @@ describe("autocrat", async function () { console.log(PriceMath.getHumanPrice(passTwap, 9, 6)); console.log(PriceMath.getHumanPrice(failTwap, 9, 6)); - let storedBaseVault = await vaultClient.getVault(baseVault); - let storedQuoteVault = await vaultClient.getVault(quoteVault); + let storedQuestion = await vaultClient.fetchQuestion(question); - assert.exists(storedBaseVault.status.reverted); - assert.exists(storedQuoteVault.status.reverted); + assert.equal(storedQuestion.payoutDenominator, 1); + assert.deepEqual(storedQuestion.payoutNumerators, [1, 0]); }); }); describe("#execute_proposal", async function () { - let proposal, passAmm, failAmm, baseVault, quoteVault, instruction; + let proposal, + passAmm, + failAmm, + baseVault, + quoteVault, + question: PublicKey, + instruction; beforeEach(async function () { await mintToOverride(context, treasuryMetaAccount, 1_000_000_000n); @@ -564,11 +585,23 @@ describe("autocrat", async function () { ONE_META.muln(10), ONE_USDC.muln(6_000) ); - ({ baseVault, quoteVault, passAmm, failAmm } = + + // console.log(await autocrat.account.proposal.fetch(proposal)); + ({ baseVault, quoteVault, passAmm, failAmm, question } = await autocrat.account.proposal.fetch(proposal)); - await vaultClient.mintConditionalTokens(baseVault, 10); - await vaultClient.mintConditionalTokens(quoteVault, 10_000); + await vaultClient + .splitTokensIx(question, baseVault, META, new BN(10 * 10 ** 9), 2) + .rpc(); + await vaultClient + .splitTokensIx( + question, + quoteVault, + USDC, + new BN(10_000 * 1_000_000), + 2 + ) + .rpc(); }); it("doesn't allow pending proposals to be executed", async function () { @@ -690,4 +723,4 @@ describe("autocrat", async function () { .then(callbacks[0], callbacks[1]); }); }); -}); +} diff --git a/tests/autocrat/main.test.ts b/tests/autocrat/main.test.ts new file mode 100644 index 00000000..e69de29b diff --git a/tests/migrator.ts b/tests/autocratMigrator/migrator.ts similarity index 97% rename from tests/migrator.ts rename to tests/autocratMigrator/migrator.ts index 98796d46..3c18ab44 100644 --- a/tests/migrator.ts +++ b/tests/autocratMigrator/migrator.ts @@ -13,8 +13,10 @@ const AUTOCRAT_MIGRATOR_PROGRAM_ID = new PublicKey( "MigRDW6uxyNMDBD8fX2njCRyJC4YZk2Rx9pDUZiAESt" ); -import { AutocratMigrator } from "../target/types/autocrat_migrator"; -const AutocratMigratorIDL: AutocratMigrator = require("../target/idl/autocrat_migrator.json"); +import { + AutocratMigrator, + IDL as AutocratMigratorIDL, +} from "../../target/types/autocrat_migrator"; export type PublicKey = anchor.web3.PublicKey; export type Signer = anchor.web3.Signer; diff --git a/tests/conditionalVault.ts b/tests/conditionalVault.ts deleted file mode 100644 index 5e5f60d8..00000000 --- a/tests/conditionalVault.ts +++ /dev/null @@ -1,1192 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { BN, Program, web3 } from "@coral-xyz/anchor"; -import { - MPL_TOKEN_METADATA_PROGRAM_ID as UMI_MPL_TOKEN_METADATA_PROGRAM_ID, - createMetadataAccountV3, -} from "@metaplex-foundation/mpl-token-metadata"; -import { - Umi, - createSignerFromKeypair, - keypairIdentity, - none, -} from "@metaplex-foundation/umi"; -import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; -import { - fromWeb3JsKeypair, - fromWeb3JsPublicKey, - toWeb3JsLegacyTransaction, - toWeb3JsPublicKey, -} from "@metaplex-foundation/umi-web3js-adapters"; -import * as token from "@solana/spl-token"; -import { SYSVAR_RENT_PUBKEY } from "@solana/web3.js"; -import { BankrunProvider } from "anchor-bankrun"; -import { assert } from "chai"; -import { BanksClient, ProgramTestContext, startAnchor } from "solana-bankrun"; -import { - createAccount, - createAssociatedTokenAccount, - createMint, - getAccount, - mintTo, -} from "spl-token-bankrun"; - -const { PublicKey, Keypair } = web3; - -import { ConditionalVault } from "../target/types/conditional_vault"; -import { expectError } from "./utils/utils"; -import { - CONDITIONAL_VAULT_PROGRAM_ID, - ConditionalVaultClient, - getVaultAddr, - getVaultFinalizeMintAddr, - getVaultRevertMintAddr, -} from "@metadaoproject/futarchy"; -const ConditionalVaultIDL: ConditionalVault = require("../target/idl/conditional_vault.json"); - -export type VaultProgram = anchor.Program; -export type PublicKey = anchor.web3.PublicKey; -export type Signer = anchor.web3.Signer; -export type Keypair = anchor.web3.Keypair; - -const METADATA_URI = - "https://ftgnmxferax7tpgqyzdo76sisk5fhpsjv34omvgz33m7udvnsfba.arweave.net/LMzWXKSIL_m80MZG7_pIkrpTvkmu-OZU2d7Z-g6tkUI"; -const MPL_TOKEN_METADATA_PROGRAM_ID = toWeb3JsPublicKey( - UMI_MPL_TOKEN_METADATA_PROGRAM_ID -); - -export enum VaultStatus { - Active, - Finalized, - Reverted, -} - -// this test file isn't 'clean' or DRY or whatever; sorry! - -describe("conditional_vault", async function () { - let provider: anchor.Provider; - let vaultClient: ConditionalVaultClient; - - let vault: PublicKey; - let proposal: PublicKey; - let vaultUnderlyingTokenAccount: anchor.web3.PublicKey; - let underlyingTokenMint: anchor.web3.PublicKey; - let conditionalOnFinalizeMint: anchor.web3.PublicKey; - let conditionalOnRevertMint: anchor.web3.PublicKey; - let nonce: BN; - let settlementAuthority: anchor.web3.Keypair; - let underlyingMintAuthority: anchor.web3.Keypair; - let alice: anchor.web3.Keypair; - let context: ProgramTestContext; - let banksClient: BanksClient; - let umi: Umi; - - // note: adding types to these creates a slew of type errors below - let payer; - let vaultProgram; - - before(async function () { - context = await startAnchor( - "./", - [ - // even though the program is loaded into the test validator, we need - // to tell banks test client to load it as well - { - name: "mpl_token_metadata", - programId: MPL_TOKEN_METADATA_PROGRAM_ID, - }, - ], - [] - ); - banksClient = context.banksClient; - provider = new BankrunProvider(context); - anchor.setProvider(provider); - - umi = createUmi(anchor.AnchorProvider.env().connection); - - vaultProgram = new Program( - ConditionalVaultIDL, - CONDITIONAL_VAULT_PROGRAM_ID, - provider - ); - - vaultClient = await ConditionalVaultClient.createClient({ provider }); - - payer = vaultProgram.provider.wallet.payer; - alice = anchor.web3.Keypair.generate(); - settlementAuthority = anchor.web3.Keypair.generate(); - underlyingMintAuthority = anchor.web3.Keypair.generate(); - umi.use(keypairIdentity(fromWeb3JsKeypair(payer))); - - underlyingTokenMint = await createMint( - banksClient, - payer as anchor.web3.Keypair, - underlyingMintAuthority.publicKey, - null, - 8 - ); - - proposal = Keypair.generate().publicKey; - - [vault] = getVaultAddr( - vaultProgram.programId, - settlementAuthority.publicKey, - underlyingTokenMint, - proposal - ); - - vaultUnderlyingTokenAccount = await token.getAssociatedTokenAddress( - underlyingTokenMint, - vault, - true - ); - }); - - describe("#initialize_conditional_vault", async function () { - it("initializes vaults", async function () { - await vaultClient - .initializeVaultIx( - settlementAuthority.publicKey, - underlyingTokenMint, - proposal - ) - .rpc(); - - conditionalOnFinalizeMint = getVaultFinalizeMintAddr( - vaultProgram.programId, - vault - )[0]; - - conditionalOnRevertMint = getVaultRevertMintAddr( - vaultProgram.programId, - vault - )[0]; - - const storedVault = await vaultProgram.account.conditionalVault.fetch( - vault - ); - assert.exists(storedVault.status.active); - assert.ok( - storedVault.settlementAuthority.equals(settlementAuthority.publicKey) - ); - assert.ok(storedVault.underlyingTokenMint.equals(underlyingTokenMint)); - assert.ok( - storedVault.underlyingTokenAccount.equals(vaultUnderlyingTokenAccount) - ); - assert.ok( - storedVault.conditionalOnFinalizeTokenMint.equals( - conditionalOnFinalizeMint - ) - ); - assert.ok( - storedVault.conditionalOnRevertTokenMint.equals(conditionalOnRevertMint) - ); - }); - }); - - describe("#mint_conditional_tokens", async function () { - // alice is available throughout the tests, bob is just for mint_conditional_tokens - let bob: Keypair; - let amount = 1000; - let bobUnderlyingTokenAccount: PublicKey; - let bobConditionalOnFinalizeTokenAccount: PublicKey; - let bobConditionalOnRevertTokenAccount: PublicKey; - - beforeEach(async function () { - bob = anchor.web3.Keypair.generate(); - - bobUnderlyingTokenAccount = await createAssociatedTokenAccount( - /* bobUnderlyingTokenAccount = await createAccount( */ - banksClient, - payer, - underlyingTokenMint, - bob.publicKey - ); - - bobConditionalOnFinalizeTokenAccount = await createAssociatedTokenAccount( - banksClient, - payer, - conditionalOnFinalizeMint, - bob.publicKey - ); - bobConditionalOnRevertTokenAccount = await createAssociatedTokenAccount( - banksClient, - payer, - conditionalOnRevertMint, - bob.publicKey - ); - - await mintTo( - banksClient, - payer, - underlyingTokenMint, - bobUnderlyingTokenAccount, - underlyingMintAuthority, - amount - ); - }); - - it("mints conditional tokens", async function () { - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient - ); - }); - - it("mints conditional tokens twice", async function () { - await mintConditionalTokens( - vaultProgram, - amount / 2, - bob, - vault, - banksClient - ); - - await mintConditionalTokens( - vaultProgram, - amount / 2, - bob, - vault, - banksClient - ); - }); - - it("blocks mints when the user doesn't have enough underlying tokens", async function () { - const callbacks = expectError( - "InsufficientUnderlyingTokens", - "mint suceeded despite user not having enough underlying tokens" - ); - await mintConditionalTokens( - vaultProgram, - amount + 10, - bob, - vault, - banksClient - ).then(callbacks[0], callbacks[1]); - }); - - it("checks that `vault_underlying_token_account` and `conditional_vault` match up", async function () { - const maliciousVaultUnderlyingTokenAccount = await createAccount( - banksClient, - payer, - underlyingTokenMint, - anchor.web3.Keypair.generate().publicKey - ); - - const callbacks = expectError( - "InvalidVaultUnderlyingTokenAccount", - "was able to mint conditional tokens while supplying an invalid vault underlying account" - ); - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient, - undefined, - undefined, - undefined, - maliciousVaultUnderlyingTokenAccount - ).then(callbacks[0], callbacks[1]); - }); - - it("checks that `user_underlying_token_account` is owned by the user", async function () { - const nonOwnedUserUnderlyingAccount = await createAccount( - banksClient, - payer, - underlyingTokenMint, - anchor.web3.Keypair.generate().publicKey - ); - - await mintTo( - banksClient, - payer, - underlyingTokenMint, - nonOwnedUserUnderlyingAccount, - underlyingMintAuthority, - amount - ); - - const callbacks = expectError( - "ConstraintTokenOwner", - "mint suceeded despite `user_underlying_token_account` not being owned by the user" - ); - - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient, - nonOwnedUserUnderlyingAccount - ).then(callbacks[0], callbacks[1]); - }); - - it("checks that `user_conditional_on_finalize_token_account` is owned by the user", async function () { - const nonOwnedUserConditionalAccount = await createAccount( - banksClient, - payer, - conditionalOnFinalizeMint, - anchor.web3.Keypair.generate().publicKey - ); - - const callbacks = expectError( - "ConstraintTokenOwner", - "mint suceeded despite `user_conditional_token_account` not being owned by the user" - ); - - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient, - undefined, - nonOwnedUserConditionalAccount - ).then(callbacks[0], callbacks[1]); - }); - - it("checks that `user_conditional_on_revert_token_account` is owned by the user", async function () { - const nonOwnedUserConditionalAccount = await createAccount( - banksClient, - payer, - conditionalOnRevertMint, - anchor.web3.Keypair.generate().publicKey - ); - - const callbacks = expectError( - "ConstraintTokenOwner", - "mint suceeded despite `user_conditional_token_account` not being owned by the user" - ); - - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient, - undefined, - nonOwnedUserConditionalAccount - ).then(callbacks[0], callbacks[1]); - }); - - it("checks that `user_conditional_token_account` has `conditional_token_mint` as its mint", async function () { - const wrongConditionalTokenMint = await createMint( - banksClient, - payer, - vault, - vault, - 8 - ); - const wrongMintBobConditionalTokenAccount = await createAccount( - banksClient, - payer, - wrongConditionalTokenMint, - bob.publicKey - ); - - const callbacks = expectError( - "ConstraintTokenMint", - "mint suceeded despite `user_conditional_token_account` having a wrong mint" - ); - - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient, - undefined, - wrongMintBobConditionalTokenAccount - ).then(callbacks[0], callbacks[1]); - }); - - it("checks that `user_underlying_token_account` has the correct mint", async function () { - const mintAuthority = anchor.web3.Keypair.generate(); - const randomMint = await createMint( - banksClient, - payer, - mintAuthority.publicKey, - mintAuthority.publicKey, - 8 - ); - const wrongMintBobUnderlyingAccount = await createAccount( - banksClient, - payer, - randomMint, - bob.publicKey - ); - - await mintTo( - banksClient, - payer, - randomMint, - wrongMintBobUnderlyingAccount, - mintAuthority, - amount - ); - - const callbacks = expectError( - "ConstraintTokenMint", - "mint suceeded despite `user_underlying_token_account` having the wrong mint" - ); - - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient, - wrongMintBobUnderlyingAccount - ).then(callbacks[0], callbacks[1]); - }); - - it("checks that `conditional_token_mint` is the one stored in the conditional vault", async function () { - const wrongConditionalTokenMint = await createMint( - banksClient, - payer, - vault, - null, - 10 - ); - - const wrongMintBobConditionalTokenAccount = await createAccount( - banksClient, - payer, - wrongConditionalTokenMint, - bob.publicKey - ); - - const callbacks = expectError( - "InvalidConditionalTokenMint", - "mint suceeded despite `conditional_token_mint` not being the one stored in the conditional vault" - ); - - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient, - undefined, - wrongMintBobConditionalTokenAccount, - undefined, - undefined, - wrongConditionalTokenMint - ).then(callbacks[0], callbacks[1]); - }); - }); - - describe("#settle_conditional_vault", async function () { - it("allows vaults to be finalized", async function () { - let [vault, _, settlementAuthority] = await generateRandomVault( - vaultProgram, - vaultClient, - payer, - banksClient, - umi - ); - - await vaultProgram.methods - .settleConditionalVault({ finalized: {} }) - .accounts({ - settlementAuthority: settlementAuthority.publicKey, - vault, - }) - .signers([settlementAuthority]) - .rpc(); - }); - - it("allows vaults to be reverted", async function () { - let [vault, _, settlementAuthority] = await generateRandomVault( - vaultProgram, - vaultClient, - payer, - banksClient, - umi - ); - - await vaultProgram.methods - .settleConditionalVault({ reverted: {} }) - .accounts({ - settlementAuthority: settlementAuthority.publicKey, - vault, - }) - .signers([settlementAuthority]) - .rpc(); - }); - - it("disallows vaults from being finalized twice", async function () { - let [vault, _, settlementAuthority] = await generateRandomVault( - vaultProgram, - vaultClient, - payer, - banksClient, - umi - ); - - await vaultProgram.methods - .settleConditionalVault({ finalized: {} }) - .accounts({ - settlementAuthority: settlementAuthority.publicKey, - vault, - }) - .signers([settlementAuthority]) - .rpc(); - - const callbacks = expectError( - "VaultAlreadySettled", - "settle suceeded even though this vault had already been settled" - ); - - await vaultProgram.methods - .settleConditionalVault({ reverted: {} }) - .accounts({ - settlementAuthority: settlementAuthority.publicKey, - vault, - }) - .signers([settlementAuthority]) - .rpc() - .then(callbacks[0], callbacks[1]); - }); - }); - - describe("#redeem_and_merge_conditional_tokens_for_underlying_tokens", async function () { - let bob: Keypair; - let amount = 1000; - let mergeAmount = 10; - let bobUnderlyingTokenAccount: PublicKey; - let bobConditionalOnFinalizeTokenAccount: PublicKey; - let bobConditionalOnRevertTokenAccount: PublicKey; - - beforeEach(async function () { - [vault, underlyingMintAuthority, settlementAuthority] = - await generateRandomVault( - vaultProgram, - vaultClient, - payer, - banksClient, - umi - ); - let storedVault = await vaultProgram.account.conditionalVault.fetch( - vault - ); - underlyingTokenMint = storedVault.underlyingTokenMint; - conditionalOnFinalizeMint = storedVault.conditionalOnFinalizeTokenMint; - conditionalOnRevertMint = storedVault.conditionalOnRevertTokenMint; - vaultUnderlyingTokenAccount = storedVault.underlyingTokenAccount; - - bob = anchor.web3.Keypair.generate(); - - bobUnderlyingTokenAccount = await createAssociatedTokenAccount( - banksClient, - payer, - underlyingTokenMint, - bob.publicKey - ); - - bobConditionalOnFinalizeTokenAccount = await createAssociatedTokenAccount( - banksClient, - payer, - conditionalOnFinalizeMint, - bob.publicKey - ); - - bobConditionalOnRevertTokenAccount = await createAccount( - banksClient, - payer, - conditionalOnRevertMint, - bob.publicKey - ); - - await mintTo( - banksClient, - payer, - underlyingTokenMint, - bobUnderlyingTokenAccount, - underlyingMintAuthority, - amount - ); - - await mintConditionalTokens( - vaultProgram, - amount, - bob, - vault, - banksClient - ); - }); - - it("successfully merges 10 tokens before the vault has been finalized", async function () { - // Assuming the vault has not yet been finalized - - await mergeConditionalTokens( - vaultProgram, - mergeAmount, - bob, - bobConditionalOnFinalizeTokenAccount, - bobConditionalOnRevertTokenAccount, - conditionalOnFinalizeMint, - conditionalOnRevertMint, - bobUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - banksClient - ); - }); - - it("prevents users from merging conditional tokens after the vault has been finalized", async function () { - await vaultProgram.methods - .settleConditionalVault({ finalized: {} }) - .accounts({ - settlementAuthority: settlementAuthority.publicKey, - vault, - }) - .signers([settlementAuthority]) - .rpc(); - - const callbacks = expectError( - "VaultAlreadySettled", - "merge suceeded even though this vault was finalized" - ); - await mergeConditionalTokens( - vaultProgram, - mergeAmount, - bob, - bobConditionalOnFinalizeTokenAccount, - bobConditionalOnRevertTokenAccount, - conditionalOnFinalizeMint, - conditionalOnRevertMint, - bobUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - banksClient - ).then(callbacks[0], callbacks[1]); - }); - - it("allows users to redeem conditional-on-finalize tokens for underlying tokens when a vault has been finalized", async function () { - await vaultProgram.methods - .settleConditionalVault({ finalized: {} }) - .accounts({ - settlementAuthority: settlementAuthority.publicKey, - vault, - }) - .signers([settlementAuthority]) - .rpc(); - - await redeemConditionalTokens( - vaultProgram, - bob, - bobConditionalOnFinalizeTokenAccount, - bobConditionalOnRevertTokenAccount, - conditionalOnFinalizeMint, - conditionalOnRevertMint, - bobUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - banksClient - ); - }); - - it("allows user to redeeming conditional-on-revert tokens for underlying tokens when a vault is reverted", async function () { - await vaultProgram.methods - .settleConditionalVault({ reverted: {} }) - .accounts({ - settlementAuthority: settlementAuthority.publicKey, - vault, - }) - .signers([settlementAuthority]) - .rpc(); - - await redeemConditionalTokens( - vaultProgram, - bob, - bobConditionalOnFinalizeTokenAccount, - bobConditionalOnRevertTokenAccount, - conditionalOnFinalizeMint, - conditionalOnRevertMint, - bobUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - banksClient - ); - }); - - it("prevents users from redeeming conditional tokens while a vault is still active", async function () { - const callbacks = expectError( - "CantRedeemConditionalTokens", - "redemption suceeded even though this vault was still active" - ); - await redeemConditionalTokens( - vaultProgram, - bob, - bobConditionalOnFinalizeTokenAccount, - bobConditionalOnRevertTokenAccount, - conditionalOnFinalizeMint, - conditionalOnRevertMint, - bobUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - banksClient - ).then(callbacks[0], callbacks[1]); - }); - - it("checks that the user has provided the correct conditional token mint", async function () { - const wrongConditionalTokenMint = await createMint( - banksClient, - payer, - vault, - null, - 10 - ); - - const wrongMintBobConditionalTokenAccount = await createAccount( - banksClient, - payer, - wrongConditionalTokenMint, - bob.publicKey - ); - - const callbacks = expectError( - "InvalidConditionalTokenMint", - "redemption suceeded despite `conditional_token_mint` not being the one stored in the conditional vault" - ); - await redeemConditionalTokens( - vaultProgram, - bob, - wrongMintBobConditionalTokenAccount, - bobConditionalOnRevertTokenAccount, - wrongConditionalTokenMint, - conditionalOnRevertMint, - bobUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - banksClient - ).then(callbacks[0], callbacks[1]); - }); - }); -}); - -async function generateRandomVault( - vaultProgram: VaultProgram, - vaultClient: ConditionalVaultClient, - payer: Keypair, - banksClient: BanksClient, - umi: Umi, - settlementAuthority: Keypair = anchor.web3.Keypair.generate() -): Promise<[PublicKey, Keypair, Keypair]> { - const underlyingMintAuthority = anchor.web3.Keypair.generate(); - - const underlyingTokenMint = await createMint( - banksClient, - payer, - underlyingMintAuthority.publicKey, - null, - 8 - ); - - const tokenMint = fromWeb3JsPublicKey(underlyingTokenMint); - let builder = createMetadataAccountV3(umi, { - mint: tokenMint, - mintAuthority: createSignerFromKeypair( - umi, - fromWeb3JsKeypair(underlyingMintAuthority) - ), - data: { - name: "TOKE", - symbol: "TOKE", - uri: "METADATA_URI", - sellerFeeBasisPoints: 0, - creators: none(), - collection: none(), - uses: none(), - }, - isMutable: false, - collectionDetails: none(), - }); - builder = builder.setBlockhash( - (await umi.rpc.getLatestBlockhash()).blockhash - ); - - const createMetadataResult = await vaultProgram.provider.sendAndConfirm( - toWeb3JsLegacyTransaction(builder.build(umi)), - [underlyingMintAuthority], - { - skipPreflight: true, - commitment: "confirmed", - } - ); - // console.log(createMetadataResult); - - const proposal = Keypair.generate().publicKey; - - const [vault] = getVaultAddr( - vaultProgram.programId, - settlementAuthority.publicKey, - underlyingTokenMint, - proposal - ); - - const conditionalOnFinalizeTokenMint = getVaultFinalizeMintAddr( - vaultProgram.programId, - vault - )[0]; - const conditionalOnRevertTokenMint = getVaultRevertMintAddr( - vaultProgram.programId, - vault - )[0]; - - const vaultUnderlyingTokenAccount = await token.getAssociatedTokenAddress( - underlyingTokenMint, - vault, - true - ); - - // when we have a ts lib, we can consolidate this logic there - const [conditionalOnFinalizeTokenMetadata] = - anchor.web3.PublicKey.findProgramAddressSync( - [ - anchor.utils.bytes.utf8.encode("metadata"), - MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), - conditionalOnFinalizeTokenMint.toBuffer(), - ], - MPL_TOKEN_METADATA_PROGRAM_ID - ); - - const [conditionalOnRevertTokenMetadata] = - anchor.web3.PublicKey.findProgramAddressSync( - [ - anchor.utils.bytes.utf8.encode("metadata"), - MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), - conditionalOnRevertTokenMint.toBuffer(), - ], - MPL_TOKEN_METADATA_PROGRAM_ID - ); - - const [underlyingTokenMetadata] = - anchor.web3.PublicKey.findProgramAddressSync( - [ - anchor.utils.bytes.utf8.encode("metadata"), - MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), - underlyingTokenMint.toBuffer(), - ], - MPL_TOKEN_METADATA_PROGRAM_ID - ); - - // const addMetadataToConditionalTokensIx = await vaultProgram.methods - // .addMetadataToConditionalTokens({ - // proposalNumber: new BN(0), // nonce, - // onFinalizeUri: METADATA_URI, - // onRevertUri: METADATA_URI, - // }) - // .accounts({ - // payer: payer.publicKey, - // vault, - // underlyingTokenMint, - // underlyingTokenMetadata, - // conditionalOnFinalizeTokenMint, - // conditionalOnRevertTokenMint, - // conditionalOnFinalizeTokenMetadata, - // conditionalOnRevertTokenMetadata, - // tokenMetadataProgram: MPL_TOKEN_METADATA_PROGRAM_ID, - // systemProgram: anchor.web3.SystemProgram.programId, - // rent: SYSVAR_RENT_PUBKEY, - // }) - // .instruction(); - const addMetadataToConditionalTokensIx = await vaultClient.addMetadataToConditionalTokensIx( - vault, - underlyingTokenMint, - 1, - METADATA_URI, - METADATA_URI - ).instruction(); - - await vaultClient - .initializeVaultIx( - settlementAuthority.publicKey, - underlyingTokenMint, - proposal - ) - .postInstructions([addMetadataToConditionalTokensIx]) - .rpc(); - - return [vault, underlyingMintAuthority, settlementAuthority]; -} - -export async function mintConditionalTokens( - program: VaultProgram, - amount: number | bigint, - user: Signer, - vault: PublicKey, - banksClient: BanksClient, - userUnderlyingTokenAccount?: PublicKey, - userConditionalOnFinalizeTokenAccount?: PublicKey, - userConditionalOnRevertTokenAccount?: PublicKey, - vaultUnderlyingTokenAccount?: PublicKey, - conditionalOnFinalizeTokenMint?: PublicKey -) { - const storedVault = await program.account.conditionalVault.fetch(vault); - if (!userUnderlyingTokenAccount) { - userUnderlyingTokenAccount = await token.getAssociatedTokenAddress( - storedVault.underlyingTokenMint, - user.publicKey, - true - ); - } - if (!userConditionalOnFinalizeTokenAccount) { - userConditionalOnFinalizeTokenAccount = - await token.getAssociatedTokenAddress( - storedVault.conditionalOnFinalizeTokenMint, - user.publicKey, - true - ); - } - if (!userConditionalOnRevertTokenAccount) { - userConditionalOnRevertTokenAccount = await token.getAssociatedTokenAddress( - storedVault.conditionalOnRevertTokenMint, - user.publicKey, - true - ); - } - if (!vaultUnderlyingTokenAccount) { - vaultUnderlyingTokenAccount = storedVault.underlyingTokenAccount; - } - if (!conditionalOnFinalizeTokenMint) { - conditionalOnFinalizeTokenMint = storedVault.conditionalOnFinalizeTokenMint; - } - - const vaultUnderlyingTokenAccountBefore = await getAccount( - banksClient, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountBefore = await getAccount( - banksClient, - userUnderlyingTokenAccount - ); - const userConditionalOnFinalizeTokenAccountBefore = await getAccount( - banksClient, - userConditionalOnFinalizeTokenAccount - ); - const userConditionalOnRevertTokenAccountBefore = await getAccount( - banksClient, - userConditionalOnRevertTokenAccount - ); - - const bnAmount = new anchor.BN(amount.toString()); - /* try { */ - await program.methods - .mintConditionalTokens(bnAmount) - .accounts({ - authority: user.publicKey, - vault, - vaultUnderlyingTokenAccount, - userUnderlyingTokenAccount, - conditionalOnFinalizeTokenMint, - userConditionalOnFinalizeTokenAccount, - conditionalOnRevertTokenMint: storedVault.conditionalOnRevertTokenMint, - userConditionalOnRevertTokenAccount, - }) - .signers([user]) - .rpc(); - - const vaultUnderlyingTokenAccountAfter = await getAccount( - banksClient, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountAfter = await getAccount( - banksClient, - userUnderlyingTokenAccount - ); - const userConditionalOnFinalizeTokenAccountAfter = await getAccount( - banksClient, - userConditionalOnFinalizeTokenAccount - ); - const userConditionalOnRevertTokenAccountAfter = await getAccount( - banksClient, - userConditionalOnRevertTokenAccount - ); - - assert.equal( - vaultUnderlyingTokenAccountAfter.amount, - vaultUnderlyingTokenAccountBefore.amount + BigInt(amount) - ); - assert.equal( - userUnderlyingTokenAccountAfter.amount, - userUnderlyingTokenAccountBefore.amount - BigInt(amount) - ); - assert.equal( - userConditionalOnFinalizeTokenAccountAfter.amount, - userConditionalOnFinalizeTokenAccountBefore.amount + BigInt(amount) - ); - assert.equal( - userConditionalOnRevertTokenAccountAfter.amount, - userConditionalOnRevertTokenAccountBefore.amount + BigInt(amount) - ); -} - -export async function mergeConditionalTokens( - vaultProgram: VaultProgram, - amount: number | bigint, - user: Signer, - userConditionalOnFinalizeTokenAccount: PublicKey, - userConditionalOnRevertTokenAccount: PublicKey, - conditionalOnFinalizeTokenMint: PublicKey, - conditionalOnRevertTokenMint: PublicKey, - userUnderlyingTokenAccount: PublicKey, - vaultUnderlyingTokenAccount: PublicKey, - vault: PublicKey, - banksClient: BanksClient -) { - const vaultUnderlyingTokenAccountBefore = await getAccount( - banksClient, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountBefore = await getAccount( - banksClient, - userUnderlyingTokenAccount - ); - const userConditionalOnFinalizeTokenAccountBefore = await getAccount( - banksClient, - userConditionalOnFinalizeTokenAccount - ); - const userConditionalOnRevertTokenAccountBefore = await getAccount( - banksClient, - userConditionalOnRevertTokenAccount - ); - - const bnAmount = new anchor.BN(amount.toString()); - await vaultProgram.methods - .mergeConditionalTokensForUnderlyingTokens(bnAmount) - .accounts({ - authority: user.publicKey, - userConditionalOnFinalizeTokenAccount, - userConditionalOnRevertTokenAccount, - userUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - conditionalOnFinalizeTokenMint, - conditionalOnRevertTokenMint, - tokenProgram: token.TOKEN_PROGRAM_ID, - }) - .signers([user]) - .rpc(); - - const vaultUnderlyingTokenAccountAfter = await getAccount( - banksClient, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountAfter = await getAccount( - banksClient, - userUnderlyingTokenAccount - ); - const userConditionalOnFinalizeTokenAccountAfter = await getAccount( - banksClient, - userConditionalOnFinalizeTokenAccount - ); - const userConditionalOnRevertTokenAccountAfter = await getAccount( - banksClient, - userConditionalOnRevertTokenAccount - ); - - assert.equal( - vaultUnderlyingTokenAccountAfter.amount, - vaultUnderlyingTokenAccountBefore.amount - BigInt(amount) - ); - assert.equal( - userUnderlyingTokenAccountAfter.amount, - userUnderlyingTokenAccountBefore.amount + BigInt(amount) - ); - assert.equal( - userConditionalOnFinalizeTokenAccountAfter.amount, - userConditionalOnFinalizeTokenAccountBefore.amount - BigInt(amount) - ); - assert.equal( - userConditionalOnRevertTokenAccountAfter.amount, - userConditionalOnRevertTokenAccountBefore.amount - BigInt(amount) - ); -} - -export async function redeemConditionalTokens( - vaultProgram: VaultProgram, - user: Signer, - userConditionalOnFinalizeTokenAccount: PublicKey, - userConditionalOnRevertTokenAccount: PublicKey, - conditionalOnFinalizeTokenMint: PublicKey, - conditionalOnRevertTokenMint: PublicKey, - userUnderlyingTokenAccount: PublicKey, - vaultUnderlyingTokenAccount: PublicKey, - vault: PublicKey, - banksClient: BanksClient -) { - const vaultUnderlyingTokenAccountBefore = await getAccount( - banksClient, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountBefore = await getAccount( - banksClient, - userUnderlyingTokenAccount - ); - const userConditionalOnFinalizeTokenAccountBefore = await getAccount( - banksClient, - userConditionalOnFinalizeTokenAccount - ); - const userConditionalOnRevertTokenAccountBefore = await getAccount( - banksClient, - userConditionalOnRevertTokenAccount - ); - - await vaultProgram.methods - .redeemConditionalTokensForUnderlyingTokens() - .accounts({ - authority: user.publicKey, - userConditionalOnFinalizeTokenAccount, - userConditionalOnRevertTokenAccount, - userUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - conditionalOnFinalizeTokenMint, - conditionalOnRevertTokenMint, - tokenProgram: token.TOKEN_PROGRAM_ID, - }) - .signers([user]) - .rpc(); - - const vaultUnderlyingTokenAccountAfter = await getAccount( - banksClient, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountAfter = await getAccount( - banksClient, - userUnderlyingTokenAccount - ); - const userConditionalOnFinalizeTokenAccountAfter = await getAccount( - banksClient, - userConditionalOnFinalizeTokenAccount - ); - const userConditionalOnRevertTokenAccountAfter = await getAccount( - banksClient, - userConditionalOnRevertTokenAccount - ); - - let storedVault = await vaultProgram.account.conditionalVault.fetch(vault); - - let amount; - if (storedVault.status.finalized) { - amount = userConditionalOnFinalizeTokenAccountBefore.amount; - } else { - amount = userConditionalOnRevertTokenAccountBefore.amount; - } - - assert.equal( - vaultUnderlyingTokenAccountAfter.amount, - vaultUnderlyingTokenAccountBefore.amount - BigInt(amount) - ); - assert.equal( - userUnderlyingTokenAccountAfter.amount, - userUnderlyingTokenAccountBefore.amount + BigInt(amount) - ); - assert.equal(userConditionalOnFinalizeTokenAccountAfter.amount, BigInt(0)); - assert.equal(userConditionalOnRevertTokenAccountAfter.amount, BigInt(0)); -} diff --git a/tests/conditionalVault/integration/binaryPredictionMarket.test.ts b/tests/conditionalVault/integration/binaryPredictionMarket.test.ts new file mode 100644 index 00000000..985adc18 --- /dev/null +++ b/tests/conditionalVault/integration/binaryPredictionMarket.test.ts @@ -0,0 +1,116 @@ +import { ConditionalVaultClient, sha256 } from "@metadaoproject/futarchy"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { assert } from "chai"; +import { + createMint, + getMint, + mintTo, + createAssociatedTokenAccount, + transfer, + getAccount, +} from "spl-token-bankrun"; +import * as token from "@solana/spl-token"; + +export default async function test() { + // A binary prediction market test. Alice, Bob, and Charlie are betting on + // who's going to win the next election: Trump or Harris. Alice and Bob each + // split 100 USDC into TRUMP and HARRIS tokens. Alice is a trump supporter + // and buys 30 TRUMP tokens in exchange for 40 HARRIS tokens from Bob. Charlie + // buys an additional 30 HARRIS tokens from Alice. + + // Alice should have 130 TRUMP and 30 HARRIS tokens. Bob should have 70 TRUMP + // and 140 HARRIS tokens. Charlie should have 30 HARRIS tokens. + + // Alice faces a cash crunch, and merges 20 TRUMP and 20 HARRIS tokens into 20 + // USDC. She should now have 20 USDC, 110 TRUMP, and 10 HARRIS tokens. + + // Bob becomes a trump supporter, and as a display of his newfound + // allegiance, he sends all of his HARRIS tokens to the vault (to burn them). + // Bob should now have 70 TRUMP tokens. + + // The market resolves in favor of Harris. When redeeming, Alice should get 15 + // USDC, Bob should get nothing, and Charlie should get 30 USDC. + + let vaultClient: ConditionalVaultClient = this.vaultClient; + + let alice: Keypair = Keypair.generate(); + let bob: Keypair = Keypair.generate(); + let charlie: Keypair = Keypair.generate(); + let operator: Keypair = Keypair.generate(); + + let question: PublicKey = await vaultClient.initializeQuestion( + sha256( + new TextEncoder().encode( + "Who's going to win the next election?/TRUMP/HARRIS" + ) + ), + operator.publicKey, + 2 + ); + + let USDC: PublicKey = await this.createMint(operator.publicKey, 6); + + await this.createTokenAccount(USDC, alice.publicKey); + await this.createTokenAccount(USDC, bob.publicKey); + await this.createTokenAccount(USDC, charlie.publicKey); + + await this.mintTo(USDC, alice.publicKey, operator, 100); + await this.mintTo(USDC, bob.publicKey, operator, 100); + + const vault = await vaultClient.initializeVault(question, USDC, 2); + const storedVault = await vaultClient.fetchVault(vault); + + await vaultClient.addMetadataToConditionalTokensIx(vault, 0, "Trump Share", "TRUMP", "https://example.com/trump.png").rpc(); + await vaultClient.addMetadataToConditionalTokensIx(vault, 1, "Harris Share", "HARRIS", "https://example.com/harris.png").rpc(); + + await vaultClient + .splitTokensIx(question, vault, USDC, new BN(100), 2, alice.publicKey) + .signers([alice]) + .rpc(); + + await vaultClient + .splitTokensIx(question, vault, USDC, new BN(100), 2, bob.publicKey) + .signers([bob]) + .rpc(); + + const TRUMP = storedVault.conditionalTokenMints[0]; + const HARRIS = storedVault.conditionalTokenMints[1]; + + await this.createTokenAccount(HARRIS, charlie.publicKey); + + await this.transfer(HARRIS, alice, bob.publicKey, 40); + await this.transfer(TRUMP, bob, alice.publicKey, 30); + await this.transfer(HARRIS, alice, charlie.publicKey, 30); + + await vaultClient + .mergeTokensIx(question, vault, USDC, new BN(20), 2, alice.publicKey) + .signers([alice]) + .rpc(); + + await this.assertBalance(USDC, alice.publicKey, 20); + await this.assertBalance(TRUMP, alice.publicKey, 110); + await this.assertBalance(HARRIS, alice.publicKey, 10); + + await this.createTokenAccount(HARRIS, vault); + await this.transfer(HARRIS, bob, vault, 140); + + await vaultClient.resolveQuestionIx(question, operator, [0, 1]).rpc(); + + await vaultClient + .redeemTokensIx(question, vault, USDC, 2, alice.publicKey) + .signers([alice]) + .rpc(); + await vaultClient + .redeemTokensIx(question, vault, USDC, 2, bob.publicKey) + .signers([bob]) + .rpc(); + await vaultClient + .redeemTokensIx(question, vault, USDC, 2, charlie.publicKey) + .signers([charlie]) + .rpc(); + + await this.assertBalance(USDC, alice.publicKey, 30); + await this.assertBalance(USDC, bob.publicKey, 0); + await this.assertBalance(USDC, charlie.publicKey, 30); +} diff --git a/tests/conditionalVault/integration/scalarGrantMarket.test.ts b/tests/conditionalVault/integration/scalarGrantMarket.test.ts new file mode 100644 index 00000000..e0e996e8 --- /dev/null +++ b/tests/conditionalVault/integration/scalarGrantMarket.test.ts @@ -0,0 +1,72 @@ +import { ConditionalVaultClient, sha256 } from "@metadaoproject/futarchy"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { assert } from "chai"; +import { + createMint, + getMint, + mintTo, + createAssociatedTokenAccount, + transfer, + getAccount, +} from "spl-token-bankrun"; +import * as token from "@solana/spl-token"; + +export default async function test() { + // A scalar grant market test. Alice splits 100 USDC into E-UP and E-DOWN tokens. + // She sends 30 E-UPs to Bob. The grant committee resolves the question with 60% effectiveness. + // Alice and Bob redeem their tokens. + + let vaultClient: ConditionalVaultClient = this.vaultClient; + + let alice: Keypair = Keypair.generate(); + let bob: Keypair = Keypair.generate(); + let grantCommittee: Keypair = Keypair.generate(); + + let question: PublicKey = await vaultClient.initializeQuestion( + sha256( + new TextEncoder().encode( + "What is the effectiveness of the grant?/E-UP/E-DOWN" + ) + ), + grantCommittee.publicKey, + 2 + ); + + let USDC: PublicKey = await this.createMint(this.payer.publicKey, 6); + + await this.createTokenAccount(USDC, alice.publicKey); + await this.createTokenAccount(USDC, bob.publicKey); + + await this.mintTo(USDC, alice.publicKey, this.payer, 100); + + const vault = await vaultClient.initializeVault(question, USDC, 2); + const storedVault = await vaultClient.fetchVault(vault); + + await vaultClient + .splitTokensIx(question, vault, USDC, new BN(100), 2, alice.publicKey) + .signers([alice]) + .rpc(); + + const E_UP = storedVault.conditionalTokenMints[0]; + const E_DOWN = storedVault.conditionalTokenMints[1]; + + await this.createTokenAccount(E_UP, bob.publicKey); + + await this.transfer(E_UP, alice, bob.publicKey, 30); + + // Grant committee resolves the question with 60% effectiveness + await vaultClient.resolveQuestionIx(question, grantCommittee, [6, 4]).rpc(); + + await vaultClient + .redeemTokensIx(question, vault, USDC, 2, alice.publicKey) + .signers([alice]) + .rpc(); + await vaultClient + .redeemTokensIx(question, vault, USDC, 2, bob.publicKey) + .signers([bob]) + .rpc(); + + await this.assertBalance(USDC, bob.publicKey, 18); + await this.assertBalance(USDC, alice.publicKey, 82); +} diff --git a/tests/conditionalVault/main.test.ts b/tests/conditionalVault/main.test.ts new file mode 100644 index 00000000..58429b1e --- /dev/null +++ b/tests/conditionalVault/main.test.ts @@ -0,0 +1,21 @@ +import initializeQuestion from "./unit/initializeQuestion.test.js"; +import initializeConditionalVault from "./unit/initializeConditionalVault.test.js"; +import resolveQuestion from "./unit/resolveQuestion.test.js"; +import splitTokens from "./unit/splitTokens.test.js"; +import mergeTokens from "./unit/mergeTokens.test.js"; +import redeemTokens from "./unit/redeemTokens.test.js"; +import addMetadataToConditionalTokens from "./unit/addMetadataToConditionalTokens.test.js"; +import binaryPredictionMarket from "./integration/binaryPredictionMarket.test.js"; +import scalarGrantMarket from "./integration/scalarGrantMarket.test.js"; + +export default function suite() { + it("binary prediction market", binaryPredictionMarket); + it("scalar grant market", scalarGrantMarket); + describe("#initialize_question", initializeQuestion); + describe("#initialize_conditional_vault", initializeConditionalVault); + describe("#resolve_question", resolveQuestion); + describe("#split_tokens", splitTokens); + describe("#merge_tokens", mergeTokens); + describe("#redeem_tokens", redeemTokens); + describe("#add_metadata_to_conditional_tokens", addMetadataToConditionalTokens); +} diff --git a/tests/conditionalVault/unit.ts b/tests/conditionalVault/unit.ts new file mode 100644 index 00000000..9c0a9835 --- /dev/null +++ b/tests/conditionalVault/unit.ts @@ -0,0 +1,1545 @@ +import * as anchor from "@coral-xyz/anchor"; +import { BN, Program, web3 } from "@coral-xyz/anchor"; +import { + MPL_TOKEN_METADATA_PROGRAM_ID as UMI_MPL_TOKEN_METADATA_PROGRAM_ID, + createMetadataAccountV3, +} from "@metaplex-foundation/mpl-token-metadata"; +import { + Umi, + createSignerFromKeypair, + keypairIdentity, + none, +} from "@metaplex-foundation/umi"; +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { + fromWeb3JsKeypair, + fromWeb3JsPublicKey, + toWeb3JsLegacyTransaction, + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; +import * as token from "@solana/spl-token"; +import { SYSVAR_RENT_PUBKEY } from "@solana/web3.js"; +import { BankrunProvider } from "anchor-bankrun"; +import { assert } from "chai"; +import { BanksClient, ProgramTestContext, startAnchor } from "solana-bankrun"; +import { + createAccount, + createAssociatedTokenAccount, + createMint, + getAccount, + getMint, + mintTo, + transfer, +} from "spl-token-bankrun"; + +const { PublicKey, Keypair } = web3; + +import { + ConditionalVault, + IDL as ConditionalVaultIDL, +} from "../../target/types/conditional_vault"; +import { expectError } from "../utils"; +import { + CONDITIONAL_VAULT_PROGRAM_ID, + ConditionalVaultClient, + getConditionalTokenMintAddr, + getQuestionAddr, + getVaultAddr, + getVaultFinalizeMintAddr, + getVaultRevertMintAddr, + sha256, +} from "@metadaoproject/futarchy"; +import { set } from "@metaplex-foundation/umi/serializers"; + +export type VaultProgram = anchor.Program; +export type PublicKey = anchor.web3.PublicKey; +export type Signer = anchor.web3.Signer; +export type Keypair = anchor.web3.Keypair; + +const METADATA_URI = + "https://ftgnmxferax7tpgqyzdo76sisk5fhpsjv34omvgz33m7udvnsfba.arweave.net/LMzWXKSIL_m80MZG7_pIkrpTvkmu-OZU2d7Z-g6tkUI"; +const MPL_TOKEN_METADATA_PROGRAM_ID = toWeb3JsPublicKey( + UMI_MPL_TOKEN_METADATA_PROGRAM_ID +); + +export enum VaultStatus { + Active, + Finalized, + Reverted, +} + +// this test file isn't 'clean' or DRY or whatever; sorry! + +describe("conditional_vault", async function () { + let provider: anchor.Provider; + let vaultClient: ConditionalVaultClient; + + let vault: PublicKey; + let proposal: PublicKey; + let vaultUnderlyingTokenAccount: anchor.web3.PublicKey; + let underlyingTokenMint: anchor.web3.PublicKey; + let conditionalOnFinalizeMint: anchor.web3.PublicKey; + let conditionalOnRevertMint: anchor.web3.PublicKey; + let nonce: BN; + let settlementAuthority: anchor.web3.Keypair; + let underlyingMintAuthority: anchor.web3.Keypair; + let alice: anchor.web3.Keypair; + let context: ProgramTestContext; + let banksClient: BanksClient; + let umi: Umi; + + // note: adding types to these creates a slew of type errors below + let payer; + let vaultProgram; + + before(async function () { + context = await startAnchor( + "./", + [ + // even though the program is loaded into the test validator, we need + // to tell banks test client to load it as well + { + name: "mpl_token_metadata", + programId: MPL_TOKEN_METADATA_PROGRAM_ID, + }, + ], + [] + ); + banksClient = context.banksClient; + provider = new BankrunProvider(context); + anchor.setProvider(provider); + + umi = createUmi(anchor.AnchorProvider.env().connection); + + vaultProgram = new Program( + ConditionalVaultIDL, + CONDITIONAL_VAULT_PROGRAM_ID, + provider + ); + + vaultClient = ConditionalVaultClient.createClient({ + provider: provider as any, + }); + + payer = vaultProgram.provider.wallet.payer; + alice = anchor.web3.Keypair.generate(); + settlementAuthority = anchor.web3.Keypair.generate(); + underlyingMintAuthority = anchor.web3.Keypair.generate(); + umi.use(keypairIdentity(fromWeb3JsKeypair(payer))); + + underlyingTokenMint = await createMint( + banksClient, + payer as anchor.web3.Keypair, + underlyingMintAuthority.publicKey, + null, + 8 + ); + + proposal = Keypair.generate().publicKey; + + [vault] = getVaultAddr( + vaultProgram.programId, + settlementAuthority.publicKey, + underlyingTokenMint + ); + + vaultUnderlyingTokenAccount = await token.getAssociatedTokenAddress( + underlyingTokenMint, + vault, + true + ); + }); + + describe("#initialize_question", async function () { + it("initializes 2-outcome questions", async function () { + let questionId = sha256(new Uint8Array([1, 2, 3])); + + await vaultClient + .initializeQuestionIx(questionId, settlementAuthority.publicKey, 2) + .rpc(); + + let [question] = getQuestionAddr( + vaultProgram.programId, + questionId, + settlementAuthority.publicKey, + 2 + ); + + const storedQuestion = await vaultClient.fetchQuestion(question); + assert.deepEqual(storedQuestion.questionId, Array.from(questionId)); + assert.ok(storedQuestion.oracle.equals(settlementAuthority.publicKey)); + assert.deepEqual(storedQuestion.payoutNumerators, [0, 0]); + assert.equal(storedQuestion.payoutDenominator, 0); + }); + }); + + describe("#initialize_new_conditional_vault", async function () { + const testCases = [ + { name: "2-outcome question", idArray: [3, 2, 1], outcomes: 2 }, + { name: "3-outcome question", idArray: [4, 5, 6], outcomes: 3 }, + { name: "4-outcome question", idArray: [7, 8, 9], outcomes: 4 }, + ]; + + testCases.forEach(({ name, idArray, outcomes }) => { + describe(name, function () { + let question: PublicKey; + + beforeEach(async function () { + let questionId = sha256(new Uint8Array(idArray)); + question = await vaultClient.initializeQuestion( + questionId, + settlementAuthority.publicKey, + outcomes + ); + }); + + it("initializes vaults correctly", async function () { + await vaultClient + .initializeVaultIx(question, underlyingTokenMint, outcomes) + .rpc(); + + const [vault, pdaBump] = getVaultAddr( + vaultProgram.programId, + question, + underlyingTokenMint + ); + + const storedVault = await vaultClient.fetchVault(vault); + assert.ok(storedVault.question.equals(question)); + assert.ok( + storedVault.underlyingTokenMint.equals(underlyingTokenMint) + ); + + const vaultUnderlyingTokenAccount = + token.getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ); + assert.ok( + storedVault.underlyingTokenAccount.equals( + vaultUnderlyingTokenAccount + ) + ); + const storedConditionalTokenMints = storedVault.conditionalTokenMints; + storedConditionalTokenMints.forEach((mint, i) => { + const [expectedMint] = getConditionalTokenMintAddr( + vaultProgram.programId, + vault, + i + ); + assert.ok(mint.equals(expectedMint)); + }); + assert.equal(storedVault.pdaBump, pdaBump); + assert.equal(storedVault.decimals, 8); + + for (let mint of storedConditionalTokenMints) { + const storedMint = await getMint(banksClient, mint); + assert.ok(storedMint.mintAuthority.equals(vault)); + assert.equal(storedMint.supply.toString(), "0"); + assert.equal(storedMint.decimals, 8); + assert.isNull(storedMint.freezeAuthority); + } + }); + }); + }); + }); + + describe("#resolve_question", async function () { + let question: PublicKey; + + beforeEach(async function () { + let questionId = sha256(new Uint8Array([4, 2, 1])); + + question = await vaultClient.initializeQuestion( + questionId, + settlementAuthority.publicKey, + 2 + ); + }); + + it("resolves questions", async function () { + let storedQuestion = await vaultClient.fetchQuestion(question); + + assert.deepEqual(storedQuestion.payoutNumerators, [0, 0]); + assert.equal(storedQuestion.payoutDenominator, 0); + + await vaultClient + .resolveQuestionIx(question, settlementAuthority, [1, 0]) + .rpc(); + + storedQuestion = await vaultClient.fetchQuestion(question); + + assert.deepEqual(storedQuestion.payoutNumerators, [1, 0]); + assert.equal(storedQuestion.payoutDenominator, 1); + }); + }); + + describe("#split_tokens", async function () { + let question: PublicKey; + let vault: PublicKey; + + beforeEach(async function () { + let questionId = sha256(new Uint8Array([5, 2, 1])); + + question = await vaultClient.initializeQuestion( + questionId, + settlementAuthority.publicKey, + 2 + ); + vault = await vaultClient.initializeVault( + question, + underlyingTokenMint, + 2 + ); + + let userUnderlyingTokenAccount = await createAssociatedTokenAccount( + banksClient, + payer, + underlyingTokenMint, + payer.publicKey + ); + + await mintTo( + banksClient, + payer, + underlyingTokenMint, + userUnderlyingTokenAccount, + underlyingMintAuthority, + 10_000_000_000n + ); + }); + + it("splits tokens", async function () { + await vaultClient + .splitTokensIx(question, vault, underlyingTokenMint, new BN(1000), 2) + .rpc(); + + const storedVault = await vaultClient.fetchVault(vault); + + let storedVaultUnderlyingAcc = await getAccount( + banksClient, + storedVault.underlyingTokenAccount + ); + assert.equal(storedVaultUnderlyingAcc.amount.toString(), "1000"); + + const storedConditionalTokenMints = storedVault.conditionalTokenMints; + for (let mint of storedConditionalTokenMints) { + let storedMint = await getMint(banksClient, mint); + assert.equal(storedMint.supply.toString(), "1000"); + let storedTokenAcc = await getAccount( + banksClient, + token.getAssociatedTokenAddressSync(mint, payer.publicKey) + ); + assert.equal(storedTokenAcc.amount.toString(), "1000"); + } + }); + }); + + describe("#merge_tokens", async function () { + let question: PublicKey; + let vault: PublicKey; + + beforeEach(async function () { + let questionId = sha256(new Uint8Array([9, 2, 1])); + + question = await vaultClient.initializeQuestion( + questionId, + settlementAuthority.publicKey, + 2 + ); + vault = await vaultClient.initializeVault( + question, + underlyingTokenMint, + 2 + ); + + await vaultClient + .splitTokensIx(question, vault, underlyingTokenMint, new BN(1000), 2) + .rpc(); + }); + + it("merges tokens", async function () { + const balanceBefore = await getAccount( + banksClient, + token.getAssociatedTokenAddressSync( + underlyingTokenMint, + payer.publicKey + ) + ).then((acc) => acc.amount); + await vaultClient + .mergeTokensIx(question, vault, underlyingTokenMint, new BN(600), 2) + .rpc(); + const balanceAfter = await getAccount( + banksClient, + token.getAssociatedTokenAddressSync( + underlyingTokenMint, + payer.publicKey + ) + ).then((acc) => acc.amount); + + assert.isTrue(balanceAfter > balanceBefore); + assert.equal(balanceAfter - balanceBefore, 600); + }); + }); + + describe("#redeem_tokens", async function () { + let question: PublicKey; + let vault: PublicKey; + + beforeEach(async function () { + let questionId = sha256(new Uint8Array([9, 28, 2, 1])); + + question = await vaultClient.initializeQuestion( + questionId, + settlementAuthority.publicKey, + 2 + ); + vault = await vaultClient.initializeVault( + question, + underlyingTokenMint, + 2 + ); + + await vaultClient + .splitTokensIx(question, vault, underlyingTokenMint, new BN(1000), 2) + .rpc(); + }); + + // it("can't redeem tokens when question is not resolved", async function () { + // const callbacks = expectError( + // "CantRedeemConditionalTokens", + // "redeemed tokens despite question not being resolved" + // ); + + // await vaultClient + // .redeemTokensIx(question, vault, underlyingTokenMint, new BN(600), 2) + // .rpc() + // .then(callbacks[0], callbacks[1]); + // }); + + // it("can redeem tokens when question is resolved", async function () { + // await vaultClient + // .resolveQuestionIx(question, settlementAuthority, [1, 0]) + // .rpc(); + + // const underlyingTokenAccount = await token.getAssociatedTokenAddress( + // underlyingTokenMint, + // payer.publicKey + // ); + + // const balanceBefore = await getAccount(banksClient, underlyingTokenAccount) + // .then(acc => acc.amount); + + // await vaultClient + // .redeemTokensIx(question, vault, underlyingTokenMint, new BN(600), 2) + // .rpc(); + + // const balanceAfter = await getAccount(banksClient, underlyingTokenAccount) + // .then(acc => acc.amount); + + // assert.isTrue(balanceAfter > balanceBefore); + // assert.equal(balanceAfter - balanceBefore, 1000n); + // }); + + it("can redeem tokens when question is resolved", async function () { + await vaultClient + .resolveQuestionIx(question, settlementAuthority, [1, 0]) + .rpc(); + + const storedVault = await vaultClient.fetchVault(vault); + + const outcome0Tokens = storedVault.conditionalTokenMints[0]; + + let burne = Keypair.generate(); + await createAssociatedTokenAccount( + banksClient, + payer, + outcome0Tokens, + burne.publicKey + ); + + await transfer( + banksClient, + payer, + token.getAssociatedTokenAddressSync(outcome0Tokens, payer.publicKey), + token.getAssociatedTokenAddressSync(outcome0Tokens, burne.publicKey), + payer, + 1000n + ); + + const underlyingTokenAccount = await token.getAssociatedTokenAddress( + underlyingTokenMint, + payer.publicKey + ); + + const balanceBefore = await getAccount( + banksClient, + underlyingTokenAccount + ).then((acc) => acc.amount); + + await vaultClient + .redeemTokensIx(question, vault, underlyingTokenMint, new BN(600), 2) + .rpc(); + + const balanceAfter = await getAccount( + banksClient, + underlyingTokenAccount + ).then((acc) => acc.amount); + + assert.isTrue(balanceAfter == balanceBefore); + }); + }); +}); + +// describe("#initialize_conditional_vault", async function () { +// it("initializes vaults", async function () { +// await vaultClient +// .initializeVaultIx( +// settlementAuthority.publicKey, +// underlyingTokenMint, +// proposal +// ) +// .rpc(); + +// conditionalOnFinalizeMint = getVaultFinalizeMintAddr( +// vaultProgram.programId, +// vault +// )[0]; + +// conditionalOnRevertMint = getVaultRevertMintAddr( +// vaultProgram.programId, +// vault +// )[0]; + +// const storedVault = await vaultProgram.account.conditionalVault.fetch( +// vault +// ); +// assert.exists(storedVault.status.active); +// assert.ok( +// storedVault.settlementAuthority.equals(settlementAuthority.publicKey) +// ); +// assert.ok(storedVault.underlyingTokenMint.equals(underlyingTokenMint)); +// assert.ok( +// storedVault.underlyingTokenAccount.equals(vaultUnderlyingTokenAccount) +// ); +// assert.ok( +// storedVault.conditionalOnFinalizeTokenMint.equals( +// conditionalOnFinalizeMint +// ) +// ); +// assert.ok( +// storedVault.conditionalOnRevertTokenMint.equals(conditionalOnRevertMint) +// ); +// }); +// }); + +// describe("#mint_conditional_tokens", async function () { +// // alice is available throughout the tests, bob is just for mint_conditional_tokens +// let bob: Keypair; +// let amount = 1000; +// let bobUnderlyingTokenAccount: PublicKey; +// let bobConditionalOnFinalizeTokenAccount: PublicKey; +// let bobConditionalOnRevertTokenAccount: PublicKey; + +// beforeEach(async function () { +// bob = anchor.web3.Keypair.generate(); + +// bobUnderlyingTokenAccount = await createAssociatedTokenAccount( +// /* bobUnderlyingTokenAccount = await createAccount( */ +// banksClient, +// payer, +// underlyingTokenMint, +// bob.publicKey +// ); + +// bobConditionalOnFinalizeTokenAccount = await createAssociatedTokenAccount( +// banksClient, +// payer, +// conditionalOnFinalizeMint, +// bob.publicKey +// ); +// bobConditionalOnRevertTokenAccount = await createAssociatedTokenAccount( +// banksClient, +// payer, +// conditionalOnRevertMint, +// bob.publicKey +// ); + +// await mintTo( +// banksClient, +// payer, +// underlyingTokenMint, +// bobUnderlyingTokenAccount, +// underlyingMintAuthority, +// amount +// ); +// }); + +// it("mints conditional tokens", async function () { +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient +// ); +// }); + +// it("mints conditional tokens twice", async function () { +// await mintConditionalTokens( +// vaultProgram, +// amount / 2, +// bob, +// vault, +// banksClient +// ); + +// await mintConditionalTokens( +// vaultProgram, +// amount / 2, +// bob, +// vault, +// banksClient +// ); +// }); + +// it("blocks mints when the user doesn't have enough underlying tokens", async function () { +// const callbacks = expectError( +// "InsufficientUnderlyingTokens", +// "mint suceeded despite user not having enough underlying tokens" +// ); +// await mintConditionalTokens( +// vaultProgram, +// amount + 10, +// bob, +// vault, +// banksClient +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("checks that `vault_underlying_token_account` and `conditional_vault` match up", async function () { +// const maliciousVaultUnderlyingTokenAccount = await createAccount( +// banksClient, +// payer, +// underlyingTokenMint, +// anchor.web3.Keypair.generate().publicKey +// ); + +// const callbacks = expectError( +// "InvalidVaultUnderlyingTokenAccount", +// "was able to mint conditional tokens while supplying an invalid vault underlying account" +// ); +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient, +// undefined, +// undefined, +// undefined, +// maliciousVaultUnderlyingTokenAccount +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("checks that `user_underlying_token_account` is owned by the user", async function () { +// const nonOwnedUserUnderlyingAccount = await createAccount( +// banksClient, +// payer, +// underlyingTokenMint, +// anchor.web3.Keypair.generate().publicKey +// ); + +// await mintTo( +// banksClient, +// payer, +// underlyingTokenMint, +// nonOwnedUserUnderlyingAccount, +// underlyingMintAuthority, +// amount +// ); + +// const callbacks = expectError( +// "ConstraintTokenOwner", +// "mint suceeded despite `user_underlying_token_account` not being owned by the user" +// ); + +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient, +// nonOwnedUserUnderlyingAccount +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("checks that `user_conditional_on_finalize_token_account` is owned by the user", async function () { +// const nonOwnedUserConditionalAccount = await createAccount( +// banksClient, +// payer, +// conditionalOnFinalizeMint, +// anchor.web3.Keypair.generate().publicKey +// ); + +// const callbacks = expectError( +// "ConstraintTokenOwner", +// "mint suceeded despite `user_conditional_token_account` not being owned by the user" +// ); + +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient, +// undefined, +// nonOwnedUserConditionalAccount +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("checks that `user_conditional_on_revert_token_account` is owned by the user", async function () { +// const nonOwnedUserConditionalAccount = await createAccount( +// banksClient, +// payer, +// conditionalOnRevertMint, +// anchor.web3.Keypair.generate().publicKey +// ); + +// const callbacks = expectError( +// "ConstraintTokenOwner", +// "mint suceeded despite `user_conditional_token_account` not being owned by the user" +// ); + +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient, +// undefined, +// nonOwnedUserConditionalAccount +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("checks that `user_conditional_token_account` has `conditional_token_mint` as its mint", async function () { +// const wrongConditionalTokenMint = await createMint( +// banksClient, +// payer, +// vault, +// vault, +// 8 +// ); +// const wrongMintBobConditionalTokenAccount = await createAccount( +// banksClient, +// payer, +// wrongConditionalTokenMint, +// bob.publicKey +// ); + +// const callbacks = expectError( +// "ConstraintTokenMint", +// "mint suceeded despite `user_conditional_token_account` having a wrong mint" +// ); + +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient, +// undefined, +// wrongMintBobConditionalTokenAccount +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("checks that `user_underlying_token_account` has the correct mint", async function () { +// const mintAuthority = anchor.web3.Keypair.generate(); +// const randomMint = await createMint( +// banksClient, +// payer, +// mintAuthority.publicKey, +// mintAuthority.publicKey, +// 8 +// ); +// const wrongMintBobUnderlyingAccount = await createAccount( +// banksClient, +// payer, +// randomMint, +// bob.publicKey +// ); + +// await mintTo( +// banksClient, +// payer, +// randomMint, +// wrongMintBobUnderlyingAccount, +// mintAuthority, +// amount +// ); + +// const callbacks = expectError( +// "ConstraintTokenMint", +// "mint suceeded despite `user_underlying_token_account` having the wrong mint" +// ); + +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient, +// wrongMintBobUnderlyingAccount +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("checks that `conditional_token_mint` is the one stored in the conditional vault", async function () { +// const wrongConditionalTokenMint = await createMint( +// banksClient, +// payer, +// vault, +// null, +// 10 +// ); + +// const wrongMintBobConditionalTokenAccount = await createAccount( +// banksClient, +// payer, +// wrongConditionalTokenMint, +// bob.publicKey +// ); + +// const callbacks = expectError( +// "InvalidConditionalTokenMint", +// "mint suceeded despite `conditional_token_mint` not being the one stored in the conditional vault" +// ); + +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient, +// undefined, +// wrongMintBobConditionalTokenAccount, +// undefined, +// undefined, +// wrongConditionalTokenMint +// ).then(callbacks[0], callbacks[1]); +// }); +// }); + +// describe("#settle_conditional_vault", async function () { +// it("allows vaults to be finalized", async function () { +// let [vault, _, settlementAuthority] = await generateRandomVault( +// vaultProgram, +// vaultClient, +// payer, +// banksClient, +// umi +// ); + +// await vaultProgram.methods +// .settleConditionalVault({ finalized: {} }) +// .accounts({ +// settlementAuthority: settlementAuthority.publicKey, +// vault, +// }) +// .signers([settlementAuthority]) +// .rpc(); +// }); + +// it("allows vaults to be reverted", async function () { +// let [vault, _, settlementAuthority] = await generateRandomVault( +// vaultProgram, +// vaultClient, +// payer, +// banksClient, +// umi +// ); + +// await vaultProgram.methods +// .settleConditionalVault({ reverted: {} }) +// .accounts({ +// settlementAuthority: settlementAuthority.publicKey, +// vault, +// }) +// .signers([settlementAuthority]) +// .rpc(); +// }); + +// it("disallows vaults from being finalized twice", async function () { +// let [vault, _, settlementAuthority] = await generateRandomVault( +// vaultProgram, +// vaultClient, +// payer, +// banksClient, +// umi +// ); + +// await vaultProgram.methods +// .settleConditionalVault({ finalized: {} }) +// .accounts({ +// settlementAuthority: settlementAuthority.publicKey, +// vault, +// }) +// .signers([settlementAuthority]) +// .rpc(); + +// const callbacks = expectError( +// "VaultAlreadySettled", +// "settle suceeded even though this vault had already been settled" +// ); + +// await vaultProgram.methods +// .settleConditionalVault({ reverted: {} }) +// .accounts({ +// settlementAuthority: settlementAuthority.publicKey, +// vault, +// }) +// .signers([settlementAuthority]) +// .rpc() +// .then(callbacks[0], callbacks[1]); +// }); +// }); + +// describe("#redeem_and_merge_conditional_tokens_for_underlying_tokens", async function () { +// let bob: Keypair; +// let amount = 1000; +// let mergeAmount = 10; +// let bobUnderlyingTokenAccount: PublicKey; +// let bobConditionalOnFinalizeTokenAccount: PublicKey; +// let bobConditionalOnRevertTokenAccount: PublicKey; + +// beforeEach(async function () { +// [vault, underlyingMintAuthority, settlementAuthority] = +// await generateRandomVault( +// vaultProgram, +// vaultClient, +// payer, +// banksClient, +// umi +// ); +// let storedVault = await vaultProgram.account.conditionalVault.fetch( +// vault +// ); +// underlyingTokenMint = storedVault.underlyingTokenMint; +// conditionalOnFinalizeMint = storedVault.conditionalOnFinalizeTokenMint; +// conditionalOnRevertMint = storedVault.conditionalOnRevertTokenMint; +// vaultUnderlyingTokenAccount = storedVault.underlyingTokenAccount; + +// bob = anchor.web3.Keypair.generate(); + +// bobUnderlyingTokenAccount = await createAssociatedTokenAccount( +// banksClient, +// payer, +// underlyingTokenMint, +// bob.publicKey +// ); + +// bobConditionalOnFinalizeTokenAccount = await createAssociatedTokenAccount( +// banksClient, +// payer, +// conditionalOnFinalizeMint, +// bob.publicKey +// ); + +// bobConditionalOnRevertTokenAccount = await createAccount( +// banksClient, +// payer, +// conditionalOnRevertMint, +// bob.publicKey +// ); + +// await mintTo( +// banksClient, +// payer, +// underlyingTokenMint, +// bobUnderlyingTokenAccount, +// underlyingMintAuthority, +// amount +// ); + +// await mintConditionalTokens( +// vaultProgram, +// amount, +// bob, +// vault, +// banksClient +// ); +// }); + +// it("successfully merges 10 tokens before the vault has been finalized", async function () { +// // Assuming the vault has not yet been finalized + +// await mergeConditionalTokens( +// vaultProgram, +// mergeAmount, +// bob, +// bobConditionalOnFinalizeTokenAccount, +// bobConditionalOnRevertTokenAccount, +// conditionalOnFinalizeMint, +// conditionalOnRevertMint, +// bobUnderlyingTokenAccount, +// vaultUnderlyingTokenAccount, +// vault, +// banksClient +// ); +// }); + +// it("prevents users from merging conditional tokens after the vault has been finalized", async function () { +// await vaultProgram.methods +// .settleConditionalVault({ finalized: {} }) +// .accounts({ +// settlementAuthority: settlementAuthority.publicKey, +// vault, +// }) +// .signers([settlementAuthority]) +// .rpc(); + +// const callbacks = expectError( +// "VaultAlreadySettled", +// "merge suceeded even though this vault was finalized" +// ); +// await mergeConditionalTokens( +// vaultProgram, +// mergeAmount, +// bob, +// bobConditionalOnFinalizeTokenAccount, +// bobConditionalOnRevertTokenAccount, +// conditionalOnFinalizeMint, +// conditionalOnRevertMint, +// bobUnderlyingTokenAccount, +// vaultUnderlyingTokenAccount, +// vault, +// banksClient +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("allows users to redeem conditional-on-finalize tokens for underlying tokens when a vault has been finalized", async function () { +// await vaultProgram.methods +// .settleConditionalVault({ finalized: {} }) +// .accounts({ +// settlementAuthority: settlementAuthority.publicKey, +// vault, +// }) +// .signers([settlementAuthority]) +// .rpc(); + +// await redeemConditionalTokens( +// vaultProgram, +// bob, +// bobConditionalOnFinalizeTokenAccount, +// bobConditionalOnRevertTokenAccount, +// conditionalOnFinalizeMint, +// conditionalOnRevertMint, +// bobUnderlyingTokenAccount, +// vaultUnderlyingTokenAccount, +// vault, +// banksClient +// ); +// }); + +// it("allows user to redeeming conditional-on-revert tokens for underlying tokens when a vault is reverted", async function () { +// await vaultProgram.methods +// .settleConditionalVault({ reverted: {} }) +// .accounts({ +// settlementAuthority: settlementAuthority.publicKey, +// vault, +// }) +// .signers([settlementAuthority]) +// .rpc(); + +// await redeemConditionalTokens( +// vaultProgram, +// bob, +// bobConditionalOnFinalizeTokenAccount, +// bobConditionalOnRevertTokenAccount, +// conditionalOnFinalizeMint, +// conditionalOnRevertMint, +// bobUnderlyingTokenAccount, +// vaultUnderlyingTokenAccount, +// vault, +// banksClient +// ); +// }); + +// it("prevents users from redeeming conditional tokens while a vault is still active", async function () { +// const callbacks = expectError( +// "CantRedeemConditionalTokens", +// "redemption suceeded even though this vault was still active" +// ); +// await redeemConditionalTokens( +// vaultProgram, +// bob, +// bobConditionalOnFinalizeTokenAccount, +// bobConditionalOnRevertTokenAccount, +// conditionalOnFinalizeMint, +// conditionalOnRevertMint, +// bobUnderlyingTokenAccount, +// vaultUnderlyingTokenAccount, +// vault, +// banksClient +// ).then(callbacks[0], callbacks[1]); +// }); + +// it("checks that the user has provided the correct conditional token mint", async function () { +// const wrongConditionalTokenMint = await createMint( +// banksClient, +// payer, +// vault, +// null, +// 10 +// ); + +// const wrongMintBobConditionalTokenAccount = await createAccount( +// banksClient, +// payer, +// wrongConditionalTokenMint, +// bob.publicKey +// ); + +// const callbacks = expectError( +// "InvalidConditionalTokenMint", +// "redemption suceeded despite `conditional_token_mint` not being the one stored in the conditional vault" +// ); +// await redeemConditionalTokens( +// vaultProgram, +// bob, +// wrongMintBobConditionalTokenAccount, +// bobConditionalOnRevertTokenAccount, +// wrongConditionalTokenMint, +// conditionalOnRevertMint, +// bobUnderlyingTokenAccount, +// vaultUnderlyingTokenAccount, +// vault, +// banksClient +// ).then(callbacks[0], callbacks[1]); +// }); +// }); +// }); + +// async function generateRandomVault( +// vaultProgram: VaultProgram, +// vaultClient: ConditionalVaultClient, +// payer: Keypair, +// banksClient: BanksClient, +// umi: Umi, +// settlementAuthority: Keypair = anchor.web3.Keypair.generate() +// ): Promise<[PublicKey, Keypair, Keypair]> { +// const underlyingMintAuthority = anchor.web3.Keypair.generate(); + +// const underlyingTokenMint = await createMint( +// banksClient, +// payer, +// underlyingMintAuthority.publicKey, +// null, +// 8 +// ); + +// const tokenMint = fromWeb3JsPublicKey(underlyingTokenMint); +// let builder = createMetadataAccountV3(umi, { +// mint: tokenMint, +// mintAuthority: createSignerFromKeypair( +// umi, +// fromWeb3JsKeypair(underlyingMintAuthority) +// ), +// data: { +// name: "TOKE", +// symbol: "TOKE", +// uri: "METADATA_URI", +// sellerFeeBasisPoints: 0, +// creators: none(), +// collection: none(), +// uses: none(), +// }, +// isMutable: false, +// collectionDetails: none(), +// }); +// builder = builder.setBlockhash( +// (await umi.rpc.getLatestBlockhash()).blockhash +// ); + +// const createMetadataResult = await vaultProgram.provider.sendAndConfirm( +// toWeb3JsLegacyTransaction(builder.build(umi)), +// [underlyingMintAuthority], +// { +// skipPreflight: true, +// commitment: "confirmed", +// } +// ); +// // console.log(createMetadataResult); + +// const proposal = Keypair.generate().publicKey; + +// const [vault] = getVaultAddr( +// vaultProgram.programId, +// settlementAuthority.publicKey, +// underlyingTokenMint, +// proposal +// ); + +// const conditionalOnFinalizeTokenMint = getVaultFinalizeMintAddr( +// vaultProgram.programId, +// vault +// )[0]; +// const conditionalOnRevertTokenMint = getVaultRevertMintAddr( +// vaultProgram.programId, +// vault +// )[0]; + +// const vaultUnderlyingTokenAccount = await token.getAssociatedTokenAddress( +// underlyingTokenMint, +// vault, +// true +// ); + +// // when we have a ts lib, we can consolidate this logic there +// const [conditionalOnFinalizeTokenMetadata] = +// anchor.web3.PublicKey.findProgramAddressSync( +// [ +// anchor.utils.bytes.utf8.encode("metadata"), +// MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), +// conditionalOnFinalizeTokenMint.toBuffer(), +// ], +// MPL_TOKEN_METADATA_PROGRAM_ID +// ); + +// const [conditionalOnRevertTokenMetadata] = +// anchor.web3.PublicKey.findProgramAddressSync( +// [ +// anchor.utils.bytes.utf8.encode("metadata"), +// MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), +// conditionalOnRevertTokenMint.toBuffer(), +// ], +// MPL_TOKEN_METADATA_PROGRAM_ID +// ); + +// const [underlyingTokenMetadata] = +// anchor.web3.PublicKey.findProgramAddressSync( +// [ +// anchor.utils.bytes.utf8.encode("metadata"), +// MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), +// underlyingTokenMint.toBuffer(), +// ], +// MPL_TOKEN_METADATA_PROGRAM_ID +// ); + +// // const addMetadataToConditionalTokensIx = await vaultProgram.methods +// // .addMetadataToConditionalTokens({ +// // proposalNumber: new BN(0), // nonce, +// // onFinalizeUri: METADATA_URI, +// // onRevertUri: METADATA_URI, +// // }) +// // .accounts({ +// // payer: payer.publicKey, +// // vault, +// // underlyingTokenMint, +// // underlyingTokenMetadata, +// // conditionalOnFinalizeTokenMint, +// // conditionalOnRevertTokenMint, +// // conditionalOnFinalizeTokenMetadata, +// // conditionalOnRevertTokenMetadata, +// // tokenMetadataProgram: MPL_TOKEN_METADATA_PROGRAM_ID, +// // systemProgram: anchor.web3.SystemProgram.programId, +// // rent: SYSVAR_RENT_PUBKEY, +// // }) +// // .instruction(); +// const addMetadataToConditionalTokensIx = await vaultClient +// .addMetadataToConditionalTokensIx( +// vault, +// underlyingTokenMint, +// 1, +// METADATA_URI, +// METADATA_URI +// ) +// .instruction(); + +// await vaultClient +// .initializeVaultIx( +// settlementAuthority.publicKey, +// underlyingTokenMint, +// proposal +// ) +// .postInstructions([addMetadataToConditionalTokensIx]) +// .rpc(); + +// return [vault, underlyingMintAuthority, settlementAuthority]; +// } + +// export async function mintConditionalTokens( +// program: VaultProgram, +// amount: number | bigint, +// user: Signer, +// vault: PublicKey, +// banksClient: BanksClient, +// userUnderlyingTokenAccount?: PublicKey, +// userConditionalOnFinalizeTokenAccount?: PublicKey, +// userConditionalOnRevertTokenAccount?: PublicKey, +// vaultUnderlyingTokenAccount?: PublicKey, +// conditionalOnFinalizeTokenMint?: PublicKey +// ) { +// const storedVault = await program.account.conditionalVault.fetch(vault); +// if (!userUnderlyingTokenAccount) { +// userUnderlyingTokenAccount = await token.getAssociatedTokenAddress( +// storedVault.underlyingTokenMint, +// user.publicKey, +// true +// ); +// } +// if (!userConditionalOnFinalizeTokenAccount) { +// userConditionalOnFinalizeTokenAccount = +// await token.getAssociatedTokenAddress( +// storedVault.conditionalOnFinalizeTokenMint, +// user.publicKey, +// true +// ); +// } +// if (!userConditionalOnRevertTokenAccount) { +// userConditionalOnRevertTokenAccount = await token.getAssociatedTokenAddress( +// storedVault.conditionalOnRevertTokenMint, +// user.publicKey, +// true +// ); +// } +// if (!vaultUnderlyingTokenAccount) { +// vaultUnderlyingTokenAccount = storedVault.underlyingTokenAccount; +// } +// if (!conditionalOnFinalizeTokenMint) { +// conditionalOnFinalizeTokenMint = storedVault.conditionalOnFinalizeTokenMint; +// } + +// const vaultUnderlyingTokenAccountBefore = await getAccount( +// banksClient, +// vaultUnderlyingTokenAccount +// ); +// const userUnderlyingTokenAccountBefore = await getAccount( +// banksClient, +// userUnderlyingTokenAccount +// ); +// const userConditionalOnFinalizeTokenAccountBefore = await getAccount( +// banksClient, +// userConditionalOnFinalizeTokenAccount +// ); +// const userConditionalOnRevertTokenAccountBefore = await getAccount( +// banksClient, +// userConditionalOnRevertTokenAccount +// ); + +// const bnAmount = new anchor.BN(amount.toString()); +// /* try { */ +// await program.methods +// .mintConditionalTokens(bnAmount) +// .accounts({ +// authority: user.publicKey, +// vault, +// vaultUnderlyingTokenAccount, +// userUnderlyingTokenAccount, +// conditionalOnFinalizeTokenMint, +// userConditionalOnFinalizeTokenAccount, +// conditionalOnRevertTokenMint: storedVault.conditionalOnRevertTokenMint, +// userConditionalOnRevertTokenAccount, +// }) +// .signers([user]) +// .rpc(); + +// const vaultUnderlyingTokenAccountAfter = await getAccount( +// banksClient, +// vaultUnderlyingTokenAccount +// ); +// const userUnderlyingTokenAccountAfter = await getAccount( +// banksClient, +// userUnderlyingTokenAccount +// ); +// const userConditionalOnFinalizeTokenAccountAfter = await getAccount( +// banksClient, +// userConditionalOnFinalizeTokenAccount +// ); +// const userConditionalOnRevertTokenAccountAfter = await getAccount( +// banksClient, +// userConditionalOnRevertTokenAccount +// ); + +// assert.equal( +// vaultUnderlyingTokenAccountAfter.amount, +// vaultUnderlyingTokenAccountBefore.amount + BigInt(amount) +// ); +// assert.equal( +// userUnderlyingTokenAccountAfter.amount, +// userUnderlyingTokenAccountBefore.amount - BigInt(amount) +// ); +// assert.equal( +// userConditionalOnFinalizeTokenAccountAfter.amount, +// userConditionalOnFinalizeTokenAccountBefore.amount + BigInt(amount) +// ); +// assert.equal( +// userConditionalOnRevertTokenAccountAfter.amount, +// userConditionalOnRevertTokenAccountBefore.amount + BigInt(amount) +// ); +// } + +// export async function mergeConditionalTokens( +// vaultProgram: VaultProgram, +// amount: number | bigint, +// user: Signer, +// userConditionalOnFinalizeTokenAccount: PublicKey, +// userConditionalOnRevertTokenAccount: PublicKey, +// conditionalOnFinalizeTokenMint: PublicKey, +// conditionalOnRevertTokenMint: PublicKey, +// userUnderlyingTokenAccount: PublicKey, +// vaultUnderlyingTokenAccount: PublicKey, +// vault: PublicKey, +// banksClient: BanksClient +// ) { +// const vaultUnderlyingTokenAccountBefore = await getAccount( +// banksClient, +// vaultUnderlyingTokenAccount +// ); +// const userUnderlyingTokenAccountBefore = await getAccount( +// banksClient, +// userUnderlyingTokenAccount +// ); +// const userConditionalOnFinalizeTokenAccountBefore = await getAccount( +// banksClient, +// userConditionalOnFinalizeTokenAccount +// ); +// const userConditionalOnRevertTokenAccountBefore = await getAccount( +// banksClient, +// userConditionalOnRevertTokenAccount +// ); + +// const bnAmount = new anchor.BN(amount.toString()); +// await vaultProgram.methods +// .mergeConditionalTokensForUnderlyingTokens(bnAmount) +// .accounts({ +// authority: user.publicKey, +// userConditionalOnFinalizeTokenAccount, +// userConditionalOnRevertTokenAccount, +// userUnderlyingTokenAccount, +// vaultUnderlyingTokenAccount, +// vault, +// conditionalOnFinalizeTokenMint, +// conditionalOnRevertTokenMint, +// tokenProgram: token.TOKEN_PROGRAM_ID, +// }) +// .signers([user]) +// .rpc(); + +// const vaultUnderlyingTokenAccountAfter = await getAccount( +// banksClient, +// vaultUnderlyingTokenAccount +// ); +// const userUnderlyingTokenAccountAfter = await getAccount( +// banksClient, +// userUnderlyingTokenAccount +// ); +// const userConditionalOnFinalizeTokenAccountAfter = await getAccount( +// banksClient, +// userConditionalOnFinalizeTokenAccount +// ); +// const userConditionalOnRevertTokenAccountAfter = await getAccount( +// banksClient, +// userConditionalOnRevertTokenAccount +// ); + +// assert.equal( +// vaultUnderlyingTokenAccountAfter.amount, +// vaultUnderlyingTokenAccountBefore.amount - BigInt(amount) +// ); +// assert.equal( +// userUnderlyingTokenAccountAfter.amount, +// userUnderlyingTokenAccountBefore.amount + BigInt(amount) +// ); +// assert.equal( +// userConditionalOnFinalizeTokenAccountAfter.amount, +// userConditionalOnFinalizeTokenAccountBefore.amount - BigInt(amount) +// ); +// assert.equal( +// userConditionalOnRevertTokenAccountAfter.amount, +// userConditionalOnRevertTokenAccountBefore.amount - BigInt(amount) +// ); +// } + +// export async function redeemConditionalTokens( +// vaultProgram: VaultProgram, +// user: Signer, +// userConditionalOnFinalizeTokenAccount: PublicKey, +// userConditionalOnRevertTokenAccount: PublicKey, +// conditionalOnFinalizeTokenMint: PublicKey, +// conditionalOnRevertTokenMint: PublicKey, +// userUnderlyingTokenAccount: PublicKey, +// vaultUnderlyingTokenAccount: PublicKey, +// vault: PublicKey, +// banksClient: BanksClient +// ) { +// const vaultUnderlyingTokenAccountBefore = await getAccount( +// banksClient, +// vaultUnderlyingTokenAccount +// ); +// const userUnderlyingTokenAccountBefore = await getAccount( +// banksClient, +// userUnderlyingTokenAccount +// ); +// const userConditionalOnFinalizeTokenAccountBefore = await getAccount( +// banksClient, +// userConditionalOnFinalizeTokenAccount +// ); +// const userConditionalOnRevertTokenAccountBefore = await getAccount( +// banksClient, +// userConditionalOnRevertTokenAccount +// ); + +// await vaultProgram.methods +// .redeemConditionalTokensForUnderlyingTokens() +// .accounts({ +// authority: user.publicKey, +// userConditionalOnFinalizeTokenAccount, +// userConditionalOnRevertTokenAccount, +// userUnderlyingTokenAccount, +// vaultUnderlyingTokenAccount, +// vault, +// conditionalOnFinalizeTokenMint, +// conditionalOnRevertTokenMint, +// tokenProgram: token.TOKEN_PROGRAM_ID, +// }) +// .signers([user]) +// .rpc(); + +// const vaultUnderlyingTokenAccountAfter = await getAccount( +// banksClient, +// vaultUnderlyingTokenAccount +// ); +// const userUnderlyingTokenAccountAfter = await getAccount( +// banksClient, +// userUnderlyingTokenAccount +// ); +// const userConditionalOnFinalizeTokenAccountAfter = await getAccount( +// banksClient, +// userConditionalOnFinalizeTokenAccount +// ); +// const userConditionalOnRevertTokenAccountAfter = await getAccount( +// banksClient, +// userConditionalOnRevertTokenAccount +// ); + +// let storedVault = await vaultProgram.account.conditionalVault.fetch(vault); + +// let amount; +// if (storedVault.status.finalized) { +// amount = userConditionalOnFinalizeTokenAccountBefore.amount; +// } else { +// amount = userConditionalOnRevertTokenAccountBefore.amount; +// } + +// assert.equal( +// vaultUnderlyingTokenAccountAfter.amount, +// vaultUnderlyingTokenAccountBefore.amount - BigInt(amount) +// ); +// assert.equal( +// userUnderlyingTokenAccountAfter.amount, +// userUnderlyingTokenAccountBefore.amount + BigInt(amount) +// ); +// assert.equal(userConditionalOnFinalizeTokenAccountAfter.amount, BigInt(0)); +// assert.equal(userConditionalOnRevertTokenAccountAfter.amount, BigInt(0)); +// } diff --git a/tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts b/tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts new file mode 100644 index 00000000..efecd3f7 --- /dev/null +++ b/tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts @@ -0,0 +1,109 @@ +import { sha256 } from "@metadaoproject/futarchy"; +import { ConditionalVaultClient, getConditionalTokenMintAddr, getMetadataAddr } from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { createMint } from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import { expectError } from "../../utils.js"; +import { Metadata, deserializeMetadata, getMetadataAccountDataSerializer } from "@metaplex-foundation/mpl-token-metadata"; + +export default function suite() { + let vaultClient: ConditionalVaultClient; + let question: PublicKey; + let vault: PublicKey; + let underlyingTokenMint: PublicKey; + + const metadataSerializer = getMetadataAccountDataSerializer(); + + before(function () { + vaultClient = this.vaultClient; + }); + + async function setupVault(outcomes: number) { + let questionId = sha256(new Uint8Array([1, 2, 3])); + let oracle = Keypair.generate(); + + question = await vaultClient.initializeQuestion( + questionId, + oracle.publicKey, + outcomes + ); + + underlyingTokenMint = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + null, + 8 + ); + + vault = await vaultClient.initializeVault(question, underlyingTokenMint, outcomes); + } + + async function addMetadataToConditionalTokens(outcomes: number) { + for (let i = 0; i < outcomes; i++) { + await vaultClient.addMetadataToConditionalTokensIx( + vault, + i, + `Outcome ${i}`, + `OUT${i}`, + `https://example.com/uri${i}.png` + ).rpc(); + } + } + + async function verifyMetadata(outcomes: number) { + for (let i = 0; i < outcomes; i++) { + const [conditionalTokenMint] = getConditionalTokenMintAddr( + vaultClient.vaultProgram.programId, + vault, + i + ); + + const storedMetadata = await this.banksClient.getAccount(getMetadataAddr(conditionalTokenMint)[0]); + assert.isNotNull(storedMetadata); + const metadata = metadataSerializer.deserialize(storedMetadata.data)[0]; + assert.equal(metadata.name, `Outcome ${i}`); + assert.equal(metadata.symbol, `OUT${i}`); + assert.equal(metadata.uri, `https://example.com/uri${i}.png`); + } + } + + it("adds metadata to 2-token vault", async function () { + await setupVault.call(this, 2); + await addMetadataToConditionalTokens(2); + await verifyMetadata.call(this, 2); + }); + + it("adds metadata to 3-token vault", async function () { + await setupVault.call(this, 3); + await addMetadataToConditionalTokens(3); + await verifyMetadata.call(this, 3); + }); + + it("adds metadata to 10-token vault", async function () { + await setupVault.call(this, 10); + await addMetadataToConditionalTokens(10); + await verifyMetadata.call(this, 10); + }); + + it("cannot add metadata twice for the same conditional token", async function () { + await setupVault.call(this, 2); + await addMetadataToConditionalTokens(2); + + const callbacks = expectError( + "ConditionalTokenMetadataAlreadySet", + "added metadata to a conditional token that already had metadata" + ); + + await vaultClient.addMetadataToConditionalTokensIx( + vault, + 0, + "New Outcome", + "NEW", + "https://example.com/new.png" + ) + .rpc() + .then(callbacks[0], callbacks[1]); + }); +} \ No newline at end of file diff --git a/tests/conditionalVault/unit/initializeConditionalVault.test.ts b/tests/conditionalVault/unit/initializeConditionalVault.test.ts new file mode 100644 index 00000000..dcebb627 --- /dev/null +++ b/tests/conditionalVault/unit/initializeConditionalVault.test.ts @@ -0,0 +1,93 @@ +import { + ConditionalVaultClient, + getVaultAddr, + getConditionalTokenMintAddr, +} from "@metadaoproject/futarchy/v0.4"; +import { sha256 } from "@metadaoproject/futarchy"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { createMint, getMint } from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import * as token from "@solana/spl-token"; + +export default function suite() { + let vaultClient: ConditionalVaultClient; + let underlyingTokenMint: PublicKey; + + before(async function () { + vaultClient = this.vaultClient; + underlyingTokenMint = await createMint( + this.banksClient, + this.payer as Keypair, + Keypair.generate().publicKey, + null, + 8 + ); + }); + + const testCases = [ + { name: "2-outcome question", idArray: [3, 2, 1], outcomes: 2 }, + { name: "3-outcome question", idArray: [4, 5, 6], outcomes: 3 }, + { name: "4-outcome question", idArray: [7, 8, 9], outcomes: 4 }, + ]; + + testCases.forEach(({ name, idArray, outcomes }) => { + describe(name, function () { + let question: PublicKey; + let oracle: Keypair = Keypair.generate(); + + beforeEach(async function () { + let questionId = sha256(new Uint8Array(idArray)); + question = await vaultClient.initializeQuestion( + questionId, + oracle.publicKey, + outcomes + ); + }); + + it("initializes vaults correctly", async function () { + await vaultClient + .initializeVaultIx(question, underlyingTokenMint, outcomes) + .rpc(); + + const [vault, pdaBump] = getVaultAddr( + vaultClient.vaultProgram.programId, + question, + underlyingTokenMint + ); + + const storedVault = await vaultClient.fetchVault(vault); + assert.ok(storedVault.question.equals(question)); + assert.ok(storedVault.underlyingTokenMint.equals(underlyingTokenMint)); + + const vaultUnderlyingTokenAccount = token.getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ); + assert.ok( + storedVault.underlyingTokenAccount.equals(vaultUnderlyingTokenAccount) + ); + const storedConditionalTokenMints = storedVault.conditionalTokenMints; + storedConditionalTokenMints.forEach((mint, i) => { + const [expectedMint] = getConditionalTokenMintAddr( + vaultClient.vaultProgram.programId, + vault, + i + ); + assert.ok(mint.equals(expectedMint)); + }); + assert.equal(storedVault.pdaBump, pdaBump); + assert.equal(storedVault.decimals, 8); + + for (let mint of storedConditionalTokenMints) { + const storedMint = await getMint(this.banksClient, mint); + assert.ok(storedMint.mintAuthority.equals(vault)); + assert.equal(storedMint.supply.toString(), "0"); + assert.equal(storedMint.decimals, 8); + assert.isNull(storedMint.freezeAuthority); + } + }); + }); + }); +} diff --git a/tests/conditionalVault/unit/initializeQuestion.test.ts b/tests/conditionalVault/unit/initializeQuestion.test.ts new file mode 100644 index 00000000..db29a812 --- /dev/null +++ b/tests/conditionalVault/unit/initializeQuestion.test.ts @@ -0,0 +1,51 @@ +import { + sha256 +} from "@metadaoproject/futarchy"; +// const { ConditionalVaultClient, getQuestionAddr } = futarchy; +import { Keypair } from "@solana/web3.js"; +import { assert } from "chai"; +import { expectError } from "../../utils"; +import { ConditionalVaultClient, getQuestionAddr } from "@metadaoproject/futarchy/v0.4"; +// import { getQuestionAddr } from "@metadaoproject/futarchy/dist/v0.4"; + +export default function suite() { + let vaultClient: ConditionalVaultClient; + before(function () { + vaultClient = this.vaultClient; + }); + + it("initializes 2-outcome questions", async function () { + let questionId = sha256(new Uint8Array([1, 2, 3])); + + let oracle = Keypair.generate(); + + await vaultClient + .initializeQuestionIx(questionId, oracle.publicKey, 2) + .rpc(); + + let [question] = getQuestionAddr( + vaultClient.vaultProgram.programId, + questionId, + oracle.publicKey, + 2 + ); + + const storedQuestion = await vaultClient.fetchQuestion(question); + assert.deepEqual(storedQuestion.questionId, Array.from(questionId)); + assert.ok(storedQuestion.oracle.equals(oracle.publicKey)); + assert.deepEqual(storedQuestion.payoutNumerators, [0, 0]); + assert.equal(storedQuestion.payoutDenominator, 0); + }); + + it("throws error when initializing a question with insufficient conditions", async function () { + const callbacks = expectError( + "InsufficientNumConditions", + "question initialization succeeded despite insufficient conditions" + ); + + await vaultClient + .initializeQuestionIx(sha256(new Uint8Array([4, 5, 6])), Keypair.generate().publicKey, 1) + .rpc() + .then(callbacks[0], callbacks[1]); + }); +} diff --git a/tests/conditionalVault/unit/mergeTokens.test.ts b/tests/conditionalVault/unit/mergeTokens.test.ts new file mode 100644 index 00000000..cd7a104d --- /dev/null +++ b/tests/conditionalVault/unit/mergeTokens.test.ts @@ -0,0 +1,114 @@ +import { sha256 } from "@metadaoproject/futarchy"; +import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { + createAssociatedTokenAccount, + createMint, + getAccount, + mintTo, +} from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import * as token from "@solana/spl-token"; +import { expectError } from "../../utils.js"; +import { BN } from "bn.js"; + +export default function suite() { + let vaultClient: ConditionalVaultClient; + let question: PublicKey; + let vault: PublicKey; + let underlyingTokenMint: PublicKey; + let userUnderlyingTokenAccount: PublicKey; + before(function () { + vaultClient = this.vaultClient; + }); + + beforeEach(async function () { + let questionId = sha256(new Uint8Array([9, 2, 1])); + let oracle = Keypair.generate(); + + question = await vaultClient.initializeQuestion( + questionId, + oracle.publicKey, + 2 + ); + + underlyingTokenMint = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + null, + 8 + ); + + vault = await vaultClient.initializeVault(question, underlyingTokenMint, 2); + + userUnderlyingTokenAccount = await createAssociatedTokenAccount( + this.banksClient, + this.payer, + underlyingTokenMint, + this.payer.publicKey + ); + + // Mint some underlying tokens to the user's account + await mintTo( + this.banksClient, + this.payer, + underlyingTokenMint, + userUnderlyingTokenAccount, + this.payer, + 1000 + ); + + await vaultClient + .splitTokensIx( + question, + vault, + underlyingTokenMint, + new BN(1000), + 2 + ) + .rpc(); + }); + + it("merges tokens", async function () { + const balanceBefore = await getAccount( + this.banksClient, + token.getAssociatedTokenAddressSync( + underlyingTokenMint, + this.payer.publicKey + ) + ).then((acc) => acc.amount); + await vaultClient + .mergeTokensIx( + question, + vault, + underlyingTokenMint, + new BN(600), + 2 + ) + .rpc(); + const balanceAfter = await getAccount( + this.banksClient, + token.getAssociatedTokenAddressSync( + underlyingTokenMint, + this.payer.publicKey + ) + ).then((acc) => acc.amount); + + assert.isTrue(balanceAfter > balanceBefore); + assert.equal(balanceAfter - balanceBefore, 600); + }); + + it("throws error when trying to merge more tokens than available", async function () { + const callbacks = expectError( + "InsufficientConditionalTokens", + "merge succeeded despite insufficient conditional tokens" + ); + + await vaultClient + .mergeTokensIx(question, vault, underlyingTokenMint, new BN(2000), 2) + .rpc() + .then(callbacks[0], callbacks[1]); + }); +} diff --git a/tests/conditionalVault/unit/redeemTokens.test.ts b/tests/conditionalVault/unit/redeemTokens.test.ts new file mode 100644 index 00000000..2790aa0f --- /dev/null +++ b/tests/conditionalVault/unit/redeemTokens.test.ts @@ -0,0 +1,113 @@ +import { sha256 } from "@metadaoproject/futarchy"; +import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { + createAssociatedTokenAccount, + createMint, + getAccount, + mintTo, +} from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import * as token from "@solana/spl-token"; +import { BN } from "bn.js"; + +export default function suite() { + let vaultClient: ConditionalVaultClient; + let question: PublicKey; + let vault: PublicKey; + let underlyingTokenMint: PublicKey; + let settlementAuthority: Keypair; + let userUnderlyingTokenAccount: PublicKey; + + before(function () { + vaultClient = this.vaultClient; + }); + + beforeEach(async function () { + let questionId = sha256(new Uint8Array([9, 28, 2, 1])); + settlementAuthority = Keypair.generate(); + + question = await vaultClient.initializeQuestion( + questionId, + settlementAuthority.publicKey, + 2 + ); + + underlyingTokenMint = await createMint( + this.banksClient, + this.payer, + this.payer.publicKey, + null, + 8 + ); + + vault = await vaultClient.initializeVault(question, underlyingTokenMint, 2); + + userUnderlyingTokenAccount = await createAssociatedTokenAccount( + this.banksClient, + this.payer, + underlyingTokenMint, + this.payer.publicKey + ); + + // Mint some underlying tokens to the user's account + await mintTo( + this.banksClient, + this.payer, + underlyingTokenMint, + userUnderlyingTokenAccount, + this.payer, + 1000 + ); + + await vaultClient + .splitTokensIx( + question, + vault, + underlyingTokenMint, + new BN(1000), + 2 + ) + .rpc(); + }); + + it("can't redeem tokens when question is not resolved", async function () { + try { + await vaultClient + .redeemTokensIx(question, vault, underlyingTokenMint, 2) + .rpc(); + assert.fail("Should have thrown an error"); + } catch (error) { + assert.include(error.message, "CantRedeemConditionalTokens"); + } + }); + + it("can redeem tokens when question is resolved", async function () { + await vaultClient + .resolveQuestionIx(question, settlementAuthority, [1, 0]) + .rpc(); + + const underlyingTokenAccount = await token.getAssociatedTokenAddress( + underlyingTokenMint, + this.payer.publicKey + ); + + const balanceBefore = await getAccount( + this.banksClient, + underlyingTokenAccount + ).then((acc) => acc.amount); + + await vaultClient + .redeemTokensIx(question, vault, underlyingTokenMint, 2) + .rpc(); + + const balanceAfter = await getAccount( + this.banksClient, + underlyingTokenAccount + ).then((acc) => acc.amount); + + assert.isTrue(balanceAfter > balanceBefore); + assert.equal(balanceAfter - balanceBefore, 1000); + }); +} diff --git a/tests/conditionalVault/unit/resolveQuestion.test.ts b/tests/conditionalVault/unit/resolveQuestion.test.ts new file mode 100644 index 00000000..c00a01a1 --- /dev/null +++ b/tests/conditionalVault/unit/resolveQuestion.test.ts @@ -0,0 +1,65 @@ +import { sha256 } from "@metadaoproject/futarchy"; +import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { expectError } from "../../utils.js"; + +export default function suite() { + let vaultClient: ConditionalVaultClient; + let question: PublicKey; + let settlementAuthority: Keypair; + + before(function () { + vaultClient = this.vaultClient; + }); + + beforeEach(async function () { + let questionId = sha256(new Uint8Array([4, 2, 1])); + settlementAuthority = Keypair.generate(); + question = await vaultClient.initializeQuestion( + questionId, + settlementAuthority.publicKey, + 2 + ); + }); + + it("resolves questions", async function () { + let storedQuestion = await vaultClient.fetchQuestion(question); + + assert.deepEqual(storedQuestion.payoutNumerators, [0, 0]); + assert.equal(storedQuestion.payoutDenominator, 0); + + await vaultClient + .resolveQuestionIx(question, settlementAuthority, [1, 0]) + .rpc(); + + storedQuestion = await vaultClient.fetchQuestion(question); + + assert.deepEqual(storedQuestion.payoutNumerators, [1, 0]); + assert.equal(storedQuestion.payoutDenominator, 1); + }); + + it("throws error when resolving a question with invalid number of payout numerators", async function () { + const callbacks = expectError( + "InvalidNumPayoutNumerators", + "question resolution succeeded despite invalid number of payout numerators" + ); + + await vaultClient + .resolveQuestionIx(question, settlementAuthority, [1, 0, 1]) + .rpc() + .then(callbacks[0], callbacks[1]); + }); + + it("throws error when resolving a question with zero payout", async function () { + const callbacks = expectError( + "PayoutZero", + "question resolution succeeded despite zero payout" + ); + + await vaultClient + .resolveQuestionIx(question, settlementAuthority, [0, 0]) + .rpc() + .then(callbacks[0], callbacks[1]); + }); +} diff --git a/tests/conditionalVault/unit/splitTokens.test.ts b/tests/conditionalVault/unit/splitTokens.test.ts new file mode 100644 index 00000000..840320d1 --- /dev/null +++ b/tests/conditionalVault/unit/splitTokens.test.ts @@ -0,0 +1,211 @@ +import { sha256 } from "@metadaoproject/futarchy"; +import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.4"; +import { Keypair, PublicKey } from "@solana/web3.js"; +import { assert } from "chai"; +import { + createAssociatedTokenAccount, + createMint, + getAccount, + getMint, + mintTo, +} from "spl-token-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import * as token from "@solana/spl-token"; +import { expectError } from "../../utils.js"; +import { BN } from "bn.js"; + +export default function suite() { + let vaultClient: ConditionalVaultClient; + let question: PublicKey; + let vault: PublicKey; + let underlyingTokenMint: PublicKey; + + before(function () { + vaultClient = this.vaultClient; + }); + + beforeEach(async function () { + let questionId = sha256(new Uint8Array([5, 2, 1])); + let oracle = Keypair.generate(); + + question = await vaultClient.initializeQuestion( + questionId, + oracle.publicKey, + 2 + ); + + underlyingTokenMint = await this.createMint(this.payer.publicKey, 8); + + vault = await vaultClient.initializeVault(question, underlyingTokenMint, 2); + + await this.createTokenAccount(underlyingTokenMint, this.payer.publicKey); + + await this.mintTo( + underlyingTokenMint, + this.payer.publicKey, + this.payer, + 10_000_000_000n + ); + }); + + it("splits tokens", async function () { + await vaultClient + .splitTokensIx( + question, + vault, + underlyingTokenMint, + new BN(1000), + 2 + ) + .rpc(); + + const storedVault = await vaultClient.fetchVault(vault); + + this.assertBalance(underlyingTokenMint, vault, 1000); + + const storedConditionalTokenMints = storedVault.conditionalTokenMints; + for (let mint of storedConditionalTokenMints) { + let storedMint = await getMint(this.banksClient, mint); + assert.equal(storedMint.supply.toString(), "1000"); + await this.assertBalance(mint, this.payer.publicKey, 1000); + } + }); + + it("throws error if conditional token accounts don't exist", async function () { + let { remainingAccounts } = + vaultClient.getConditionalTokenAccountsAndInstructions( + vault, + 2, + this.payer.publicKey + ); + + const callbacks = expectError( + "BadConditionalTokenAccount", + "split succeeded despite conditional token account not existing" + ); + + await vaultClient.vaultProgram.methods + .splitTokens(new BN(1000)) + .accounts({ + question, + authority: this.payer.publicKey, + vault, + vaultUnderlyingTokenAccount: token.getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: token.getAssociatedTokenAddressSync( + underlyingTokenMint, + this.payer.publicKey, + true + ), + }) + .remainingAccounts(remainingAccounts) + .rpc() + .then(callbacks[0], callbacks[1]); + }); + + it("throws error if the conditional mints are wrong", async function () { + const callbacks = expectError( + "ConditionalMintMismatch", + "split succeeded despite conditional mint not being in vault" + ); + + const fakeConditionalMint1 = await this.createMint(vault, 8); + + const fakeConditionalMint2 = await this.createMint(vault, 8); + + const fakeConditionalTokenAccount1 = await this.createTokenAccount( + fakeConditionalMint1, + this.payer.publicKey + ); + + const fakeConditionalTokenAccount2 = await this.createTokenAccount( + fakeConditionalMint2, + this.payer.publicKey + ); + + // Attempt to split tokens using the original vault but with the malicious vault's conditional token accounts + await vaultClient.vaultProgram.methods + .splitTokens(new BN(1000)) + .accounts({ + question, + authority: this.payer.publicKey, + vault, + vaultUnderlyingTokenAccount: token.getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: token.getAssociatedTokenAddressSync( + underlyingTokenMint, + this.payer.publicKey, + true + ), + }) + .remainingAccounts( + vaultClient.getRemainingAccounts( + [fakeConditionalMint1, fakeConditionalMint2], + [fakeConditionalTokenAccount1, fakeConditionalTokenAccount2] + ) + ) + .rpc() + .then(callbacks[0], callbacks[1]); + }); + + it("throws error when using an invalid vault underlying token account", async function () { + const fakeUnderlyingTokenMint = await this.createMint(vault, 8); + const invalidVaultUnderlyingTokenAccount = await this.createTokenAccount( + fakeUnderlyingTokenMint, + vault + ); + + const callbacks = expectError( + "InvalidVaultUnderlyingTokenAccount", + "split succeeded despite invalid vault underlying token account" + ); + + await vaultClient + .splitTokensIx(question, vault, underlyingTokenMint, new BN(1000), 2) + .accounts({ + vaultUnderlyingTokenAccount: invalidVaultUnderlyingTokenAccount, + }) + .rpc() + .then(callbacks[0], callbacks[1]); + }); + + it("throws error when providing invalid number of conditional accounts", async function () { + const callbacks = expectError( + "InvalidConditionals", + "split succeeded despite invalid number of conditional accounts" + ); + + const { remainingAccounts } = vaultClient.getConditionalTokenAccountsAndInstructions( + vault, + 1, // Incorrect number of outcomes + this.payer.publicKey + ); + + await vaultClient.vaultProgram.methods + .splitTokens(new BN(1000)) + .accounts({ + question, + authority: this.payer.publicKey, + vault, + vaultUnderlyingTokenAccount: token.getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: token.getAssociatedTokenAddressSync( + underlyingTokenMint, + this.payer.publicKey, + true + ), + }) + .remainingAccounts(remainingAccounts) + .rpc() + .then(callbacks[0], callbacks[1]); + }); +} diff --git a/tests/main.test.ts b/tests/main.test.ts new file mode 100644 index 00000000..7a6926b1 --- /dev/null +++ b/tests/main.test.ts @@ -0,0 +1,144 @@ +import conditionalVault from "./conditionalVault/main.test.js"; +import amm from "./amm/main.test.js"; +import autocrat from "./autocrat/autocrat.js"; + +import { startAnchor } from "solana-bankrun"; +import { BankrunProvider } from "anchor-bankrun"; +import * as anchor from "@coral-xyz/anchor"; +import { + AmmClient, + AutocratClient, + ConditionalVaultClient, +} from "@metadaoproject/futarchy/v0.4"; +// import { +// // AmmClient, +// // AutocratClient, +// // ConditionalVaultClient, +// getVersion, +// VersionKey +// } from "@metadaoproject/futarchy"; +import { PublicKey, Keypair } from "@solana/web3.js"; +import { + createAssociatedTokenAccount, + createMint, + mintTo, + getAccount, + transfer, +} from "spl-token-bankrun"; +import * as token from "@solana/spl-token"; +import { assert } from "chai"; +import { + MPL_TOKEN_METADATA_PROGRAM_ID as UMI_MPL_TOKEN_METADATA_PROGRAM_ID, +} from "@metaplex-foundation/mpl-token-metadata"; +import { + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; + +const MPL_TOKEN_METADATA_PROGRAM_ID = toWeb3JsPublicKey( + UMI_MPL_TOKEN_METADATA_PROGRAM_ID +); + +before(async function () { + // const version: VersionKey = "0.4"; + // const { AmmClient, AutocratClient, ConditionalVaultClient } = getVersion(version); + + this.context = await startAnchor( + "./", + // [], + [ + // even though the program is loaded into the test validator, we need + // to tell banks test client to load it as well + { + name: "mpl_token_metadata", + programId: MPL_TOKEN_METADATA_PROGRAM_ID, + }, + ], + [] + ); + this.banksClient = this.context.banksClient; + let provider = new BankrunProvider(this.context); + anchor.setProvider(provider); + + // umi = createUmi(anchor.AnchorProvider.env().connection); + + // vaultProgram = new Program( + // ConditionalVaultIDL, + // CONDITIONAL_VAULT_PROGRAM_ID, + // provider + // ); + + this.vaultClient = ConditionalVaultClient.createClient({ + provider: provider as any, + }); + this.autocratClient = AutocratClient.createClient({ + provider: provider as any, + }); + this.ammClient = AmmClient.createClient({ provider: provider as any }); + this.payer = provider.wallet.payer; + + this.createTokenAccount = async (mint: PublicKey, owner: PublicKey) => { + return await createAssociatedTokenAccount( + this.banksClient, + this.payer, + mint, + owner + ); + }; + + this.createMint = async (mintAuthority: PublicKey, decimals: number) => { + return await createMint( + this.banksClient, + this.payer, + mintAuthority, + null, + decimals + ); + }; + + this.mintTo = async ( + mint: PublicKey, + to: PublicKey, + mintAuthority: Keypair, + amount: number + ) => { + const tokenAccount = token.getAssociatedTokenAddressSync(mint, to, true); + return await mintTo( + this.banksClient, + this.payer, + mint, + tokenAccount, + mintAuthority, + amount + ); + }; + + this.assertBalance = async ( + mint: PublicKey, + owner: PublicKey, + amount: number + ) => { + const tokenAccount = token.getAssociatedTokenAddressSync(mint, owner, true); + const storedTokenAccount = await getAccount(this.banksClient, tokenAccount); + assert.equal(storedTokenAccount.amount.toString(), amount.toString()); + }; + + this.transfer = async ( + mint: PublicKey, + from: Keypair, + to: PublicKey, + amount: number + ) => { + return await transfer( + this.banksClient, + this.payer, + token.getAssociatedTokenAddressSync(mint, from.publicKey, true), + token.getAssociatedTokenAddressSync(mint, to, true), + from, + amount + ); + }; +}); + +describe("conditional_vault", conditionalVault); +describe("amm", amm); +describe("autocrat", autocrat); diff --git a/tests/timelock.ts b/tests/optimisticTimelock/timelock.ts similarity index 86% rename from tests/timelock.ts rename to tests/optimisticTimelock/timelock.ts index e68c5ed7..b0b7cb2c 100644 --- a/tests/timelock.ts +++ b/tests/optimisticTimelock/timelock.ts @@ -13,10 +13,13 @@ const TIMELOCK_PROGRAM_ID = new PublicKey( "tiME1hz9F5C5ZecbvE5z6Msjy8PKfTqo1UuRYXfndKF" ); -import { OptimisticTimelock } from "../target/types/optimistic_timelock"; +import { + OptimisticTimelock, + IDL as OptimisticTimelockIDL, +} from "../../target/types/optimistic_timelock"; import { ComputeBudgetProgram, Connection } from "@solana/web3.js"; import { printArgs } from "@metaplex-foundation/mpl-token-metadata"; -const OptimisticTimelockIDL: OptimisticTimelock = require("../target/idl/optimistic_timelock.json"); +// const OptimisticTimelockIDL: OptimisticTimelock = require("../target/idl/optimistic_timelock.json"); export type PublicKey = anchor.web3.PublicKey; export type Signer = anchor.web3.Signer; @@ -148,7 +151,9 @@ describe("timelock", async function () { .rpc(); const transactionBatchAccount = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Assertions to check the transaction batch creation assert.strictEqual( transactionBatchAccount.transactionBatchAuthority.toString(), @@ -197,15 +202,13 @@ describe("timelock", async function () { // Transaction 2: Set Delay in Slots const newDelayInSlots = new BN(2); - let setDelayInSlotsInstruction = timelockProgram.instruction.setDelayInSlots( - newDelayInSlots, - { + let setDelayInSlotsInstruction = + timelockProgram.instruction.setDelayInSlots(newDelayInSlots, { accounts: { timelock: timelockKp.publicKey, timelockSigner: timelockSignerPubkey, }, - } - ); + }); await timelockProgram.methods .addTransaction( @@ -253,15 +256,13 @@ describe("timelock", async function () { .rpc(); // Transaction 4: Add enqueuer - let addEnqueuerInstruction = timelockProgram.instruction.addOptimisticProposer( - enqueuer4.publicKey, - { + let addEnqueuerInstruction = + timelockProgram.instruction.addOptimisticProposer(enqueuer4.publicKey, { accounts: { timelock: timelockKp.publicKey, timelockSigner: timelockSignerPubkey, }, - } - ); + }); await timelockProgram.methods .addTransaction( @@ -281,15 +282,16 @@ describe("timelock", async function () { .rpc(); // Transaction 5: Remove enqueuer - let removeOptimisticProposerInstruction = timelockProgram.instruction.removeOptimisticProposer( - enqueuer3.publicKey, - { - accounts: { - timelock: timelockKp.publicKey, - timelockSigner: timelockSignerPubkey, - }, - } - ); + let removeOptimisticProposerInstruction = + timelockProgram.instruction.removeOptimisticProposer( + enqueuer3.publicKey, + { + accounts: { + timelock: timelockKp.publicKey, + timelockSigner: timelockSignerPubkey, + }, + } + ); await timelockProgram.methods .addTransaction( @@ -310,7 +312,9 @@ describe("timelock", async function () { // Verify the transactions const transactionBatchAccount = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); assert.strictEqual( transactionBatchAccount.transactions.length, 5, @@ -325,7 +329,7 @@ describe("timelock", async function () { .enqueueTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:timelockAuthority.publicKey, + authority: timelockAuthority.publicKey, timelock: timelockKp.publicKey, }) .signers([timelockAuthority]) @@ -349,7 +353,9 @@ describe("timelock", async function () { .rpc(); const sealedTransactionBatch = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Assert the transaction batch is now sealed assert.ok( @@ -365,7 +371,7 @@ describe("timelock", async function () { .cancelTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:timelockAuthority.publicKey, + authority: timelockAuthority.publicKey, timelock: timelockKp.publicKey, }) .signers([timelockAuthority]) @@ -457,7 +463,7 @@ describe("timelock", async function () { .enqueueTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:fakeAuthority.publicKey, + authority: fakeAuthority.publicKey, timelock: timelockKp.publicKey, }) .signers([fakeAuthority]) @@ -475,14 +481,16 @@ describe("timelock", async function () { .enqueueTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:timelockAuthority.publicKey, + authority: timelockAuthority.publicKey, timelock: timelockKp.publicKey, }) .signers([timelockAuthority]) .rpc(); const enqueuedTransactionBatch = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Assert the transaction batch is now in TimelockStarted status assert.ok( @@ -508,7 +516,7 @@ describe("timelock", async function () { .cancelTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:enqueuer1.publicKey, + authority: enqueuer1.publicKey, timelock: timelockKp.publicKey, }) .signers([enqueuer1]) @@ -571,7 +579,9 @@ describe("timelock", async function () { // Verification step const transactionBatchAccount = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Check if the first transaction did execute assert.strictEqual( @@ -599,13 +609,19 @@ describe("timelock", async function () { .remainingAccounts([ { pubkey: timelockSignerPubkey, isWritable: false, isSigner: false }, { pubkey: timelockKp.publicKey, isWritable: true, isSigner: false }, - { pubkey: timelockProgram.programId, isWritable: false, isSigner: false }, + { + pubkey: timelockProgram.programId, + isWritable: false, + isSigner: false, + }, ]) .rpc(); // Verification step const transactionBatchAccount = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Check if the second transaction did execute assert.strictEqual( @@ -640,7 +656,11 @@ describe("timelock", async function () { .remainingAccounts([ { pubkey: timelockSignerPubkey, isWritable: false, isSigner: false }, { pubkey: timelockKp.publicKey, isWritable: true, isSigner: false }, - { pubkey: timelockProgram.programId, isWritable: false, isSigner: false }, + { + pubkey: timelockProgram.programId, + isWritable: false, + isSigner: false, + }, ]) .preInstructions([ // this is to get around bankrun thinking we've processed the same transaction multiple times @@ -652,7 +672,9 @@ describe("timelock", async function () { // Fetch the updated TransactionBatch and timelock account to verify changes const updatedTransactionBatch = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); const updatedTimelockAccount = await timelockProgram.account.timelock.fetch( timelockKp.publicKey ); @@ -682,13 +704,19 @@ describe("timelock", async function () { .remainingAccounts([ { pubkey: timelockSignerPubkey, isWritable: false, isSigner: false }, { pubkey: timelockKp.publicKey, isWritable: true, isSigner: false }, - { pubkey: timelockProgram.programId, isWritable: false, isSigner: false }, + { + pubkey: timelockProgram.programId, + isWritable: false, + isSigner: false, + }, ]) .rpc(); // Fetch the updated TransactionBatch and timelock account to verify changes const updatedTransactionBatch = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); const updatedTimelockAccount = await timelockProgram.account.timelock.fetch( timelockKp.publicKey ); @@ -720,7 +748,11 @@ describe("timelock", async function () { .remainingAccounts([ { pubkey: timelockSignerPubkey, isWritable: false, isSigner: false }, { pubkey: timelockKp.publicKey, isWritable: true, isSigner: false }, - { pubkey: timelockProgram.programId, isWritable: false, isSigner: false }, + { + pubkey: timelockProgram.programId, + isWritable: false, + isSigner: false, + }, ]) .preInstructions([ // this is to get around bankrun thinking we've processed the same transaction multiple times @@ -732,7 +764,9 @@ describe("timelock", async function () { // Fetch the updated TransactionBatch and timelock account to verify changes const updatedTransactionBatch = - await timelockProgram.account.transactionBatch.fetch(transactionBatch.publicKey); + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); const updatedTimelockAccount = await timelockProgram.account.timelock.fetch( timelockKp.publicKey ); @@ -781,9 +815,10 @@ describe("timelock", async function () { .signers([enqueuer1, transactionBatch]) .rpc(); - let transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + let transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been created assert.ok( @@ -801,9 +836,10 @@ describe("timelock", async function () { .signers([enqueuer1]) .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been sealed assert.ok( @@ -816,15 +852,16 @@ describe("timelock", async function () { .enqueueTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:enqueuer1.publicKey, // Assuming recipient as the new authority + authority: enqueuer1.publicKey, // Assuming recipient as the new authority timelock: timelockKp.publicKey, }) .signers([enqueuer1]) .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been enqueued assert.ok( @@ -842,15 +879,16 @@ describe("timelock", async function () { .cancelTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:enqueuer1.publicKey, + authority: enqueuer1.publicKey, timelock: timelockKp.publicKey, }) .signers([enqueuer1]) .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been cancelled assert.ok( @@ -881,9 +919,10 @@ describe("timelock", async function () { .signers([enqueuer1, transactionBatch]) .rpc(); - let transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + let transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been created assert.ok( @@ -901,9 +940,10 @@ describe("timelock", async function () { .signers([enqueuer1]) .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been sealed assert.ok( @@ -919,7 +959,7 @@ describe("timelock", async function () { .enqueueTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:enqueuer1.publicKey, // Assuming recipient as the new authority + authority: enqueuer1.publicKey, // Assuming recipient as the new authority timelock: timelockKp.publicKey, }) .signers([enqueuer1]) @@ -943,24 +983,25 @@ describe("timelock", async function () { // now it'll succeed await timelockProgram.methods - .enqueueTransactionBatch() - .accounts({ - transactionBatch: transactionBatch.publicKey, - authority:enqueuer1.publicKey, // Assuming recipient as the new authority - timelock: timelockKp.publicKey, - }) - .signers([enqueuer1]) - .preInstructions([ - // this is to get around bankrun thinking we've processed the same transaction multiple times - ComputeBudgetProgram.setComputeUnitPrice({ - microLamports: 69, - }), - ]) - .rpc(); + .enqueueTransactionBatch() + .accounts({ + transactionBatch: transactionBatch.publicKey, + authority: enqueuer1.publicKey, // Assuming recipient as the new authority + timelock: timelockKp.publicKey, + }) + .signers([enqueuer1]) + .preInstructions([ + // this is to get around bankrun thinking we've processed the same transaction multiple times + ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: 69, + }), + ]) + .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been enqueued assert.ok( @@ -973,15 +1014,16 @@ describe("timelock", async function () { .cancelTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:enqueuer2.publicKey, + authority: enqueuer2.publicKey, timelock: timelockKp.publicKey, }) .signers([enqueuer2]) .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been cancelled assert.ok( @@ -1012,9 +1054,10 @@ describe("timelock", async function () { .signers([enqueuer2, transactionBatch]) .rpc(); - let transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + let transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been created assert.ok( @@ -1032,9 +1075,10 @@ describe("timelock", async function () { .signers([enqueuer2]) .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been sealed assert.ok( @@ -1047,15 +1091,16 @@ describe("timelock", async function () { .enqueueTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:enqueuer2.publicKey, // Assuming recipient as the new authority + authority: enqueuer2.publicKey, // Assuming recipient as the new authority timelock: timelockKp.publicKey, }) .signers([enqueuer2]) .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been enqueued assert.ok( @@ -1068,15 +1113,16 @@ describe("timelock", async function () { .cancelTransactionBatch() .accounts({ transactionBatch: transactionBatch.publicKey, - authority:recipient.publicKey, + authority: recipient.publicKey, timelock: timelockKp.publicKey, }) .signers([recipient]) .rpc(); - transactionBatchAccount = await timelockProgram.account.transactionBatch.fetch( - transactionBatch.publicKey - ); + transactionBatchAccount = + await timelockProgram.account.transactionBatch.fetch( + transactionBatch.publicKey + ); // Verify the transaction batch has been cancelled assert.ok( diff --git a/tests/utils/utils.ts b/tests/utils.ts similarity index 74% rename from tests/utils/utils.ts rename to tests/utils.ts index 2e0395af..7291b9a5 100644 --- a/tests/utils/utils.ts +++ b/tests/utils.ts @@ -1,19 +1,5 @@ -import { expect, assert } from "chai"; -import { Program } from "@coral-xyz/anchor"; - -export const advanceBySlots = async (context: any, slots: BigInt) => { - const currentClock = await context.banksClient.getClock(); - const slot = currentClock.slot + slots; - context.setClock( - new Clock( - slot, - currentClock.epochStartTimestamp, - currentClock.epoch, - currentClock.leaderScheduleEpoch, - currentClock.unixTimestamp - ) - ); -}; +import { assert } from "chai"; +import { Clock, ProgramTestContext } from "solana-bankrun"; export const expectError = ( expectedError: string, @@ -49,9 +35,7 @@ export const expectError = ( ]; }; -import { Clock, ProgramTestContext } from "solana-bankrun"; - -export const fastForward = async ( +export const advanceBySlots = async ( context: ProgramTestContext, slots: bigint ) => { diff --git a/tests/utils/bankrunUtils.ts b/tests/utils/bankrunUtils.ts deleted file mode 100644 index 43f74ebe..00000000 --- a/tests/utils/bankrunUtils.ts +++ /dev/null @@ -1,226 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -const { Signer, PublicKey, Transaction, Commitment, ConfirmOptions } = - anchor.web3; -import * as token from "@solana/spl-token"; -import { - BanksClient, - BanksTransactionMeta, - ProgramTestContext, -} from "solana-bankrun"; - -export async function createMint( - banksClient: BanksClient, - payer: Keypair, - mintAuthority: PublicKey, - freezeAuthority: PublicKey | null, - decimals: number, - keypair = anchor.web3.Keypair.generate(), - programId = token.TOKEN_PROGRAM_ID -): PublicKey { - let rent = await banksClient.getRent(); - - const tx = new anchor.web3.Transaction().add( - anchor.web3.SystemProgram.createAccount({ - fromPubkey: payer.publicKey, - newAccountPubkey: keypair.publicKey, - space: token.MINT_SIZE, - lamports: Number(await rent.minimumBalance(BigInt(token.MINT_SIZE))), - programId: token.TOKEN_PROGRAM_ID, - }), - token.createInitializeMint2Instruction( - keypair.publicKey, - decimals, - mintAuthority, - freezeAuthority, - programId - ) - ); - [tx.recentBlockhash] = await banksClient.getLatestBlockhash(); - tx.sign(payer, keypair); - - await banksClient.processTransaction(tx); - - return keypair.publicKey; -} - -export async function createAccount( - banksClient: BanksClient, - payer: Signer, - mint: PublicKey, - owner: PublicKey, - keypair?: Keypair, - confirmOptions?: ConfirmOptions, - programId = token.TOKEN_PROGRAM_ID -): Promise { - let rent = await banksClient.getRent(); - // If a keypair isn't provided, create the associated token account and return its address - if (!keypair) - return await createAssociatedTokenAccount( - banksClient, - payer, - mint, - owner, - programId - ); - - // Otherwise, create the account with the provided keypair and return its public key - const mintState = await getMint( - banksClient, - mint, - confirmOptions?.commitment, - programId - ); - const space = token.getAccountLenForMint(mintState); - - const tx = new Transaction().add( - SystemProgram.createAccount({ - fromPubkey: payer.publicKey, - newAccountPubkey: keypair.publicKey, - space, - lamports: Number(await rent.minimumBalance(BigInt(space))), - programId, - }), - token.createInitializeAccountInstruction( - keypair.publicKey, - mint, - owner, - programId - ) - ); - [tx.recentBlockhash] = await banksClient.getLatestBlockhash(); - tx.sign(payer, keypair); - - await banksClient.processTransaction(tx); - - return keypair.publicKey; -} - -export async function createAssociatedTokenAccount( - banksClient: BanksClient, - payer: Signer, - mint: PublicKey, - owner: PublicKey, - programId = token.TOKEN_PROGRAM_ID, - associatedTokenProgramId = token.ASSOCIATED_TOKEN_PROGRAM_ID -): Promise { - const associatedToken = token.getAssociatedTokenAddressSync( - mint, - owner, - false, - programId, - associatedTokenProgramId - ); - - const tx = new Transaction().add( - token.createAssociatedTokenAccountInstruction( - payer.publicKey, - associatedToken, - owner, - mint, - programId, - associatedTokenProgramId - ) - ); - - [tx.recentBlockhash] = await banksClient.getLatestBlockhash(); - tx.sign(payer); - - await banksClient.processTransaction(tx); - - return associatedToken; -} - -export async function getMint( - banksClient: BanksClient, - address: PublicKey, - commitment?: Commitment, - programId = token.TOKEN_PROGRAM_ID -): Promise { - const info = await banksClient.getAccountInfo(address, commitment); - return token.unpackMint(address, info, programId); -} - -// `mintTo` without the mintAuthority signer -// uses bankrun's special `setAccount` function -export async function mintToOverride( - context: ProgramTestContext, - destination: PublicKey, - amount: bigint -) { - const banksClient = context.banksClient; - - const existingAccount = await getAccount(banksClient, destination); - const { mint, owner } = existingAccount; - - const accData = Buffer.alloc(token.ACCOUNT_SIZE); - token.AccountLayout.encode( - { - mint, - owner, - amount, - delegateOption: 0, - delegate: PublicKey.default, - delegatedAmount: 0n, - state: 1, - isNativeOption: 0, - isNative: 0n, - closeAuthorityOption: 0, - closeAuthority: PublicKey.default, - }, - accData - ); - - await context.setAccount(destination, { - data: accData, - executable: false, - lamports: 1_000_000_000n, - owner: token.TOKEN_PROGRAM_ID, - }); -} - -export async function mintTo( - banksClient: BanksClient, - payer: Signer, - mint: PublicKey, - destination: PublicKey, - authority: Signer | PublicKey, - amount: number | bigint, - multiSigners: Signer[] = [], - programId = token.TOKEN_PROGRAM_ID -): Promise { - const [authorityPublicKey, signers] = getSigners(authority, multiSigners); - - const tx = new Transaction().add( - token.createMintToInstruction( - mint, - destination, - authorityPublicKey, - amount, - multiSigners, - programId - ) - ); - [tx.recentBlockhash] = await banksClient.getLatestBlockhash(); - tx.sign(payer, ...signers); - - return await banksClient.processTransaction(tx); -} - -export function getSigners( - signerOrMultisig: Signer | PublicKey, - multiSigners: Signer[] -): [PublicKey, Signer[]] { - return signerOrMultisig instanceof PublicKey - ? [signerOrMultisig, multiSigners] - : [signerOrMultisig.publicKey, [signerOrMultisig]]; -} - -export async function getAccount( - banksClient: BanksClient, - address: PublicKey, - commitment?: Commitment, - programId = token.TOKEN_PROGRAM_ID -): Promise { - const info = await banksClient.getAccount(address, commitment); - return token.unpackAccount(address, info, programId); -} diff --git a/tests/utils/pdaGenerator.ts b/tests/utils/pdaGenerator.ts deleted file mode 100644 index d9c16a35..00000000 --- a/tests/utils/pdaGenerator.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; - -import { Program, PublicKey } from "./metaDAO"; - -export type AddressAndBump = [PublicKey, number]; - -export class PDAGenerator { - program: Program; - - constructor(program: Program) { - this.program = program; - } - - generateMetaDAOPDAAddress(): AddressAndBump { - return anchor.web3.PublicKey.findProgramAddressSync( - [anchor.utils.bytes.utf8.encode("WWCACOTMICMIBMHAFTTWYGHMB")], - this.program.programId - ); - } - - generateMemberPDAAddress(name: string): AddressAndBump { - return anchor.web3.PublicKey.findProgramAddressSync( - [ - anchor.utils.bytes.utf8.encode("member"), - anchor.utils.bytes.utf8.encode(name), - ], - this.program.programId - ); - } - - generateTreasuryPDAAddress(memberAddress: PublicKey): AddressAndBump { - return anchor.web3.PublicKey.findProgramAddressSync( - [anchor.utils.bytes.utf8.encode("treasury"), memberAddress.toBuffer()], - this.program.programId - ); - } - - generateConditionalExpressionPDAAddress( - proposal: PublicKey, - redeemableOnPass: boolean - ): AddressAndBump { - return anchor.web3.PublicKey.findProgramAddressSync( - [ - anchor.utils.bytes.utf8.encode("conditional_expression"), - proposal.toBuffer(), - Buffer.from([redeemableOnPass]), - ], - this.program.programId - ); - } - - generateVaultPDAAddress( - conditionalExpressionAddress: PublicKey, - underlyingMint: PublicKey - ): AddressAndBump { - return anchor.web3.PublicKey.findProgramAddressSync( - [ - anchor.utils.bytes.utf8.encode("vault"), - conditionalExpressionAddress.toBuffer(), - underlyingMint.toBuffer(), - ], - this.program.programId - ); - } - - generateDepositSlipPDAAddress( - conditionalVault: PublicKey, - user: PublicKey - ): AddressAndBump { - return anchor.web3.PublicKey.findProgramAddressSync( - [ - anchor.utils.bytes.utf8.encode("deposit_slip"), - conditionalVault.toBuffer(), - user.toBuffer(), - ], - this.program.programId - ); - } -} diff --git a/tests/utils/programFacade.ts b/tests/utils/programFacade.ts deleted file mode 100644 index e3a83d91..00000000 --- a/tests/utils/programFacade.ts +++ /dev/null @@ -1,527 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { assert } from "chai"; -import * as token from "@solana/spl-token"; - -import { randomMemberName } from "./testUtils"; - -import { PDAGenerator } from "./pdaGenerator"; -import { Program, PublicKey, Signer } from "./metaDAO"; - -export class ProgramFacade { - program: Program; - generator: PDAGenerator; - connection: anchor.web3.Connection; - payer: Signer; - metaDAO: PublicKey; - - constructor(program: Program) { - this.generator = new PDAGenerator(program); - this.program = program; - this.connection = program.provider.connection; - this.payer = program.provider.wallet.payer; - } - - async createTokenAccount( - mint: PublicKey, - owner: PublicKey - ): Promise { - return await token.createAccount(this.connection, this.payer, mint, owner); - } - - async createMint( - decimals?: number, - mintAuthority?: PublicKey - ): Promise<[PublicKey, Signer | PublicKey]> { - let mintAuthorityToUse; - let mintAuthorityToReturn; - - if (typeof mintAuthority != "undefined") { - mintAuthorityToUse = mintAuthority; - mintAuthorityToReturn = mintAuthority; - } else { - let signer = anchor.web3.Keypair.generate(); - mintAuthorityToUse = signer.publicKey; - mintAuthorityToReturn = signer; - } - - const mint = await token.createMint( - this.connection, - this.payer, - mintAuthorityToUse, - mintAuthorityToUse, - typeof decimals != "undefined" ? decimals : 2 - ); - - return [mint, mintAuthorityToReturn]; - } - - async mintTo( - mint: PublicKey, - destination: PublicKey, - mintAuthority: Signer, - amount: number - ) { - await token.mintTo( - this.connection, - this.payer, - mint, - destination, - mintAuthority, - amount - ); - } - - async transfer( - from: PublicKey, - to: PublicKey, - amount: number, - authority: Signer - ) { - await token.transfer( - this.connection, - this.payer, - from, - to, - authority, - amount - ); - } - - async initializeMember(name: string): Promise { - const [member] = this.generator.generateMemberPDAAddress(name); - const [treasury] = this.generator.generateTreasuryPDAAddress(member); - - const tokenMint = anchor.web3.Keypair.generate(); - - await this.program.methods - .initializeMember(name) - .accounts({ - member, - treasury, - tokenMint: tokenMint.publicKey, - initializer: this.payer.publicKey, - }) - .signers([tokenMint]) - .rpc(); - - const storedMember = await this.program.account.member.fetch(member); - - assert.equal(storedMember.name, name); - assert.ok(storedMember.tokenMint.equals(tokenMint.publicKey)); - - return member; - } - - async initializeMetaDAO(seedMember: PublicKey): Promise { - const [metaDAO] = this.generator.generateMetaDAOPDAAddress(); - - await this.program.methods - .initializeMetaDao() - .accounts({ - metaDao: metaDAO, - seedMember, - initializer: this.payer.publicKey, - systemProgram: anchor.web3.SystemProgram.programId, - }) - .rpc(); - - const storedMetaDAO = await this.program.account.metaDao.fetch(metaDAO); - - assert.equal(storedMetaDAO.members.length, 1); - - this.metaDAO = metaDAO; - - return metaDAO; - } - - async getOrCreateMetaDAO() { - if (this.metaDAO == null) { - let seedMember = await this.initializeMember(randomMemberName()); - await this.initializeMetaDAO(seedMember); - } - - return this.metaDAO; - } - - async initializeProposal( - metaDAO: PublicKey, - instructions: [], - accounts: [] - ): Promise { - const provider = this.program.provider; - const proposalKeypair = anchor.web3.Keypair.generate(); - - await this.program.methods - .initializeProposal(instructions, accounts) - .preInstructions([ - await this.program.account.proposal.createInstruction( - proposalKeypair, - 1000 - ), - ]) - .accounts({ - proposal: proposalKeypair.publicKey, - metaDao: metaDAO, - initializer: this.payer.publicKey, - systemProgram: anchor.web3.SystemProgram.programId, - }) - .signers([proposalKeypair]) - .rpc(); - - const storedProposal = await this.program.account.proposal.fetch( - proposalKeypair.publicKey - ); - - assert.exists(storedProposal.status.pending); - assert.equal(storedProposal.instructions.length, instructions.length); - - for (let i = 0; i < instructions.length; i++) { - const ix = instructions[i]; - const storedIx = storedProposal.instructions[i]; - - // assert.ok(storedIx.memberSigner.equals(ix.memberSigner)); - assert.ok(storedIx.programId.equals(ix.programId)); - assert.deepEqual(storedIx.accounts, ix.accounts); - assert.deepEqual(storedIx.data, ix.data); - } - - return proposalKeypair.publicKey; - } - - async executeProposal(proposal: PublicKey, remainingAccounts?: []) { - let builder = this.program.methods.executeProposal().accounts({ - proposal, - }); - - if (typeof remainingAccounts != "undefined") { - builder = builder.remainingAccounts(remainingAccounts); - } - - await builder.rpc(); - - const storedProposal = await this.program.account.proposal.fetch(proposal); - - assert.notExists(storedProposal.status.pending); - assert.exists(storedProposal.status.passed); - } - - async initializeConditionalExpression( - proposal: anchor.web3.PublicKey, - redeemableOnPass: boolean - ): Promise { - const [conditionalExpression] = - this.generator.generateConditionalExpressionPDAAddress( - proposal, - redeemableOnPass - ); - - const passOrFail = redeemableOnPass ? { pass: {} } : { fail: {} }; - - await this.program.methods - .initializeConditionalExpression(passOrFail) - .accounts({ - conditionalExpression, - initializer: this.payer.publicKey, - systemProgram: anchor.web3.SystemProgram.programId, - proposal, - }) - .rpc(); - - const storedConditionalExpression = - await this.program.account.conditionalExpression.fetch( - conditionalExpression - ); - - assert.ok(storedConditionalExpression.proposal.equals(proposal)); - assert.deepEqual(storedConditionalExpression.passOrFail, passOrFail); - - return conditionalExpression; - } - - async initializeVault( - conditionalExpression: PublicKey, - underlyingTokenMint: PublicKey - ): Promise<[PublicKey, PublicKey, PublicKey]> { - const [vault] = this.generator.generateVaultPDAAddress( - conditionalExpression, - underlyingTokenMint - ); - - const conditionalTokenMint: Signer = anchor.web3.Keypair.generate(); - const vaultUnderlyingTokenAccount = await token.getAssociatedTokenAddress( - underlyingTokenMint, - vault, - true - ); - - await this.program.methods - .initializeVault() - .accounts({ - vault, - conditionalExpression, - underlyingTokenMint, - conditionalTokenMint: conditionalTokenMint.publicKey, - vaultUnderlyingTokenAccount, - initializer: this.payer.publicKey, - }) - .signers([conditionalTokenMint]) - .rpc(); - - const storedVault = await this.program.account.vault.fetch(vault); - - assert.ok(storedVault.conditionalExpression.equals(conditionalExpression)); - assert.ok( - storedVault.underlyingTokenAccount.equals(vaultUnderlyingTokenAccount) - ); - assert.ok(storedVault.underlyingTokenMint.equals(underlyingTokenMint)); - assert.ok( - storedVault.conditionalTokenMint.equals(conditionalTokenMint.publicKey) - ); - - return [vault, conditionalTokenMint.publicKey, vaultUnderlyingTokenAccount]; - } - - async initializeDepositSlip( - vault: PublicKey, - _depositor?: PublicKey - ): Promise { - const provider = this.program.provider; - - let depositor = - typeof _depositor == "undefined" ? this.payer.publicKey : _depositor; - - const [depositSlip] = this.generator.generateDepositSlipPDAAddress( - vault, - depositor - ); - - await this.program.methods - .initializeDepositSlip(depositor) - .accounts({ - vault, - depositSlip, - initializer: this.payer.publicKey, - systemProgram: anchor.web3.SystemProgram.programId, - }) - .rpc(); - - let storedDepositSlip = await this.program.account.depositSlip.fetch( - depositSlip - ); - - assert.ok(storedDepositSlip.vault.equals(vault)); - assert.ok(storedDepositSlip.user.equals(depositor)); - assert.ok(storedDepositSlip.depositedAmount.eq(new anchor.BN(0))); - - return depositSlip; - } - - async mintConditionalTokens( - amount: number, - user: Signer, - depositSlip: PublicKey, - vault: PublicKey, - vaultUnderlyingTokenAccount: PublicKey, - userUnderlyingTokenAccount: PublicKey, - conditionalTokenMint: PublicKey, - userConditionalTokenAccount: PublicKey - ) { - const depositSlipBefore = await this.program.account.depositSlip.fetch( - depositSlip - ); - const vaultUnderlyingTokenAccountBefore = await token.getAccount( - this.connection, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountBefore = await token.getAccount( - this.connection, - userUnderlyingTokenAccount - ); - const userConditionalTokenAccountBefore = await token.getAccount( - this.connection, - userConditionalTokenAccount - ); - - const bnAmount = new anchor.BN(amount); - await this.program.methods - .mintConditionalTokens(bnAmount) - .accounts({ - user: user.publicKey, - depositSlip, - vault, - vaultUnderlyingTokenAccount, - userUnderlyingTokenAccount, - conditionalTokenMint, - userConditionalTokenAccount, - tokenProgram: token.TOKEN_PROGRAM_ID, - }) - .signers([user]) - .rpc(); - - const depositSlipAfter = await this.program.account.depositSlip.fetch( - depositSlip - ); - const vaultUnderlyingTokenAccountAfter = await token.getAccount( - this.connection, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountAfter = await token.getAccount( - this.connection, - userUnderlyingTokenAccount - ); - const userConditionalTokenAccountAfter = await token.getAccount( - this.connection, - userConditionalTokenAccount - ); - - assert.ok( - depositSlipAfter.depositedAmount.eq( - depositSlipBefore.depositedAmount.add(bnAmount) - ) - ); - assert.equal( - vaultUnderlyingTokenAccountAfter.amount, - vaultUnderlyingTokenAccountBefore.amount + BigInt(amount) - ); - assert.equal( - userUnderlyingTokenAccountAfter.amount, - userUnderlyingTokenAccountBefore.amount - BigInt(amount) - ); - assert.equal( - userConditionalTokenAccountAfter.amount, - userConditionalTokenAccountBefore.amount + BigInt(amount) - ); - } - - async redeemConditionalForUnderlyingTokens( - user: Signer, - userConditionalTokenAccount: PublicKey, - userUnderlyingTokenAccount: PublicKey, - vaultUnderlyingTokenAccount: PublicKey, - vault: PublicKey, - proposal: PublicKey, - conditionalExpression: PublicKey, - conditionalTokenMint: PublicKey - ) { - const vaultUnderlyingTokenAccountBefore = await token.getAccount( - this.connection, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountBefore = await token.getAccount( - this.connection, - userUnderlyingTokenAccount - ); - const userConditionalTokenAccountBefore = await token.getAccount( - this.connection, - userConditionalTokenAccount - ); - - await this.program.methods - .redeemConditionalTokensForUnderlyingTokens() - .accounts({ - user: user.publicKey, - userConditionalTokenAccount, - userUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - proposal, - tokenProgram: token.TOKEN_PROGRAM_ID, - conditionalExpression, - conditionalTokenMint, - }) - .signers([user]) - .rpc(); - - const vaultUnderlyingTokenAccountAfter = await token.getAccount( - this.connection, - vaultUnderlyingTokenAccount - ); - const userUnderlyingTokenAccountAfter = await token.getAccount( - this.connection, - userUnderlyingTokenAccount - ); - const userConditionalTokenAccountAfter = await token.getAccount( - this.connection, - userConditionalTokenAccount - ); - - assert.equal( - vaultUnderlyingTokenAccountAfter.amount, - vaultUnderlyingTokenAccountBefore.amount - - BigInt(userConditionalTokenAccountBefore.amount) - ); - assert.equal( - userUnderlyingTokenAccountAfter.amount, - userUnderlyingTokenAccountBefore.amount + - BigInt(userConditionalTokenAccountBefore.amount) - ); - assert.equal(userConditionalTokenAccountAfter.amount, BigInt(0)); - } - - async redeemDepositSlipForUnderlyingTokens( - user: Signer, - userDepositSlip: PublicKey, - userUnderlyingTokenAccount: PublicKey, - vaultUnderlyingTokenAccount: PublicKey, - vault: PublicKey, - proposal: PublicKey, - conditionalExpression: PublicKey - ) { - // const vaultUnderlyingTokenAccountBefore = await token.getAccount( - // this.connection, - // vaultUnderlyingTokenAccount - // ); - // const userUnderlyingTokenAccountBefore = await token.getAccount( - // this.connection, - // userUnderlyingTokenAccount - // ); - // const userConditionalTokenAccountBefore = await token.getAccount( - // this.connection, - // userConditionalTokenAccount - // ); - - await this.program.methods - .redeemDepositSlipForUnderlyingTokens() - .accounts({ - user: user.publicKey, - userDepositSlip, - userUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - proposal, - tokenProgram: token.TOKEN_PROGRAM_ID, - conditionalExpression, - }) - .signers([user]) - .rpc(); - - // const vaultUnderlyingTokenAccountAfter = await token.getAccount( - // this.connection, - // vaultUnderlyingTokenAccount - // ); - // const userUnderlyingTokenAccountAfter = await token.getAccount( - // this.connection, - // userUnderlyingTokenAccount - // ); - // const userConditionalTokenAccountAfter = await token.getAccount( - // this.connection, - // userConditionalTokenAccount - // ); - - // assert.equal( - // vaultUnderlyingTokenAccountAfter.amount, - // vaultUnderlyingTokenAccountBefore.amount - - // BigInt(userConditionalTokenAccountBefore.amount) - // ); - // assert.equal( - // userUnderlyingTokenAccountAfter.amount, - // userUnderlyingTokenAccountBefore.amount + - // BigInt(userConditionalTokenAccountBefore.amount) - // ); - // assert.equal(userConditionalTokenAccountAfter.amount, BigInt(0)); - } - - async failProposal(proposal: PublicKey) { - await this.program.methods.failProposal().accounts({ proposal }).rpc(); - } -} diff --git a/tests/utils/testUtils.ts b/tests/utils/testUtils.ts deleted file mode 100644 index 64496d90..00000000 --- a/tests/utils/testUtils.ts +++ /dev/null @@ -1,299 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; - -import { expect, assert } from "chai"; -import { randomBytes } from "crypto"; - -import { ProgramFacade } from "./programFacade"; - -import { - Program, - PublicKey, - Signer, - ProposalState, - RedemptionType, -} from "./autocrat"; - -export const expectError = ( - expectedErrorCode: string, - message: string -): [() => void, (e: any) => void] => { - return [ - () => assert.fail(message), - (e) => { - console.log(e); - assert( - e["error"] != undefined, - `the program threw for a reason that we didn't expect. error: ${e}` - ); - assert.equal(e.error.errorCode.code, expectedErrorCode); - }, - ]; -}; - -export const randomMemberName = () => randomBytes(5).toString("hex"); - -export const initializeSampleProposal = async ( - program: ProgramFacade -): Promise<[PublicKey, PublicKey]> => { - const memberToAdd = await program.initializeMember(randomMemberName()); - const metaDAO = await program.getOrCreateMetaDAO(); - - const [proposalAccounts, proposalInstructions] = - sampleProposalAccountsAndInstructions( - program.program, - metaDAO, - memberToAdd - ); - const proposal = await program.initializeProposal( - metaDAO, - proposalInstructions, - proposalAccounts - ); - - return [proposal, memberToAdd]; -}; - -export const executeSampleProposal = async ( - sampleProposal: PublicKey, - memberToAdd: PublicKey, - programFacade: ProgramFacade -) => { - const metaDAO = await programFacade.getOrCreateMetaDAO(); - const program = programFacade.program; - - let accountInfos = program.instruction.addMember - .accounts({ metaDao: metaDAO, member: memberToAdd }) - .map((accountInfo) => - accountInfo.pubkey.equals(metaDAO) - ? { ...accountInfo, isSigner: false } - : accountInfo - ) - .concat({ - pubkey: program.programId, - isWritable: false, - isSigner: false, - }); - - await programFacade.executeProposal(sampleProposal, accountInfos); -}; - -export const initializeSampleConditionalExpression = async ( - program: ProgramFacade, - passOrFailFlag: boolean = true -): Promise<[PublicKey, PublicKey, PublicKey]> => { - const [proposal, memberToAdd] = await initializeSampleProposal(program); - - const conditionalExpression = await program.initializeConditionalExpression( - proposal, - passOrFailFlag - ); - - return [conditionalExpression, proposal, memberToAdd]; -}; - -export const initializeSampleVault = async ( - program: ProgramFacade, - passOrFailFlag: boolean = true -): Promise< - [ - PublicKey, - PublicKey, - PublicKey, - PublicKey, - Signer, - PublicKey, - PublicKey, - PublicKey - ] -> => { - const [conditionalExpression, proposal, memberToAdd] = - await initializeSampleConditionalExpression(program, passOrFailFlag); - - const [underlyingTokenMint, underlyingTokenMintAuthority] = - await program.createMint(); - - const [vault, conditionalTokenMint, vaultUnderlyingTokenAccount] = - await program.initializeVault(conditionalExpression, underlyingTokenMint); - - return [ - vault, - conditionalTokenMint, - vaultUnderlyingTokenAccount, - underlyingTokenMint, - underlyingTokenMintAuthority, - conditionalExpression, - proposal, - memberToAdd, - ]; -}; - -// have `minter` mint conditional tokens, then move them to `holder` -export const mintConditionalTokens = async ( - program: ProgramFacade, - minter: Signer, - holder: Signer, - amount: number, - vault: PublicKey, - vaultUnderlyingTokenAccount: PublicKey, - underlyingTokenMint: PublicKey, - underlyingTokenMintAuthority: Signer, - conditionalTokenMint: PublicKey -) => { - let minterUnderlyingTokenAccount = await program.createTokenAccount( - underlyingTokenMint, - minter.publicKey - ); - - let holderUnderlyingTokenAccount = await program.createTokenAccount( - underlyingTokenMint, - holder.publicKey - ); - - let minterConditionalTokenAccount = await program.createTokenAccount( - conditionalTokenMint, - minter.publicKey - ); - - let holderConditionalTokenAccount = await program.createTokenAccount( - conditionalTokenMint, - holder.publicKey - ); - - let minterDepositSlip = await program.initializeDepositSlip( - vault, - minter.publicKey - ); - - let holderDepositSlip = await program.initializeDepositSlip( - vault, - holder.publicKey - ); - - await program.mintTo( - underlyingTokenMint, - minterUnderlyingTokenAccount, - underlyingTokenMintAuthority, - amount - ); - - await program.mintConditionalTokens( - amount, - minter, - minterDepositSlip, - vault, - vaultUnderlyingTokenAccount, - minterUnderlyingTokenAccount, - conditionalTokenMint, - minterConditionalTokenAccount - ); - - await program.transfer( - minterConditionalTokenAccount, - holderConditionalTokenAccount, - amount, - minter - ); - - return [ - minterUnderlyingTokenAccount, - minterConditionalTokenAccount, - minterDepositSlip, - holderUnderlyingTokenAccount, - holderConditionalTokenAccount, - holderDepositSlip, - ]; -}; - -export const testRedemption = async ( - programFacade: ProgramFacade, - passOrFailFlag: boolean, - desiredProposalState: ProposalState, - redemptionType: RedemptionType, - shouldGoThrough: boolean -) => { - const [ - vault, - conditionalTokenMint, - vaultUnderlyingTokenAccount, - underlyingTokenMint, - underlyingTokenMintAuthority, - conditionalExpression, - proposal, - memberToAdd, - ] = await initializeSampleVault(programFacade, passOrFailFlag); - - let minter = anchor.web3.Keypair.generate(); - let holder = anchor.web3.Keypair.generate(); - let amount = 1000; - - const [ - minterUnderlyingTokenAccount, - minterConditionalTokenAccount, - minterDepositSlip, - holderUnderlyingTokenAccount, - holderConditionalTokenAccount, - holderDepositSlip, - ] = await mintConditionalTokens( - programFacade, - minter, - holder, - amount, - vault, - vaultUnderlyingTokenAccount, - underlyingTokenMint, - underlyingTokenMintAuthority, - conditionalTokenMint - ); - - if (desiredProposalState == ProposalState.Passed) { - await executeSampleProposal(proposal, memberToAdd, programFacade); - } else if (desiredProposalState == ProposalState.Failed) { - await programFacade.failProposal(proposal); - } - - let expectedErrorCode; - if (desiredProposalState == ProposalState.Pending) { - expectedErrorCode = "ConditionalExpressionNotEvaluatable"; - } else if (redemptionType == RedemptionType.ConditionalToken) { - expectedErrorCode = "CantRedeemConditionalTokens"; - } else { - expectedErrorCode = "CantRedeemDepositSlip"; - } - - let callbacks; - if (shouldGoThrough) { - callbacks = [() => {}, (e) => assert.fail(e)]; - } else { - callbacks = expectError( - expectedErrorCode, - "a redemption should have failed but instead suceeded" - ); - } - - if (redemptionType == RedemptionType.ConditionalToken) { - await programFacade - .redeemConditionalForUnderlyingTokens( - holder, - holderConditionalTokenAccount, - holderUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - proposal, - conditionalExpression, - conditionalTokenMint - ) - .then(callbacks[0], callbacks[1]); - } else { - await programFacade - .redeemDepositSlipForUnderlyingTokens( - minter, - minterDepositSlip, - minterUnderlyingTokenAccount, - vaultUnderlyingTokenAccount, - vault, - proposal, - conditionalExpression - ) - .then(callbacks[0], callbacks[1]); - } -}; diff --git a/token/dark-metadata.json b/token/dark-metadata.json deleted file mode 100644 index 2970d60f..00000000 --- a/token/dark-metadata.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Dark Protocol", - "symbol": "DARK", - "uri": "https://arweave.net/EtLH9bBZdhhs9OFkntBPvQBW8r_TNBouOom4yJctcbI" -} diff --git a/token/devnet-usdc-metadata.json b/token/devnet-usdc-metadata.json deleted file mode 100644 index b86f2f7c..00000000 --- a/token/devnet-usdc-metadata.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Meta USDC", - "symbol": "mUSDC", - "uri": "https://arweave.net/pmEBiqDAxmLQ6nPTfdG893WZ1PJMD2jhRepG2P79Ea8" -} \ No newline at end of file diff --git a/token/drift-metadata.json b/token/drift-metadata.json deleted file mode 100644 index 822b8602..00000000 --- a/token/drift-metadata.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Drift", - "symbol": "DRIFT", - "uri": "https://arweave.net/-B72mZZumiJmHaL78xT5sOzUS9pXEGtylX9C1DSOV0I" -} diff --git a/token/logo_black.png b/token/logo_black.png deleted file mode 100644 index 320fc730..00000000 Binary files a/token/logo_black.png and /dev/null differ diff --git a/token/metadata.json b/token/metadata.json deleted file mode 100644 index 5abe8d79..00000000 --- a/token/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "META", - "symbol": "META", - "description": "Native token of the Meta-DAO", - "image": "https://6hgaiayuroxlfrn3djpb7mx4ocwielgo2ovpj4ka4v47jsxj2p2a.arweave.net/8cwEAxSLrrLFuxpeH7L8cKyCLM7TqvTxQOV59Mrp0_Q?ext=png" -} \ No newline at end of file diff --git a/token/ore-metadata.json b/token/ore-metadata.json deleted file mode 100644 index 972a88d5..00000000 --- a/token/ore-metadata.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Ore", - "symbol": "ORE", - "uri": "https://ore.supply/metadata.json" -} diff --git a/tsconfig.json b/tsconfig.json index ce468706..f1dd71d7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,10 +8,12 @@ "./node_modules/@types" ], "lib": [ - "es2015" + "es2015", + "dom" ], - "module": "commonjs", + "module": "nodenext", "target": "ES2020", + "moduleResolution": "nodenext", "esModuleInterop": true, "resolveJsonModule": true, "paths": { diff --git a/yarn.lock b/yarn.lock index 413d163f..46e2f6eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,31 +2,13 @@ # yarn lockfile v1 -"@babel/runtime@^7.10.5", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.23.4": +"@babel/runtime@^7.17.2", "@babel/runtime@^7.23.4": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== dependencies: regenerator-runtime "^0.14.0" -"@blockworks-foundation/mango-client@^3.4.7": - version "3.6.20" - resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-client/-/mango-client-3.6.20.tgz#66ed0ae4545959fdc31ca1918de0f931de579d41" - integrity sha512-Te0i52KUyp5e8jQQZlIMsTy9fKIfefPHvkA8+NRGIH80kQcnJKKfzw3T1NxaDsc3KFMZwpuN3m4afDNpKTuF0g== - dependencies: - "@project-serum/anchor" "^0.21.0" - "@project-serum/serum" "^0.13.65" - "@project-serum/sol-wallet-adapter" "^0.2.0" - "@solana/spl-token" "^0.1.6" - "@solana/web3.js" "^1.43.5" - big.js "^6.1.1" - bn.js "^5.1.0" - buffer-layout "^1.2.1" - cross-fetch "^3.1.5" - dotenv "^10.0.0" - toformat "^2.0.0" - yargs "^17.0.1" - "@bundlr-network/client@^0.8.8": version "0.8.9" resolved "https://registry.yarnpkg.com/@bundlr-network/client/-/client-0.8.9.tgz#58e969a5d80f8d25d212d46bb7a060730a3c1736" @@ -72,85 +54,6 @@ superstruct "^0.15.4" toml "^3.0.0" -"@coral-xyz/anchor@^0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.26.0.tgz#c8e4f7177e93441afd030f22d777d54d0194d7d1" - integrity sha512-PxRl+wu5YyptWiR9F2MBHOLLibm87Z4IMUBPreX+DYBtPM+xggvcPi0KAN7+kIL4IrIhXI8ma5V0MCXxSN1pHg== - dependencies: - "@coral-xyz/borsh" "^0.26.0" - "@solana/web3.js" "^1.68.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^6.3.0" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - superstruct "^0.15.4" - toml "^3.0.0" - -"@coral-xyz/anchor@^0.28.0": - version "0.28.0" - resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.28.0.tgz#8345c3c9186a91f095f704d7b90cd256f7e8b2dc" - integrity sha512-kQ02Hv2ZqxtWP30WN1d4xxT4QqlOXYDxmEd3k/bbneqhV3X5QMO4LAtoUFs7otxyivOgoqam5Il5qx81FuI4vw== - dependencies: - "@coral-xyz/borsh" "^0.28.0" - "@solana/web3.js" "^1.68.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^6.3.0" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - superstruct "^0.15.4" - toml "^3.0.0" - -"@coral-xyz/anchor@^0.28.1-beta.2": - version "0.28.1-beta.2" - resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.28.1-beta.2.tgz#4ddd4b2b66af04407be47cf9524147793ec514a0" - integrity sha512-xreUcOFF8+IQKWOBUrDKJbIw2ftpRVybFlEPVrbSlOBCbreCWrQ5754Gt9cHIcuBDAzearCDiBqzsGQdNgPJiw== - dependencies: - "@coral-xyz/borsh" "^0.28.0" - "@noble/hashes" "^1.3.1" - "@solana/web3.js" "^1.68.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^6.3.0" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - pako "^2.0.3" - snake-case "^3.0.4" - superstruct "^0.15.4" - toml "^3.0.0" - -"@coral-xyz/borsh@^0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.26.0.tgz#d054f64536d824634969e74138f9f7c52bbbc0d5" - integrity sha512-uCZ0xus0CszQPHYfWAqKS5swS1UxvePu83oOF+TWpUkedsNlg6p2p4azxZNSSqwXb9uXMFgxhuMBX9r3Xoi0vQ== - dependencies: - bn.js "^5.1.2" - buffer-layout "^1.2.0" - -"@coral-xyz/borsh@^0.28.0": - version "0.28.0" - resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.28.0.tgz#fa368a2f2475bbf6f828f4657f40a52102e02b6d" - integrity sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ== - dependencies: - bn.js "^5.1.2" - buffer-layout "^1.2.0" - "@coral-xyz/borsh@^0.29.0": version "0.29.0" resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.29.0.tgz#79f7045df2ef66da8006d47f5399c7190363e71f" @@ -726,268 +629,19 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": - version "9.3.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" - integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== - -"@hapi/topo@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" - integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== - dependencies: - "@hapi/hoek" "^9.0.0" - -"@mercurial-finance/apricot-sdk@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@mercurial-finance/apricot-sdk/-/apricot-sdk-0.17.6.tgz#e5e2266dbf3d454a09d745561f486aaa351d625a" - integrity sha512-/x/nMksG2h3uB7G4bPVXk0YjvsGVUniSikRmCf/VFFly9BqcRcBtSk4aMdSvIjYsJrpSzWVrHXUYeOtUF1ObDA== - dependencies: - "@solana/spl-token" "0.1.8" - "@solana/web3.js" "^1.37.0" - decimal.js "^10.3.1" - tiny-invariant "^1.1.0" - -"@mercurial-finance/cypher-client@^4.1.4": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@mercurial-finance/cypher-client/-/cypher-client-4.1.4.tgz#17b4d76b9f53d2919e6aee4be2fa22432188c52f" - integrity sha512-W5zy+weni9LPPCL6ImGMjb/Ykg8x09kRVSsVg+OaXZ7qrA+/lwEvv32aEn8kKuha0drvuvTNdXHPUuC60UEnsg== - dependencies: - "@project-serum/anchor" "^0.26.0" - "@solana/web3.js" "~1.72.0" - -"@mercurial-finance/drift-sdk@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@mercurial-finance/drift-sdk/-/drift-sdk-1.0.3.tgz#c9426fd7c019aa973914841ca1f6c9397de444ca" - integrity sha512-I+K95ZK7FpSY67UcZ1JW0M2jOnEVoK5k3TMLzqbrv30m0IGBJYZ1zmrdPlIsNdd4N83KMsYbCjiGltL7h0/bYQ== - dependencies: - "@project-serum/anchor" "0.25.0-beta.1" - "@project-serum/serum" "^0.13.38" - "@pythnetwork/client" "2.5.3" - "@solana/spl-token" "^0.1.6" - "@solana/web3.js" "1.66.2" - "@switchboard-xyz/switchboard-v2" "^0.0.67" - bs58 "^5.0.0" - strict-event-emitter-types "^2.0.0" - uuid "^8.3.2" - -"@mercurial-finance/dynamic-amm-sdk@^0.4.19": - version "0.4.19" - resolved "https://registry.yarnpkg.com/@mercurial-finance/dynamic-amm-sdk/-/dynamic-amm-sdk-0.4.19.tgz#30a45199472b745cf536d5be5f30cdd8752c3adb" - integrity sha512-mN3EubUvwXnoY60RANsu67YhEfUIA3gyR25VsM9lHNAsOtwSPOc0gUl5u63TuDNZdcCVsLScklMJytUPuJ/AHg== - dependencies: - "@mercurial-finance/vault-sdk" "0.5.3" - "@project-serum/anchor" "0.24.2" - "@project-serum/borsh" "^0.2.5" - "@saberhq/anchor-contrib" "1.13.32" - "@saberhq/stableswap-sdk" "1.13.32" - "@saberhq/token-utils" "1.13.32" - "@solana/spl-token" "0.1.8" - "@solana/spl-token-registry" "0.2.1105" - "@solana/web3.js" "^1.42.0" - bn-sqrt "^1.0.0" - bn.js "5.2.1" - decimal.js "^10.4.1" - dotenv "^16.0.1" - invariant "^2.2.4" - jsbi "^4.3.0" - -"@mercurial-finance/frakt-sdk@0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@mercurial-finance/frakt-sdk/-/frakt-sdk-0.0.2.tgz#0a0f39aef240c1c7f092156c643f1eb27adfa566" - integrity sha512-x/3W7BMyUzMigkeJMLXNCnZunGw6JFSaG5hx4oaioDy9qT3MxT05OhaoKLs9zMl3RPLjy/xm1Y79eoDdz8qxEQ== - dependencies: - "@project-serum/anchor" "0.24.2" - axios "^1.2.1" - -"@mercurial-finance/francium-sdk@1.4.3": - version "1.4.3" - resolved "https://registry.yarnpkg.com/@mercurial-finance/francium-sdk/-/francium-sdk-1.4.3.tgz#aa6c43da1a923a700bec0b0e425fe72a76d8dd68" - integrity sha512-beFsxFx9WsHsImCSZAPXlitE4kQMugHczATishmJdxXGEHvBfJ3hrncjaWf+znwlMTknx8zYgPFfeP9JzbHHgw== - -"@mercurial-finance/mango-v4@0.5.4": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@mercurial-finance/mango-v4/-/mango-v4-0.5.4.tgz#9df78a7f146c59c8a645877b6587ab44c51e7303" - integrity sha512-KD0xdmU5+05F/Or7YYtzyhFGwAXqDD+LmN9fJIp/KJfieQcKq/GnLnFdGA8iTLMydyqcO0ymgSxu5Uky2IpyaA== - dependencies: - "@project-serum/anchor" "^0.25.0" - "@project-serum/serum" "^0.13.65" - "@pythnetwork/client" "~2.14.0" - "@solana/spl-token" "0.3.7" - "@solana/web3.js" "^1.63.1" - "@switchboard-xyz/sbv2-lite" "^0.1.6" - big.js "^6.1.1" - binance-api-node "^0.12.0" - bs58 "^5.0.0" - cross-fetch "^3.1.5" - dotenv "^16.0.3" - node-kraken-api "^2.2.2" - -"@mercurial-finance/marginfi-client-v2@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@mercurial-finance/marginfi-client-v2/-/marginfi-client-v2-1.0.2.tgz#685dc3b235081741c97ae0cfd5a63ee2241159c0" - integrity sha512-Bmd6yJhVZLdiHMkJvNmEP+MxT0QCNXDGwwKEgIQxtTsIhAYtnlgBQegXz1t8aad5qEmimWRjyYQWu8jjaZ7UcQ== - dependencies: - "@coral-xyz/anchor" "^0.26.0" - "@mrgnlabs/mrgn-common" "*" - "@project-serum/anchor" "^0.26.0" - "@pythnetwork/client" "^2.9.0" - "@solana/wallet-adapter-base" "^0.9.20" - "@solana/web3.js" "^1.71.0" - "@switchboard-xyz/solana.js" "^2.1.10" - bignumber.js "^9.1.1" - decimal.js "^10.4.3" - superstruct "^1.0.3" - -"@mercurial-finance/optimist@^0.1.4": - version "0.1.9" - resolved "https://registry.yarnpkg.com/@mercurial-finance/optimist/-/optimist-0.1.9.tgz#82b612fc6d602c1010cada4fb396d92b7fcae03a" - integrity sha512-cOJan58djQdg2iHKV/jPFgD1bNm2hffa5S0FXREKSNfzZRfsYLZOnRNJ24X0o+VJ9kC5BY0HYwduT/+dAyZ0AQ== - dependencies: - promise-retry "2.0.1" - -"@mercurial-finance/port-sdk@0.2.69": - version "0.2.69" - resolved "https://registry.yarnpkg.com/@mercurial-finance/port-sdk/-/port-sdk-0.2.69.tgz#79978c4be9175afb3640e18e16f21e439f203ef2" - integrity sha512-DDZBLkoIQVhLQRy+t7dVuiHNw0nAmWD7xqwMekHT71bBLU5ajQglRvQ9b8d2RQQn1WJsXhbGbc7eTUGWdZqWoQ== - dependencies: - "@solana/buffer-layout" "^3.0.0" - "@solana/spl-token" "0.1.8" - "@solana/spl-token-registry" "^0.2.1107" - "@solana/web3.js" "^1.32.0" - big.js "^6.1.1" - bn.js "^5.2.1" - buffer-layout "1.2.2" - -"@mercurial-finance/solend-sdk@0.6.5": - version "0.6.5" - resolved "https://registry.yarnpkg.com/@mercurial-finance/solend-sdk/-/solend-sdk-0.6.5.tgz#54b2fe6fb28356ba8e749e8c42fb9193cec4f258" - integrity sha512-544KqvD1IkpnyTUDOCt0yVlTcayt9rv+CTXHTFQDinWQQkA8uWBoiNbI0g49bJVE//Np3SbJSOgJmq5KlxgvWQ== - dependencies: - "@solana/web3.js" "^1.52.0" - bn.js "^5.2.0" - buffer "^6.0.3" - buffer-layout "^1.2.0" - -"@mercurial-finance/tulip-platform-sdk@2.0.30": - version "2.0.30" - resolved "https://registry.yarnpkg.com/@mercurial-finance/tulip-platform-sdk/-/tulip-platform-sdk-2.0.30.tgz#c528ca8efd96e4667d8d905274065d6435438ad6" - integrity sha512-ySPxAtFLtati9Vv7g3czrcNEiT9HBZboRDNnfEDmCFJqsub87Y2ZF125dpspaZzKUlolOrBIqBy1FZYIreMgfg== - dependencies: - "@project-serum/anchor" "^0.25.0" - "@project-serum/associated-token" "^0.1.1" - "@project-serum/borsh" "^0.2.5" - "@solana/web3.js" "^1.66.2" - lodash "^4.17.21" - -"@mercurial-finance/vault-sdk@0.5.3": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@mercurial-finance/vault-sdk/-/vault-sdk-0.5.3.tgz#4a6ef72474a6c81f86d1219c57cbbbd1978879fe" - integrity sha512-JnG5moumWHg15utCMVD/G+1xLveGXSTUAkTQUSiITs7Du1Nw47GtHlpJEa9+z+0uhcy6/eKNiNLkDUrq0z3zSg== - dependencies: - "@blockworks-foundation/mango-client" "^3.4.7" - "@mercurial-finance/apricot-sdk" "0.17.6" - "@mercurial-finance/cypher-client" "^4.1.4" - "@mercurial-finance/drift-sdk" "1.0.3" - "@mercurial-finance/frakt-sdk" "0.0.2" - "@mercurial-finance/francium-sdk" "1.4.3" - "@mercurial-finance/mango-v4" "0.5.4" - "@mercurial-finance/marginfi-client-v2" "1.0.2" - "@mercurial-finance/optimist" "^0.1.4" - "@mercurial-finance/port-sdk" "0.2.69" - "@mercurial-finance/solend-sdk" "0.6.5" - "@mercurial-finance/tulip-platform-sdk" "2.0.30" - "@mithraic-labs/psylend-utils" "0.0.3-rc39" - "@project-serum/anchor" "0.25.0" - "@quarryprotocol/quarry-sdk" "5.0.2" - "@saberhq/anchor-contrib" "1.13.32" - "@solana/buffer-layout" "^4.0.0" - "@solana/spl-token" "0.1.8" - "@solana/spl-token-registry" "0.2.1105" - "@solana/web3.js" "~1.72.0" - bn.js "5.2.1" - cross-fetch "^3.1.5" - decimal.js "10.3.1" - jsbi "4.3.0" - -"@metadaoproject/futarchy@0.3.0-alpha.8": - version "0.3.0-alpha.8" - resolved "https://registry.yarnpkg.com/@metadaoproject/futarchy/-/futarchy-0.3.0-alpha.8.tgz#eaf4d898129df2c8a1408bb1974fa61dacb87ade" - integrity sha512-5gyYsEpAMCC9x5Gij4Zlj7j33GwmVormuigilnhZTlpm0/RsKdPHxPiPoBmjQL5fHR1N8+5B9vHyQvFbc4KaZA== +"@metadaoproject/futarchy@0.4.0-alpha.0": + version "0.4.0-alpha.0" + resolved "https://registry.yarnpkg.com/@metadaoproject/futarchy/-/futarchy-0.4.0-alpha.0.tgz#50a4c4f8cc57a047dbc05e44f512a1e008c54f5c" + integrity sha512-iURmMXOkzD5Wjduvsi7/5zKx6AB2YJa1AG/Vwh8HZjLHGT3cjGQ2lf36ugpHryImDRg1RAPO+l8WjXgLVNZwCw== dependencies: "@coral-xyz/anchor" "^0.29.0" + "@noble/hashes" "^1.4.0" "@solana/spl-token" "^0.3.7" "@solana/web3.js" "^1.74.0" bn.js "^5.2.1" decimal.js "^10.4.3" esbuild "^0.17.15" -"@metaplex-foundation/beet-solana@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet-solana/-/beet-solana-0.4.0.tgz#52891e78674aaa54e0031f1bca5bfbc40de12e8d" - integrity sha512-B1L94N3ZGMo53b0uOSoznbuM5GBNJ8LwSeznxBxJ+OThvfHQ4B5oMUqb+0zdLRfkKGS7Q6tpHK9P+QK0j3w2cQ== - dependencies: - "@metaplex-foundation/beet" ">=0.1.0" - "@solana/web3.js" "^1.56.2" - bs58 "^5.0.0" - debug "^4.3.4" - -"@metaplex-foundation/beet-solana@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet-solana/-/beet-solana-0.3.1.tgz#4b37cda5c7f32ffd2bdd8b3164edc05c6463ab35" - integrity sha512-tgyEl6dvtLln8XX81JyBvWjIiEcjTkUwZbrM5dIobTmoqMuGewSyk9CClno8qsMsFdB5T3jC91Rjeqmu/6xk2g== - dependencies: - "@metaplex-foundation/beet" ">=0.1.0" - "@solana/web3.js" "^1.56.2" - bs58 "^5.0.0" - debug "^4.3.4" - -"@metaplex-foundation/beet@0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet/-/beet-0.7.1.tgz#0975314211643f87b5f6f3e584fa31abcf4c612c" - integrity sha512-hNCEnS2WyCiYyko82rwuISsBY3KYpe828ubsd2ckeqZr7tl0WVLivGkoyA/qdiaaHEBGdGl71OpfWa2rqL3DiA== - dependencies: - ansicolors "^0.3.2" - bn.js "^5.2.0" - debug "^4.3.3" - -"@metaplex-foundation/beet@>=0.1.0": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet/-/beet-0.7.2.tgz#fa4726e4cfd4fb6fed6cddc9b5213c1c2a2d0b77" - integrity sha512-K+g3WhyFxKPc0xIvcIjNyV1eaTVJTiuaHZpig7Xx0MuYRMoJLLvhLTnUXhFdR5Tu2l2QSyKwfyXDgZlzhULqFg== - dependencies: - ansicolors "^0.3.2" - assert "^2.1.0" - bn.js "^5.2.0" - debug "^4.3.3" - -"@metaplex-foundation/beet@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet/-/beet-0.4.0.tgz#eb2a0a6eb084bb25d67dd9bed2f7387ee7e63a55" - integrity sha512-2OAKJnLatCc3mBXNL0QmWVQKAWK2C7XDfepgL0p/9+8oSx4bmRAFHFqptl1A/C0U5O3dxGwKfmKluW161OVGcA== - dependencies: - ansicolors "^0.3.2" - bn.js "^5.2.0" - debug "^4.3.3" - -"@metaplex-foundation/cusper@^0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/cusper/-/cusper-0.0.2.tgz#dc2032a452d6c269e25f016aa4dd63600e2af975" - integrity sha512-S9RulC2fFCFOQraz61bij+5YCHhSO9llJegK8c8Y6731fSi6snUSQJdCUqYS8AIgR0TKbQvdvgSyIIdbDFZbBA== - -"@metaplex-foundation/mpl-token-metadata@2.2.4": - version "2.2.4" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-2.2.4.tgz#d934cf20d6e22f7923fc96b80c7534595780eda6" - integrity sha512-cayIZ7w/XUKkUygNyWyx5l5Q8PO5qzIemk6c/7dxKhdHLlaVPwKjRhbg6kIuzZ8tvYP5afUmJKln9rWnI8tQCA== - dependencies: - "@metaplex-foundation/beet" "^0.4.0" - "@metaplex-foundation/beet-solana" "^0.3.0" - "@metaplex-foundation/cusper" "^0.0.2" - "@solana/spl-token" "^0.2.0" - "@solana/web3.js" "^1.35.1" - bn.js "^5.2.0" - debug "^4.3.3" - "@metaplex-foundation/mpl-token-metadata@^3.2.0": version "3.2.1" resolved "https://registry.yarnpkg.com/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-3.2.1.tgz#d424e378a1ee441a6431d2641d66873118d6dc67" @@ -1131,34 +785,6 @@ "@metaplex-foundation/umi-public-keys" "^0.8.9" "@metaplex-foundation/umi-serializers" "^0.9.0" -"@mithraic-labs/psylend-utils@0.0.3-rc39": - version "0.0.3-rc39" - resolved "https://registry.yarnpkg.com/@mithraic-labs/psylend-utils/-/psylend-utils-0.0.3-rc39.tgz#05b0d2733f5ad8ea0868e20b3e78922808d4a1f3" - integrity sha512-7bfGwg9brPF+mxDck8m9GNWUI23YV7eeWA21WKM51aPnz8IJXR6XBTbi3TrQPSA96B77Qx1cP3uE43CsI29tcA== - dependencies: - "@project-serum/anchor" "0.25.0" - "@project-serum/serum" "^0.13.65" - "@pythnetwork/client" "2.7.3" - "@solana/web3.js" "^1.30.2" - chai "^4.3.7" - psyfi-euros-test "0.0.2-rc.5" - spl2 "npm:@solana/spl-token@^0.2.0" - -"@mrgnlabs/mrgn-common@*": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@mrgnlabs/mrgn-common/-/mrgn-common-1.3.1.tgz#1651923ceda82517acd5c121a38e54dd3b48105f" - integrity sha512-AN+OEqNXGOAjgzbYWayBKCpWs8fXK8XyvOpNtrl/9C3rOAGddQgOCQEx050/5Uudxr7P/ZSTD7RaCV/+bKjLkg== - dependencies: - "@coral-xyz/anchor" "^0.28.1-beta.2" - "@solana/buffer-layout-utils" "^0.2.0" - "@solana/wallet-adapter-base" "^0.9.20" - "@solana/web3.js" "^1.87.6" - bignumber.js "^9.1.1" - bs58 "^5.0.0" - decimal.js "^10.4.3" - numeral "^2.0.6" - superstruct "^1.0.3" - "@noble/curves@^1.0.0", "@noble/curves@^1.2.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" @@ -1173,7 +799,7 @@ dependencies: "@noble/hashes" "1.4.0" -"@noble/ed25519@^1.6.1", "@noble/ed25519@^1.7.0": +"@noble/ed25519@^1.6.1": version "1.7.3" resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123" integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ== @@ -1183,338 +809,21 @@ resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-2.0.0.tgz#5964c8190a4b4b804985717ca566113b93379e43" integrity sha512-/extjhkwFupyopDrt80OMWKdLgP429qLZj+z6sYJz90rF2Iz0gjZh2ArMKPImUl13Kx+0EXI2hN9T/KJV0/Zng== -"@noble/hashes@1.3.3", "@noble/hashes@^1.1.2", "@noble/hashes@^1.3.1", "@noble/hashes@^1.3.3": +"@noble/hashes@1.3.3", "@noble/hashes@^1.3.1", "@noble/hashes@^1.3.3": version "1.3.3" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== -"@noble/hashes@1.4.0": +"@noble/hashes@1.4.0", "@noble/hashes@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== -"@noble/secp256k1@^1.6.3": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" - integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== - "@noble/secp256k1@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-2.0.0.tgz#c214269d45e0233ad6a8ae5104655453636e253d" integrity sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw== -"@openbook-dex/openbook-v2@0.1.7": - version "0.1.7" - resolved "https://registry.yarnpkg.com/@openbook-dex/openbook-v2/-/openbook-v2-0.1.7.tgz#55ae6a1bbc76faa84023cd59b6dfc759a886539b" - integrity sha512-dyL/q01BTmI+KtxjYfaHOat+JDppCIbqGiNQYFIFMqcawHlyXFaK/y4m3lR0A82iAOvr7+27z5FPtbAMWpyHHw== - dependencies: - "@coral-xyz/anchor" "^0.28.1-beta.2" - "@solana/spl-token" "0.3.8" - "@solana/web3.js" "^1.77.3" - big.js "^6.2.1" - -"@project-serum/anchor@0.23.0", "@project-serum/anchor@^0.23.0": - version "0.23.0" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.23.0.tgz#2b2eb6b51601b073e8db26663aa2d6c2f2841771" - integrity sha512-LV2/ifZOJVFTZ4GbEloXln3iVfCvO1YM8i7BBCrUm4tehP7irMx4nr4/IabHWOzrQcQElsxSP/lb1tBp+2ff8A== - dependencies: - "@project-serum/borsh" "^0.2.5" - "@solana/web3.js" "^1.36.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^5.3.1" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - find "^0.3.0" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - toml "^3.0.0" - -"@project-serum/anchor@0.24.2", "@project-serum/anchor@^0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.24.2.tgz#a3c52a99605c80735f446ca9b3a4885034731004" - integrity sha512-0/718g8/DnEuwAidUwh5wLYphUYXhUbiClkuRNhvNoa+1Y8a4g2tJyxoae+emV+PG/Gikd/QUBNMkIcimiIRTA== - dependencies: - "@project-serum/borsh" "^0.2.5" - "@solana/web3.js" "^1.36.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^5.3.1" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - toml "^3.0.0" - -"@project-serum/anchor@0.25.0", "@project-serum/anchor@^0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.25.0.tgz#88ee4843336005cf5a64c80636ce626f0996f503" - integrity sha512-E6A5Y/ijqpfMJ5psJvbw0kVTzLZFUcOFgs6eSM2M2iWE1lVRF18T6hWZVNl6zqZsoz98jgnNHtVGJMs+ds9A7A== - dependencies: - "@project-serum/borsh" "^0.2.5" - "@solana/web3.js" "^1.36.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^5.3.1" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - superstruct "^0.15.4" - toml "^3.0.0" - -"@project-serum/anchor@0.25.0-beta.1": - version "0.25.0-beta.1" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.25.0-beta.1.tgz#7b113fb6604483d6740c8da9c6d86e9a5d5f6cf7" - integrity sha512-edesFlclgQzIluD2mC0xrGPnABBllKvbGd6MOtNZMCauUnx1Xbu073um8O6mrCeuZrz4PG9AhwAp1y5cOl3R4A== - dependencies: - "@project-serum/borsh" "^0.2.5" - "@solana/web3.js" "^1.36.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^5.3.1" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - superstruct "^0.15.4" - toml "^3.0.0" - -"@project-serum/anchor@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.11.1.tgz#155bff2c70652eafdcfd5559c81a83bb19cec9ff" - integrity sha512-oIdm4vTJkUy6GmE6JgqDAuQPKI7XM4TPJkjtoIzp69RZe0iAD9JP2XHx7lV1jLdYXeYHqDXfBt3zcq7W91K6PA== - dependencies: - "@project-serum/borsh" "^0.2.2" - "@solana/web3.js" "^1.17.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.0" - camelcase "^5.3.1" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - find "^0.3.0" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - toml "^3.0.0" - -"@project-serum/anchor@^0.21.0": - version "0.21.0" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.21.0.tgz#ad5fb33744991ec1900cdb2fd22707c908b12b5f" - integrity sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA== - dependencies: - "@project-serum/borsh" "^0.2.4" - "@solana/web3.js" "^1.17.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^5.3.1" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - find "^0.3.0" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - toml "^3.0.0" - -"@project-serum/anchor@^0.22.0": - version "0.22.1" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.22.1.tgz#698a9620f94691de0a12bbc650a5c8380e2f0e8a" - integrity sha512-5pHeyvQhzLahIQ8aZymmDMZJAJFklN0joZdI+YIqFkK2uU/mlKr6rBLQjxysf/j1mLLiNG00tdyLfUtTAdQz7w== - dependencies: - "@project-serum/borsh" "^0.2.5" - "@solana/web3.js" "^1.17.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^5.3.1" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - find "^0.3.0" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - toml "^3.0.0" - -"@project-serum/anchor@^0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.26.0.tgz#99e15a3923a5d10514f8185b2d3909e5699d60d5" - integrity sha512-Nq+COIjE1135T7qfnOHEn7E0q39bQTgXLFk837/rgFe6Hkew9WML7eHsS+lSYD2p3OJaTiUOHTAq1lHy36oIqQ== - dependencies: - "@coral-xyz/borsh" "^0.26.0" - "@solana/web3.js" "^1.68.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^6.3.0" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - superstruct "^0.15.4" - toml "^3.0.0" - -"@project-serum/associated-token@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@project-serum/associated-token/-/associated-token-0.1.1.tgz#9acf745e84dad21e2ea26e06694704b9d698e532" - integrity sha512-Zc1wdqragbDiyBVagzIbIsMe37P7fgkArWZPIj+jJjDIoznlmYMK6ASU5mtdDZrPJ7sNABF/lzZ3+jvCCcU+oA== - -"@project-serum/borsh@^0.2.2", "@project-serum/borsh@^0.2.4", "@project-serum/borsh@^0.2.5": - version "0.2.5" - resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.5.tgz#6059287aa624ecebbfc0edd35e4c28ff987d8663" - integrity sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q== - dependencies: - bn.js "^5.1.2" - buffer-layout "^1.2.0" - -"@project-serum/common@^0.0.1-beta.3": - version "0.0.1-beta.3" - resolved "https://registry.yarnpkg.com/@project-serum/common/-/common-0.0.1-beta.3.tgz#53586eaff9d9fd7e8938b1e12080c935b8b6ad07" - integrity sha512-gnQE/eUydTtto5okCgLWj1M97R9RRPJqnhKklikYI7jP/pnNhDmngSXC/dmfzED2GXSJEIKNIlxVw1k+E2Aw3w== - dependencies: - "@project-serum/serum" "^0.13.21" - bn.js "^5.1.2" - superstruct "0.8.3" - -"@project-serum/serum@^0.13.21", "@project-serum/serum@^0.13.38", "@project-serum/serum@^0.13.61", "@project-serum/serum@^0.13.65": - version "0.13.65" - resolved "https://registry.yarnpkg.com/@project-serum/serum/-/serum-0.13.65.tgz#6d3cf07912f13985765237f053cca716fe84b0b0" - integrity sha512-BHRqsTqPSfFB5p+MgI2pjvMBAQtO8ibTK2fYY96boIFkCI3TTwXDt2gUmspeChKO2pqHr5aKevmexzAcXxrSRA== - dependencies: - "@project-serum/anchor" "^0.11.1" - "@solana/spl-token" "^0.1.6" - "@solana/web3.js" "^1.21.0" - bn.js "^5.1.2" - buffer-layout "^1.2.0" - -"@project-serum/sol-wallet-adapter@^0.2.0": - version "0.2.6" - resolved "https://registry.yarnpkg.com/@project-serum/sol-wallet-adapter/-/sol-wallet-adapter-0.2.6.tgz#b4cd25a566294354427c97c26d716112b91a0107" - integrity sha512-cpIb13aWPW8y4KzkZAPDgw+Kb+DXjCC6rZoH74MGm3I/6e/zKyGnfAuW5olb2zxonFqsYgnv7ev8MQnvSgJ3/g== - dependencies: - bs58 "^4.0.1" - eventemitter3 "^4.0.7" - -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== - -"@pythnetwork/client@2.5.3": - version "2.5.3" - resolved "https://registry.yarnpkg.com/@pythnetwork/client/-/client-2.5.3.tgz#86c9f92d01d8f282fdd8b5b11039da654e263988" - integrity sha512-NBLxPnA6A3tZb/DYUooD4SO63UJ70s9DzzFPGXcQNBR9itcycp7aaV+UA5oUPloD/4UHL9soo2fRuDVur0gmhA== - dependencies: - "@solana/web3.js" "^1.30.2" - assert "^2.0.0" - buffer "^6.0.1" - -"@pythnetwork/client@2.7.3": - version "2.7.3" - resolved "https://registry.yarnpkg.com/@pythnetwork/client/-/client-2.7.3.tgz#6075a16dc394d1734e76b04e907a680490a61536" - integrity sha512-+2k5JXxv/yUA6WMESSppJlg4T/AP+nZZfBnHmeG3RPCIJx+bargxFLCK4B2KgpQYdeTWb+2z8yRCNF7tHooCFQ== - dependencies: - buffer "^6.0.1" - -"@pythnetwork/client@^2.9.0": - version "2.21.0" - resolved "https://registry.yarnpkg.com/@pythnetwork/client/-/client-2.21.0.tgz#01506bcdf2b62878fbe1368656bfe1c7581c72d7" - integrity sha512-jqUuPLuVKRNUsZfwLuvK/MwnJ3LIrIxBNoz43xt0fjvVuH5QyTlz51ek76CkeKfCbomGKe41Vq7bvn8aqWVOGA== - dependencies: - "@coral-xyz/anchor" "^0.29.0" - "@coral-xyz/borsh" "^0.28.0" - buffer "^6.0.1" - -"@pythnetwork/client@~2.14.0": - version "2.14.0" - resolved "https://registry.yarnpkg.com/@pythnetwork/client/-/client-2.14.0.tgz#0c12a7e1bcc66ff198fdb64c003b8d4a24431efc" - integrity sha512-tFLGnuIBjlzDa8TrJULzJIdykketGXDJZtO+8+i4XO9l2uOKXzxt+pjt05ng5B9iY63FzJqgAkawT/O3V0NAdQ== - dependencies: - "@coral-xyz/anchor" "^0.26.0" - buffer "^6.0.1" - -"@quarryprotocol/quarry-sdk@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@quarryprotocol/quarry-sdk/-/quarry-sdk-5.0.2.tgz#f306ef4c0446a2ae7432e6e0593bc3dcb75812ee" - integrity sha512-wczlmNfb8fk6WCZsLLR7ysSjgxl6ZdEJ7cNDhgvFpU9E1YMSN1f2l2NK9yw+VksuLxWCightFsBrHSqqIftDzQ== - dependencies: - superstruct "^0.15.4" - tiny-invariant "^1.2.0" - tslib "^2.3.1" - "@randlabs/communication-bridge@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@randlabs/communication-bridge/-/communication-bridge-1.0.1.tgz#d1ecfc29157afcbb0ca2d73122d67905eecb5bf3" @@ -1527,90 +836,6 @@ dependencies: "@randlabs/communication-bridge" "1.0.1" -"@saberhq/anchor-contrib@1.13.32": - version "1.13.32" - resolved "https://registry.yarnpkg.com/@saberhq/anchor-contrib/-/anchor-contrib-1.13.32.tgz#99c7da5030c92a073a6b934dd11cee3c2893bc9d" - integrity sha512-coU3mFuwJCM5hdNkMSxse+WyJskDer6OzAAXCE5bxe8Lm2bQFN1P3uohrBmV6r+eQlK+im+oozne7CyCSmR1lw== - dependencies: - "@saberhq/solana-contrib" "^1.13.32" - eventemitter3 "^4.0.7" - lodash.camelcase "^4.3.0" - lodash.mapvalues "^4.6.0" - tslib "^2.4.0" - -"@saberhq/option-utils@^1.15.0": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@saberhq/option-utils/-/option-utils-1.15.0.tgz#6415e2ecacac060ef8e00a5f1b32fb113856c1ac" - integrity sha512-XVbS9H4b8PIGXJGaErkOurxV2FKFyvMwYq0pD8Y1iEPoi6HB//+HnpEKAv8tCssIQ5Nn1zQWzmQ9CmGkrwzcsw== - dependencies: - tslib "^2.6.2" - -"@saberhq/solana-contrib@^1.13.32", "@saberhq/solana-contrib@^1.15.0": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@saberhq/solana-contrib/-/solana-contrib-1.15.0.tgz#5b9059fd3bd73eda640a50c9fa89fcd030befe69" - integrity sha512-OExL5qGrNMmIKINU7qFUDmY7+xIwVM2s360g99k8CRNHSnjpnqIzwDjr2CnvEFpeQPp22OdGlS63woDp0w0JsQ== - dependencies: - "@saberhq/option-utils" "^1.15.0" - "@solana/buffer-layout" "^4.0.0" - "@types/promise-retry" "^1.1.6" - "@types/retry" "^0.12.5" - promise-retry "^2.0.1" - retry "^0.13.1" - tiny-invariant "^1.3.1" - tslib "^2.6.2" - -"@saberhq/stableswap-sdk@1.13.32": - version "1.13.32" - resolved "https://registry.yarnpkg.com/@saberhq/stableswap-sdk/-/stableswap-sdk-1.13.32.tgz#eb439f7ed08102c971571821e38980c4d0841223" - integrity sha512-dE9P6EeXCkH0ay+L0a41SmqQfD/YkSRP+z3p9LCADH4gnKpoSgObEB7LKm7Xp06kq+DQiClJV/ycKd9LRJjCVA== - dependencies: - "@saberhq/solana-contrib" "^1.13.32" - "@saberhq/token-utils" "^1.13.32" - "@solana/buffer-layout" "^4.0.0" - tiny-invariant "^1.2.0" - tslib "^2.4.0" - -"@saberhq/token-utils@1.13.32": - version "1.13.32" - resolved "https://registry.yarnpkg.com/@saberhq/token-utils/-/token-utils-1.13.32.tgz#2acc98bd4d3732b826396a70b958198e0d20dee8" - integrity sha512-n5ECiw82IQJwyq9bTkcrbNWVi+lAQoQlJlTmIye8odUQATBsqOWN+clqfrFkn/UMmezO60bo34bUaM0Oir7Pew== - dependencies: - "@saberhq/solana-contrib" "^1.13.32" - "@solana/buffer-layout" "^4.0.0" - "@solana/spl-token" "^0.1.8" - "@ubeswap/token-math" "^5.1.6" - tiny-invariant "^1.2.0" - tslib "^2.4.0" - -"@saberhq/token-utils@^1.13.32": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@saberhq/token-utils/-/token-utils-1.15.0.tgz#7f7a222110276ce53332183de00bae5f59eb284d" - integrity sha512-XydjtT08Qq6hdJXnfk1NtIZeyOhNyb0YXrVtM6K3OoaH88HjF36niIRv6kMMcWAGm+Hkp1111NyYFhk55PNfOA== - dependencies: - "@saberhq/solana-contrib" "^1.15.0" - "@solana/buffer-layout" "^4.0.0" - "@solana/spl-token" "^0.1.8" - "@ubeswap/token-math" "^5.2.1" - tiny-invariant "^1.3.1" - tslib "^2.6.2" - -"@sideway/address@^4.1.5": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5" - integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q== - dependencies: - "@hapi/hoek" "^9.0.0" - -"@sideway/formula@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" - integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== - -"@sideway/pinpoint@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" - integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== - "@solana/buffer-layout-utils@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca" @@ -1621,13 +846,6 @@ bigint-buffer "^1.1.5" bignumber.js "^9.0.1" -"@solana/buffer-layout@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz#b9353caeb9a1589cb77a1b145bcb1a9a93114326" - integrity sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w== - dependencies: - buffer "~6.0.3" - "@solana/buffer-layout@^4.0.0", "@solana/buffer-layout@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" @@ -1690,62 +908,14 @@ "@solana/options" "2.0.0-experimental.8618508" "@solana/spl-type-length-value" "0.1.0" -"@solana/spl-token-registry@0.2.1105": - version "0.2.1105" - resolved "https://registry.yarnpkg.com/@solana/spl-token-registry/-/spl-token-registry-0.2.1105.tgz#460fc363096aa59c5150f67736cddc1d5a810e8a" - integrity sha512-s9MIUoTAtqYsg1RaXIHXq7DhsUVS9VckvrwYuJBFn68YCZNSMUEquqaimbaHi88OVduFsApVAbKRmsGnJ9abIw== - dependencies: - cross-fetch "3.0.6" - -"@solana/spl-token-registry@^0.2.1107", "@solana/spl-token-registry@^0.2.4574": +"@solana/spl-token-registry@^0.2.4574": version "0.2.4574" resolved "https://registry.yarnpkg.com/@solana/spl-token-registry/-/spl-token-registry-0.2.4574.tgz#13f4636b7bec90d2bb43bbbb83512cd90d2ce257" integrity sha512-JzlfZmke8Rxug20VT/VpI2XsXlsqMlcORIUivF+Yucj7tFi7A0dXG7h+2UnD0WaZJw8BrUz2ABNkUnv89vbv1A== dependencies: cross-fetch "3.0.6" -"@solana/spl-token@0.1.8", "@solana/spl-token@^0.1.6", "@solana/spl-token@^0.1.8": - version "0.1.8" - resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.1.8.tgz#f06e746341ef8d04165e21fc7f555492a2a0faa6" - integrity sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ== - dependencies: - "@babel/runtime" "^7.10.5" - "@solana/web3.js" "^1.21.0" - bn.js "^5.1.0" - buffer "6.0.3" - buffer-layout "^1.2.0" - dotenv "10.0.0" - -"@solana/spl-token@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.7.tgz#6f027f9ad8e841f792c32e50920d9d2e714fc8da" - integrity sha512-bKGxWTtIw6VDdCBngjtsGlKGLSmiu/8ghSt/IOYJV24BsymRbgq7r12GToeetpxmPaZYLddKwAz7+EwprLfkfg== - dependencies: - "@solana/buffer-layout" "^4.0.0" - "@solana/buffer-layout-utils" "^0.2.0" - buffer "^6.0.3" - -"@solana/spl-token@0.3.8": - version "0.3.8" - resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.8.tgz#8e9515ea876e40a4cc1040af865f61fc51d27edf" - integrity sha512-ogwGDcunP9Lkj+9CODOWMiVJEdRtqHAtX2rWF62KxnnSWtMZtV9rDhTrZFshiyJmxDnRL/1nKE1yJHg4jjs3gg== - dependencies: - "@solana/buffer-layout" "^4.0.0" - "@solana/buffer-layout-utils" "^0.2.0" - buffer "^6.0.3" - -"@solana/spl-token@^0.2.0", "spl2@npm:@solana/spl-token@^0.2.0": - name spl2 - version "0.2.0" - resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.2.0.tgz#329bb6babb5de0f9c40035ddb1657f01a8347acd" - integrity sha512-RWcn31OXtdqIxmkzQfB2R+WpsJOVS6rKuvpxJFjvik2LyODd+WN58ZP3Rpjpro03fscGAkzlFuP3r42doRJgyQ== - dependencies: - "@solana/buffer-layout" "^4.0.0" - "@solana/buffer-layout-utils" "^0.2.0" - "@solana/web3.js" "^1.32.0" - start-server-and-test "^1.14.0" - -"@solana/spl-token@^0.3.6", "@solana/spl-token@^0.3.7", "@solana/spl-token@^0.3.8": +"@solana/spl-token@^0.3.7", "@solana/spl-token@^0.3.8": version "0.3.11" resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.11.tgz#cdc10f9472b29b39c8983c92592cadd06627fb9a" integrity sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ== @@ -1762,7 +932,7 @@ dependencies: buffer "^6.0.3" -"@solana/wallet-adapter-base@^0.9.2", "@solana/wallet-adapter-base@^0.9.20": +"@solana/wallet-adapter-base@^0.9.2": version "0.9.23" resolved "https://registry.yarnpkg.com/@solana/wallet-adapter-base/-/wallet-adapter-base-0.9.23.tgz#3b17c28afd44e173f44f658bf9700fd637e12a11" integrity sha512-apqMuYwFp1jFi55NxDfvXUX2x1T0Zh07MxhZ/nCCTGys5raSfYUh82zen2BLv8BSDj/JxZ2P/s7jrQZGrX8uAw== @@ -1780,28 +950,7 @@ "@wallet-standard/base" "^1.0.1" "@wallet-standard/features" "^1.0.3" -"@solana/web3.js@1.66.2": - version "1.66.2" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.66.2.tgz#80b43c5868b846124fe3ebac7d3943930c3fa60c" - integrity sha512-RyaHMR2jGmaesnYP045VLeBGfR/gAW3cvZHzMFGg7bkO+WOYOYp1nEllf0/la4U4qsYGKCsO9eEevR5fhHiVHg== - dependencies: - "@babel/runtime" "^7.12.5" - "@noble/ed25519" "^1.7.0" - "@noble/hashes" "^1.1.2" - "@noble/secp256k1" "^1.6.3" - "@solana/buffer-layout" "^4.0.0" - bigint-buffer "^1.1.5" - bn.js "^5.0.0" - borsh "^0.7.0" - bs58 "^4.0.1" - buffer "6.0.1" - fast-stable-stringify "^1.0.0" - jayson "^3.4.4" - node-fetch "2" - rpc-websockets "^7.5.0" - superstruct "^0.14.2" - -"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.30.2", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.33.0", "@solana/web3.js@^1.35.1", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.37.0", "@solana/web3.js@^1.42.0", "@solana/web3.js@^1.43.5", "@solana/web3.js@^1.52.0", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.63.1", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.70.3", "@solana/web3.js@^1.71.0", "@solana/web3.js@^1.77.3", "@solana/web3.js@^1.78.3", "@solana/web3.js@^1.87.6", "@solana/web3.js@^1.90.0": +"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.90.0": version "1.91.0" resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.91.0.tgz#a763b0fcca0fa005adce3d02f3a4b6d1b84eccb7" integrity sha512-iqOL9RjNra0TM9BbQWxBRUcZUiNmCJJO+vXLp0GiELUJhbNAoE/K6OV6s+gNEsC13dslvKtfA4mmzRnZNWXtIQ== @@ -1843,123 +992,12 @@ rpc-websockets "^7.5.1" superstruct "^0.14.2" -"@solana/web3.js@~1.72.0": - version "1.72.0" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.72.0.tgz#8d54de6887bc885c78a4a2bebe891c349fbb029e" - integrity sha512-xMoCk0y/GpiQhHbRjMcrd5NpmkwhAA0c01id7lrr6nhNdz6Uc/CywPdBeZw3Qz6BVZ/qlUoerpKPWeiXqMUjwA== - dependencies: - "@babel/runtime" "^7.12.5" - "@noble/ed25519" "^1.7.0" - "@noble/hashes" "^1.1.2" - "@noble/secp256k1" "^1.6.3" - "@solana/buffer-layout" "^4.0.0" - agentkeepalive "^4.2.1" - bigint-buffer "^1.1.5" - bn.js "^5.0.0" - borsh "^0.7.0" - bs58 "^4.0.1" - buffer "6.0.1" - fast-stable-stringify "^1.0.0" - jayson "^3.4.4" - node-fetch "2" - rpc-websockets "^7.5.0" - superstruct "^0.14.2" - -"@sqds/multisig@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sqds/multisig/-/multisig-2.0.0.tgz#ac9c842c47b828dc2994813e3f7858efb317b886" - integrity sha512-tiZB1cOi/6Xzolqq/xBAtjoXnmto9tH3qGkbTL9j1SsRFVkIdIZaP2qkzh2ocgH3vYb8e1xsfA4hHjiVJVHLXA== - dependencies: - "@metaplex-foundation/beet" "0.7.1" - "@metaplex-foundation/beet-solana" "0.4.0" - "@metaplex-foundation/cusper" "^0.0.2" - "@solana/spl-token" "^0.3.6" - "@solana/web3.js" "^1.70.3" - "@types/bn.js" "^5.1.1" - assert "^2.0.0" - bn.js "^5.2.1" - buffer "6.0.3" - invariant "2.2.4" - "@supercharge/promise-pool@^2.1.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@supercharge/promise-pool/-/promise-pool-2.4.0.tgz#6050eea8c2d7f92ddd4ddc582ee328b15c034ad3" integrity sha512-O9CMipBlq5OObdt1uKJGIzm9cdjpPWfj+a+Zw9EgWKxaMNHKC7EU7X9taj3H0EGQNLOSq2jAcOa3EzxlfHsD6w== -"@switchboard-xyz/common@^2.3.6": - version "2.3.17" - resolved "https://registry.yarnpkg.com/@switchboard-xyz/common/-/common-2.3.17.tgz#4da631540cf189909df394cb3aa54ca32241d9ba" - integrity sha512-gg3nLz1Esb1pMt1mhhEkAYNFsvlYEpH+n3mNyguaGPIUF7AFnpzj9xU3aKPQqT2MeJWg+EmU32WFOdLwTK7X7A== - dependencies: - big.js "^6.2.1" - bn.js "^5.2.1" - bs58 "^5.0.0" - cron-validator "^1.3.1" - decimal.js "^10.4.3" - lodash "^4.17.21" - protobufjs "^7.2.4" - yaml "^2.2.1" - -"@switchboard-xyz/sbv2-lite@^0.1.6": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@switchboard-xyz/sbv2-lite/-/sbv2-lite-0.1.6.tgz#dc3fbb5b3b028dbd3c688b991bcc48a670131ddb" - integrity sha512-yNNBBPpqefrf6QaUw7pKj1MYOtITaH5lqpGKdSMOqzGmtTOCBPI9P9Hz/ZfQEzbuRIUws1aNEazxYzitBo1q7Q== - dependencies: - "@project-serum/anchor" "^0.24.2" - big.js "^6.1.1" - -"@switchboard-xyz/solana.js@^2.1.10": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@switchboard-xyz/solana.js/-/solana.js-2.8.4.tgz#383ee63d17040199acf36a88802a65df512ed9c3" - integrity sha512-kiFLAXKfNdAEUWZSdXuCCgs2ISKRJL8dayweKq5KIvQfxOmNEqENuaWwEaWP+7MiVUZotbF3oNG1xQNlKDcXLg== - dependencies: - "@coral-xyz/anchor" "^0.28.0" - "@coral-xyz/borsh" "^0.28.0" - "@solana/spl-token" "^0.3.8" - "@solana/web3.js" "^1.78.3" - "@switchboard-xyz/common" "^2.3.6" - cron-validator "^1.3.1" - dotenv "^16.3.1" - lodash "^4.17.21" - -"@switchboard-xyz/switchboard-api@^0.2.150": - version "0.2.201" - resolved "https://registry.yarnpkg.com/@switchboard-xyz/switchboard-api/-/switchboard-api-0.2.201.tgz#d082206d521d24dbcdeb06a77e6637a56ab883eb" - integrity sha512-hlxgeYmO6dbOEcmQzT1SqRxdiCFyVOMpyW4HFPgmPKT0+wSVkjsLc+BKkMGYPDaO0sWMLTJrj0FGhhTsrqd8Mg== - dependencies: - "@solana/web3.js" "^1.17.0" - form-data "^4.0.0" - protobufjs "^6.10.2" - rpc-websockets "^7.4.12" - typedoc "^0.22.15" - ws "^7.4.6" - -"@switchboard-xyz/switchboard-v2@^0.0.67": - version "0.0.67" - resolved "https://registry.yarnpkg.com/@switchboard-xyz/switchboard-v2/-/switchboard-v2-0.0.67.tgz#2fb1f2f18266f6963cca3ff31da1196dc3172c8d" - integrity sha512-6yFFCSrc7MGLEu2bfRt4dzcYfWyBF8JoA2N/hTZUDqAw9xaEgSSR7laTvHAjVy4m4MVwu7DLadpCivLy/QEPLA== - dependencies: - "@project-serum/anchor" "^0.22.0" - "@solana/spl-token" "^0.1.8" - "@solana/web3.js" "^1.33.0" - "@switchboard-xyz/switchboard-api" "^0.2.150" - assert "^2.0.0" - big.js "^6.1.1" - bs58 "^4.0.1" - buffer-layout "^1.2.0" - chan "^0.6.1" - crypto-js "^4.0.0" - long "^4.0.0" - protobufjs "^6.10.2" - ts-proto "^1.79.0" - typescript "^4.2.4" - -"@types/big.js@^6.1.6": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.2.tgz#69422ec9ef59df1330ccfde2106d9e1159a083c3" - integrity sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA== - -"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1": +"@types/bn.js@^5.1.0": version "5.1.5" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== @@ -1983,17 +1021,12 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/long@^4.0.1": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" - integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== - -"@types/mocha@^9.0.0": - version "9.1.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" - integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== +"@types/mocha@^10.0.7": + version "10.0.7" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.7.tgz#4c620090f28ca7f905a94b706f74dc5b57b44f2f" + integrity sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw== -"@types/node@*", "@types/node@>=13.7.0", "@types/node@^20.8.6": +"@types/node@*", "@types/node@^20.8.6": version "20.11.25" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.25.tgz#0f50d62f274e54dd7a49f7704cc16bfbcccaf49f" integrity sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw== @@ -2010,18 +1043,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== -"@types/promise-retry@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@types/promise-retry/-/promise-retry-1.1.6.tgz#3c48826d8a27f68f9d4900fc7448f08a1532db44" - integrity sha512-EC1+OMXV0PZb0pf+cmyxc43MEP2CDumZe4AfuxWboxxEixztIebknpJPZAX5XlodGF1OY+C1E/RAeNGzxf+bJA== - dependencies: - "@types/retry" "*" - -"@types/retry@*", "@types/retry@^0.12.5": - version "0.12.5" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.5.tgz#f090ff4bd8d2e5b940ff270ab39fd5ca1834a07e" - integrity sha512-3xSjTp3v03X/lSQLkczaN9UIEwJMoMCA1+Nb5HfbJEQWogdeQIyVtTvxPXDQjZ5zws8rFQfVfRdz03ARihPJgw== - "@types/ws@^7.4.4": version "7.4.7" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" @@ -2029,17 +1050,6 @@ dependencies: "@types/node" "*" -"@ubeswap/token-math@^5.1.6", "@ubeswap/token-math@^5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@ubeswap/token-math/-/token-math-5.2.1.tgz#66e70ba8d65b5fdb1b7459332fbdad4ddec32a64" - integrity sha512-wkIKDKIl6rml4CVK3fvjjLVk55Z8qEYTgjxZx7MnrTwECazyhiDuekb9WAaDPXcW5QNffCu8uv4Ba8wE96CJsg== - dependencies: - "@types/big.js" "^6.1.6" - big.js "^6.2.1" - decimal.js-light "^2.5.1" - tiny-invariant "^1.2.0" - tslib "^2.4.0" - "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -2070,14 +1080,7 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agentkeepalive@^4.2.1, agentkeepalive@^4.5.0: +agentkeepalive@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== @@ -2134,11 +1137,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansicolors@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== - anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -2176,11 +1174,6 @@ arconnect@^0.4.2: dependencies: arweave "^1.10.13" -arg@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" - integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== - argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -2218,17 +1211,6 @@ asn1.js@^5.4.1: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -assert@^2.0.0, assert@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" - integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== - dependencies: - call-bind "^1.0.2" - is-nan "^1.3.2" - object-is "^1.1.5" - object.assign "^4.1.4" - util "^0.12.5" - assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -2241,18 +1223,6 @@ async-retry@^1.3.3: dependencies: retry "0.13.1" -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -available-typed-arrays@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" - integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== - dependencies: - possible-typed-array-names "^1.0.0" - "avsc@https://github.com/Irys-xyz/avsc#csp-fixes": version "5.4.7" resolved "https://github.com/Irys-xyz/avsc#a730cc8018b79e114b6a3381bbb57760a24c6cef" @@ -2271,23 +1241,6 @@ axios@^0.25.0: dependencies: follow-redirects "^1.14.7" -axios@^0.27.2: - version "0.27.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" - integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== - dependencies: - follow-redirects "^1.14.9" - form-data "^4.0.0" - -axios@^1.2.1: - version "1.6.7" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" - integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== - dependencies: - follow-redirects "^1.15.4" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -2300,11 +1253,6 @@ base-x@^3.0.2: dependencies: safe-buffer "^5.0.1" -base-x@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" - integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== - base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -2320,11 +1268,6 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== -big.js@^6.1.1, big.js@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" - integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== - bigint-buffer@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" @@ -2332,24 +1275,11 @@ bigint-buffer@^1.1.5: dependencies: bindings "^1.3.0" -bignumber.js@^9.0.0, bignumber.js@^9.0.1, bignumber.js@^9.0.2, bignumber.js@^9.1.1: +bignumber.js@^9.0.0, bignumber.js@^9.0.1, bignumber.js@^9.0.2: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== -binance-api-node@^0.12.0: - version "0.12.7" - resolved "https://registry.yarnpkg.com/binance-api-node/-/binance-api-node-0.12.7.tgz#bce64742d5dc5a9398df3cbd861c486b4d4df075" - integrity sha512-hEIPaZg1YwZClOznAJo5Zb1JyxsqdYjT8twG48rhOwhbNVrLJRxkeGj+PTa881wFXOtyOtyrXsDytsEcI2EUHA== - dependencies: - https-proxy-agent "^5.0.0" - isomorphic-fetch "^3.0.0" - isomorphic-ws "^4.0.1" - json-bigint "^1.0.0" - lodash.zipobject "^4.1.3" - reconnecting-websocket "^4.2.0" - ws "^7.2.0" - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -2389,33 +1319,21 @@ bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -bluebird@3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn-sqrt@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/bn-sqrt/-/bn-sqrt-1.0.0.tgz#aac3fcb56a359850d8339d3925213ac27c22b782" - integrity sha512-XdCMQ7tfEF/f7nrQgnrJ+DLQBwQzSQyPOKIXdUOTcGEvsRKBcIsdfORp7B5H8DWo8FOzZ4+a2TjSZzaqKgzicg== - dependencies: - bn.js "^5.2.0" - bn.js@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== -bn.js@5.2.1, bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - bn.js@^4.0.0, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== +bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + borsh@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.6.0.tgz#a7c9eeca6a31ca9e0607cb49f329cb659eb791e1" @@ -2442,13 +1360,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2473,32 +1384,17 @@ bs58@^4.0.0, bs58@^4.0.1: dependencies: base-x "^3.0.2" -bs58@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" - integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== - dependencies: - base-x "^4.0.0" - buffer-from@^1.0.0, buffer-from@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer-layout@1.2.2, buffer-layout@^1.2.0, buffer-layout@^1.2.1, buffer-layout@^1.2.2: +buffer-layout@^1.2.0, buffer-layout@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== -buffer@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" - integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -buffer@6.0.3, buffer@^6.0.1, buffer@^6.0.2, buffer@^6.0.3, buffer@~6.0.3: +buffer@6.0.3, buffer@^6.0.2, buffer@^6.0.3, buffer@~6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -2514,29 +1410,13 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -bufferutil@^4.0.1, bufferutil@^4.0.6: +bufferutil@^4.0.1: version "4.0.8" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.8.tgz#1de6a71092d65d7766c4d8a522b261a6e787e8ea" integrity sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw== dependencies: node-gyp-build "^4.3.0" -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - set-function-length "^1.2.1" - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - camelcase@^6.0.0, camelcase@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" @@ -2547,12 +1427,7 @@ capability@^0.2.5: resolved "https://registry.yarnpkg.com/capability/-/capability-0.2.5.tgz#51ad87353f1936ffd77f2f21c74633a4dea88801" integrity sha512-rsJZYVCgXd08sPqwmaIqjAd5SUTfonV0z/gDJ8D6cN8wQphky1kkAYEqQ+hmDxTw7UihvBfjUVUSY+DBEe44jg== -case-anything@^2.1.13: - version "2.1.13" - resolved "https://registry.yarnpkg.com/case-anything/-/case-anything-2.1.13.tgz#0cdc16278cb29a7fcdeb072400da3f342ba329e9" - integrity sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng== - -chai@^4.3.4, chai@^4.3.7: +chai@^4.3.4: version "4.4.1" resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== @@ -2573,11 +1448,6 @@ chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" -chan@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/chan/-/chan-0.6.1.tgz#ec0ad132e5bc62c27ef10ccbfc4d8dcd8ca00640" - integrity sha512-/TdBP2UhbBmw7qnqkzo9Mk4rzvwRv4dlNPXFerqWy90T8oBspKagJNZxrDbExKHhx9uXXHjo3f9mHgs9iKO3nQ== - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -2590,11 +1460,6 @@ check-error@^1.0.3: dependencies: get-func-name "^2.0.2" -check-more-types@2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" - integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA== - chokidar@3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -2644,15 +1509,6 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -2670,13 +1526,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - commander@^2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2692,11 +1541,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -crc@^4.1.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/crc/-/crc-4.3.2.tgz#49b7821cbf2cf61dfd079ed93863bbebd5469b9a" - integrity sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A== - create-hash@^1.1.0, create-hash@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -2720,11 +1564,6 @@ create-hmac@1.1.7, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -cron-validator@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/cron-validator/-/cron-validator-1.3.1.tgz#8f2fe430f92140df77f91178ae31fc1e3a48a20e" - integrity sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A== - cross-fetch@3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" @@ -2739,25 +1578,11 @@ cross-fetch@^3.1.5: dependencies: node-fetch "^2.6.12" -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypto-hash@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/crypto-hash/-/crypto-hash-1.3.0.tgz#b402cb08f4529e9f4f09346c3e275942f845e247" integrity sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg== -crypto-js@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" - integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== - csv-generate@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-4.4.0.tgz#007575d825e537d9690e687f82fdf4a745e8c226" @@ -2783,13 +1608,6 @@ csv@^6.0.5: csv-stringify "^6.4.6" stream-transform "^3.3.1" -debug@4, debug@4.3.4, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - debug@4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" @@ -2802,17 +1620,7 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -decimal.js-light@^2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" - integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== - -decimal.js@10.3.1: - version "10.3.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" - integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== - -decimal.js@^10.3.1, decimal.js@^10.4.1, decimal.js@^10.4.3: +decimal.js@^10.4.3: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== @@ -2831,34 +1639,11 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -define-data-property@^1.0.1, define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - -define-properties@^1.1.3, define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - delay@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - depd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -2869,11 +1654,6 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== - diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" @@ -2892,28 +1672,6 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -dotenv@10.0.0, dotenv@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== - -dotenv@^16.0.1, dotenv@^16.0.3, dotenv@^16.3.1: - version "16.4.5" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" - integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== - -dprint-node@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/dprint-node/-/dprint-node-1.0.8.tgz#a02470722d8208a7d7eb3704328afda1d6758625" - integrity sha512-iVKnUtYfGrYcW1ZAlfR/F59cUVL8QIhWoBJoSjkkdua/dkWIgjZfiLMeTjiB06X0ZLkQ0M2C1VbUj/CxkIf1zg== - dependencies: - detect-libc "^1.0.3" - -duplexer@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - elliptic@6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -2945,11 +1703,6 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - error-polyfill@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/error-polyfill/-/error-polyfill-0.1.3.tgz#df848b61ad8834f7a5db69a70b9913df86721d15" @@ -2959,18 +1712,6 @@ error-polyfill@^0.1.3: o3 "^1.0.3" u3 "^0.1.1" -es-define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" - integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== - dependencies: - get-intrinsic "^1.2.4" - -es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" @@ -3091,39 +1832,11 @@ ethers@^5.5.1: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -event-stream@=3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" - integrity sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g== - dependencies: - duplexer "~0.1.1" - from "~0" - map-stream "~0.1.0" - pause-stream "0.0.11" - split "0.3" - stream-combiner "~0.0.4" - through "~2.3.1" - eventemitter3@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -execa@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - exponential-backoff@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" @@ -3175,44 +1888,16 @@ find-up@5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -find@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/find/-/find-0.3.0.tgz#4082e8fc8d8320f1a382b5e4f521b9bc50775cb8" - integrity sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw== - dependencies: - traverse-chain "~0.1.0" - flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -follow-redirects@^1.14.0, follow-redirects@^1.14.7, follow-redirects@^1.14.9, follow-redirects@^1.15.4: +follow-redirects@^1.14.0, follow-redirects@^1.14.7: version "1.15.5" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -from@~0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" - integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g== - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -3223,11 +1908,6 @@ fsevents@~2.3.2, fsevents@~2.3.3: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -3238,22 +1918,6 @@ get-func-name@^2.0.1, get-func-name@^2.0.2: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== -get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" - integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - get-tsconfig@^4.7.2: version "4.7.3" resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.3.tgz#0498163d98f7b58484dd4906999c0c9d5f103f83" @@ -3280,24 +1944,6 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.3: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -3308,30 +1954,6 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-proto@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" - integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== - -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0, has-tostringtag@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - hash-base@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" @@ -3349,13 +1971,6 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hasown@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.1.tgz#26f48f039de2c0f8d3356c223fb8d50253519faa" - integrity sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA== - dependencies: - function-bind "^1.1.2" - he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -3386,19 +2001,6 @@ http-errors@^1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.1" -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -3452,21 +2054,6 @@ inquirer@^8.2.0: through "^2.3.6" wrap-ansi "^6.0.1" -invariant@2.2.4, invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -3474,11 +2061,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-callable@^1.1.3: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -3489,13 +2071,6 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -3508,14 +2083,6 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== -is-nan@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" - integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -3526,18 +2093,6 @@ is-plain-obj@^2.1.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-typed-array@^1.1.3: - version "1.1.13" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" - integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== - dependencies: - which-typed-array "^1.1.14" - is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" @@ -3548,38 +2103,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isomorphic-fetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" - integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== - dependencies: - node-fetch "^2.6.1" - whatwg-fetch "^3.4.1" - isomorphic-ws@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== -jayson@^3.4.4: - version "3.7.0" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" - integrity sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ== - dependencies: - "@types/connect" "^3.4.33" - "@types/node" "^12.12.54" - "@types/ws" "^7.4.4" - JSONStream "^1.3.5" - commander "^2.20.3" - delay "^5.0.0" - es6-promisify "^5.0.0" - eyes "^0.1.8" - isomorphic-ws "^4.0.1" - json-stringify-safe "^5.0.1" - lodash "^4.17.20" - uuid "^8.3.2" - ws "^7.4.5" - jayson@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.0.tgz#60dc946a85197317f2b1439d672a8b0a99cea2f9" @@ -3598,17 +2126,6 @@ jayson@^4.1.0: uuid "^8.3.2" ws "^7.4.5" -joi@^17.7.0: - version "17.12.2" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.12.2.tgz#283a664dabb80c7e52943c557aab82faea09f521" - integrity sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw== - dependencies: - "@hapi/hoek" "^9.3.0" - "@hapi/topo" "^5.1.0" - "@sideway/address" "^4.1.5" - "@sideway/formula" "^3.0.1" - "@sideway/pinpoint" "^2.0.0" - js-sha256@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" @@ -3624,11 +2141,6 @@ js-sha512@^0.8.0: resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.8.0.tgz#dd22db8d02756faccf19f218e3ed61ec8249f7d4" integrity sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ== -"js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - js-yaml@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" @@ -3636,11 +2148,6 @@ js-yaml@4.1.0: dependencies: argparse "^2.0.1" -jsbi@4.3.0, jsbi@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-4.3.0.tgz#b54ee074fb6fcbc00619559305c8f7e912b04741" - integrity sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g== - json-bigint@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" @@ -3660,11 +2167,6 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" -jsonc-parser@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" - integrity sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA== - jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -3679,16 +2181,6 @@ keccak@^3.0.2: node-gyp-build "^4.2.0" readable-stream "^3.6.0" -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -lazy-ass@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" - integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== - locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -3696,22 +2188,7 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - -lodash.mapvalues@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" - integrity sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ== - -lodash.zipobject@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/lodash.zipobject/-/lodash.zipobject-4.1.3.tgz#b399f5aba8ff62a746f6979bf20b214f964dbef8" - integrity sha512-A9SzX4hMKWS25MyalwcOnNoplyHbkNVsjidhTp8ru0Sj23wY9GWBKS8gAIGDSAqeWjIjvE4KBEl24XXAs+v4wQ== - -lodash@^4.17.20, lodash@^4.17.21: +lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3724,23 +2201,6 @@ log-symbols@4.1.0, log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -long@^5.0.0, long@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" - integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - loupe@^2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" @@ -3755,26 +2215,11 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lunr@^2.3.9: - version "2.3.9" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" - integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== - make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -map-stream@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" - integrity sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g== - -marked@^4.0.16: - version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" - integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== - md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -3784,17 +2229,12 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.34: +mime-types@^2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -3830,14 +2270,7 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1, minimatch@^5.1.0: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.7: +minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -3961,52 +2394,28 @@ node-addon-api@^2.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== -node-fetch@2, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7, node-fetch@^2.7.0: +node-fetch@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7, node-fetch@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" -node-fetch@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: version "4.8.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.0.tgz#3fee9c1731df4581a3f9ead74664369ff00d26dd" integrity sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og== -node-kraken-api@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/node-kraken-api/-/node-kraken-api-2.2.2.tgz#28bf56eec1f0ffe7e784b2ffa29b360ed98b0e4c" - integrity sha512-f+BZpgT1gD9705hlsRDDGj9m96Psb0Gxu3Td/P2fs0/gFy58YQONrTPiqfYzOBxvpmYnuAMxCRuRmdmkw04eRw== - dependencies: - crc "^4.1.0" - ts-ev "^0.4.0" - ws "^8.5.0" - optionalDependencies: - bufferutil "^4.0.6" - utf-8-validate "^5.0.9" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -numeral@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" - integrity sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA== - o3@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/o3/-/o3-1.0.3.tgz#192ce877a882dfa6751f0412a865fafb2da1dac0" @@ -4014,29 +2423,6 @@ o3@^1.0.3: dependencies: capability "^0.2.5" -object-is@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" - integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.4: - version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" - integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - has-symbols "^1.0.3" - object-keys "^1.1.1" - once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -4044,7 +2430,7 @@ once@^1.3.0, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.0, onetime@^5.1.2: +onetime@^5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -4100,23 +2486,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - pathval@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -pause-stream@0.0.11: - version "0.0.11" - resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" - integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A== - dependencies: - through "~2.3" - pbkdf2@^3.0.9: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" @@ -4133,11 +2507,6 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -possible-typed-array-names@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" - integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== - prettier@^2.6.2: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" @@ -4148,87 +2517,6 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== -promise-retry@2.0.1, promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - -protobufjs@^6.10.2: - version "6.11.4" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" - integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" ">=13.7.0" - long "^4.0.0" - -protobufjs@^7.2.4: - version "7.2.6" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.6.tgz#4a0ccd79eb292717aacf07530a07e0ed20278215" - integrity sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/node" ">=13.7.0" - long "^5.0.0" - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -ps-tree@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd" - integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA== - dependencies: - event-stream "=3.3.4" - -psyfi-euros-test@0.0.2-rc.5: - version "0.0.2-rc.5" - resolved "https://registry.yarnpkg.com/psyfi-euros-test/-/psyfi-euros-test-0.0.2-rc.5.tgz#7b0db21ecbe7bac490de764f022feb01a9b501d9" - integrity sha512-bTeM4wrS9x6+9Z69uN9wWELTc7MyM3KpNdntp9T3uUkQwnN9Pygwjd/a+Mf/x7PbmAHKMabY7tLbSVxpifVt4g== - dependencies: - "@metaplex-foundation/mpl-token-metadata" "2.2.4" - "@project-serum/anchor" "0.23.0" - "@project-serum/common" "^0.0.1-beta.3" - "@project-serum/serum" "^0.13.61" - "@solana/spl-token" "0.1.8" - "@solana/web3.js" "^1.35.1" - psystake-test "0.0.1-rc.8" - -psystake-test@0.0.1-rc.8: - version "0.0.1-rc.8" - resolved "https://registry.yarnpkg.com/psystake-test/-/psystake-test-0.0.1-rc.8.tgz#67ce3c7546c47ac44bd213997fadcee346efe440" - integrity sha512-wng85jJDM8SwVeH/6fUMKBxHiVPl6SwFm6Y1j3fNmhqEINwu1L+kShO3YCIhPN7oK2tox7Fb7tUrXdbk5HQ54g== - dependencies: - "@project-serum/anchor" "^0.23.0" - "@project-serum/common" "^0.0.1-beta.3" - "@project-serum/serum" "^0.13.61" - "@solana/spl-token" "^0.1.8" - "@solana/web3.js" "^1.35.1" - randombytes@^2.0.1, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -4252,11 +2540,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -reconnecting-websocket@^4.2.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783" - integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng== - regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" @@ -4280,16 +2563,11 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -retry@0.13.1, retry@^0.13.1: +retry@0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -4298,7 +2576,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rpc-websockets@^7.4.12, rpc-websockets@^7.5.0, rpc-websockets@^7.5.1: +rpc-websockets@^7.5.1: version "7.9.0" resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.9.0.tgz#a3938e16d6f134a3999fdfac422a503731bf8973" integrity sha512-DwKewQz1IUA5wfLvgM8wDpPRcr+nWSxuFxx5CbrI2z/MyyZ4nXLM86TvIA+cI1ZAdqC8JIBR1mZR55dzaLU+Hw== @@ -4316,7 +2594,7 @@ run-async@^2.4.0: resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== -rxjs@^7.5.5, rxjs@^7.8.0: +rxjs@^7.5.5: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== @@ -4354,18 +2632,6 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" -set-function-length@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -4379,28 +2645,7 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shiki@^0.10.1: - version "0.10.1" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14" - integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng== - dependencies: - jsonc-parser "^3.0.0" - vscode-oniguruma "^1.6.1" - vscode-textmate "5.2.0" - -signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.2: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -4465,58 +2710,25 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -spl-token-bankrun@0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/spl-token-bankrun/-/spl-token-bankrun-0.2.5.tgz#0a026be083a19300d593c41034c9685968dd50d3" - integrity sha512-1Tb0bksg5Q3r48LInbQh+uBYhekrz1OWP1XVd4zMj7FAwdQzqQ1puJHd6vJhCuIbB8Vr6CQSGf5Ke716EH0khw== +spl-token-bankrun@0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/spl-token-bankrun/-/spl-token-bankrun-0.2.6.tgz#c820c2f8777d64966b58eb37556f0add4eeeb16d" + integrity sha512-tD4qpg7s4bagnjlWiDKaY158TcYq9odecM2rwqlKFjKzeVyjYnyoQq54BxwofghWD9Q+gOR/0BbWYK2KW2VbJQ== dependencies: "@solana/spl-token" "^0.3.8" solana-bankrun "^0.3.0" -split@0.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" - integrity sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA== - dependencies: - through "2" - -start-server-and-test@^1.14.0: - version "1.15.5" - resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-1.15.5.tgz#5c9103bd87c06678fc62658fbe97d09501714011" - integrity sha512-o3EmkX0++GV+qsvIJ/OKWm3w91fD8uS/bPQVPrh/7loaxkpXSuAIHdnmN/P/regQK9eNAK76aBJcHt+OSTk+nA== - dependencies: - arg "^5.0.2" - bluebird "3.7.2" - check-more-types "2.24.0" - debug "4.3.4" - execa "5.1.1" - lazy-ass "1.6.0" - ps-tree "1.2.0" - wait-on "7.0.1" - "statuses@>= 1.5.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-combiner@~0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" - integrity sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw== - dependencies: - duplexer "~0.1.1" - stream-transform@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/stream-transform/-/stream-transform-3.3.1.tgz#f8bb6a811e505056b6a215c466e4c2760347189f" integrity sha512-BL8pv9QL8Ikd11oZwlRDp1qYMhGR0i50zI9ltoijKGc4ubQWal/Rc4p6SYJp1TBOGpE0uAGchwbxOZ1ycwTuqQ== -strict-event-emitter-types@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz#05e15549cb4da1694478a53543e4e2f4abcf277f" - integrity sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA== - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4544,24 +2756,11 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - strip-json-comments@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -superstruct@0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.8.3.tgz#fb4d8901aca3bf9f79afab1bbab7a7f335cc4ef2" - integrity sha512-LbtbFpktW1FcwxVIJlxdk7bCyBq/GzOx2FSFLRLTUhWIA1gHkYPIl3aXRG5mBdGZtnPNT6t+4eEcLDCMOuBHww== - dependencies: - kind-of "^6.0.2" - tiny-invariant "^1.0.6" - superstruct@^0.14.2: version "0.14.2" resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" @@ -4572,11 +2771,6 @@ superstruct@^0.15.4: resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab" integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== -superstruct@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.3.tgz#de626a5b49c6641ff4d37da3c7598e7a87697046" - integrity sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg== - supports-color@8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" @@ -4596,16 +2790,11 @@ text-encoding-utf-8@^1.0.2: resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== -through@2, "through@>=2.2.7 <3", through@^2.3.6, through@~2.3, through@~2.3.1: +"through@>=2.2.7 <3", through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -tiny-invariant@^1.0.6, tiny-invariant@^1.1.0, tiny-invariant@^1.2.0, tiny-invariant@^1.3.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" - integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== - tmp-promise@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" @@ -4632,11 +2821,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toformat@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/toformat/-/toformat-2.0.0.tgz#7a043fd2dfbe9021a4e36e508835ba32056739d8" - integrity sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ== - toidentifier@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" @@ -4652,16 +2836,6 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -traverse-chain@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1" - integrity sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg== - -ts-ev@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/ts-ev/-/ts-ev-0.4.0.tgz#b30bbab35bd57516efba7ab89b6417424a1ebf0e" - integrity sha512-rLX6QdkC1/jA9sS4y9/DxHABTcOussp33J90h+TxHmya9CWvbGc9uLqdM4c/N4pNRmSdtq9zqhz7sB9KcN1NFQ== - ts-mocha@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" @@ -4685,31 +2859,6 @@ ts-node@7.0.1: source-map-support "^0.5.6" yn "^2.0.0" -ts-poet@^6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/ts-poet/-/ts-poet-6.7.0.tgz#6b2ff3b7b0c70ea650d6d570dfe6899f73fb3c38" - integrity sha512-A0wvFtpkTCWPw7ftTIwbEH+L+7ul4CU0x3jXKQ+kCnmEQIAOwhpUaBmcAYKxZCxHae9/MUl4LbyTqw25BpzW5Q== - dependencies: - dprint-node "^1.0.8" - -ts-proto-descriptors@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/ts-proto-descriptors/-/ts-proto-descriptors-1.15.0.tgz#e859e3a2887da2d954c552524719b80bdb6ee355" - integrity sha512-TYyJ7+H+7Jsqawdv+mfsEpZPTIj9siDHS6EMCzG/z3b/PZiphsX+mWtqFfFVe5/N0Th6V3elK9lQqjnrgTOfrg== - dependencies: - long "^5.2.3" - protobufjs "^7.2.4" - -ts-proto@^1.79.0: - version "1.168.0" - resolved "https://registry.yarnpkg.com/ts-proto/-/ts-proto-1.168.0.tgz#049895ec546bf729dd5d927866aa967e1fb96257" - integrity sha512-3ae1eXY3VCmhIvM/8Q/q4/3bJrdftmtY+5GwrSkhZh+UnHpI1l5rYu0mm1V75qiQJcdAXRc5m7gfnYbdnuQl5g== - dependencies: - case-anything "^2.1.13" - protobufjs "^7.2.4" - ts-poet "^6.7.0" - ts-proto-descriptors "1.15.0" - tsconfig-paths@^3.5.0: version "3.15.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" @@ -4720,7 +2869,7 @@ tsconfig-paths@^3.5.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.6.2: +tslib@^2.0.3, tslib@^2.1.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -4750,18 +2899,7 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typedoc@^0.22.15: - version "0.22.18" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.18.tgz#1d000c33b66b88fd8cdfea14a26113a83b7e6591" - integrity sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA== - dependencies: - glob "^8.0.3" - lunr "^2.3.9" - marked "^4.0.16" - minimatch "^5.1.0" - shiki "^0.10.1" - -typescript@^4.2.4, typescript@^4.3.5: +typescript@^4.3.5: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== @@ -4776,7 +2914,7 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -utf-8-validate@^5.0.2, utf-8-validate@^5.0.9: +utf-8-validate@^5.0.2: version "5.0.10" resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== @@ -4788,17 +2926,6 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util@^0.12.5: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" @@ -4809,27 +2936,6 @@ vlq@^2.0.4: resolved "https://registry.yarnpkg.com/vlq/-/vlq-2.0.4.tgz#6057b85729245b9829e3cc7755f95b228d4fe041" integrity sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA== -vscode-oniguruma@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" - integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== - -vscode-textmate@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" - integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== - -wait-on@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-7.0.1.tgz#5cff9f8427e94f4deacbc2762e6b0a489b19eae9" - integrity sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog== - dependencies: - axios "^0.27.2" - joi "^17.7.0" - lodash "^4.17.21" - minimist "^1.2.7" - rxjs "^7.8.0" - wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -4842,11 +2948,6 @@ webidl-conversions@^3.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== -whatwg-fetch@^3.4.1: - version "3.6.20" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" - integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -4855,18 +2956,7 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -which-typed-array@^1.1.14, which-typed-array@^1.1.2: - version "1.1.14" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.14.tgz#1f78a111aee1e131ca66164d8bdc3ab062c95a06" - integrity sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg== - dependencies: - available-typed-arrays "^1.0.6" - call-bind "^1.0.5" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.1" - -which@2.0.2, which@^2.0.1: +which@2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -4906,7 +2996,7 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -ws@^7.2.0, ws@^7.4.5, ws@^7.4.6: +ws@^7.4.5: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== @@ -4921,11 +3011,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yaml@^2.2.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.1.tgz#2e57e0b5e995292c25c75d2658f0664765210eed" - integrity sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg== - yargs-parser@20.2.4: version "20.2.4" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" @@ -4936,11 +3021,6 @@ yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - yargs-unparser@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" @@ -4964,19 +3044,6 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.0.1: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - yn@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"