From a63824008d789f38b139c99ecc56063054f41a5a Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Fri, 14 Jan 2022 11:53:46 +0000 Subject: [PATCH 01/88] Governance sdk get token owners (#482) * chore: add jest * feat: add getTokenOwnerRecordsByOwner * feat: add getTokenOwnerRecordsByOwner --- packages/arweave-push/package.json | 9 +- packages/bridge-sdk/package.json | 1 + packages/bridge/package.json | 3 +- packages/common/package.json | 1 + packages/governance-sdk/package.json | 16 +- packages/governance-sdk/src/governance/api.ts | 19 + .../tests/governance/api.test.ts | 21 + packages/governance/package.json | 3 +- packages/lending/package.json | 5 +- packages/metavinci/package.json | 1 + yarn.lock | 1427 ++++++++++++++++- 11 files changed, 1471 insertions(+), 35 deletions(-) create mode 100644 packages/governance-sdk/tests/governance/api.test.ts diff --git a/packages/arweave-push/package.json b/packages/arweave-push/package.json index a806db64..28ac4fb2 100644 --- a/packages/arweave-push/package.json +++ b/packages/arweave-push/package.json @@ -15,18 +15,19 @@ "test": "mocha test/*.test.js --timeout=60000" }, "devDependencies": { + "jest": "^27.4.7", "mocha": "^8.0.0", "proxyquire": "^2.1.0", "sinon": "^10.0.0" }, "dependencies": { "@google-cloud/storage": "^5.0.0", + "@solana/web3.js": "^1.22.0", + "arweave": "1.10.13", "busboy": "^0.3.0", + "coingecko-api": "1.0.10", "escape-html": "^1.0.3", - "arweave": "1.10.13", - "@solana/web3.js": "^1.22.0", "mime-types": "2.1.30", - "node-fetch": "2.6.1", - "coingecko-api": "1.0.10" + "node-fetch": "2.6.1" } } diff --git a/packages/bridge-sdk/package.json b/packages/bridge-sdk/package.json index 9398a730..59e239c5 100644 --- a/packages/bridge-sdk/package.json +++ b/packages/bridge-sdk/package.json @@ -77,6 +77,7 @@ "@types/node": "^12.12.62", "arweave-deploy": "^1.9.1", "gh-pages": "^3.1.0", + "jest": "^27.4.7", "prettier": "^2.1.2" } } diff --git a/packages/bridge/package.json b/packages/bridge/package.json index ea55c651..60dae503 100644 --- a/packages/bridge/package.json +++ b/packages/bridge/package.json @@ -8,10 +8,10 @@ "@oyster/common": "0.0.2", "@project-serum/serum": "^0.13.11", "@react-three/drei": "^3.8.0", + "@solana/bridge-sdk": "0.0.1", "@solana/spl-token": "0.0.13", "@solana/spl-token-registry": "^0.2.0", "@solana/spl-token-swap": "0.1.0", - "@solana/bridge-sdk": "0.0.1", "@solana/web3.js": "^1.22.0", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.5.0", @@ -103,6 +103,7 @@ "@types/node": "^12.12.62", "arweave-deploy": "^1.9.1", "gh-pages": "^3.1.0", + "jest": "^27.4.7", "npm-link-shared": "0.5.6", "prettier": "^2.1.2", "typechain": "^4.0.3" diff --git a/packages/common/package.json b/packages/common/package.json index 921651d4..539c3501 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -61,6 +61,7 @@ "@types/node": "^12.12.62", "arweave-deploy": "^1.9.1", "gh-pages": "^3.1.0", + "jest": "^27.4.7", "less": "4.1.1", "less-watch-compiler": "v1.14.6", "prettier": "^2.1.2" diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 2214268b..5ecfde78 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.8", + "version": "0.0.9", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", @@ -20,7 +20,7 @@ "sideEffects": false, "scripts": { "build": "tsc", - "test": "echo \"Error: run tests from root\" && exit 1", + "test": "jest", "start": "npm-run-all --parallel watch", "watch": "tsc --watch" }, @@ -28,15 +28,21 @@ "url": "https://github.com/solana-labs/oyster/issues" }, "dependencies": { - "superstruct": "^0.15.2", "@solana/web3.js": "^1.22.0", "bignumber.js": "^9.0.1", "bn.js": "^5.1.3", - "bs58": "^4.0.1", "borsh": "^0.3.1", - "moment": "^2.29.1" + "bs58": "^4.0.1", + "moment": "^2.29.1", + "superstruct": "^0.15.2" }, "devDependencies": { + "jest": "^27.4.7", "typescript": "^4.5.4" + }, + "jest": { + "transform": { + "^.+\\.tsx?$": "esbuild-jest" + } } } \ No newline at end of file diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index 5d3716a5..56011458 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -65,6 +65,25 @@ export async function getTokenOwnerRecordForRealm( return getGovernanceAccount(connection, tokenOwnerRecordPk, TokenOwnerRecord); } +/** + * Returns TokenOwnerRecords for given token owner + + * + * @param rpcEndpoint + * @param programId + * @param governingTokenOwner + * @returns + */ +export async function getTokenOwnerRecordsByOwner( + rpcEndpoint: string, + programId: PublicKey, + governingTokenOwner: PublicKey, +) { + return getGovernanceAccounts(rpcEndpoint, programId, TokenOwnerRecord, [ + pubkeyFilter(1 + 32 + 32, governingTokenOwner)!, + ]); +} + // Governances export async function getGovernance( diff --git a/packages/governance-sdk/tests/governance/api.test.ts b/packages/governance-sdk/tests/governance/api.test.ts new file mode 100644 index 00000000..3c3d3e7e --- /dev/null +++ b/packages/governance-sdk/tests/governance/api.test.ts @@ -0,0 +1,21 @@ + + +import { PublicKey } from '@solana/web3.js'; +//import { getTokenOwnerRecordsByOwner } from '../../src' + + +const programId = new PublicKey("GTesTBiEWE32WHXXE2S4XbZvA5CrEc4xs6ZgRe895dP") +const rpcEndpoint = "https://psytrbhymqlkfrhudd.dev.genesysgo.net:8899" + + +test('getTokenOwnerRecordsByOwner', async () => { + // Arrange + const tokenOwnerPk = new PublicKey("EZLvwGdGyeks3jQLWeBbjL1uGeGbqb2MYU4157pDP9ch") + + // Act + //const results = await getTokenOwnerRecordsByOwner(rpcEndpoint, programId, tokenOwnerPk) + + // Assert + + +}); \ No newline at end of file diff --git a/packages/governance/package.json b/packages/governance/package.json index bbcc6557..3548a3d0 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -8,8 +8,8 @@ "@craco/craco": "^5.7.0", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.0.8", "@project-serum/serum": "^0.13.11", + "@solana/spl-governance": "0.0.9", "@solana/spl-token": "0.0.13", "@solana/spl-token-swap": "0.1.0", "@solana/web3.js": "^1.22.0", @@ -95,6 +95,7 @@ "arweave-deploy": "^1.9.1", "eslint-config-react-app": "^6.0.0", "gh-pages": "^3.1.0", + "jest": "^27.4.7", "npm-link-shared": "0.5.6", "prettier": "^2.1.2" }, diff --git a/packages/lending/package.json b/packages/lending/package.json index 41c3fca2..607a5e5e 100644 --- a/packages/lending/package.json +++ b/packages/lending/package.json @@ -84,8 +84,9 @@ "@types/node": "^12.12.62", "arweave-deploy": "^1.9.1", "gh-pages": "^3.1.0", - "prettier": "^2.1.2", - "npm-link-shared": "0.5.6" + "jest": "^27.4.7", + "npm-link-shared": "0.5.6", + "prettier": "^2.1.2" }, "peerDependencies": { "react": "*", diff --git a/packages/metavinci/package.json b/packages/metavinci/package.json index 03e4d9de..3ebec042 100644 --- a/packages/metavinci/package.json +++ b/packages/metavinci/package.json @@ -90,6 +90,7 @@ "@types/node": "^12.12.62", "arweave-deploy": "^1.9.1", "gh-pages": "^3.1.0", + "jest": "^27.4.7", "npm-link-shared": "0.5.6", "prettier": "^2.1.2" }, diff --git a/yarn.lock b/yarn.lock index a9cb87b3..6d21035e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -113,11 +113,23 @@ dependencies: "@babel/highlight" "^7.12.13" +"@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + "@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.12", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.9.0": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1" integrity sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ== +"@babel/compat-data@^7.16.4": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" + integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== + "@babel/core@7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" @@ -161,6 +173,27 @@ semver "^6.3.0" source-map "^0.5.0" +"@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf" + integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.7" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helpers" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + "@babel/generator@^7.13.9", "@babel/generator@^7.4.0", "@babel/generator@^7.9.0": version "7.13.9" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" @@ -170,6 +203,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.16.7", "@babel/generator@^7.16.8", "@babel/generator@^7.7.2": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" + integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== + dependencies: + "@babel/types" "^7.16.8" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" @@ -195,6 +237,16 @@ browserslist "^4.14.5" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + "@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.8.3": version "7.13.11" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6" @@ -228,6 +280,13 @@ resolve "^1.14.2" semver "^6.1.2" +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-explode-assignable-expression@^7.12.13": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" @@ -244,6 +303,15 @@ "@babel/template" "^7.12.13" "@babel/types" "^7.12.13" +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/helper-get-function-arity@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" @@ -251,6 +319,13 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-hoist-variables@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz#5d5882e855b5c5eda91e0cadc26c6e7a2c8593d8" @@ -259,6 +334,13 @@ "@babel/traverse" "^7.13.0" "@babel/types" "^7.13.0" +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-member-expression-to-functions@^7.13.0", "@babel/helper-member-expression-to-functions@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" @@ -273,6 +355,13 @@ dependencies: "@babel/types" "^7.13.12" +"@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.13.14", "@babel/helper-module-transforms@^7.9.0": version "7.13.14" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef" @@ -287,6 +376,20 @@ "@babel/traverse" "^7.13.13" "@babel/types" "^7.13.14" +"@babel/helper-module-transforms@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" + integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/helper-optimise-call-expression@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" @@ -299,6 +402,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== +"@babel/helper-plugin-utils@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== + "@babel/helper-remap-async-to-generator@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" @@ -325,6 +433,13 @@ dependencies: "@babel/types" "^7.13.12" +"@babel/helper-simple-access@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" + integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" @@ -339,16 +454,33 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-validator-identifier@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + "@babel/helper-validator-option@^7.12.17": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + "@babel/helper-wrap-function@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" @@ -368,6 +500,15 @@ "@babel/traverse" "^7.13.0" "@babel/types" "^7.13.0" +"@babel/helpers@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" + integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/highlight@^7.12.13", "@babel/highlight@^7.8.3": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" @@ -377,11 +518,25 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b" + integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.13.13", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": version "7.13.13" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df" integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw== +"@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" + integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" @@ -548,7 +703,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.12.13": +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -583,6 +745,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" @@ -597,7 +766,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== @@ -653,6 +822,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" + integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-arrow-functions@^7.13.0", "@babel/plugin-transform-arrow-functions@^7.8.3": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" @@ -1232,6 +1408,15 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" +"@babel/template@^7.16.7", "@babel/template@^7.3.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0": version "7.13.13" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d" @@ -1246,6 +1431,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.16.7", "@babel/traverse@^7.7.2": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.8.tgz#bab2f2b09a5fe8a8d9cad22cbfe3ba1d126fef9c" + integrity sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.8" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.16.8" + "@babel/types" "^7.16.8" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.13", "@babel/types@^7.13.14", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0": version "7.13.14" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.14.tgz#c35a4abb15c7cd45a2746d78ab328e362cbace0d" @@ -1255,6 +1456,19 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.3.3": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" + integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@blocto/sdk@^0.2.11": version "0.2.15" resolved "https://registry.yarnpkg.com/@blocto/sdk/-/sdk-0.2.15.tgz#acdc7098439fee8ded09511fb34150cd58dae033" @@ -1827,6 +2041,22 @@ dependencies: "@hapi/hoek" "^8.3.0" +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + "@jest/console@^24.7.1", "@jest/console@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" @@ -1836,6 +2066,18 @@ chalk "^2.0.1" slash "^2.0.0" +"@jest/console@^27.4.6": + version "27.4.6" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.4.6.tgz#0742e6787f682b22bdad56f9db2a8a77f6a86107" + integrity sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA== + dependencies: + "@jest/types" "^27.4.2" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.4.6" + jest-util "^27.4.2" + slash "^3.0.0" + "@jest/core@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" @@ -1870,6 +2112,40 @@ slash "^2.0.0" strip-ansi "^5.0.0" +"@jest/core@^27.4.7": + version "27.4.7" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.4.7.tgz#84eabdf42a25f1fa138272ed229bcf0a1b5e6913" + integrity sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg== + dependencies: + "@jest/console" "^27.4.6" + "@jest/reporters" "^27.4.6" + "@jest/test-result" "^27.4.6" + "@jest/transform" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-changed-files "^27.4.2" + jest-config "^27.4.7" + jest-haste-map "^27.4.6" + jest-message-util "^27.4.6" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.6" + jest-resolve-dependencies "^27.4.6" + jest-runner "^27.4.6" + jest-runtime "^27.4.6" + jest-snapshot "^27.4.6" + jest-util "^27.4.2" + jest-validate "^27.4.6" + jest-watcher "^27.4.6" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + "@jest/environment@^24.3.0", "@jest/environment@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" @@ -1880,6 +2156,16 @@ "@jest/types" "^24.9.0" jest-mock "^24.9.0" +"@jest/environment@^27.4.6": + version "27.4.6" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.4.6.tgz#1e92885d64f48c8454df35ed9779fbcf31c56d8b" + integrity sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg== + dependencies: + "@jest/fake-timers" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + jest-mock "^27.4.6" + "@jest/fake-timers@^24.3.0", "@jest/fake-timers@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" @@ -1889,6 +2175,27 @@ jest-message-util "^24.9.0" jest-mock "^24.9.0" +"@jest/fake-timers@^27.4.6": + version "27.4.6" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.4.6.tgz#e026ae1671316dbd04a56945be2fa251204324e8" + integrity sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A== + dependencies: + "@jest/types" "^27.4.2" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.4.6" + jest-mock "^27.4.6" + jest-util "^27.4.2" + +"@jest/globals@^27.4.6": + version "27.4.6" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.4.6.tgz#3f09bed64b0fd7f5f996920258bd4be8f52f060a" + integrity sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw== + dependencies: + "@jest/environment" "^27.4.6" + "@jest/types" "^27.4.2" + expect "^27.4.6" + "@jest/reporters@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" @@ -1916,6 +2223,37 @@ source-map "^0.6.0" string-length "^2.0.0" +"@jest/reporters@^27.4.6": + version "27.4.6" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.4.6.tgz#b53dec3a93baf9b00826abf95b932de919d6d8dd" + integrity sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.4.6" + "@jest/test-result" "^27.4.6" + "@jest/transform" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.4" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.4.6" + jest-resolve "^27.4.6" + jest-util "^27.4.2" + jest-worker "^27.4.6" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + "@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" @@ -1925,6 +2263,15 @@ graceful-fs "^4.1.15" source-map "^0.6.0" +"@jest/source-map@^27.4.0": + version "27.4.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.4.0.tgz#2f0385d0d884fb3e2554e8f71f8fa957af9a74b6" + integrity sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.4" + source-map "^0.6.0" + "@jest/test-result@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" @@ -1934,6 +2281,16 @@ "@jest/types" "^24.9.0" "@types/istanbul-lib-coverage" "^2.0.0" +"@jest/test-result@^27.4.6": + version "27.4.6" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.4.6.tgz#b3df94c3d899c040f602cea296979844f61bdf69" + integrity sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ== + dependencies: + "@jest/console" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" @@ -1944,6 +2301,16 @@ jest-runner "^24.9.0" jest-runtime "^24.9.0" +"@jest/test-sequencer@^27.4.6": + version "27.4.6" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz#447339b8a3d7b5436f50934df30854e442a9d904" + integrity sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw== + dependencies: + "@jest/test-result" "^27.4.6" + graceful-fs "^4.2.4" + jest-haste-map "^27.4.6" + jest-runtime "^27.4.6" + "@jest/transform@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" @@ -1966,6 +2333,27 @@ source-map "^0.6.1" write-file-atomic "2.4.1" +"@jest/transform@^27.4.6": + version "27.4.6" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.6.tgz#153621940b1ed500305eacdb31105d415dc30231" + integrity sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.4.2" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^27.4.6" + jest-regex-util "^27.4.0" + jest-util "^27.4.2" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + "@jest/types@^24.3.0", "@jest/types@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" @@ -1996,6 +2384,17 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jest/types@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.4.2.tgz#96536ebd34da6392c2b7c7737d693885b5dd44a5" + integrity sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + "@json-rpc-tools/provider@^1.5.5": version "1.7.6" resolved "https://registry.yarnpkg.com/@json-rpc-tools/provider/-/provider-1.7.6.tgz#8a17c34c493fa892632e278fd9331104e8491ec6" @@ -3099,6 +3498,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sinonjs/samsam@^5.3.1": version "5.3.1" resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f" @@ -3714,6 +4120,17 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.1.tgz#78b5433344e2f92e8b306c06a5622c50c245bf6b" integrity sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg== +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.18" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.18.tgz#1a29abcc411a9c05e2094c98f9a1b7da6cdf49f8" + integrity sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + "@types/babel__core@^7.1.0": version "7.1.14" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" @@ -3747,6 +4164,13 @@ dependencies: "@babel/types" "^7.3.0" +"@types/babel__traverse@^7.0.4": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + dependencies: + "@babel/types" "^7.3.0" + "@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" @@ -4036,6 +4460,13 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + "@types/history@*": version "4.7.8" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" @@ -4059,6 +4490,11 @@ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== +"@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + "@types/istanbul-lib-report@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" @@ -4166,6 +4602,11 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== +"@types/prettier@^2.1.5": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.3.tgz#a3c65525b91fca7da00ab1a3ac2b5a2a4afbffbf" + integrity sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w== + "@types/prop-types@*": version "15.7.3" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" @@ -4267,6 +4708,11 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + "@types/testing-library__dom@*": version "7.5.0" resolved "https://registry.yarnpkg.com/@types/testing-library__dom/-/testing-library__dom-7.5.0.tgz#e0a00dd766983b1d6e9d10d33e708005ce6ad13e" @@ -4326,6 +4772,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + "@types/zrender@*": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/zrender/-/zrender-4.0.0.tgz#a6806f12ec4eccaaebd9b0d816f049aca6188fbd" @@ -4862,7 +5315,7 @@ JSONStream@^1.0.4, JSONStream@^1.3.4, JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^2.0.0: +abab@^2.0.0, abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== @@ -4909,6 +5362,14 @@ acorn-globals@^4.1.0, acorn-globals@^4.3.0: acorn "^6.0.1" acorn-walk "^6.0.1" +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + acorn-jsx@^5.2.0: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" @@ -4919,6 +5380,11 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + acorn@^5.5.3: version "5.7.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" @@ -4934,6 +5400,11 @@ acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.2.4: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + acorn@^8.4.1: version "8.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" @@ -5083,6 +5554,11 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -5102,6 +5578,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + antd@^4.6.6: version "4.15.0" resolved "https://registry.yarnpkg.com/antd/-/antd-4.15.0.tgz#4bfcd7eba7ae7812d95bcd391bf113a32e5a2143" @@ -5163,6 +5644,14 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +anymatch@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + anymatch@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" @@ -5775,6 +6264,20 @@ babel-jest@^24.9.0: chalk "^2.4.2" slash "^2.0.0" +babel-jest@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.6.tgz#4d024e69e241cdf4f396e453a07100f44f7ce314" + integrity sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg== + dependencies: + "@jest/transform" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.4.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" + babel-loader@8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" @@ -5817,6 +6320,17 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.3.0" test-exclude "^5.2.3" +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + babel-plugin-jest-hoist@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" @@ -5824,6 +6338,16 @@ babel-plugin-jest-hoist@^24.9.0: dependencies: "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz#d7831fc0f93573788d80dee7e682482da4c730d6" + integrity sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + babel-plugin-macros@2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" @@ -6127,6 +6651,24 @@ babel-polyfill@6.26.0: core-js "^2.5.0" regenerator-runtime "^0.10.5" +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + babel-preset-env@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" @@ -6171,6 +6713,14 @@ babel-preset-jest@^24.9.0: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" babel-plugin-jest-hoist "^24.9.0" +babel-preset-jest@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz#70d0e676a282ccb200fbabd7f415db5fdf393bca" + integrity sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg== + dependencies: + babel-plugin-jest-hoist "^27.4.0" + babel-preset-current-node-syntax "^1.0.0" + babel-preset-react-app@^9.1.2: version "9.1.2" resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz#54775d976588a8a6d1a99201a702befecaf48030" @@ -6601,6 +7151,17 @@ browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4 escalade "^3.1.1" node-releases "^1.1.70" +browserslist@^4.17.5: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -6935,6 +7496,11 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -6950,6 +7516,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000981, can resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001207.tgz#364d47d35a3007e528f69adb6fecb07c2bb2cc50" integrity sha512-UPQZdmAsyp2qfCTiMU/zqGSWOYaY9F9LL61V8f+8MrubsaDGpaHD9HRV/EWZGULZn0Hxu48SKzI5DgFwTvHuYw== +caniuse-lite@^1.0.30001286: + version "1.0.30001299" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001299.tgz#d753bf6444ed401eb503cbbe17aa3e1451b5a68c" + integrity sha512-iujN4+x7QzqA2NCSrS5VUy+4gLmRd4xv6vbBBsmfVqTx8bLAD8097euLqQgKxSVLvxjSDcvF1T/i9ocgnUFexw== + cannon@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/cannon/-/cannon-0.6.2.tgz#1e7bc72dd5841982f3c104c2bc578bfa4fb1c572" @@ -7008,6 +7579,11 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + character-entities-legacy@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" @@ -7131,6 +7707,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + cids@^0.7.1: version "0.7.5" resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" @@ -7155,6 +7736,11 @@ circular-json@^0.5.9: resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + class-is@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" @@ -7303,6 +7889,11 @@ coingecko-api@1.0.10: resolved "https://registry.yarnpkg.com/coingecko-api/-/coingecko-api-1.0.10.tgz#ac8694d5999f00727fe55f0078ce2917603076b2" integrity sha512-7YLLC85+daxAw5QlBWoHVBVpJRwoPr4HtwanCr8V/WRjoyHTa1Lb9DQAvv4MDJZHiz4no6HGnDQnddtjV35oRA== +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -7380,7 +7971,7 @@ columnify@^1.5.4: strip-ansi "^3.0.0" wcwidth "^1.0.0" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -7697,6 +8288,13 @@ convert-source-map@^0.3.3: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= +convert-source-map@^1.6.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -7902,7 +8500,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: +cross-spawn@^7.0.0, 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== @@ -8147,11 +8745,16 @@ csso@^4.0.2: dependencies: css-tree "^1.1.2" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4: +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4, cssom@~0.3.6: version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + cssstyle@^1.0.0, cssstyle@^1.1.1: version "1.4.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" @@ -8159,6 +8762,13 @@ cssstyle@^1.0.0, cssstyle@^1.1.1: dependencies: cssom "0.3.x" +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + csstype@^3.0.2: version "3.0.7" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" @@ -8459,6 +9069,15 @@ data-urls@^1.0.0, data-urls@^1.1.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + date-and-time@^0.14.2: version "0.14.2" resolved "https://registry.yarnpkg.com/date-and-time/-/date-and-time-0.14.2.tgz#a4266c3dead460f6c231fe9674e585908dac354e" @@ -8530,6 +9149,11 @@ 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@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -8722,6 +9346,11 @@ detect-newline@^2.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + detect-node@^2.0.4: version "2.0.5" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" @@ -8755,6 +9384,11 @@ diff-sequences@^24.9.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== +diff-sequences@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" + integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== + diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" @@ -8925,6 +9559,13 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + domhandler@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" @@ -9095,6 +9736,11 @@ electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.47, electron-to-chromiu resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.707.tgz#71386d0ceca6727835c33ba31f507f6824d18c35" integrity sha512-BqddgxNPrcWnbDdJw7SzXVzPmp+oiyjVrc7tkQVaznPGSS9SKZatw6qxoP857M+HbOyyqJQwYQtsuFIMSTNSZA== +electron-to-chromium@^1.4.17: + version "1.4.45" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.45.tgz#cf1144091d6683cbd45a231954a745f02fb24598" + integrity sha512-czF9eYVuOmlY/vxyMQz2rGlNSjZpxNQYBe1gmQv7al171qOIhgyO9k7D5AKlgeTCSPKk+LHhj5ZyIdmEub9oNg== + elliptic@6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" @@ -9139,6 +9785,11 @@ email-addresses@^3.0.1: resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-3.1.0.tgz#cabf7e085cbdb63008a70319a74e6136188812fb" integrity sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg== +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + emoji-regex@^7.0.1, emoji-regex@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -9352,6 +10003,18 @@ escodegen@^1.11.0, escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + esdoc-inject-style-plugin@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/esdoc-inject-style-plugin/-/esdoc-inject-style-plugin-1.0.0.tgz#a13597368bb9fb89c365e066495caf97a4decbb1" @@ -10187,6 +10850,21 @@ execa@^4.1.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^5.0.0: + 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" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -10217,6 +10895,16 @@ expect@^24.9.0: jest-message-util "^24.9.0" jest-regex-util "^24.9.0" +expect@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.4.6.tgz#f335e128b0335b6ceb4fcab67ece7cbd14c942e6" + integrity sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag== + dependencies: + "@jest/types" "^27.4.2" + jest-get-type "^27.4.0" + jest-matcher-utils "^27.4.6" + jest-message-util "^27.4.6" + express@^4.14.0, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -10710,6 +11398,15 @@ fork-ts-checker-webpack-plugin@3.1.1: tapable "^1.0.0" worker-rpc "^0.1.0" +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -10834,7 +11531,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@~2.3.1: +fsevents@^2.3.2, fsevents@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -10924,6 +11621,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-pkg-repo@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" @@ -11273,6 +11975,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== +graceful-fs@^4.2.4: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -11542,6 +12249,13 @@ html-encoding-sniffer@^1.0.2: dependencies: whatwg-encoding "^1.0.1" +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + html-entities@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" @@ -11674,7 +12388,7 @@ http-proxy-agent@^2.1.0: agent-base "4" debug "3.1.0" -http-proxy-agent@^4.0.0: +http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== @@ -11737,6 +12451,11 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +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" @@ -11893,6 +12612,14 @@ import-local@^2.0.0: pkg-dir "^3.0.0" resolve-cwd "^2.0.0" +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -12431,6 +13158,11 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + is-regex@^1.0.4, is-regex@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" @@ -12599,6 +13331,11 @@ istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" @@ -12612,6 +13349,17 @@ istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: istanbul-lib-coverage "^2.0.5" semver "^6.0.0" +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + istanbul-lib-report@^2.0.4: version "2.0.8" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" @@ -12621,6 +13369,15 @@ istanbul-lib-report@^2.0.4: make-dir "^2.1.0" supports-color "^6.1.0" +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + istanbul-lib-source-maps@^3.0.1: version "3.0.6" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" @@ -12632,6 +13389,15 @@ istanbul-lib-source-maps@^3.0.1: rimraf "^2.6.3" source-map "^0.6.1" +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + istanbul-reports@^2.2.6: version "2.2.7" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" @@ -12639,6 +13405,14 @@ istanbul-reports@^2.2.6: dependencies: html-escaper "^2.0.0" +istanbul-reports@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.3.tgz#4bcae3103b94518117930d51283690960b50d3c2" + integrity sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" @@ -12706,6 +13480,40 @@ jest-changed-files@^24.9.0: execa "^1.0.0" throat "^4.0.0" +jest-changed-files@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.4.2.tgz#da2547ea47c6e6a5f6ed336151bd2075736eb4a5" + integrity sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A== + dependencies: + "@jest/types" "^27.4.2" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.4.6.tgz#d3af34c0eb742a967b1919fbb351430727bcea6c" + integrity sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ== + dependencies: + "@jest/environment" "^27.4.6" + "@jest/test-result" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.4.6" + is-generator-fn "^2.0.0" + jest-each "^27.4.6" + jest-matcher-utils "^27.4.6" + jest-message-util "^27.4.6" + jest-runtime "^27.4.6" + jest-snapshot "^27.4.6" + jest-util "^27.4.2" + pretty-format "^27.4.6" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + jest-cli@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" @@ -12725,6 +13533,24 @@ jest-cli@^24.9.0: realpath-native "^1.1.0" yargs "^13.3.0" +jest-cli@^27.4.7: + version "27.4.7" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.4.7.tgz#d00e759e55d77b3bcfea0715f527c394ca314e5a" + integrity sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw== + dependencies: + "@jest/core" "^27.4.7" + "@jest/test-result" "^27.4.6" + "@jest/types" "^27.4.2" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.4" + import-local "^3.0.2" + jest-config "^27.4.7" + jest-util "^27.4.2" + jest-validate "^27.4.6" + prompts "^2.0.1" + yargs "^16.2.0" + jest-config@24.9.0, jest-config@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" @@ -12748,6 +13574,34 @@ jest-config@24.9.0, jest-config@^24.9.0: pretty-format "^24.9.0" realpath-native "^1.1.0" +jest-config@^27.4.7: + version "27.4.7" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.4.7.tgz#4f084b2acbd172c8b43aa4cdffe75d89378d3972" + integrity sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.4.6" + "@jest/types" "^27.4.2" + babel-jest "^27.4.6" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.4" + jest-circus "^27.4.6" + jest-environment-jsdom "^27.4.6" + jest-environment-node "^27.4.6" + jest-get-type "^27.4.0" + jest-jasmine2 "^27.4.6" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.6" + jest-runner "^27.4.6" + jest-util "^27.4.2" + jest-validate "^27.4.6" + micromatch "^4.0.4" + pretty-format "^27.4.6" + slash "^3.0.0" + jest-diff@^24.0.0, jest-diff@^24.3.0, jest-diff@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" @@ -12758,6 +13612,16 @@ jest-diff@^24.0.0, jest-diff@^24.3.0, jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" +jest-diff@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.6.tgz#93815774d2012a2cbb6cf23f84d48c7a2618f98d" + integrity sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.4.0" + jest-get-type "^27.4.0" + pretty-format "^27.4.6" + jest-docblock@^24.3.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" @@ -12765,6 +13629,13 @@ jest-docblock@^24.3.0: dependencies: detect-newline "^2.1.0" +jest-docblock@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.4.0.tgz#06c78035ca93cbbb84faf8fce64deae79a59f69f" + integrity sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg== + dependencies: + detect-newline "^3.0.0" + jest-each@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" @@ -12776,6 +13647,17 @@ jest-each@^24.9.0: jest-util "^24.9.0" pretty-format "^24.9.0" +jest-each@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.4.6.tgz#e7e8561be61d8cc6dbf04296688747ab186c40ff" + integrity sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA== + dependencies: + "@jest/types" "^27.4.2" + chalk "^4.0.0" + jest-get-type "^27.4.0" + jest-util "^27.4.2" + pretty-format "^27.4.6" + jest-environment-jsdom-fourteen@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz#4cd0042f58b4ab666950d96532ecb2fc188f96fb" @@ -12800,6 +13682,19 @@ jest-environment-jsdom@^24.9.0: jest-util "^24.9.0" jsdom "^11.5.1" +jest-environment-jsdom@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz#c23a394eb445b33621dfae9c09e4c8021dea7b36" + integrity sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA== + dependencies: + "@jest/environment" "^27.4.6" + "@jest/fake-timers" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + jest-mock "^27.4.6" + jest-util "^27.4.2" + jsdom "^16.6.0" + jest-environment-node@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" @@ -12811,11 +13706,28 @@ jest-environment-node@^24.9.0: jest-mock "^24.9.0" jest-util "^24.9.0" +jest-environment-node@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.4.6.tgz#ee8cd4ef458a0ef09d087c8cd52ca5856df90242" + integrity sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ== + dependencies: + "@jest/environment" "^27.4.6" + "@jest/fake-timers" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + jest-mock "^27.4.6" + jest-util "^27.4.2" + jest-get-type@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== +jest-get-type@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" + integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== + jest-haste-map@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" @@ -12835,6 +13747,26 @@ jest-haste-map@^24.9.0: optionalDependencies: fsevents "^1.2.7" +jest-haste-map@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.6.tgz#c60b5233a34ca0520f325b7e2cc0a0140ad0862a" + integrity sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ== + dependencies: + "@jest/types" "^27.4.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^27.4.0" + jest-serializer "^27.4.0" + jest-util "^27.4.2" + jest-worker "^27.4.6" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + jest-jasmine2@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" @@ -12857,6 +13789,29 @@ jest-jasmine2@^24.9.0: pretty-format "^24.9.0" throat "^4.0.0" +jest-jasmine2@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz#109e8bc036cb455950ae28a018f983f2abe50127" + integrity sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw== + dependencies: + "@jest/environment" "^27.4.6" + "@jest/source-map" "^27.4.0" + "@jest/test-result" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.4.6" + is-generator-fn "^2.0.0" + jest-each "^27.4.6" + jest-matcher-utils "^27.4.6" + jest-message-util "^27.4.6" + jest-runtime "^27.4.6" + jest-snapshot "^27.4.6" + jest-util "^27.4.2" + pretty-format "^27.4.6" + throat "^6.0.1" + jest-leak-detector@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" @@ -12865,6 +13820,14 @@ jest-leak-detector@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" +jest-leak-detector@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz#ed9bc3ce514b4c582637088d9faf58a33bd59bf4" + integrity sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA== + dependencies: + jest-get-type "^27.4.0" + pretty-format "^27.4.6" + jest-matcher-utils@^24.0.0, jest-matcher-utils@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" @@ -12875,6 +13838,16 @@ jest-matcher-utils@^24.0.0, jest-matcher-utils@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" +jest-matcher-utils@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz#53ca7f7b58170638590e946f5363b988775509b8" + integrity sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA== + dependencies: + chalk "^4.0.0" + jest-diff "^27.4.6" + jest-get-type "^27.4.0" + pretty-format "^27.4.6" + jest-message-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" @@ -12889,6 +13862,21 @@ jest-message-util@^24.9.0: slash "^2.0.0" stack-utils "^1.0.1" +jest-message-util@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.4.6.tgz#9fdde41a33820ded3127465e1a5896061524da31" + integrity sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.4.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.4" + pretty-format "^27.4.6" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^24.0.0, jest-mock@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" @@ -12896,7 +13884,15 @@ jest-mock@^24.0.0, jest-mock@^24.9.0: dependencies: "@jest/types" "^24.9.0" -jest-pnp-resolver@^1.2.1: +jest-mock@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.4.6.tgz#77d1ba87fbd33ccb8ef1f061697e7341b7635195" + integrity sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw== + dependencies: + "@jest/types" "^27.4.2" + "@types/node" "*" + +jest-pnp-resolver@^1.2.1, jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== @@ -12906,6 +13902,11 @@ jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== +jest-regex-util@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" + integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== + jest-resolve-dependencies@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" @@ -12915,6 +13916,15 @@ jest-resolve-dependencies@^24.9.0: jest-regex-util "^24.3.0" jest-snapshot "^24.9.0" +jest-resolve-dependencies@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz#fc50ee56a67d2c2183063f6a500cc4042b5e2327" + integrity sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw== + dependencies: + "@jest/types" "^27.4.2" + jest-regex-util "^27.4.0" + jest-snapshot "^27.4.6" + jest-resolve@24.9.0, jest-resolve@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" @@ -12926,6 +13936,22 @@ jest-resolve@24.9.0, jest-resolve@^24.9.0: jest-pnp-resolver "^1.2.1" realpath-native "^1.1.0" +jest-resolve@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.4.6.tgz#2ec3110655e86d5bfcfa992e404e22f96b0b5977" + integrity sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw== + dependencies: + "@jest/types" "^27.4.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^27.4.6" + jest-pnp-resolver "^1.2.2" + jest-util "^27.4.2" + jest-validate "^27.4.6" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + jest-runner@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" @@ -12951,6 +13977,34 @@ jest-runner@^24.9.0: source-map-support "^0.5.6" throat "^4.0.0" +jest-runner@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.4.6.tgz#1d390d276ec417e9b4d0d081783584cbc3e24773" + integrity sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg== + dependencies: + "@jest/console" "^27.4.6" + "@jest/environment" "^27.4.6" + "@jest/test-result" "^27.4.6" + "@jest/transform" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-docblock "^27.4.0" + jest-environment-jsdom "^27.4.6" + jest-environment-node "^27.4.6" + jest-haste-map "^27.4.6" + jest-leak-detector "^27.4.6" + jest-message-util "^27.4.6" + jest-resolve "^27.4.6" + jest-runtime "^27.4.6" + jest-util "^27.4.2" + jest-worker "^27.4.6" + source-map-support "^0.5.6" + throat "^6.0.1" + jest-runtime@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" @@ -12980,11 +14034,47 @@ jest-runtime@^24.9.0: strip-bom "^3.0.0" yargs "^13.3.0" +jest-runtime@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.4.6.tgz#83ae923818e3ea04463b22f3597f017bb5a1cffa" + integrity sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ== + dependencies: + "@jest/environment" "^27.4.6" + "@jest/fake-timers" "^27.4.6" + "@jest/globals" "^27.4.6" + "@jest/source-map" "^27.4.0" + "@jest/test-result" "^27.4.6" + "@jest/transform" "^27.4.6" + "@jest/types" "^27.4.2" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.4" + jest-haste-map "^27.4.6" + jest-message-util "^27.4.6" + jest-mock "^27.4.6" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.6" + jest-snapshot "^27.4.6" + jest-util "^27.4.2" + slash "^3.0.0" + strip-bom "^4.0.0" + jest-serializer@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== +jest-serializer@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.4.0.tgz#34866586e1cae2388b7d12ffa2c7819edef5958a" + integrity sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + jest-snapshot@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" @@ -13004,6 +14094,34 @@ jest-snapshot@^24.9.0: pretty-format "^24.9.0" semver "^6.2.0" +jest-snapshot@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.4.6.tgz#e2a3b4fff8bdce3033f2373b2e525d8b6871f616" + integrity sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.4.6" + graceful-fs "^4.2.4" + jest-diff "^27.4.6" + jest-get-type "^27.4.0" + jest-haste-map "^27.4.6" + jest-matcher-utils "^27.4.6" + jest-message-util "^27.4.6" + jest-util "^27.4.2" + natural-compare "^1.4.0" + pretty-format "^27.4.6" + semver "^7.3.2" + jest-util@^24.0.0, jest-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" @@ -13022,6 +14140,18 @@ jest-util@^24.0.0, jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.4.2.tgz#ed95b05b1adfd761e2cda47e0144c6a58e05a621" + integrity sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA== + dependencies: + "@jest/types" "^27.4.2" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.4" + picomatch "^2.2.3" + jest-validate@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" @@ -13034,6 +14164,18 @@ jest-validate@^24.9.0: leven "^3.1.0" pretty-format "^24.9.0" +jest-validate@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.4.6.tgz#efc000acc4697b6cf4fa68c7f3f324c92d0c4f1f" + integrity sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ== + dependencies: + "@jest/types" "^27.4.2" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.4.0" + leven "^3.1.0" + pretty-format "^27.4.6" + jest-watch-typeahead@0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz#e5be959698a7fa2302229a5082c488c3c8780a4a" @@ -13060,6 +14202,19 @@ jest-watcher@^24.3.0, jest-watcher@^24.9.0: jest-util "^24.9.0" string-length "^2.0.0" +jest-watcher@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.4.6.tgz#673679ebeffdd3f94338c24f399b85efc932272d" + integrity sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw== + dependencies: + "@jest/test-result" "^27.4.6" + "@jest/types" "^27.4.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.4.2" + string-length "^4.0.1" + jest-worker@^24.6.0, jest-worker@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" @@ -13076,6 +14231,15 @@ jest-worker@^25.4.0: merge-stream "^2.0.0" supports-color "^7.0.0" +jest-worker@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.6.tgz#5d2d93db419566cb680752ca0792780e71b3273e" + integrity sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest@24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" @@ -13084,6 +14248,15 @@ jest@24.9.0: import-local "^2.0.0" jest-cli "^24.9.0" +jest@^27.4.7: + version "27.4.7" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.4.7.tgz#87f74b9026a1592f2da05b4d258e57505f28eca4" + integrity sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg== + dependencies: + "@jest/core" "^27.4.7" + import-local "^3.0.2" + jest-cli "^27.4.7" + js-sha3@0.5.7, js-sha3@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" @@ -13193,6 +14366,39 @@ jsdom@^14.1.0: ws "^6.1.2" xml-name-validator "^3.0.0" +jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.6" + xml-name-validator "^3.0.0" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -13976,7 +15182,7 @@ lodash@4.17.15: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -"lodash@>=3.5 <5", lodash@^4, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1: +"lodash@>=3.5 <5", lodash@^4, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -14396,6 +15602,14 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.0.5" +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -14981,6 +16195,11 @@ node-releases@^1.1.52, node-releases@^1.1.70: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + nopt@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" @@ -15137,7 +16356,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^4.0.0: +npm-run-path@^4.0.0, 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== @@ -15179,7 +16398,7 @@ number-to-bn@1.7.0: bn.js "4.11.6" strip-hex-prefix "1.0.0" -nwsapi@^2.0.7, nwsapi@^2.1.3: +nwsapi@^2.0.7, nwsapi@^2.1.3, nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== @@ -15378,7 +16597,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -15730,6 +16949,11 @@ parse5@5.1.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -15871,11 +17095,21 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.2.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pidtree@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" @@ -15920,6 +17154,11 @@ pirates@^4.0.1: dependencies: node-modules-regexp "^1.0.0" +pirates@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.4.tgz#07df81e61028e402735cdd49db701e4885b4e6e6" + integrity sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw== + pkg-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" @@ -15941,7 +17180,7 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-dir@^4.1.0: +pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== @@ -16754,6 +17993,15 @@ pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" +pretty-format@^27.4.6: + version "27.4.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.6.tgz#1b784d2f53c68db31797b2348fa39b49e31846b7" + integrity sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -16865,7 +18113,7 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -psl@^1.1.28: +psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -18199,6 +19447,13 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-from@5.0.0, resolve-from@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" @@ -18247,6 +19502,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -18368,7 +19628,7 @@ rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1: dependencies: glob "^7.1.3" -rimraf@^3.0.2: +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -18528,6 +19788,13 @@ saxes@^3.1.9: dependencies: xmlchars "^2.1.1" +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + scheduler@0.20.1: version "0.20.1" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.1.tgz#da0b907e24026b01181ecbc75efdc7f27b5a000c" @@ -18858,6 +20125,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +signal-exit@^3.0.3: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -19080,6 +20352,11 @@ source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" @@ -19245,6 +20522,13 @@ stack-utils@^1.0.1: dependencies: escape-string-regexp "^2.0.0" +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -19353,6 +20637,14 @@ string-length@^3.1.0: astral-regex "^1.0.0" strip-ansi "^5.2.0" +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -19503,6 +20795,11 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + strip-comments@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-1.0.2.tgz#82b9c45e7f05873bee53f37168af930aa368679d" @@ -19613,7 +20910,7 @@ superstruct@^0.8.3: kind-of "^6.0.2" tiny-invariant "^1.0.6" -supports-color@8.1.1: +supports-color@8.1.1, supports-color@^8.0.0: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -19646,6 +20943,14 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + svg-parser@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" @@ -19694,7 +20999,7 @@ swr@^0.5.4: dependencies: dequal "2.0.2" -symbol-tree@^3.2.2: +symbol-tree@^3.2.2, symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== @@ -19776,6 +21081,14 @@ temp-write@^3.4.0: temp-dir "^1.0.0" uuid "^3.0.1" +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + terser-webpack-plugin@2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz#894764a19b0743f2f704e7c2a848c5283a696724" @@ -19825,6 +21138,15 @@ test-exclude@^5.2.3: read-pkg-up "^4.0.0" require-main-filename "^2.0.0" +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + test-value@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" @@ -19872,6 +21194,11 @@ throat@^4.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + through2@^2.0.0, through2@^2.0.2, through2@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -20026,6 +21353,15 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5 psl "^1.1.28" punycode "^2.1.1" +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -20033,6 +21369,13 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -20452,7 +21795,7 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== -universalify@^0.1.0: +universalify@^0.1.0, universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== @@ -20717,6 +22060,15 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -20784,7 +22136,7 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -w3c-hr-time@^1.0.1: +w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== @@ -20800,6 +22152,13 @@ w3c-xmlserializer@^1.1.2: webidl-conversions "^4.0.2" xml-name-validator "^3.0.0" +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + wait-for-expect@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-3.0.2.tgz#d2f14b2f7b778c9b82144109c8fa89ceaadaa463" @@ -21181,6 +22540,16 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + webpack-dev-middleware@^3.7.2: version "3.7.3" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" @@ -21366,6 +22735,15 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -21753,6 +23131,11 @@ ws@^7.4.0: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== +ws@^7.4.6: + version "7.5.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" + integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== + xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" @@ -21800,7 +23183,7 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -xmlchars@^2.1.1: +xmlchars@^2.1.1, xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== @@ -21902,7 +23285,7 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@16.2.0: +yargs@16.2.0, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== From a3c4c010c0249ebace1c644901b9fc425bae21c3 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Fri, 14 Jan 2022 17:54:42 +0000 Subject: [PATCH 02/88] Use connection for all api calls (#484) --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/chat/api.ts | 10 ++++---- packages/governance-sdk/src/core/api.ts | 5 ++-- packages/governance-sdk/src/governance/api.ts | 25 ++++++++----------- packages/governance/package.json | 2 +- .../src/contexts/GovernanceContext.tsx | 2 +- packages/governance/src/hooks/accountHooks.ts | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 5ecfde78..9b5c3bda 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.9", + "version": "0.0.10", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/chat/api.ts b/packages/governance-sdk/src/chat/api.ts index a2762627..a8e4cd8e 100644 --- a/packages/governance-sdk/src/chat/api.ts +++ b/packages/governance-sdk/src/chat/api.ts @@ -1,4 +1,4 @@ -import { PublicKey } from '@solana/web3.js'; +import { Connection, PublicKey } from '@solana/web3.js'; import { getBorshProgramAccounts, @@ -10,11 +10,11 @@ import { ChatMessage, GOVERNANCE_CHAT_PROGRAM_ID } from './accounts'; import { GOVERNANCE_CHAT_SCHEMA } from './serialisation'; export function getGovernanceChatMessages( - rpcEndpoint: string, + connection: Connection, proposal: PublicKey, ) { return getBorshProgramAccounts( - rpcEndpoint, + connection, GOVERNANCE_CHAT_PROGRAM_ID, _ => GOVERNANCE_CHAT_SCHEMA, ChatMessage, @@ -23,11 +23,11 @@ export function getGovernanceChatMessages( } export function getGovernanceChatMessagesByVoter( - rpcEndpoint: string, + connection: Connection, voter: PublicKey, ) { return getBorshProgramAccounts( - rpcEndpoint, + connection, GOVERNANCE_CHAT_PROGRAM_ID, _ => GOVERNANCE_CHAT_SCHEMA, ChatMessage, diff --git a/packages/governance-sdk/src/core/api.ts b/packages/governance-sdk/src/core/api.ts index db2440df..ec5d118e 100644 --- a/packages/governance-sdk/src/core/api.ts +++ b/packages/governance-sdk/src/core/api.ts @@ -78,7 +78,7 @@ export const booleanFilter = (offset: number, value: boolean) => export async function getBorshProgramAccounts< TAccount extends ProgramAccountWithType >( - rpcEndpoint: string, + connection: Connection, programId: PublicKey, getSchema: (accountType: number) => Schema, accountFactory: new (args: any) => TAccount, @@ -86,6 +86,7 @@ export async function getBorshProgramAccounts< accountType?: number, ) { accountType = accountType ?? new accountFactory({}).accountType; + const rpcEndpoint = (connection as any)._rpcEndpoint; let getProgramAccounts = await fetch(rpcEndpoint, { method: 'POST', @@ -99,7 +100,7 @@ export async function getBorshProgramAccounts< params: [ programId.toBase58(), { - commitment: 'recent', + commitment: connection.commitment, encoding: 'base64', filters: [ { diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index 56011458..82148bcc 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -30,18 +30,18 @@ export async function getRealm(connection: Connection, realm: PublicKey) { return getGovernanceAccount(connection, realm, Realm); } -export async function getRealms(rpcEndpoint: string, programId: PublicKey) { - return getGovernanceAccounts(rpcEndpoint, programId, Realm); +export async function getRealms(connection: Connection, programId: PublicKey) { + return getGovernanceAccounts(connection, programId, Realm); } // VoteRecords export async function getVoteRecordsByVoter( - rpcEndpoint: string, + connection: Connection, programId: PublicKey, voter: PublicKey, ) { - return getGovernanceAccounts(rpcEndpoint, programId, VoteRecord, [ + return getGovernanceAccounts(connection, programId, VoteRecord, [ pubkeyFilter(33, voter)!, ]); } @@ -75,11 +75,11 @@ export async function getTokenOwnerRecordForRealm( * @returns */ export async function getTokenOwnerRecordsByOwner( - rpcEndpoint: string, + connection: Connection, programId: PublicKey, governingTokenOwner: PublicKey, ) { - return getGovernanceAccounts(rpcEndpoint, programId, TokenOwnerRecord, [ + return getGovernanceAccounts(connection, programId, TokenOwnerRecord, [ pubkeyFilter(1 + 32 + 32, governingTokenOwner)!, ]); } @@ -95,17 +95,14 @@ export async function getGovernance( // Proposal -export async function getProposal( - connection: Connection, - proposalPk: PublicKey, -) { - return getGovernanceAccount(connection, proposalPk, Proposal); +export async function getProposal(connection: Connection, proposal: PublicKey) { + return getGovernanceAccount(connection, proposal, Proposal); } // Generic API export async function getGovernanceAccounts( - rpcEndpoint: string, + connection: Connection, programId: PublicKey, accountClass: new (args: any) => TAccount, filters: MemcmpFilter[] = [], @@ -116,7 +113,7 @@ export async function getGovernanceAccounts( if (accountTypes.length === 1) { return getBorshProgramAccounts( - rpcEndpoint, + connection, programId, at => getGovernanceSchemaForAccount(at), accountClass, @@ -128,7 +125,7 @@ export async function getGovernanceAccounts( const all = await Promise.all( accountTypes.map(at => getBorshProgramAccounts( - rpcEndpoint, + connection, programId, at => getGovernanceSchemaForAccount(at), accountClass as any, diff --git a/packages/governance/package.json b/packages/governance/package.json index 3548a3d0..36696b00 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -9,7 +9,7 @@ "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", "@project-serum/serum": "^0.13.11", - "@solana/spl-governance": "0.0.9", + "@solana/spl-governance": "0.0.10", "@solana/spl-token": "0.0.13", "@solana/spl-token-swap": "0.1.0", "@solana/web3.js": "^1.22.0", diff --git a/packages/governance/src/contexts/GovernanceContext.tsx b/packages/governance/src/contexts/GovernanceContext.tsx index e2dfacba..c8bf58ad 100644 --- a/packages/governance/src/contexts/GovernanceContext.tsx +++ b/packages/governance/src/contexts/GovernanceContext.tsx @@ -126,7 +126,7 @@ export default function GovernanceProvider({ children = null as any }) { const programPk = new PublicKey(programId); try { - const loadedRealms = await getRealms(endpoint, programPk); + const loadedRealms = await getRealms(connection, programPk); setRealms(loadedRealms); } catch (ex) { console.error("Can't load Realms", ex); diff --git a/packages/governance/src/hooks/accountHooks.ts b/packages/governance/src/hooks/accountHooks.ts index 3ad8b43a..73b84dd3 100644 --- a/packages/governance/src/hooks/accountHooks.ts +++ b/packages/governance/src/hooks/accountHooks.ts @@ -120,7 +120,7 @@ export function useGovernanceAccountsByFilter< try { // TODO: add retries for transient errors const loadedAccounts = await getGovernanceAccounts( - endpoint, + connection, programId, (accountClass as any) as new (args: any) => TAccount, queryFilters, From 718f3ed9fed98143d8cee8d5dd429e44307a672b Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Fri, 14 Jan 2022 19:09:37 +0000 Subject: [PATCH 03/88] Governance: use getProgramAccounts instead of fetch (#485) * fix: use getProgramAccounts instead of fetch * fix: use getProgramAccounts --- packages/governance-sdk/README.md | 6 +-- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/core/api.ts | 48 +++++++------------ .../tests/governance/api.test.ts | 4 +- packages/governance/package.json | 2 +- 5 files changed, 23 insertions(+), 39 deletions(-) diff --git a/packages/governance-sdk/README.md b/packages/governance-sdk/README.md index e3f70580..7dcfd342 100644 --- a/packages/governance-sdk/README.md +++ b/packages/governance-sdk/README.md @@ -10,10 +10,10 @@ SPL Governance Client API for spl-governance program ```typescript import { getRealms } from '@solana/spl-governance'; -import { PublicKey } from '@solana/web3.js'; +import { Connection, PublicKey } from '@solana/web3.js'; +const connection = new Connection("https://api.mainnet-beta.solana.com", 'recent'); const programId = new PublicKey('GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw'); -const rpcEndpoint = "https://api.mainnet-beta.solana.com"; -const realms = getRealms(rpcEndpoint, programId); +const realms = getRealms(connection, programId); diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 9b5c3bda..8d2f6aaa 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.10", + "version": "0.0.11", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/core/api.ts b/packages/governance-sdk/src/core/api.ts index ec5d118e..2656b92c 100644 --- a/packages/governance-sdk/src/core/api.ts +++ b/packages/governance-sdk/src/core/api.ts @@ -86,43 +86,27 @@ export async function getBorshProgramAccounts< accountType?: number, ) { accountType = accountType ?? new accountFactory({}).accountType; - const rpcEndpoint = (connection as any)._rpcEndpoint; - - let getProgramAccounts = await fetch(rpcEndpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - jsonrpc: '2.0', - id: 1, - method: 'getProgramAccounts', - params: [ - programId.toBase58(), - { - commitment: connection.commitment, - encoding: 'base64', - filters: [ - { - memcmp: { - offset: 0, - bytes: bs58.encode([accountType]), - }, - }, - ...filters.map(f => ({ - memcmp: { offset: f.offset, bytes: bs58.encode(f.bytes) }, - })), - ], + + let programAccounts = await connection.getProgramAccounts(programId, { + commitment: connection.commitment, + filters: [ + { + memcmp: { + offset: 0, + bytes: bs58.encode([accountType]), }, - ], - }), + }, + ...filters.map(f => ({ + memcmp: { offset: f.offset, bytes: bs58.encode(f.bytes) }, + })), + ], }); - const rawAccounts = (await getProgramAccounts.json())['result']; + let accounts: { [pubKey: string]: ProgramAccount } = {}; - for (let rawAccount of rawAccounts) { + for (let rawAccount of programAccounts) { try { - const data = Buffer.from(rawAccount.account.data[0], 'base64'); + const data = rawAccount.account.data; const accountType = data[0]; const account: ProgramAccount = { diff --git a/packages/governance-sdk/tests/governance/api.test.ts b/packages/governance-sdk/tests/governance/api.test.ts index 3c3d3e7e..ba8846d1 100644 --- a/packages/governance-sdk/tests/governance/api.test.ts +++ b/packages/governance-sdk/tests/governance/api.test.ts @@ -1,7 +1,7 @@ import { PublicKey } from '@solana/web3.js'; -//import { getTokenOwnerRecordsByOwner } from '../../src' +import { getTokenOwnerRecordsByOwner } from '../../src' const programId = new PublicKey("GTesTBiEWE32WHXXE2S4XbZvA5CrEc4xs6ZgRe895dP") @@ -13,7 +13,7 @@ test('getTokenOwnerRecordsByOwner', async () => { const tokenOwnerPk = new PublicKey("EZLvwGdGyeks3jQLWeBbjL1uGeGbqb2MYU4157pDP9ch") // Act - //const results = await getTokenOwnerRecordsByOwner(rpcEndpoint, programId, tokenOwnerPk) + const results = await getTokenOwnerRecordsByOwner(rpcEndpoint, programId, tokenOwnerPk) // Assert diff --git a/packages/governance/package.json b/packages/governance/package.json index 36696b00..f08ce07f 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -9,7 +9,7 @@ "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", "@project-serum/serum": "^0.13.11", - "@solana/spl-governance": "0.0.10", + "@solana/spl-governance": "0.0.11", "@solana/spl-token": "0.0.13", "@solana/spl-token-swap": "0.1.0", "@solana/web3.js": "^1.22.0", From 75402e9ce4adc697ae690185b89433debd7857c8 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Fri, 14 Jan 2022 20:09:37 +0000 Subject: [PATCH 04/88] Governace sdk tests (#486) * chore: bump sdk version * chore: add getTokenOwnerRecordsByOwner test --- packages/governance-sdk/package.json | 6 +- .../tests/governance/api.test.ts | 12 +- packages/governance/package.json | 2 +- yarn.lock | 249 +++++++++++++++++- 4 files changed, 257 insertions(+), 12 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 8d2f6aaa..bcf21f3a 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.11", + "version": "0.0.12", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", @@ -37,6 +37,8 @@ "superstruct": "^0.15.2" }, "devDependencies": { + "esbuild": "^0.14.11", + "esbuild-jest": "^0.5.0", "jest": "^27.4.7", "typescript": "^4.5.4" }, @@ -45,4 +47,4 @@ "^.+\\.tsx?$": "esbuild-jest" } } -} \ No newline at end of file +} diff --git a/packages/governance-sdk/tests/governance/api.test.ts b/packages/governance-sdk/tests/governance/api.test.ts index ba8846d1..ca951f1d 100644 --- a/packages/governance-sdk/tests/governance/api.test.ts +++ b/packages/governance-sdk/tests/governance/api.test.ts @@ -1,21 +1,23 @@ -import { PublicKey } from '@solana/web3.js'; +import { Connection, PublicKey } from '@solana/web3.js'; import { getTokenOwnerRecordsByOwner } from '../../src' - const programId = new PublicKey("GTesTBiEWE32WHXXE2S4XbZvA5CrEc4xs6ZgRe895dP") const rpcEndpoint = "https://psytrbhymqlkfrhudd.dev.genesysgo.net:8899" - +const connection = new Connection(rpcEndpoint, 'recent') test('getTokenOwnerRecordsByOwner', async () => { // Arrange const tokenOwnerPk = new PublicKey("EZLvwGdGyeks3jQLWeBbjL1uGeGbqb2MYU4157pDP9ch") // Act - const results = await getTokenOwnerRecordsByOwner(rpcEndpoint, programId, tokenOwnerPk) + const results = Object.values(await getTokenOwnerRecordsByOwner(connection, programId, tokenOwnerPk)) // Assert + expect(results.length).toBeGreaterThan(0) - + for (let tor of results) { + expect(tor.account.governingTokenOwner.toBase58()).toBe(tokenOwnerPk.toBase58()) + } }); \ No newline at end of file diff --git a/packages/governance/package.json b/packages/governance/package.json index f08ce07f..5500a807 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -9,7 +9,7 @@ "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", "@project-serum/serum": "^0.13.11", - "@solana/spl-governance": "0.0.11", + "@solana/spl-governance": "0.0.12", "@solana/spl-token": "0.0.13", "@solana/spl-token-swap": "0.1.0", "@solana/web3.js": "^1.22.0", diff --git a/yarn.lock b/yarn.lock index 6d21035e..bbba31fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -173,7 +173,7 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": +"@babel/core@^7.12.17", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf" integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA== @@ -955,6 +955,16 @@ "@babel/helper-plugin-utils" "^7.13.0" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-commonjs@^7.12.13": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" + integrity sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + "@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.9.0": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz#7b01ad7c2dcf2275b06fa1781e00d13d420b3e1b" @@ -2333,6 +2343,27 @@ source-map "^0.6.1" write-file-atomic "2.4.1" +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^26.6.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-regex-util "^26.0.0" + jest-util "^26.6.2" + micromatch "^4.0.2" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + "@jest/transform@^27.4.6": version "27.4.6" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.6.tgz#153621940b1ed500305eacdb31105d415dc30231" @@ -4120,7 +4151,7 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.1.tgz#78b5433344e2f92e8b306c06a5622c50c245bf6b" integrity sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg== -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7": version "7.1.18" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.18.tgz#1a29abcc411a9c05e2094c98f9a1b7da6cdf49f8" integrity sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ== @@ -6264,6 +6295,20 @@ babel-jest@^24.9.0: chalk "^2.4.2" slash "^2.0.0" +babel-jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" + integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== + dependencies: + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/babel__core" "^7.1.7" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^26.6.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" + babel-jest@^27.4.6: version "27.4.6" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.6.tgz#4d024e69e241cdf4f396e453a07100f44f7ce314" @@ -6320,7 +6365,7 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.3.0" test-exclude "^5.2.3" -babel-plugin-istanbul@^6.1.1: +babel-plugin-istanbul@^6.0.0, babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== @@ -6338,6 +6383,16 @@ babel-plugin-jest-hoist@^24.9.0: dependencies: "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" + integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + babel-plugin-jest-hoist@^27.4.0: version "27.4.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz#d7831fc0f93573788d80dee7e682482da4c730d6" @@ -6713,6 +6768,14 @@ babel-preset-jest@^24.9.0: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" babel-plugin-jest-hoist "^24.9.0" +babel-preset-jest@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" + integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== + dependencies: + babel-plugin-jest-hoist "^26.6.2" + babel-preset-current-node-syntax "^1.0.0" + babel-preset-jest@^27.4.0: version "27.4.0" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz#70d0e676a282ccb200fbabd7f415db5fdf393bca" @@ -9966,6 +10029,129 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3: d "^1.0.1" ext "^1.1.2" +esbuild-android-arm64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.11.tgz#b8b34e35a5b43880664ac7a3fbc70243d7ed894f" + integrity sha512-6iHjgvMnC/SzDH8TefL+/3lgCjYWwAd1LixYfmz/TBPbDQlxcuSkX0yiQgcJB9k+ibZ54yjVXziIwGdlc+6WNw== + +esbuild-darwin-64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.11.tgz#ba805de98c0412e50fcd0636451797da157b0625" + integrity sha512-olq84ikh6TiBcrs3FnM4eR5VPPlcJcdW8BnUz/lNoEWYifYQ+Po5DuYV1oz1CTFMw4k6bQIZl8T3yxL+ZT2uvQ== + +esbuild-darwin-arm64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.11.tgz#4d3573e448af76ce33e16231f3d9f878542d6fe8" + integrity sha512-Jj0ieWLREPBYr/TZJrb2GFH8PVzDqiQWavo1pOFFShrcmHWDBDrlDxPzEZ67NF/Un3t6sNNmeI1TUS/fe1xARg== + +esbuild-freebsd-64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.11.tgz#9294e6ab359ec93590ab097b0f2017de7c78ab4d" + integrity sha512-C5sT3/XIztxxz/zwDjPRHyzj/NJFOnakAanXuyfLDwhwupKPd76/PPHHyJx6Po6NI6PomgVp/zi6GRB8PfrOTA== + +esbuild-freebsd-arm64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.11.tgz#ae3e0b09173350b66cf8321583c9a1c1fcb8bb55" + integrity sha512-y3Llu4wbs0bk4cwjsdAtVOesXb6JkdfZDLKMt+v1U3tOEPBdSu6w8796VTksJgPfqvpX22JmPLClls0h5p+L9w== + +esbuild-jest@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/esbuild-jest/-/esbuild-jest-0.5.0.tgz#7a9964bfdecafca3b675a8aeb08193bcdba8b9d7" + integrity sha512-AMZZCdEpXfNVOIDvURlqYyHwC8qC1/BFjgsrOiSL1eyiIArVtHL8YAC83Shhn16cYYoAWEW17yZn0W/RJKJKHQ== + dependencies: + "@babel/core" "^7.12.17" + "@babel/plugin-transform-modules-commonjs" "^7.12.13" + babel-jest "^26.6.3" + +esbuild-linux-32@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.11.tgz#ddadbc7038aa5a6b1675bb1503cf79a0cbf1229a" + integrity sha512-Cg3nVsxArjyLke9EuwictFF3Sva+UlDTwHIuIyx8qpxRYAOUTmxr2LzYrhHyTcGOleLGXUXYsnUVwKqnKAgkcg== + +esbuild-linux-64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.11.tgz#d698e3ce3a231ddfeec6b5df8c546ae8883fcd88" + integrity sha512-oeR6dIrrojr8DKVrxtH3xl4eencmjsgI6kPkDCRIIFwv4p+K7ySviM85K66BN01oLjzthpUMvBVfWSJkBLeRbg== + +esbuild-linux-arm64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.11.tgz#85faea9fa99ad355b5e3b283197a4dfd0a110fe7" + integrity sha512-+e6ZCgTFQYZlmg2OqLkg1jHLYtkNDksxWDBWNtI4XG4WxuOCUErLqfEt9qWjvzK3XBcCzHImrajkUjO+rRkbMg== + +esbuild-linux-arm@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.11.tgz#74cbcf0b8a22c8401bcbcd6ebd4cbf2baca8b7b4" + integrity sha512-vcwskfD9g0tojux/ZaTJptJQU3a7YgTYsptK1y6LQ/rJmw7U5QJvboNawqM98Ca3ToYEucfCRGbl66OTNtp6KQ== + +esbuild-linux-mips64le@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.11.tgz#490429211a3233f5cbbd8575b7758b897e42979a" + integrity sha512-Rrs99L+p54vepmXIb87xTG6ukrQv+CzrM8eoeR+r/OFL2Rg8RlyEtCeshXJ2+Q66MXZOgPJaokXJZb9snq28bw== + +esbuild-linux-ppc64le@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.11.tgz#fc79d60710213b5b98345f5b138d48245616827a" + integrity sha512-JyzziGAI0D30Vyzt0HDihp4s1IUtJ3ssV2zx9O/c+U/dhUHVP2TmlYjzCfCr2Q6mwXTeloDcLS4qkyvJtYptdQ== + +esbuild-linux-s390x@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.11.tgz#ca4b93556bbba6cc95b0644f2ee93c982165ba07" + integrity sha512-DoThrkzunZ1nfRGoDN6REwmo8ZZWHd2ztniPVIR5RMw/Il9wiWEYBahb8jnMzQaSOxBsGp0PbyJeVLTUatnlcw== + +esbuild-netbsd-64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.11.tgz#edb340bc6653c88804cac2253e21b74258fce165" + integrity sha512-12luoRQz+6eihKYh1zjrw0CBa2aw3twIiHV/FAfjh2NEBDgJQOY4WCEUEN+Rgon7xmLh4XUxCQjnwrvf8zhACw== + +esbuild-openbsd-64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.11.tgz#caeff5f946f79a60ce7bcf88871ca4c71d3476e8" + integrity sha512-l18TZDjmvwW6cDeR4fmizNoxndyDHamGOOAenwI4SOJbzlJmwfr0jUgjbaXCUuYVOA964siw+Ix+A+bhALWg8Q== + +esbuild-sunos-64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.11.tgz#90ce7e1749c2958a53509b4bae7b8f7d98f276d6" + integrity sha512-bmYzDtwASBB8c+0/HVOAiE9diR7+8zLm/i3kEojUH2z0aIs6x/S4KiTuT5/0VKJ4zk69kXel1cNWlHBMkmavQg== + +esbuild-windows-32@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.11.tgz#d067f4ce15b29efba6336e6a23597120fafe49ec" + integrity sha512-J1Ys5hMid8QgdY00OBvIolXgCQn1ARhYtxPnG6ESWNTty3ashtc4+As5nTrsErnv8ZGUcWZe4WzTP/DmEVX1UQ== + +esbuild-windows-64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.11.tgz#13e86dd37a6cd61a5276fa2d271342d0f74da864" + integrity sha512-h9FmMskMuGeN/9G9+LlHPAoiQk9jlKDUn9yA0MpiGzwLa82E7r1b1u+h2a+InprbSnSLxDq/7p5YGtYVO85Mlg== + +esbuild-windows-arm64@0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.11.tgz#e8edfdf1d712085e6dc3fba18a0c225aaae32b75" + integrity sha512-dZp7Krv13KpwKklt9/1vBFBMqxEQIO6ri7Azf8C+ob4zOegpJmha2XY9VVWP/OyQ0OWk6cEeIzMJwInRZrzBUQ== + +esbuild@^0.14.11: + version "0.14.11" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.11.tgz#ac4acb78907874832afb704c3afe58ad37715c27" + integrity sha512-xZvPtVj6yecnDeFb3KjjCM6i7B5TCAQZT77kkW/CpXTMnd6VLnRPKrUB1XHI1pSq6a4Zcy3BGueQ8VljqjDGCg== + optionalDependencies: + esbuild-android-arm64 "0.14.11" + esbuild-darwin-64 "0.14.11" + esbuild-darwin-arm64 "0.14.11" + esbuild-freebsd-64 "0.14.11" + esbuild-freebsd-arm64 "0.14.11" + esbuild-linux-32 "0.14.11" + esbuild-linux-64 "0.14.11" + esbuild-linux-arm "0.14.11" + esbuild-linux-arm64 "0.14.11" + esbuild-linux-mips64le "0.14.11" + esbuild-linux-ppc64le "0.14.11" + esbuild-linux-s390x "0.14.11" + esbuild-netbsd-64 "0.14.11" + esbuild-openbsd-64 "0.14.11" + esbuild-sunos-64 "0.14.11" + esbuild-windows-32 "0.14.11" + esbuild-windows-64 "0.14.11" + esbuild-windows-arm64 "0.14.11" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -11531,7 +11717,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@^2.3.2, fsevents@~2.3.1: +fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -13747,6 +13933,27 @@ jest-haste-map@^24.9.0: optionalDependencies: fsevents "^1.2.7" +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== + dependencies: + "@jest/types" "^26.6.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^26.0.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.1.2" + jest-haste-map@^27.4.6: version "27.4.6" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.6.tgz#c60b5233a34ca0520f325b7e2cc0a0140ad0862a" @@ -13902,6 +14109,11 @@ jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + jest-regex-util@^27.4.0: version "27.4.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" @@ -14067,6 +14279,14 @@ jest-serializer@^24.9.0: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + jest-serializer@^27.4.0: version "27.4.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.4.0.tgz#34866586e1cae2388b7d12ffa2c7819edef5958a" @@ -14140,6 +14360,18 @@ jest-util@^24.0.0, jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + micromatch "^4.0.2" + jest-util@^27.4.2: version "27.4.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.4.2.tgz#ed95b05b1adfd761e2cda47e0144c6a58e05a621" @@ -14231,6 +14463,15 @@ jest-worker@^25.4.0: merge-stream "^2.0.0" supports-color "^7.0.0" +jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + jest-worker@^27.4.6: version "27.4.6" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.6.tgz#5d2d93db419566cb680752ca0792780e71b3273e" From 91f0109244f35ae64d9ea41cca544590b6620951 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Fri, 14 Jan 2022 20:15:16 +0000 Subject: [PATCH 05/88] Governnace sdk tests (#487) * chore: bump sdk version * chore: add getTokenOwnerRecordsByOwner test From 44dfff5926bc07f16b77cc5b2215bb074272ff61 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Fri, 14 Jan 2022 21:13:43 +0000 Subject: [PATCH 06/88] Governance: sdk tests (#488) * chore: bump sdk version * chore: add getTokenOwnerRecordsByOwner test * fix: change api call result from record to array --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/core/api.ts | 6 +++--- packages/governance-sdk/src/governance/api.ts | 5 +---- packages/governance-sdk/tsconfig.json | 5 ++++- packages/governance/package.json | 2 +- .../governance/src/contexts/GovernanceContext.tsx | 3 ++- packages/governance/src/hooks/accountHooks.ts | 3 ++- packages/governance/src/tools/script.ts | 10 ++++++++++ packages/governance/src/tools/version.ts | 13 ------------- 9 files changed, 24 insertions(+), 25 deletions(-) delete mode 100644 packages/governance/src/tools/version.ts diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index bcf21f3a..c05e8258 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.12", + "version": "0.0.13", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/core/api.ts b/packages/governance-sdk/src/core/api.ts index 2656b92c..2bc9ebb2 100644 --- a/packages/governance-sdk/src/core/api.ts +++ b/packages/governance-sdk/src/core/api.ts @@ -87,7 +87,7 @@ export async function getBorshProgramAccounts< ) { accountType = accountType ?? new accountFactory({}).accountType; - let programAccounts = await connection.getProgramAccounts(programId, { + const programAccounts = await connection.getProgramAccounts(programId, { commitment: connection.commitment, filters: [ { @@ -102,7 +102,7 @@ export async function getBorshProgramAccounts< ], }); - let accounts: { [pubKey: string]: ProgramAccount } = {}; + let accounts: ProgramAccount[] = []; for (let rawAccount of programAccounts) { try { @@ -115,7 +115,7 @@ export async function getBorshProgramAccounts< owner: rawAccount.account.owner, }; - accounts[account.pubkey.toBase58()] = account; + accounts.push(account); } catch (ex) { console.info( `Can't deserialize ${accountFactory.name} @ ${rawAccount.pubkey}.`, diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index 82148bcc..a22ec5ab 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -135,10 +135,7 @@ export async function getGovernanceAccounts( ), ); - return all.reduce((res, r) => ({ ...res, ...r }), {}) as Record< - string, - ProgramAccount - >; + return all.flatMap(a => a); } export async function getGovernanceAccount( diff --git a/packages/governance-sdk/tsconfig.json b/packages/governance-sdk/tsconfig.json index 2025a051..60e1a5d4 100644 --- a/packages/governance-sdk/tsconfig.json +++ b/packages/governance-sdk/tsconfig.json @@ -4,7 +4,10 @@ "declarationMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "target": "es5", + "target": "es6", + "lib": [ + "es2019" + ], "module": "commonjs", "noFallthroughCasesInSwitch": true, "noImplicitAny": true, diff --git a/packages/governance/package.json b/packages/governance/package.json index 5500a807..b07c4f32 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -9,7 +9,7 @@ "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", "@project-serum/serum": "^0.13.11", - "@solana/spl-governance": "0.0.12", + "@solana/spl-governance": "0.0.13", "@solana/spl-token": "0.0.13", "@solana/spl-token-swap": "0.1.0", "@solana/web3.js": "^1.22.0", diff --git a/packages/governance/src/contexts/GovernanceContext.tsx b/packages/governance/src/contexts/GovernanceContext.tsx index c8bf58ad..90c11892 100644 --- a/packages/governance/src/contexts/GovernanceContext.tsx +++ b/packages/governance/src/contexts/GovernanceContext.tsx @@ -17,6 +17,7 @@ import { useLocation } from 'react-router-dom'; import { PROGRAM_VERSION } from '@solana/spl-governance'; import { getGovernanceProgramVersion, ProgramAccount } from '@solana/spl-governance'; +import { arrayToRecord } from '../tools/script'; export interface GovernanceContextState { realms: Record>; @@ -127,7 +128,7 @@ export default function GovernanceProvider({ children = null as any }) { try { const loadedRealms = await getRealms(connection, programPk); - setRealms(loadedRealms); + setRealms(arrayToRecord(loadedRealms, r => r.pubkey.toBase58())); } catch (ex) { console.error("Can't load Realms", ex); setRealms({}); diff --git a/packages/governance/src/hooks/accountHooks.ts b/packages/governance/src/hooks/accountHooks.ts index 73b84dd3..8ced8ea1 100644 --- a/packages/governance/src/hooks/accountHooks.ts +++ b/packages/governance/src/hooks/accountHooks.ts @@ -15,6 +15,7 @@ import { useRpcContext } from './useRpcContext'; import { none, Option, some } from '../tools/option'; import { getGovernanceAccounts } from '@solana/spl-governance'; import { ProgramAccount } from '@solana/spl-governance'; +import { arrayToRecord } from '../tools/script'; // Fetches Governance program account using the given key and subscribes to updates export function useGovernanceAccountByPubkey< @@ -125,7 +126,7 @@ export function useGovernanceAccountsByFilter< (accountClass as any) as new (args: any) => TAccount, queryFilters, ); - setAccounts(loadedAccounts); + setAccounts(arrayToRecord(loadedAccounts, a => a.pubkey.toBase58())); } catch (ex) { console.error(`Can't load ${accountClass.name}`, ex); setAccounts({}); diff --git a/packages/governance/src/tools/script.ts b/packages/governance/src/tools/script.ts index 1e99c2e0..95258aec 100644 --- a/packages/governance/src/tools/script.ts +++ b/packages/governance/src/tools/script.ts @@ -15,3 +15,13 @@ export function getErrorMessage(ex: any) { return JSON.stringify(ex); } + +export function arrayToRecord( + source: readonly T[], + getKey: (item: T) => string, +) { + return source.reduce((all, a) => ({ ...all, [getKey(a)]: a }), {}) as Record< + string, + T + >; +} diff --git a/packages/governance/src/tools/version.ts b/packages/governance/src/tools/version.ts deleted file mode 100644 index 8fa15807..00000000 --- a/packages/governance/src/tools/version.ts +++ /dev/null @@ -1,13 +0,0 @@ -export function parseVersion(version: string) { - var arr = version.split('.'); - - // parse int or default to 0 - var major = parseInt(arr[0]) || 0; - var minor = parseInt(arr[1]) || 0; - var patch = parseInt(arr[2]) || 0; - return { - major, - minor, - patch, - }; -} From dd8044bb97850276fab95990680fc2c6a5db749f Mon Sep 17 00:00:00 2001 From: John Rees Date: Sat, 15 Jan 2022 01:22:59 +0000 Subject: [PATCH 07/88] Governance SDK: Remove moment (#490) > Moment.js is a legacy project, now in maintenance mode. In most cases, you should choose a different library. https://github.com/moment/moment#readme --- packages/governance-sdk/package.json | 1 - packages/governance-sdk/src/governance/accounts.ts | 5 ++--- yarn.lock | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index c05e8258..89952771 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -33,7 +33,6 @@ "bn.js": "^5.1.3", "borsh": "^0.3.1", "bs58": "^4.0.1", - "moment": "^2.29.1", "superstruct": "^0.15.2" }, "devDependencies": { diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 9c1d847e..f5648c09 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -3,7 +3,6 @@ import BN from 'bn.js'; import BigNumber from 'bignumber.js'; import { Vote, VoteKind } from './instructions'; import { PROGRAM_VERSION_V1, PROGRAM_VERSION_V2 } from '../registry/constants'; -import moment from 'moment'; /// Seed prefix for Governance Program PDAs export const GOVERNANCE_PROGRAM_SEED = 'governance'; @@ -728,13 +727,13 @@ export class Proposal { } getTimeToVoteEnd(governance: Governance) { - const now = moment().unix(); + const unixTimestampInSeconds = Date.now() / 1000; return this.isPreVotingState() ? governance.config.maxVotingTime : (this.votingAt?.toNumber() ?? 0) + governance.config.maxVotingTime - - now; + unixTimestampInSeconds; } hasVoteTimeEnded(governance: Governance) { diff --git a/yarn.lock b/yarn.lock index bbba31fb..2cce4bfe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16113,7 +16113,7 @@ module-not-found-error@^1.0.1: resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0" integrity sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA= -moment@^2.10.2, moment@^2.24.0, moment@^2.25.3, moment@^2.27.0, moment@^2.29.1: +moment@^2.10.2, moment@^2.24.0, moment@^2.25.3, moment@^2.27.0: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== From 281aeb30f75dfe45b2a18934f6758ea5bf6b6956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Brzezi=C5=84ski?= Date: Tue, 18 Jan 2022 23:01:34 +0100 Subject: [PATCH 08/88] Voter weight plugin config (#481) * voter weight addin * vote weight plugin yarn * playaround wip * fixes * fix version * configuremint * chore: setup DEFAULT_GOVERNANCE_PROGRAM_ID in .env files * chore: rename useVoteRegistry to useVoterStakeRegistryClient * chore: * feat: Configure voter stake registry with default values * feat: crate mint config form * fix: hide V2 options from V1 program UI * feat: add voterWeightAddin to realm config proposal * fix: add voterWeightRecord to sdk api * feat: setup voter stake configure mint instruction Co-authored-by: Sebastian.Bor --- .gitignore | 6 + .vscode/settings.json | 1 + packages/common/src/contexts/wallet.tsx | 78 ++++---- packages/governance-sdk/package.json | 2 +- .../governance-sdk/src/governance/accounts.ts | 2 +- .../src/governance/withCastVote.ts | 4 + .../governance/withCreateAccountGovernance.ts | 4 + .../governance/withCreateMintGovernance.ts | 4 + .../governance/withCreateProgramGovernance.ts | 4 + .../src/governance/withCreateProposal.ts | 10 +- .../governance/withCreateTokenGovernance.ts | 4 + .../src/governance/withVoterWeightAccounts.ts | 25 +++ packages/governance/.env | 3 + packages/governance/.env.development | 1 + packages/governance/package.json | 5 +- .../governance/src/actions/registerRealm.ts | 3 +- .../configureVoterStakeRegistry.ts | 78 ++++++++ .../ModalFormAction/modalFormAction.tsx | 2 + .../votingMintConfigFormItem.tsx | 86 ++++++++ .../src/contexts/GovernanceContext.tsx | 10 +- .../src/hooks/useVoterStakeRegistryClient.ts | 36 ++++ packages/governance/src/tools/units.ts | 7 + .../src/tools/validators/voterWeightPlugin.ts | 11 ++ .../src/tools/voterStakeRegistry/accounts.ts | 14 ++ .../voterStakeRegistry/voterStakeRegistry.ts | 10 + .../home/buttons/registerRealmButton.tsx | 30 ++- .../accountInstructionsForm.tsx | 4 +- .../governanceInstructionForm.tsx | 30 ++- .../instructionInput/instructionInput.tsx | 19 +- .../instructionInput/instructionSelector.tsx | 6 +- .../instructionInput/mintInstructionsForm.tsx | 4 +- .../programInstructionsForm.tsx | 4 +- .../instructionInput/realmConfigForm.tsx | 30 ++- .../tokenInstructionsForm.tsx | 16 +- .../voterStakeConfigureMintForm.tsx | 90 +++++++++ .../voterStakeSetRegistrarForm.tsx | 75 +++++++ .../configureVoterStakeRegistryButton.tsx | 57 ++++++ .../views/realm/buttons/realmActionBar.tsx | 14 +- yarn.lock | 183 ++++++++++++++++-- 39 files changed, 888 insertions(+), 84 deletions(-) create mode 100644 packages/governance-sdk/src/governance/withVoterWeightAccounts.ts create mode 100644 packages/governance/.env.development create mode 100644 packages/governance/src/actions/voterStakeRegistry/configureVoterStakeRegistry.ts create mode 100644 packages/governance/src/components/voterStakeRegistry/votingMintConfigFormItem.tsx create mode 100644 packages/governance/src/hooks/useVoterStakeRegistryClient.ts create mode 100644 packages/governance/src/tools/validators/voterWeightPlugin.ts create mode 100644 packages/governance/src/tools/voterStakeRegistry/accounts.ts create mode 100644 packages/governance/src/tools/voterStakeRegistry/voterStakeRegistry.ts create mode 100644 packages/governance/src/views/proposal/components/instructionInput/voterStakeRegistry/voterStakeConfigureMintForm.tsx create mode 100644 packages/governance/src/views/proposal/components/instructionInput/voterStakeRegistry/voterStakeSetRegistrarForm.tsx create mode 100644 packages/governance/src/views/realm/buttons/configureVoterStakeRegistryButton.tsx diff --git a/.gitignore b/.gitignore index 0fbbdfef..215e4017 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,9 @@ yarn-debug.log* yarn-error.log* *.css *.css.map + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local diff --git a/.vscode/settings.json b/.vscode/settings.json index a79af11e..5d4dab63 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,7 @@ "cSpell.words": [ "Addin", "Blockhash", + "blockworks", "Lamport", "lamports", "localnet", diff --git a/packages/common/src/contexts/wallet.tsx b/packages/common/src/contexts/wallet.tsx index 926a0753..e159fd09 100644 --- a/packages/common/src/contexts/wallet.tsx +++ b/packages/common/src/contexts/wallet.tsx @@ -9,7 +9,7 @@ import { } from '@solana/wallet-adapter-base'; import { useWallet as useWalletBase, - WalletProvider as BaseWalletProvider + WalletProvider as BaseWalletProvider, } from '@solana/wallet-adapter-react'; import { getLedgerWallet, @@ -22,10 +22,19 @@ import { Wallet, WalletName, } from '@solana/wallet-adapter-wallets'; -import { Button, Modal } from "antd"; -import React, { createContext, FC, ReactNode, useCallback, useContext, useEffect, useMemo, useState } from 'react'; -import { notify } from "../utils"; -import { useConnectionConfig } from "./connection"; +import { Button, Modal } from 'antd'; +import React, { + createContext, + FC, + ReactNode, + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from 'react'; +import { notify } from '../utils'; +import { useConnectionConfig } from './connection'; export interface WalletContextState extends WalletAdapterProps { wallets: Wallet[]; @@ -43,20 +52,25 @@ export interface WalletContextState extends WalletAdapterProps { signMessage: MessageSignerWalletAdapterProps['signMessage'] | undefined; } -export function useWallet (): WalletContextState { +export function useWallet(): WalletContextState { return useWalletBase() as WalletContextState; } export { SignerWalletAdapter, WalletNotConnectedError }; -export type WalletSigner = Pick; +export type WalletSigner = Pick< + SignerWalletAdapter, + 'publicKey' | 'signTransaction' | 'signAllTransactions' +>; export interface WalletModalContextState { visible: boolean; setVisible: (open: boolean) => void; } -export const WalletModalContext = createContext({} as WalletModalContextState); +export const WalletModalContext = createContext( + {} as WalletModalContextState, +); export function useWalletModal(): WalletModalContextState { return useContext(WalletModalContext); @@ -76,20 +90,23 @@ export const WalletModal = () => { onCancel={close} width={400} > - {wallets.map((wallet) => { + {wallets.map(wallet => { return ( + + + Close + , + ]} + > + + + + + ); +} + +function getLogTextType(text: string): BaseType { + // Use some heuristics to highlight error and success log messages + + text = text.toLowerCase(); + + if (text.includes('failed')) { + return 'danger'; + } + + if (text.includes('success')) { + return 'success'; + } + + return 'secondary'; +} + +function DryRunStatus({ + isPending, + result, + rpcContext, + error, +}: { + rpcContext: RpcContext; + isPending: boolean; + result: + | { response: SimulatedTransactionResponse; transaction: Transaction } + | undefined; + error: Error | undefined; +}) { + const iconStyle = { fontSize: '150%' }; + + if (error) { + return ( + + + + + {`Can't run simulation. Error: ${error.message}`} + + ); + } + + if (isPending || !result) { + return ; + } + + const onInspect = () => { + const { endpoint, connection } = rpcContext; + + const inspectUrl = getExplorerInspectorUrl( + endpoint, + result.transaction, + connection, + ); + window.open(inspectUrl, '_blank'); + }; + + return ( + <> + + + {result.response.err ? ( + + + + ) : ( + + + + )} + + +

+ {result.response.err + ? 'Simulation returned an error' + : 'Simulation ran successfully'} +

+ +
+ + +
    + {result.response.logs?.map((log, i) => ( +
  • + {log} +
  • + ))} +
+ +
+ + + + + + + ); +} diff --git a/packages/governance/src/views/proposal/proposalView.tsx b/packages/governance/src/views/proposal/proposalView.tsx index 8f7e78f4..d9d8c4fa 100644 --- a/packages/governance/src/views/proposal/proposalView.tsx +++ b/packages/governance/src/views/proposal/proposalView.tsx @@ -43,6 +43,7 @@ import { useRealm } from '../../contexts/GovernanceContext'; import { getMintMaxVoteWeight } from '../../tools/units'; import { ProposalActionBar } from './components/buttons/proposalActionBar'; import { ProgramAccount } from '@solana/spl-governance'; +import { DryRunProposalButton } from './components/instruction/buttons/dryRunProposalButton'; const { TabPane } = Tabs; @@ -445,6 +446,16 @@ function InnerProposalView({ )} + + + Date: Mon, 21 Feb 2022 09:50:03 +0100 Subject: [PATCH 33/88] Governance: Rename vsr set-registrar instruction to create-registrar (#521) It's confusing to diverge from the upstream instruction name. --- .../instructionInput/governanceInstructionForm.tsx | 10 +++++----- .../instructionInput/instructionSelector.tsx | 4 ++-- ...strarForm.tsx => voterStakeCreateRegistrarForm.tsx} | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) rename packages/governance/src/views/proposal/components/instructionInput/voterStakeRegistry/{voterStakeSetRegistrarForm.tsx => voterStakeCreateRegistrarForm.tsx} (92%) diff --git a/packages/governance/src/views/proposal/components/instructionInput/governanceInstructionForm.tsx b/packages/governance/src/views/proposal/components/instructionInput/governanceInstructionForm.tsx index 2a0b782f..04f35bb4 100644 --- a/packages/governance/src/views/proposal/components/instructionInput/governanceInstructionForm.tsx +++ b/packages/governance/src/views/proposal/components/instructionInput/governanceInstructionForm.tsx @@ -8,7 +8,7 @@ import { TransactionInstruction } from '@solana/web3.js'; import { RealmConfigForm } from './realmConfigForm'; import { NativeTransferForm } from './nativeTokenTransferForm'; import { ProgramAccount } from '@solana/spl-governance'; -import { VoterStakeSetRegistrarForm } from './voterStakeRegistry/voterStakeSetRegistrarForm'; +import { VoterStakeCreateRegistrarForm } from './voterStakeRegistry/voterStakeCreateRegistrarForm'; import { VoterStakeConfigureMintForm } from './voterStakeRegistry/voterStakeConfigureMintForm'; import { SetRealmAuthorityForm } from './setRealmAuthority'; @@ -24,7 +24,7 @@ export function getGovernanceInstructions( instructions.push(InstructionType.SetRealmAuthority); if (programVersion > PROGRAM_VERSION_V1) { - instructions.push(InstructionType.VoterStakeSetRegistrar); + instructions.push(InstructionType.VoterStakeCreateRegistrar); instructions.push(InstructionType.VoterStakeConfigureMint); } } @@ -78,13 +78,13 @@ export function GovernanceInstructionForm({ onCreateInstruction={onCreateInstruction} > )} - {instruction === InstructionType.VoterStakeSetRegistrar && ( - + > )} {instruction === InstructionType.VoterStakeConfigureMint && ( Date: Fri, 4 Mar 2022 11:30:03 -0600 Subject: [PATCH 34/88] disallow crawling - reduce traffic --- packages/bridge/public/robots.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bridge/public/robots.txt b/packages/bridge/public/robots.txt index e9e57dc4..26c1d46a 100644 --- a/packages/bridge/public/robots.txt +++ b/packages/bridge/public/robots.txt @@ -1,3 +1,3 @@ # https://www.robotstxt.org/robotstxt.html User-agent: * -Disallow: +Disallow: * From eca8ea43d2ed71d07b2a86b73d4b607f2083693c Mon Sep 17 00:00:00 2001 From: Evan Doyle Date: Wed, 9 Mar 2022 02:46:54 -0800 Subject: [PATCH 35/88] Payer must be writable in instructions which create Accounts (#524) --- .../src/governance/withCreateProgramGovernance.ts | 2 +- packages/governance-sdk/src/governance/withCreateProposal.ts | 2 +- packages/governance-sdk/src/governance/withCreateRealm.ts | 2 +- .../governance-sdk/src/governance/withCreateTokenGovernance.ts | 2 +- .../governance-sdk/src/governance/withDepositGoverningTokens.ts | 2 +- packages/governance-sdk/src/governance/withInsertTransaction.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts index 7715cd50..812947d8 100644 --- a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts @@ -79,7 +79,7 @@ export const withCreateProgramGovernance = async ( }, { pubkey: payer, - isWritable: false, + isWritable: true, isSigner: true, }, { diff --git a/packages/governance-sdk/src/governance/withCreateProposal.ts b/packages/governance-sdk/src/governance/withCreateProposal.ts index 7bbca4f0..3df56005 100644 --- a/packages/governance-sdk/src/governance/withCreateProposal.ts +++ b/packages/governance-sdk/src/governance/withCreateProposal.ts @@ -96,7 +96,7 @@ export const withCreateProposal = async ( }, { pubkey: payer, - isWritable: false, + isWritable: true, isSigner: true, }, { diff --git a/packages/governance-sdk/src/governance/withCreateRealm.ts b/packages/governance-sdk/src/governance/withCreateRealm.ts index 9fb91319..06ba6c67 100644 --- a/packages/governance-sdk/src/governance/withCreateRealm.ts +++ b/packages/governance-sdk/src/governance/withCreateRealm.ts @@ -88,7 +88,7 @@ export async function withCreateRealm( { pubkey: payer, isSigner: true, - isWritable: false, + isWritable: true, }, { pubkey: SYSTEM_PROGRAM_ID, diff --git a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts index e3bd6a82..49f1a161 100644 --- a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts @@ -69,7 +69,7 @@ export const withCreateTokenGovernance = async ( }, { pubkey: payer, - isWritable: false, + isWritable: true, isSigner: true, }, { diff --git a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts index a1ee2fe1..88d0ba24 100644 --- a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts @@ -81,7 +81,7 @@ export const withDepositGoverningTokens = async ( }, { pubkey: payer, - isWritable: false, + isWritable: true, isSigner: true, }, { diff --git a/packages/governance-sdk/src/governance/withInsertTransaction.ts b/packages/governance-sdk/src/governance/withInsertTransaction.ts index e14b8a64..efa27060 100644 --- a/packages/governance-sdk/src/governance/withInsertTransaction.ts +++ b/packages/governance-sdk/src/governance/withInsertTransaction.ts @@ -77,7 +77,7 @@ export const withInsertTransaction = async ( }, { pubkey: payer, - isWritable: false, + isWritable: true, isSigner: true, }, { From f2061fd3248a7cee4d433b87d30d2ce4e37dd860 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Wed, 9 Mar 2022 10:48:34 +0000 Subject: [PATCH 36/88] chore: bump @solana/spl-governance version --- packages/governance-sdk/package.json | 2 +- packages/governance/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index e49d93fb..8a672a4e 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.28", + "version": "0.0.29", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance/package.json b/packages/governance/package.json index 01a43d54..cdce959f 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.0.28", + "@solana/spl-governance": "0.0.29", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From c0e78c8a1d53d924d75adcea18595255eab6b3bc Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 14 Mar 2022 14:08:59 -0400 Subject: [PATCH 37/88] feat: add tryGetRealmConfig (#529) * feat: add tryGetRealmConfig * chore: bump mpm version --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/api.ts | 29 +++++++++++++++++++ .../tests/governance/api.smoke.test.ts | 20 ++++++++++++- packages/governance/package.json | 2 +- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 8a672a4e..6a6f2170 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.29", + "version": "0.0.30", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index ecb0ed46..30d00f90 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -14,6 +14,8 @@ import { Realm, TokenOwnerRecord, VoteRecord, + RealmConfigAccount, + getRealmConfigAddress, } from './accounts'; import { @@ -34,6 +36,16 @@ export async function getRealms(connection: Connection, programId: PublicKey) { return getGovernanceAccounts(connection, programId, Realm); } +// Realm config +export async function tryGetRealmConfig( + connection: Connection, + programId: PublicKey, + realmPk: PublicKey, +) { + const realmConfigPk = await getRealmConfigAddress(programId, realmPk); + return getGovernanceAccount(connection, realmConfigPk, RealmConfigAccount); +} + // VoteRecords export async function getVoteRecordsByVoter( @@ -222,3 +234,20 @@ export async function getGovernanceAccount( accountInfo, ) as ProgramAccount; } + +export async function tryGetGovernanceAccount< + TAccount extends GovernanceAccount +>( + connection: Connection, + accountPk: PublicKey, + accountClass: new (args: any) => TAccount | undefined, +) { + const accountInfo = await connection.getAccountInfo(accountPk); + + if (accountInfo) { + return GovernanceAccountParser(accountClass as any)( + accountPk, + accountInfo, + ) as ProgramAccount; + } +} diff --git a/packages/governance-sdk/tests/governance/api.smoke.test.ts b/packages/governance-sdk/tests/governance/api.smoke.test.ts index d98a48e3..78a4cf19 100644 --- a/packages/governance-sdk/tests/governance/api.smoke.test.ts +++ b/packages/governance-sdk/tests/governance/api.smoke.test.ts @@ -31,7 +31,6 @@ import { Vote, YesNoVote, withCancelProposal, - withExecuteInstruction, withFlagTransactionError, withWithdrawGoverningTokens, withUpdateProgramMetadata, @@ -39,6 +38,12 @@ import { getAllGovernances, getAllProposals, getAllTokenOwnerRecords, + getRealmConfig, + getRealmConfigAddress, + tryGetGovernanceAccount, + RealmConfigAccount, + tryGetRealmConfig, + getRealms, } from '../../src'; import { withSetRealmConfig } from '../../src/governance/withSetRealmConfig'; @@ -448,4 +453,17 @@ test('getAllTokenOwnerRecords', async () => { expect(tokenOwnerRecords.length).toBeGreaterThan(0); +}); + +test('tryGetRealmConfig', async () => { + // Arrange + const realmPk = new PublicKey("A98TAf9KwCMMd9GmXogc9D3Lj9diYGkAZctUZZPXEf41") + const programId = new PublicKey("AuetJrDq4USDLibT83abUB9pniWFQuPsZa3YNYtrqUWP") + + // Act + const realmConfig = await tryGetRealmConfig(connection,programId,realmPk); + + // Assert + expect(realmConfig.account.realm).toEqual(realmPk); + }); \ No newline at end of file diff --git a/packages/governance/package.json b/packages/governance/package.json index cdce959f..18a2cfb6 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.0.29", + "@solana/spl-governance": "0.0.30", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From 53b7b29778242d821953997a91ab48af798ac05b Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 21 Mar 2022 12:14:54 -0400 Subject: [PATCH 38/88] Governance SDK: Implement withSetGovernanceDelegate (#532) * feat: implement withSetGovernanceDelegate * chore: bump version --- packages/governance-sdk/package.json | 2 +- .../governance-sdk/src/governance/accounts.ts | 2 + packages/governance-sdk/src/governance/api.ts | 7 ++ .../governance-sdk/src/governance/index.ts | 1 + .../src/governance/instructions.ts | 11 ++ .../src/governance/serialisation.ts | 11 ++ .../governance/withSetGovernanceDelegate.ts | 51 +++++++++ .../tests/governance/api.smoke.test.ts | 106 ++++++++++++++++-- packages/governance/package.json | 2 +- 9 files changed, 183 insertions(+), 10 deletions(-) create mode 100644 packages/governance-sdk/src/governance/withSetGovernanceDelegate.ts diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 6a6f2170..eb2603ea 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.30", + "version": "0.0.31", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 2e9d8a65..601883a3 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -463,6 +463,7 @@ export class TokenOwnerRecord { totalVotesCount: number; outstandingProposalCount: number; reserved: Uint8Array; + governanceDelegate: PublicKey | undefined; }) { this.realm = args.realm; this.governingTokenMint = args.governingTokenMint; @@ -472,6 +473,7 @@ export class TokenOwnerRecord { this.totalVotesCount = args.totalVotesCount; this.outstandingProposalCount = args.outstandingProposalCount; this.reserved = args.reserved; + this.governanceDelegate = args.governanceDelegate; } } diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index 30d00f90..b75c1f50 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -77,6 +77,13 @@ export async function getTokenOwnerRecordForRealm( return getGovernanceAccount(connection, tokenOwnerRecordPk, TokenOwnerRecord); } +export async function getTokenOwnerRecord( + connection: Connection, + tokenOwnerRecordPk: PublicKey, +) { + return getGovernanceAccount(connection, tokenOwnerRecordPk, TokenOwnerRecord); +} + /** * Returns TokenOwnerRecords for the given token owner (voter) * Note: The function returns TokenOwnerRecords for both council and community token holders diff --git a/packages/governance-sdk/src/governance/index.ts b/packages/governance-sdk/src/governance/index.ts index 98d5c55a..8942647d 100644 --- a/packages/governance-sdk/src/governance/index.ts +++ b/packages/governance-sdk/src/governance/index.ts @@ -27,6 +27,7 @@ export * from './withInsertTransaction'; export * from './withRelinquishVote'; export * from './withRemoveTransaction'; export * from './withSetRealmAuthority'; +export * from './withSetGovernanceDelegate'; export * from './withSignOffProposal'; export * from './withUpdateProgramMetadata'; export * from './withWithdrawGoverningTokens'; diff --git a/packages/governance-sdk/src/governance/instructions.ts b/packages/governance-sdk/src/governance/instructions.ts index da3628c2..8b4ab26b 100644 --- a/packages/governance-sdk/src/governance/instructions.ts +++ b/packages/governance-sdk/src/governance/instructions.ts @@ -362,3 +362,14 @@ export class CreateNativeTreasuryArgs { instruction: GovernanceInstruction = GovernanceInstruction.CreateNativeTreasury; } + +export class SetGovernanceDelegateArgs { + instruction: GovernanceInstruction = + GovernanceInstruction.SetGovernanceDelegate; + + newGovernanceDelegate: PublicKey | undefined; + + constructor(args: { newGovernanceDelegate: PublicKey | undefined }) { + this.newGovernanceDelegate = args.newGovernanceDelegate; + } +} diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 05dcb2f2..bdad145f 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -21,6 +21,7 @@ import { RelinquishVoteArgs, RemoveTransactionArgs, SetGovernanceConfigArgs, + SetGovernanceDelegateArgs, SetRealmAuthorityArgs, SetRealmConfigArgs, SignOffProposalArgs, @@ -238,6 +239,16 @@ function createGovernanceSchema(programVersion: number) { fields: [['instruction', 'u8']], }, ], + [ + SetGovernanceDelegateArgs, + { + kind: 'struct', + fields: [ + ['instruction', 'u8'], + ['newGovernanceDelegate', { kind: 'option', type: 'pubkey' }], + ], + }, + ], [ CreateGovernanceArgs, { diff --git a/packages/governance-sdk/src/governance/withSetGovernanceDelegate.ts b/packages/governance-sdk/src/governance/withSetGovernanceDelegate.ts new file mode 100644 index 00000000..1e6da0dc --- /dev/null +++ b/packages/governance-sdk/src/governance/withSetGovernanceDelegate.ts @@ -0,0 +1,51 @@ +import { PublicKey, TransactionInstruction } from '@solana/web3.js'; +import { getGovernanceSchema } from './serialisation'; +import { serialize } from 'borsh'; +import { SetGovernanceDelegateArgs } from './instructions'; +import { getTokenOwnerRecordAddress } from './accounts'; + +export const withSetGovernanceDelegate = async ( + instructions: TransactionInstruction[], + programId: PublicKey, + programVersion: number, + realm: PublicKey, + governingTokenMint: PublicKey, + governingTokenOwner: PublicKey, + governanceAuthority: PublicKey, + newGovernanceDelegate: PublicKey | undefined, +) => { + const args = new SetGovernanceDelegateArgs({ + newGovernanceDelegate: newGovernanceDelegate, + }); + const data = Buffer.from( + serialize(getGovernanceSchema(programVersion), args), + ); + + const tokenOwnerRecordAddress = await getTokenOwnerRecordAddress( + programId, + realm, + governingTokenMint, + governingTokenOwner, + ); + + let keys = [ + { + pubkey: governanceAuthority, + isWritable: false, + isSigner: true, + }, + { + pubkey: tokenOwnerRecordAddress, + isWritable: true, + isSigner: false, + }, + ]; + + instructions.push( + new TransactionInstruction({ + keys, + programId, + data, + }), + ); +}; diff --git a/packages/governance-sdk/tests/governance/api.smoke.test.ts b/packages/governance-sdk/tests/governance/api.smoke.test.ts index 78a4cf19..80ba10f2 100644 --- a/packages/governance-sdk/tests/governance/api.smoke.test.ts +++ b/packages/governance-sdk/tests/governance/api.smoke.test.ts @@ -11,7 +11,6 @@ import { createInstructionData, getGovernanceProgramVersion, getRealm, - getTokenOwnerRecordsByOwner, GovernanceConfig, MintMaxVoteWeightSource, VoteThresholdPercentage, @@ -38,12 +37,11 @@ import { getAllGovernances, getAllProposals, getAllTokenOwnerRecords, - getRealmConfig, - getRealmConfigAddress, - tryGetGovernanceAccount, - RealmConfigAccount, tryGetRealmConfig, - getRealms, + withExecuteTransaction, + withSetGovernanceDelegate, + getTokenOwnerRecordForRealm, + getTokenOwnerRecord, } from '../../src'; import { withSetRealmConfig } from '../../src/governance/withSetRealmConfig'; @@ -382,7 +380,7 @@ test('setupRealm', async () => { transactionPk, ); - await withExecuteInstruction( + await withExecuteTransaction( instructions, programId, programVersion, @@ -466,4 +464,96 @@ test('tryGetRealmConfig', async () => { // Assert expect(realmConfig.account.realm).toEqual(realmPk); -}); \ No newline at end of file +}); + + +test('setGovernanceDelegate', async () => { + // Arrange + const wallet = Keypair.generate(); + const walletPk = wallet.publicKey; + + await requestAirdrop(connection, walletPk); + + await new Promise(f => setTimeout(f, 1000)); + + // Get governance program version + const programVersion = await getGovernanceProgramVersion( + connection, + programId, + ); + + let instructions: TransactionInstruction[] = []; + let signers: Keypair[] = []; + + // Create and mint governance token + let mintPk = await withCreateMint( + connection, + instructions, + signers, + walletPk, + walletPk, + 0, + walletPk, + ); + + let ataPk = await withCreateAssociatedTokenAccount( + instructions, + mintPk, + walletPk, + walletPk, + ); + await withMintTo(instructions, mintPk, ataPk, walletPk, 1); + + // Create Realm + const name = `Realm-${new Keypair().publicKey.toBase58().slice(0, 6)}`; + const realmAuthorityPk = walletPk; + const communityMintMaxVoteWeightSource = + MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION; + const councilMintPk = undefined; + + const realmPk = await withCreateRealm( + instructions, + programId, + programVersion, + name, + realmAuthorityPk, + mintPk, + walletPk, + councilMintPk, + communityMintMaxVoteWeightSource, + new BN(1), + ); + + // Deposit governance tokens + const tokenOwnerRecordPk = await withDepositGoverningTokens( + instructions, + programId, + programVersion, + realmPk, + ataPk, + mintPk, + walletPk, + walletPk, + walletPk, + new BN(1), + ); + + await sendTransaction(connection, instructions, signers, wallet); + instructions = []; + signers = []; + + + const delegatePk = Keypair.generate().publicKey; + + // Act + await withSetGovernanceDelegate(instructions,programId,programVersion,realmPk,mintPk,walletPk,walletPk,delegatePk); + await sendTransaction(connection, instructions, signers, wallet); + + // Assert + let tokenOwnerRecord = await getTokenOwnerRecord(connection,tokenOwnerRecordPk) + + expect(tokenOwnerRecord.account.governanceDelegate).toEqual(delegatePk); + +}); + + diff --git a/packages/governance/package.json b/packages/governance/package.json index 18a2cfb6..025ff318 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.0.30", + "@solana/spl-governance": "0.0.31", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From 7f090a5f994695f25e5c1280d50f09284d7d9a90 Mon Sep 17 00:00:00 2001 From: "Sebastian.Bor" Date: Mon, 21 Mar 2022 20:23:26 +0000 Subject: [PATCH 39/88] chore: bump spl-gov-sdk version to 0.0.32 --- packages/governance-sdk/package.json | 2 +- packages/governance/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index eb2603ea..85d98cff 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.31", + "version": "0.0.32", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance/package.json b/packages/governance/package.json index 025ff318..69259425 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.0.31", + "@solana/spl-governance": "0.0.32", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From 4090e3915f05019d4f3b4a9d15c5015207fdef70 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 21 Mar 2022 19:46:36 -0400 Subject: [PATCH 40/88] Governance SDK: MaxVoterWeightRecord account and api (#533) * wip: add addins accounts * feat: add MaxVoterWeightRecord account and api --- .../governance-sdk/src/addins/accounts.ts | 49 +++++++++++++++++++ packages/governance-sdk/src/addins/api.ts | 34 +++++++++++++ packages/governance-sdk/src/addins/index.ts | 3 ++ .../src/addins/serialisation.ts | 22 +++++++++ .../governance-sdk/src/governance/accounts.ts | 1 - packages/governance-sdk/src/index.ts | 1 + .../tests/addins/api.smoke.test.ts | 45 +++++++++++++++++ 7 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 packages/governance-sdk/src/addins/accounts.ts create mode 100644 packages/governance-sdk/src/addins/api.ts create mode 100644 packages/governance-sdk/src/addins/index.ts create mode 100644 packages/governance-sdk/src/addins/serialisation.ts create mode 100644 packages/governance-sdk/tests/addins/api.smoke.test.ts diff --git a/packages/governance-sdk/src/addins/accounts.ts b/packages/governance-sdk/src/addins/accounts.ts new file mode 100644 index 00000000..7239c654 --- /dev/null +++ b/packages/governance-sdk/src/addins/accounts.ts @@ -0,0 +1,49 @@ +import { PublicKey } from '@solana/web3.js'; +import BN from 'bn.js'; + +export type GovernanceAddinAccountClass = typeof MaxVoterWeightRecord; + +export class MaxVoterWeightRecord { + accountDiscriminator = new Uint8Array([57, 100, 53, 102, 102, 50, 57, 55]); + + realm: PublicKey; + + governingTokenMint: PublicKey; + + maxVoterWeight: BN; + + maxVoterWeightExpiry: BN; + + constructor(args: { + realm: PublicKey; + governingTokenMint: PublicKey; + maxVoterWeight: BN; + maxVoterWeightExpiry: BN; + }) { + this.realm = args.realm; + this.governingTokenMint = args.governingTokenMint; + this.maxVoterWeight = args.maxVoterWeight; + this.maxVoterWeightExpiry = args.maxVoterWeightExpiry; + } +} + +/** + * Returns the default address for MaxVoterWeightRecord + * Note: individual addins are not required to use the default address and it can vary between different implementations + **/ +export async function getMaxVoterWeightRecordAddress( + programId: PublicKey, + realm: PublicKey, + governingTokenMint: PublicKey, +) { + const [maxVoterWeightRecordAddress] = await PublicKey.findProgramAddress( + [ + Buffer.from('max-voter-weight-record'), + realm.toBuffer(), + governingTokenMint.toBuffer(), + ], + programId, + ); + + return maxVoterWeightRecordAddress; +} diff --git a/packages/governance-sdk/src/addins/api.ts b/packages/governance-sdk/src/addins/api.ts new file mode 100644 index 00000000..d689dfdc --- /dev/null +++ b/packages/governance-sdk/src/addins/api.ts @@ -0,0 +1,34 @@ +import { Connection, PublicKey } from '@solana/web3.js'; +import { ProgramAccount } from '../tools/sdk/runtime'; +import { MaxVoterWeightRecord } from './accounts'; +import { GovernanceAddinAccountParser } from './serialisation'; + +export async function getMaxVoterWeightRecord( + connection: Connection, + maxVoterWeightRecordPk: PublicKey, +) { + return getGovernanceAddinAccount( + connection, + maxVoterWeightRecordPk, + MaxVoterWeightRecord, + ); +} + +export async function getGovernanceAddinAccount( + connection: Connection, + accountPk: PublicKey, + accountClass: new (args: any) => TAccount, +) { + const accountInfo = await connection.getAccountInfo(accountPk); + + if (!accountInfo) { + throw new Error( + `Account ${accountPk} of type ${accountClass.name} not found`, + ); + } + + return GovernanceAddinAccountParser(accountClass as any)( + accountPk, + accountInfo, + ) as ProgramAccount; +} diff --git a/packages/governance-sdk/src/addins/index.ts b/packages/governance-sdk/src/addins/index.ts new file mode 100644 index 00000000..7aacc424 --- /dev/null +++ b/packages/governance-sdk/src/addins/index.ts @@ -0,0 +1,3 @@ +export * from './accounts'; +export * from './api'; +export * from './serialisation'; diff --git a/packages/governance-sdk/src/addins/serialisation.ts b/packages/governance-sdk/src/addins/serialisation.ts new file mode 100644 index 00000000..1b42a778 --- /dev/null +++ b/packages/governance-sdk/src/addins/serialisation.ts @@ -0,0 +1,22 @@ +import { GovernanceAddinAccountClass, MaxVoterWeightRecord } from './accounts'; +import { BorshAccountParser } from '../core/serialisation'; + +export const GOVERNANCE_ADDINS_SCHEMA = new Map([ + [ + MaxVoterWeightRecord, + { + kind: 'struct', + fields: [ + ['accountDiscriminator', [8]], + ['realm', 'pubkey'], + ['governingTokenMint', 'pubkey'], + ['maxVoterWeight', 'u64'], + ['maxVoterWeightExpiry', 'u64'], + ], + }, + ], +]); + +export const GovernanceAddinAccountParser = ( + classType: GovernanceAddinAccountClass, +) => BorshAccountParser(classType, _ => GOVERNANCE_ADDINS_SCHEMA); diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 601883a3..3246fdc5 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -3,7 +3,6 @@ import BN from 'bn.js'; import BigNumber from 'bignumber.js'; import { Vote, VoteKind } from './instructions'; import { PROGRAM_VERSION_V1, PROGRAM_VERSION_V2 } from '../registry/constants'; -import { getErrorMessage } from '..'; /// Seed prefix for Governance Program PDAs export const GOVERNANCE_PROGRAM_SEED = 'governance'; diff --git a/packages/governance-sdk/src/index.ts b/packages/governance-sdk/src/index.ts index f12c39d4..cb59559d 100644 --- a/packages/governance-sdk/src/index.ts +++ b/packages/governance-sdk/src/index.ts @@ -1,3 +1,4 @@ +export * from './addins'; export * from './chat'; export * from './core'; export * from './governance'; diff --git a/packages/governance-sdk/tests/addins/api.smoke.test.ts b/packages/governance-sdk/tests/addins/api.smoke.test.ts new file mode 100644 index 00000000..a3337092 --- /dev/null +++ b/packages/governance-sdk/tests/addins/api.smoke.test.ts @@ -0,0 +1,45 @@ +import { clusterApiUrl, Connection, Keypair, PublicKey } from '@solana/web3.js'; +import { + getMaxVoterWeightRecord, + getMaxVoterWeightRecordAddress, +} from '../../src'; +import { requestAirdrop } from '../tools/sdk'; + +const rpcEndpoint = clusterApiUrl('devnet'); +const connection = new Connection(rpcEndpoint, 'recent'); + +test('getMaxVoterWeightRecord', async () => { + // Arrange + const wallet = Keypair.generate(); + const walletPk = wallet.publicKey; + + await requestAirdrop(connection, walletPk); + + const realmPk = new PublicKey('Bt9gu17V9DLQNYa6gnbtrbFSEiX4kqbeHAbNCH2dcKr'); + const governingTokenMintPk = new PublicKey( + '2zBFETjTFMSjeS8Rfv43qYyCTLtGSRXRk1hWwJ1u7WgH', + ); + + const addinProgramId = new PublicKey( + 'FDfF7jzJDCEkFWNi3is487k8rFPJxFkU821t2pQ1vDr1', + ); + + const maxVoterWeightRecordPk = await getMaxVoterWeightRecordAddress( + addinProgramId, + realmPk, + governingTokenMintPk, + ); + + // Act + const maxVoterWeightRecord = await getMaxVoterWeightRecord( + connection, + maxVoterWeightRecordPk, + ); + + // Assert + expect(maxVoterWeightRecord.account.realm).toEqual(realmPk); + + expect(maxVoterWeightRecord.account.governingTokenMint).toEqual( + governingTokenMintPk, + ); +}); From 90a0eb248fe043a7ccc554c6cd23242351cb0c5c Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Tue, 22 Mar 2022 18:54:37 +0000 Subject: [PATCH 41/88] Governance SDK: Add VoterWeightRecord account and api (#534) --- packages/governance-sdk/package.json | 2 +- .../governance-sdk/src/addins/accounts.ts | 71 ++++++++++++++++++- packages/governance-sdk/src/addins/api.ts | 13 +++- .../src/addins/serialisation.ts | 24 ++++++- .../tests/addins/api.smoke.test.ts | 47 ++++++++++++ packages/governance/package.json | 2 +- 6 files changed, 153 insertions(+), 6 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 85d98cff..98a2f827 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.32", + "version": "0.0.34", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/addins/accounts.ts b/packages/governance-sdk/src/addins/accounts.ts index 7239c654..3f0f1bdf 100644 --- a/packages/governance-sdk/src/addins/accounts.ts +++ b/packages/governance-sdk/src/addins/accounts.ts @@ -1,7 +1,76 @@ import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; -export type GovernanceAddinAccountClass = typeof MaxVoterWeightRecord; +export type GovernanceAddinAccountClass = + | typeof VoterWeightRecord + | MaxVoterWeightRecord; + +export enum VoterWeightAction { + CastVote, + CommentProposal, + CreateGovernance, + CreateProposal, + SignOffProposal, +} + +export class VoterWeightRecord { + accountDiscriminator = new Uint8Array([50, 101, 102, 57, 57, 98, 52, 98]); + + realm: PublicKey; + + governingTokenMint: PublicKey; + + governingTokenOwner: PublicKey; + + voterWeight: BN; + + voterWeightExpiry: BN; + + weightAction: VoterWeightAction | undefined; + + weightActionTarget: PublicKey | undefined; + + constructor(args: { + realm: PublicKey; + governingTokenMint: PublicKey; + governingTokenOwner: PublicKey; + voterWeight: BN; + voterWeightExpiry: BN; + weightAction: VoterWeightAction | undefined; + weightActionTarget: PublicKey | undefined; + }) { + this.realm = args.realm; + this.governingTokenMint = args.governingTokenMint; + this.governingTokenOwner = args.governingTokenOwner; + this.voterWeight = args.voterWeight; + this.voterWeightExpiry = args.voterWeightExpiry; + this.weightAction = args.weightAction; + this.weightActionTarget = args.weightActionTarget; + } +} + +/** + * Returns the default address for VoterWeightRecord + * Note: individual addins are not required to use the default address and it can vary between different implementations + **/ +export async function getVoterWeightRecordAddress( + programId: PublicKey, + realm: PublicKey, + governingTokenMint: PublicKey, + governingTokenOwner: PublicKey, +) { + const [voterWeightRecordAddress] = await PublicKey.findProgramAddress( + [ + Buffer.from('voter-weight-record'), + realm.toBuffer(), + governingTokenMint.toBuffer(), + governingTokenOwner.toBuffer(), + ], + programId, + ); + + return voterWeightRecordAddress; +} export class MaxVoterWeightRecord { accountDiscriminator = new Uint8Array([57, 100, 53, 102, 102, 50, 57, 55]); diff --git a/packages/governance-sdk/src/addins/api.ts b/packages/governance-sdk/src/addins/api.ts index d689dfdc..a092c46f 100644 --- a/packages/governance-sdk/src/addins/api.ts +++ b/packages/governance-sdk/src/addins/api.ts @@ -1,6 +1,6 @@ import { Connection, PublicKey } from '@solana/web3.js'; import { ProgramAccount } from '../tools/sdk/runtime'; -import { MaxVoterWeightRecord } from './accounts'; +import { MaxVoterWeightRecord, VoterWeightRecord } from './accounts'; import { GovernanceAddinAccountParser } from './serialisation'; export async function getMaxVoterWeightRecord( @@ -14,6 +14,17 @@ export async function getMaxVoterWeightRecord( ); } +export async function getVoterWeightRecord( + connection: Connection, + voterWeightRecordPk: PublicKey, +) { + return getGovernanceAddinAccount( + connection, + voterWeightRecordPk, + VoterWeightRecord, + ); +} + export async function getGovernanceAddinAccount( connection: Connection, accountPk: PublicKey, diff --git a/packages/governance-sdk/src/addins/serialisation.ts b/packages/governance-sdk/src/addins/serialisation.ts index 1b42a778..8e7b4aa5 100644 --- a/packages/governance-sdk/src/addins/serialisation.ts +++ b/packages/governance-sdk/src/addins/serialisation.ts @@ -1,4 +1,8 @@ -import { GovernanceAddinAccountClass, MaxVoterWeightRecord } from './accounts'; +import { + GovernanceAddinAccountClass, + MaxVoterWeightRecord, + VoterWeightRecord, +} from './accounts'; import { BorshAccountParser } from '../core/serialisation'; export const GOVERNANCE_ADDINS_SCHEMA = new Map([ @@ -11,7 +15,23 @@ export const GOVERNANCE_ADDINS_SCHEMA = new Map([ ['realm', 'pubkey'], ['governingTokenMint', 'pubkey'], ['maxVoterWeight', 'u64'], - ['maxVoterWeightExpiry', 'u64'], + ['maxVoterWeightExpiry', { kind: 'option', type: 'u64' }], + ], + }, + ], + [ + VoterWeightRecord, + { + kind: 'struct', + fields: [ + ['accountDiscriminator', [8]], + ['realm', 'pubkey'], + ['governingTokenMint', 'pubkey'], + ['governingTokenOwner', 'pubkey'], + ['voterWeight', 'u64'], + ['voterWeightExpiry', { kind: 'option', type: 'u64' }], + ['weightAction', { kind: 'option', type: 'u8' }], + ['weightActionTarget', { kind: 'option', type: 'pubkey' }], ], }, ], diff --git a/packages/governance-sdk/tests/addins/api.smoke.test.ts b/packages/governance-sdk/tests/addins/api.smoke.test.ts index a3337092..186db657 100644 --- a/packages/governance-sdk/tests/addins/api.smoke.test.ts +++ b/packages/governance-sdk/tests/addins/api.smoke.test.ts @@ -2,6 +2,8 @@ import { clusterApiUrl, Connection, Keypair, PublicKey } from '@solana/web3.js'; import { getMaxVoterWeightRecord, getMaxVoterWeightRecordAddress, + getVoterWeightRecord, + getVoterWeightRecordAddress, } from '../../src'; import { requestAirdrop } from '../tools/sdk'; @@ -43,3 +45,48 @@ test('getMaxVoterWeightRecord', async () => { governingTokenMintPk, ); }); + +test('getVoterWeightRecord', async () => { + // Arrange + const wallet = Keypair.generate(); + const walletPk = wallet.publicKey; + + await requestAirdrop(connection, walletPk); + + const realmPk = new PublicKey('Bt9gu17V9DLQNYa6gnbtrbFSEiX4kqbeHAbNCH2dcKr'); + const governingTokenMintPk = new PublicKey( + '2zBFETjTFMSjeS8Rfv43qYyCTLtGSRXRk1hWwJ1u7WgH', + ); + + const governingTokenOwnerPk = new PublicKey( + '56CRgykvwrWcCyKY1L5UCc3NgCKz57ZE7AMJcP5tccCu', + ); + + const addinProgramId = new PublicKey( + 'FDfF7jzJDCEkFWNi3is487k8rFPJxFkU821t2pQ1vDr1', + ); + + const voterWeightRecordPk = await getVoterWeightRecordAddress( + addinProgramId, + realmPk, + governingTokenMintPk, + governingTokenOwnerPk, + ); + + // Act + const voterWeightRecord = await getVoterWeightRecord( + connection, + voterWeightRecordPk, + ); + + // Assert + expect(voterWeightRecord.account.realm).toEqual(realmPk); + + expect(voterWeightRecord.account.governingTokenMint).toEqual( + governingTokenMintPk, + ); + + expect(voterWeightRecord.account.governingTokenOwner).toEqual( + governingTokenOwnerPk, + ); +}); diff --git a/packages/governance/package.json b/packages/governance/package.json index 69259425..ef650749 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.0.32", + "@solana/spl-governance": "0.0.34", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From cf8001c5dc1fb9c325be27ca2008e80d7d230cc7 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Fri, 6 May 2022 15:53:16 +0100 Subject: [PATCH 42/88] Governance: Support councilVoteThreshold (spl-gov v3) (#542) * feat: support councilVoteThreshold (spl-gov v3) * chore: update error messages --- packages/governance-sdk/package.json | 2 +- .../governance-sdk/src/governance/accounts.ts | 46 +++++++---- .../governance-sdk/src/governance/errors.ts | 7 +- .../src/governance/serialisation.ts | 76 ++++++++++++++----- .../governance-sdk/src/registry/constants.ts | 3 +- .../governance-sdk/tests/chat/api.test.ts | 10 ++- .../tests/governance/api.smoke.test.ts | 20 ++--- .../tests/governance/api.test.ts | 27 ++++--- packages/governance-sdk/tests/tools/setup.ts | 9 +++ packages/governance/package.json | 2 +- .../governanceConfigFormItem.tsx | 40 +++++++--- .../src/views/governance/governanceView.tsx | 2 +- .../instructionInput/governanceConfigForm.tsx | 4 +- .../src/views/proposal/proposalView.tsx | 6 +- .../buttons/createTreasuryAccountButton.tsx | 4 +- .../buttons/registerGovernanceButton.tsx | 4 +- 16 files changed, 181 insertions(+), 81 deletions(-) create mode 100644 packages/governance-sdk/tests/tools/setup.ts diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 98a2f827..13e13f65 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.0.34", + "version": "0.3.0", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 3246fdc5..6e010a9c 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -108,16 +108,21 @@ export function getAccountProgramVersion(accountType: GovernanceAccountType) { } } -export enum VoteThresholdPercentageType { - YesVote = 0, - Quorum = 1, +export enum VoteThresholdType { + // Approval Quorum + YesVotePercentage = 0, + // Not supported in the current version + QuorumPercentage = 1, + // Supported for VERSION >= 3 + Disabled = 2, } -export class VoteThresholdPercentage { - type = VoteThresholdPercentageType.YesVote; - value: number; +export class VoteThreshold { + type: VoteThresholdType; + value: number | undefined; - constructor(args: { value: number }) { + constructor(args: { type: VoteThresholdType; value?: number | undefined }) { + this.type = args.type; this.value = args.value; } } @@ -347,32 +352,41 @@ export async function getRealmConfigAddress( } export class GovernanceConfig { - voteThresholdPercentage: VoteThresholdPercentage; + communityVoteThreshold: VoteThreshold; + minCommunityTokensToCreateProposal: BN; minInstructionHoldUpTime: number; maxVotingTime: number; voteTipping: VoteTipping; - proposalCoolOffTime: number; minCouncilTokensToCreateProposal: BN; + // VERSION >= 3 + councilVoteThreshold: VoteThreshold; + reserved = [0, 0]; + constructor(args: { - voteThresholdPercentage: VoteThresholdPercentage; + communityVoteThreshold: VoteThreshold; minCommunityTokensToCreateProposal: BN; minInstructionHoldUpTime: number; maxVotingTime: number; voteTipping?: VoteTipping; - proposalCoolOffTime?: number; minCouncilTokensToCreateProposal: BN; + + // VERSION >= 3 + // For versions < 3 must be set to YesVotePercentage(0) + councilVoteThreshold: VoteThreshold; }) { - this.voteThresholdPercentage = args.voteThresholdPercentage; + this.communityVoteThreshold = args.communityVoteThreshold; this.minCommunityTokensToCreateProposal = args.minCommunityTokensToCreateProposal; this.minInstructionHoldUpTime = args.minInstructionHoldUpTime; this.maxVotingTime = args.maxVotingTime; this.voteTipping = args.voteTipping ?? VoteTipping.Strict; - this.proposalCoolOffTime = args.proposalCoolOffTime ?? 0; this.minCouncilTokensToCreateProposal = args.minCouncilTokensToCreateProposal; + + // VERSION >= 3 + this.councilVoteThreshold = args.councilVoteThreshold; } } @@ -597,7 +611,7 @@ export class Proposal { executionFlags: InstructionExecutionFlags; maxVoteWeight: BN | null; - voteThresholdPercentage: VoteThresholdPercentage | null; + voteThreshold: VoteThreshold | null; name: string; @@ -641,7 +655,7 @@ export class Proposal { executionFlags: InstructionExecutionFlags; maxVoteWeight: BN | null; - voteThresholdPercentage: VoteThresholdPercentage | null; + voteThreshold: VoteThreshold | null; }) { this.accountType = args.accountType; this.governance = args.governance; @@ -681,7 +695,7 @@ export class Proposal { this.executionFlags = args.executionFlags; this.maxVoteWeight = args.maxVoteWeight; - this.voteThresholdPercentage = args.voteThresholdPercentage; + this.voteThreshold = args.voteThreshold; } /// Returns true if Proposal is in state when no voting can happen any longer diff --git a/packages/governance-sdk/src/governance/errors.ts b/packages/governance-sdk/src/governance/errors.ts index 168d9734..b285bf73 100644 --- a/packages/governance-sdk/src/governance/errors.ts +++ b/packages/governance-sdk/src/governance/errors.ts @@ -59,9 +59,9 @@ export const GovernanceError = [ 'Given program is not upgradable', //ProgramNotUpgradable 'Invalid token owner', //InvalidTokenOwner 'Current token owner must sign transaction', // TokenOwnerMustSign - 'Given VoteThresholdPercentageType is not supported', //VoteThresholdPercentageTypeNotSupported + 'Given VoteThresholdType is not supported', //VoteThresholdTypeNotSupported 'Given VoteWeightSource is not supported', //VoteWeightSourceNotSupported - 'Proposal cool off time is not supported', // ProposalCoolOffTimeNotSupported + 'GoverningTokenMint not allowed to vote', // GoverningTokenMintNotAllowedToVote 'Governance PDA must sign', // GovernancePdaMustSign 'Instruction already flagged with error', // InstructionAlreadyFlaggedWithError 'Invalid Realm for Governance', // InvalidRealmForGovernance @@ -96,7 +96,8 @@ export const GovernanceError = [ 'Cannot execute defeated option', // MaxVoterWeightRecordExpired 'Not supported VoteType', // NotSupportedVoteType 'RealmConfig change not allowed', // RealmConfigChangeNotAllowed - 'GovernanceConfig change not allowed', // GovernanceConfigChangeNotAllowed + 'At least one VoteThreshold is required', // AtLeastOneVoteThresholdRequired + 'Reserved buffer must be empty', // ReservedBufferMustBeEmpty ] as const; export const TokenError = [ diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index bdad145f..605bd9c3 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -45,7 +45,7 @@ import { SignatoryRecord, TokenOwnerRecord, VoteRecord, - VoteThresholdPercentage, + VoteThreshold, VoteWeight, RealmConfigAccount, GovernanceAccountClass, @@ -55,6 +55,7 @@ import { GovernanceAccountType, getAccountProgramVersion, ProgramMetadata, + VoteThresholdType, } from './accounts'; import { serialize } from 'borsh'; import { BorshAccountParser } from '../core/serialisation'; @@ -153,6 +154,51 @@ import { deserializeBorsh } from '../tools/borsh'; } }; +// ------------ VoteThreshold ------------ + +(BinaryReader.prototype as any).readVoteThreshold = function () { + const reader = (this as unknown) as BinaryReader; + + // Read VoteThreshold and advance the reader by 1 + const type = reader.buf.readUInt8(reader.offset); + reader.offset += 1; + + // Read VoteThresholds with u8 value + if ( + type === VoteThresholdType.YesVotePercentage || + type === VoteThresholdType.QuorumPercentage + ) { + const percentage = reader.buf.readUInt8(reader.offset); + reader.offset += 1; + return new VoteThreshold({ type: type, value: percentage }); + } + + // Read VoteThresholds without value + if (type === VoteThresholdType.Disabled) { + return new VoteThreshold({ type: type, value: undefined }); + } + + throw new Error(`VoteThresholdType ${type} is not supported`); +}; + +(BinaryWriter.prototype as any).writeVoteThreshold = function ( + value: VoteThreshold, +) { + const writer = (this as unknown) as BinaryWriter; + writer.maybeResize(); + writer.buf.writeUInt8(value.type, writer.length); + writer.length += 1; + + // Write value for VoteThresholds with u8 value + if ( + value.type === VoteThresholdType.YesVotePercentage || + value.type === VoteThresholdType.QuorumPercentage + ) { + writer.buf.writeUInt8(value.value!, writer.length); + writer.length += 1; + } +}; + // Serializes sdk instruction into InstructionData and encodes it as base64 which then can be entered into the UI form export const serializeInstructionToBase64 = ( instruction: TransactionInstruction, @@ -179,7 +225,13 @@ export const createInstructionData = (instruction: TransactionInstruction) => { }; export const GOVERNANCE_SCHEMA_V1 = createGovernanceSchema(1); -export const GOVERNANCE_SCHEMA = createGovernanceSchema(2); +export const GOVERNANCE_SCHEMA_V2 = createGovernanceSchema(2); + +// V3 schema is backward compatible with V2 +export const GOVERNANCE_SCHEMA_V3 = GOVERNANCE_SCHEMA_V2; + +// The most recent version of spl-gov +export const GOVERNANCE_SCHEMA = GOVERNANCE_SCHEMA_V3; export function getGovernanceSchema(programVersion: number) { switch (programVersion) { @@ -553,27 +605,18 @@ function createGovernanceSchema(programVersion: number) { ], }, ], - [ - VoteThresholdPercentage, - { - kind: 'struct', - fields: [ - ['type', 'u8'], - ['value', 'u8'], - ], - }, - ], [ GovernanceConfig, { kind: 'struct', fields: [ - ['voteThresholdPercentage', VoteThresholdPercentage], + ['communityVoteThreshold', 'VoteThreshold'], ['minCommunityTokensToCreateProposal', 'u64'], ['minInstructionHoldUpTime', 'u32'], ['maxVotingTime', 'u32'], ['voteTipping', 'u8'], - ['proposalCoolOffTime', 'u32'], + ['councilVoteThreshold', 'VoteThreshold'], + ['reserved', [2]], ['minCouncilTokensToCreateProposal', 'u64'], ], }, @@ -654,10 +697,7 @@ function createGovernanceSchema(programVersion: number) { ? [] : [['maxVotingTime', { kind: 'option', type: 'u32' }]]), - [ - 'voteThresholdPercentage', - { kind: 'option', type: VoteThresholdPercentage }, - ], + ['voteThreshold', { kind: 'option', type: 'VoteThreshold' }], ...(programVersion === PROGRAM_VERSION_V1 ? [] diff --git a/packages/governance-sdk/src/registry/constants.ts b/packages/governance-sdk/src/registry/constants.ts index 85ed242a..4ecd57da 100644 --- a/packages/governance-sdk/src/registry/constants.ts +++ b/packages/governance-sdk/src/registry/constants.ts @@ -1,5 +1,6 @@ export const PROGRAM_VERSION_V1 = 1; export const PROGRAM_VERSION_V2 = 2; +export const PROGRAM_VERSION_V3 = 3; // The most up to date program version -export const PROGRAM_VERSION = PROGRAM_VERSION_V2; +export const PROGRAM_VERSION = PROGRAM_VERSION_V3; diff --git a/packages/governance-sdk/tests/chat/api.test.ts b/packages/governance-sdk/tests/chat/api.test.ts index d27a48da..62a8ffec 100644 --- a/packages/governance-sdk/tests/chat/api.test.ts +++ b/packages/governance-sdk/tests/chat/api.test.ts @@ -13,7 +13,8 @@ import { getGovernanceProgramVersion, GovernanceConfig, MintMaxVoteWeightSource, - VoteThresholdPercentage, + VoteThreshold, + VoteThresholdType, VoteTipping, VoteType, withCreateMintGovernance, @@ -110,14 +111,17 @@ test('postProposalComment', async () => { // Crate governance over the the governance token mint const config = new GovernanceConfig({ - voteThresholdPercentage: new VoteThresholdPercentage({ + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, value: 60, }), minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), voteTipping: VoteTipping.Strict, - proposalCoolOffTime: 0, + councilVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.Disabled, + }), minCouncilTokensToCreateProposal: new BN(1), }); diff --git a/packages/governance-sdk/tests/governance/api.smoke.test.ts b/packages/governance-sdk/tests/governance/api.smoke.test.ts index 80ba10f2..dfce9336 100644 --- a/packages/governance-sdk/tests/governance/api.smoke.test.ts +++ b/packages/governance-sdk/tests/governance/api.smoke.test.ts @@ -1,6 +1,6 @@ import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { - clusterApiUrl, + Connection, Keypair, PublicKey, @@ -13,7 +13,7 @@ import { getRealm, GovernanceConfig, MintMaxVoteWeightSource, - VoteThresholdPercentage, + VoteThreshold, VoteType, VoteTipping, withCreateMintGovernance, @@ -40,22 +40,18 @@ import { tryGetRealmConfig, withExecuteTransaction, withSetGovernanceDelegate, - getTokenOwnerRecordForRealm, getTokenOwnerRecord, + VoteThresholdType, } from '../../src'; import { withSetRealmConfig } from '../../src/governance/withSetRealmConfig'; import { requestAirdrop, sendTransaction } from '../tools/sdk'; +import { programId, rpcEndpoint } from '../tools/setup'; import { getTimestampFromDays } from '../tools/units'; import { withCreateAssociatedTokenAccount } from '../tools/withCreateAssociatedTokenAccount'; import { withCreateMint } from '../tools/withCreateMint'; import { withMintTo } from '../tools/withMintTo'; -const programId = new PublicKey('BfFUxwBiJLhD1wL36xGXWRe7RXAFL4QKircHydAHS3wt'); -const rpcEndpoint = clusterApiUrl('devnet'); - -// const programId = new PublicKey('GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw'); -// const rpcEndpoint = 'http://127.0.0.1:8899'; const connection = new Connection(rpcEndpoint, 'recent'); @@ -155,14 +151,18 @@ test('setupRealm', async () => { // Crate governance over the the governance token mint const config = new GovernanceConfig({ - voteThresholdPercentage: new VoteThresholdPercentage({ + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, value: 60, }), minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), voteTipping: VoteTipping.Strict, - proposalCoolOffTime: 0, + councilVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 60, + }), minCouncilTokensToCreateProposal: new BN(1), }); diff --git a/packages/governance-sdk/tests/governance/api.test.ts b/packages/governance-sdk/tests/governance/api.test.ts index fe166d39..b9076e42 100644 --- a/packages/governance-sdk/tests/governance/api.test.ts +++ b/packages/governance-sdk/tests/governance/api.test.ts @@ -9,13 +9,16 @@ import { import { BN } from 'bn.js'; import { createInstructionData, + getGovernance, getGovernanceProgramVersion, + getProposal, getRealm, getTokenOwnerRecordsByOwner, GovernanceConfig, MintMaxVoteWeightSource, SetRealmAuthorityAction, - VoteThresholdPercentage, + VoteThreshold, + VoteThresholdType, VoteTipping, VoteType, withCreateMintGovernance, @@ -26,17 +29,12 @@ import { withSetRealmAuthority, } from '../../src'; import { requestAirdrop, sendTransaction } from '../tools/sdk'; +import { programId, rpcEndpoint } from '../tools/setup'; import { getTimestampFromDays } from '../tools/units'; import { withCreateAssociatedTokenAccount } from '../tools/withCreateAssociatedTokenAccount'; import { withCreateMint } from '../tools/withCreateMint'; import { withMintTo } from '../tools/withMintTo'; -const programId = new PublicKey('GTesTBiEWE32WHXXE2S4XbZvA5CrEc4xs6ZgRe895dP'); -const rpcEndpoint = clusterApiUrl('devnet'); - -// const programId = new PublicKey('GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw'); -// const rpcEndpoint = 'http://127.0.0.1:8899'; - const connection = new Connection(rpcEndpoint, 'recent'); test('createRealmWithGovernanceAndProposal', async () => { @@ -108,14 +106,17 @@ test('createRealmWithGovernanceAndProposal', async () => { // Crate governance over the the governance token mint const config = new GovernanceConfig({ - voteThresholdPercentage: new VoteThresholdPercentage({ + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, value: 60, }), minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), voteTipping: VoteTipping.Strict, - proposalCoolOffTime: 0, + councilVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.Disabled, + }), minCouncilTokensToCreateProposal: new BN(1), }); @@ -215,6 +216,14 @@ test('createRealmWithGovernanceAndProposal', async () => { expect(results.length).toBe(1); expect(results[0].account.governingTokenOwner).toEqual(walletPk); + + // check governance + const governance = await getGovernance(connection,governancePk); + expect(governance.account.config.communityVoteThreshold).toEqual(config.communityVoteThreshold); + // expect(governance.account.config.councilVoteThreshold).toEqual(config.councilVoteThreshold); + + // check proposal + const proposal = await getProposal(connection,proposalPk); }); diff --git a/packages/governance-sdk/tests/tools/setup.ts b/packages/governance-sdk/tests/tools/setup.ts new file mode 100644 index 00000000..4ca0d02a --- /dev/null +++ b/packages/governance-sdk/tests/tools/setup.ts @@ -0,0 +1,9 @@ + + +import { PublicKey } from "@solana/web3.js"; + +// const programId = new PublicKey('GTesTBiEWE32WHXXE2S4XbZvA5CrEc4xs6ZgRe895dP'); +// const rpcEndpoint = clusterApiUrl('devnet'); + +export const programId = new PublicKey('GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw'); +export const rpcEndpoint = 'http://127.0.0.1:8899'; \ No newline at end of file diff --git a/packages/governance/package.json b/packages/governance/package.json index ef650749..7dab76d0 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.0.34", + "@solana/spl-governance": "0.3.0", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", diff --git a/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx b/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx index 8da18161..381b56c9 100644 --- a/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx +++ b/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx @@ -5,8 +5,10 @@ import { contexts, constants } from '@oyster/common'; import { LABELS } from '../../constants'; import { GovernanceConfig, + PROGRAM_VERSION_V3, Realm, - VoteThresholdPercentage, + VoteThreshold, + VoteThresholdType, VoteTipping, } from '@solana/spl-governance'; import { getNameOf } from '../../tools/script'; @@ -38,16 +40,29 @@ export interface GovernanceConfigValues { voteTipping: VoteTipping; } -export function getGovernanceConfig(values: GovernanceConfigValues) { +export function getGovernanceConfig(programVersion: number, values: GovernanceConfigValues) { const minTokensToCreateProposal = parseMinTokensToCreate( values.minTokensToCreateProposal, values.mintDecimals, ); + const communityVoteThreshold = new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: values.voteThresholdPercentage, + }); + + + const councilVoteThreshold = programVersion >= PROGRAM_VERSION_V3 + // For VERSION >-3 use the same threshold as for community (until supported in the UI) + ? communityVoteThreshold + // For older versions set to 0 + : new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 0, + }); + return new GovernanceConfig({ - voteThresholdPercentage: new VoteThresholdPercentage({ - value: values.voteThresholdPercentage, - }), + communityVoteThreshold: communityVoteThreshold, minCommunityTokensToCreateProposal: new BN( minTokensToCreateProposal.toString(), ), @@ -59,7 +74,8 @@ export function getGovernanceConfig(values: GovernanceConfigValues) { // Council tokens are rare and possession of any amount of council tokens should be sufficient to be allowed to create proposals // If it turns to be a wrong assumption then it should be exposed in the UI minCouncilTokensToCreateProposal: new BN(1), - voteTipping: values.voteTipping + voteTipping: values.voteTipping, + councilVoteThreshold:councilVoteThreshold, }); } @@ -113,13 +129,19 @@ export function GovernanceConfigFormItem({ if (!governanceConfig) { governanceConfig = new GovernanceConfig({ - voteThresholdPercentage: new VoteThresholdPercentage({ value: 60 }), + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 60, + }), minCommunityTokensToCreateProposal: ZERO, minInstructionHoldUpTime: getTimestampFromDays(0), maxVotingTime: getTimestampFromDays(3), voteTipping: VoteTipping.Strict, - proposalCoolOffTime: 0, minCouncilTokensToCreateProposal: ZERO, + councilVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 60, + }), }); } else { minTokensToCreateProposal = getMintDecimalAmountFromNatural( @@ -193,7 +215,7 @@ export function GovernanceConfigFormItem({ name={configNameOf('voteThresholdPercentage')} label={LABELS.YES_VOTE_THRESHOLD_PERCENTAGE} rules={[{ required: true }]} - initialValue={governanceConfig.voteThresholdPercentage.value} + initialValue={governanceConfig.communityVoteThreshold.value} > diff --git a/packages/governance/src/views/governance/governanceView.tsx b/packages/governance/src/views/governance/governanceView.tsx index 2beac491..d19f600a 100644 --- a/packages/governance/src/views/governance/governanceView.tsx +++ b/packages/governance/src/views/governance/governanceView.tsx @@ -135,7 +135,7 @@ export const GovernanceView = () => { {`max voting time: ${getDaysFromTimestamp( governance.account.config.maxVotingTime, )} days`} - {`yes vote threshold: ${governance.account.config.voteThresholdPercentage.value}%`} + {`yes vote threshold: ${governance.account.config.communityVoteThreshold.value}%`} diff --git a/packages/governance/src/views/proposal/components/instructionInput/governanceConfigForm.tsx b/packages/governance/src/views/proposal/components/instructionInput/governanceConfigForm.tsx index 9aa82335..d74a8f78 100644 --- a/packages/governance/src/views/proposal/components/instructionInput/governanceConfigForm.tsx +++ b/packages/governance/src/views/proposal/components/instructionInput/governanceConfigForm.tsx @@ -27,11 +27,11 @@ export const GovernanceConfigForm = ({ onCreateInstruction: (instruction: TransactionInstruction) => void; }) => { const idlAddress = useAnchorIdlAddress(governance.account.governedAccount); - const { programId } = useRpcContext(); + const { programId, programVersion } = useRpcContext(); const realm = useRealm(governance.account.realm); const onCreate = async (values: GovernanceConfigValues) => { - const config = getGovernanceConfig(values); + const config = getGovernanceConfig(programVersion,values); const setGovernanceConfigIx = createSetGovernanceConfig( programId, diff --git a/packages/governance/src/views/proposal/proposalView.tsx b/packages/governance/src/views/proposal/proposalView.tsx index d9d8c4fa..ae0397fc 100644 --- a/packages/governance/src/views/proposal/proposalView.tsx +++ b/packages/governance/src/views/proposal/proposalView.tsx @@ -524,7 +524,7 @@ function getYesVoteThreshold( ) { return proposal.account.isVoteFinalized() && // Note Canceled state is also final but we currently don't capture vote threshold at the cancellation time - proposal.account.voteThresholdPercentage - ? proposal.account.voteThresholdPercentage.value - : governance.account.config.voteThresholdPercentage.value; + proposal.account.voteThreshold + ? proposal.account.voteThreshold.value! + : governance.account.config.communityVoteThreshold.value!; } diff --git a/packages/governance/src/views/realm/buttons/createTreasuryAccountButton.tsx b/packages/governance/src/views/realm/buttons/createTreasuryAccountButton.tsx index 3f332e01..d00c09c5 100644 --- a/packages/governance/src/views/realm/buttons/createTreasuryAccountButton.tsx +++ b/packages/governance/src/views/realm/buttons/createTreasuryAccountButton.tsx @@ -36,7 +36,7 @@ export function CreateTreasuryAccountButton({ }) { const [redirectTo, setRedirectTo] = useState(''); const rpcContext = useRpcContext(); - const { programId } = rpcContext; + const { programId, programVersion } = rpcContext; const realmKey = useKeyParam(); @@ -75,7 +75,7 @@ export function CreateTreasuryAccountButton({ mintAddress: string; } & GovernanceConfigValues, ) => { - const config = getGovernanceConfig(values); + const config = getGovernanceConfig(programVersion,values); return await createTreasuryAccount( rpcContext, diff --git a/packages/governance/src/views/realm/buttons/registerGovernanceButton.tsx b/packages/governance/src/views/realm/buttons/registerGovernanceButton.tsx index 621ccec6..d13742e1 100644 --- a/packages/governance/src/views/realm/buttons/registerGovernanceButton.tsx +++ b/packages/governance/src/views/realm/buttons/registerGovernanceButton.tsx @@ -36,7 +36,7 @@ export function RegisterGovernanceButton({ }) { const [redirectTo, setRedirectTo] = useState(''); const rpcContext = useRpcContext(); - const { programId } = rpcContext; + const { programId, programVersion } = rpcContext; const realmKey = useKeyParam(); const [governanceType, setGovernanceType] = useState(GovernanceType.Account); @@ -78,7 +78,7 @@ export function RegisterGovernanceButton({ transferAuthority: boolean; } & GovernanceConfigValues, ) => { - const config = getGovernanceConfig(values); + const config = getGovernanceConfig(programVersion,values); return await registerGovernance( rpcContext, From 306d7a37d452de80703b60e71af4b72118ba727d Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Thu, 18 Aug 2022 10:32:29 +0200 Subject: [PATCH 43/88] Governance spl gov v3 api (#548) * feat: Default unresolved getGovernanceProgramVersion to 2 * feat: Impl CreateReam and SetRealmConfig v3 instructions * feat: withRevokeGoverningTokens * feat: GoverningTokenConfig and RealmConfigAccount v3 serialisation * feat: Update v3 errors * feat: Veto vote * chore: spl-gov v3 tests * chore: createGovernanceWithCouncilThresholds * chore: createProposal & castVote tests * chore: Add relinquishVote test * chore: setRealmConfig * chore: fix tests * chore: withdrawGoverningTokens * chore: setRealmConfigWithTokenConfigs * chore: createRealmWithTokenConfigs * chore: revokeGoverningToken test --- .../src/chat/withPostChatMessage.ts | 4 +- .../governance-sdk/src/governance/accounts.ts | 133 ++++- packages/governance-sdk/src/governance/api.ts | 14 + .../src/governance/createSetRealmAuthority.ts | 3 +- .../src/governance/createSetRealmConfig.ts | 15 +- .../governance-sdk/src/governance/enums.ts | 2 +- .../governance-sdk/src/governance/errors.ts | 10 + .../governance-sdk/src/governance/index.ts | 2 + .../src/governance/instructions.ts | 18 + .../src/governance/serialisation.ts | 84 ++- .../governance-sdk/src/governance/tools.ts | 139 +++++ .../governance-sdk/src/governance/version.ts | 10 +- .../src/governance/withCastVote.ts | 8 +- .../src/governance/withCreateGovernance.ts | 9 +- .../governance/withCreateMintGovernance.ts | 9 +- .../governance/withCreateProgramGovernance.ts | 9 +- .../src/governance/withCreateProposal.ts | 9 +- .../src/governance/withCreateRealm.ts | 66 +-- .../governance/withCreateTokenGovernance.ts | 9 +- .../governance/withDepositGoverningTokens.ts | 7 +- .../src/governance/withFinalizeVote.ts | 4 +- ...ts.ts => withRealmConfigPluginAccounts.ts} | 2 +- .../src/governance/withRelinquishVote.ts | 16 +- .../governance/withRevokeGoverningTokens.ts | 101 ++++ .../src/governance/withSetRealmConfig.ts | 50 +- .../governance/withWithdrawGoverningTokens.ts | 5 +- .../tests/governance/api.smoke.test.ts | 95 ++-- .../tests/governance/api.test.ts | 42 +- .../tests/governance/api.v2.test.ts | 58 +++ .../tests/governance/api.v2.v3.test.ts | 129 +++++ .../tests/governance/api.v3.test.ts | 187 +++++++ .../governance-sdk/tests/tools/builders.ts | 486 ++++++++++++++++++ packages/governance-sdk/tests/tools/setup.ts | 14 +- .../governance/src/actions/registerRealm.ts | 16 +- .../governance/src/actions/relinquishVote.ts | 5 +- .../src/actions/withdrawGoverningTokens.ts | 3 +- .../governanceConfigFormItem.tsx | 15 +- .../governance/buttons/newProposalButton.tsx | 14 +- .../buttons/relinquishVoteButton.tsx | 2 + .../instructionInput/realmConfigForm.tsx | 14 +- 40 files changed, 1623 insertions(+), 195 deletions(-) create mode 100644 packages/governance-sdk/src/governance/tools.ts rename packages/governance-sdk/src/governance/{withRealmConfigAccounts.ts => withRealmConfigPluginAccounts.ts} (93%) create mode 100644 packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts create mode 100644 packages/governance-sdk/tests/governance/api.v2.test.ts create mode 100644 packages/governance-sdk/tests/governance/api.v2.v3.test.ts create mode 100644 packages/governance-sdk/tests/governance/api.v3.test.ts create mode 100644 packages/governance-sdk/tests/tools/builders.ts diff --git a/packages/governance-sdk/src/chat/withPostChatMessage.ts b/packages/governance-sdk/src/chat/withPostChatMessage.ts index b48127e8..fdd9afba 100644 --- a/packages/governance-sdk/src/chat/withPostChatMessage.ts +++ b/packages/governance-sdk/src/chat/withPostChatMessage.ts @@ -4,7 +4,7 @@ import { serialize } from 'borsh'; import { PostChatMessageArgs } from './instructions'; import { GOVERNANCE_CHAT_PROGRAM_ID, ChatMessageBody } from './accounts'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; -import { withRealmConfigAccounts } from '../governance/withRealmConfigAccounts'; +import { withRealmConfigPluginAccounts } from '../governance/withRealmConfigPluginAccounts'; export async function withPostChatMessage( instructions: TransactionInstruction[], @@ -86,7 +86,7 @@ export async function withPostChatMessage( }); } - await withRealmConfigAccounts( + await withRealmConfigPluginAccounts( keys, governanceProgramId, realm, diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 6e010a9c..c20e7841 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -220,28 +220,77 @@ export class RealmConfigArgs { communityMintMaxVoteWeightSource: MintMaxVoteWeightSource; minCommunityTokensToCreateGovernance: BN; - // Versions >= 2 + // Version == 2 useCommunityVoterWeightAddin: boolean; useMaxCommunityVoterWeightAddin: boolean; + // Versions >= 3 + communityTokenConfigArgs: GoverningTokenConfigArgs; + councilTokenConfigArgs: GoverningTokenConfigArgs; + constructor(args: { useCouncilMint: boolean; minCommunityTokensToCreateGovernance: BN; communityMintMaxVoteWeightSource: MintMaxVoteWeightSource; + // Version == 2 useCommunityVoterWeightAddin: boolean; useMaxCommunityVoterWeightAddin: boolean; + + // Versions >= 3 + communityTokenConfigArgs: GoverningTokenConfigArgs; + councilTokenConfigArgs: GoverningTokenConfigArgs; }) { this.useCouncilMint = !!args.useCouncilMint; - this.communityMintMaxVoteWeightSource = args.communityMintMaxVoteWeightSource; - this.minCommunityTokensToCreateGovernance = args.minCommunityTokensToCreateGovernance; + this.useCommunityVoterWeightAddin = args.useCommunityVoterWeightAddin; this.useMaxCommunityVoterWeightAddin = args.useMaxCommunityVoterWeightAddin; + + this.communityTokenConfigArgs = args.communityTokenConfigArgs; + this.councilTokenConfigArgs = args.councilTokenConfigArgs; + } +} + +export enum GoverningTokenType { + Liquid = 0, + Membership = 1, + Dormant = 2, +} + +export class GoverningTokenConfigArgs { + useVoterWeightAddin: boolean; + useMaxVoterWeightAddin: boolean; + tokenType: GoverningTokenType; + + constructor(args: { + useVoterWeightAddin: boolean; + useMaxVoterWeightAddin: boolean; + tokenType: GoverningTokenType; + }) { + this.useVoterWeightAddin = args.useVoterWeightAddin; + this.useMaxVoterWeightAddin = args.useMaxVoterWeightAddin; + this.tokenType = args.tokenType; + } +} + +export class GoverningTokenConfigAccountArgs { + voterWeightAddin: PublicKey | undefined; + maxVoterWeightAddin: PublicKey | undefined; + tokenType: GoverningTokenType; + + constructor(args: { + voterWeightAddin: PublicKey | undefined; + maxVoterWeightAddin: PublicKey | undefined; + tokenType: GoverningTokenType; + }) { + this.voterWeightAddin = args.voterWeightAddin; + this.maxVoterWeightAddin = args.maxVoterWeightAddin; + this.tokenType = args.tokenType; } } @@ -249,8 +298,11 @@ export class RealmConfig { councilMint: PublicKey | undefined; communityMintMaxVoteWeightSource: MintMaxVoteWeightSource; minCommunityTokensToCreateGovernance: BN; + + // VERSION == 2 useCommunityVoterWeightAddin: boolean; useMaxCommunityVoterWeightAddin: boolean; + reserved: Uint8Array; constructor(args: { @@ -321,21 +373,44 @@ export async function getTokenHoldingAddress( return tokenHoldingAddress; } +export class GoverningTokenConfig { + voterWeightAddin: PublicKey | undefined; + maxVoterWeightAddin: PublicKey | undefined; + tokenType: GoverningTokenType; + reserved: Uint8Array; + + constructor(args: { + voterWeightAddin: PublicKey | undefined; + maxVoterWeightAddin: PublicKey | undefined; + tokenType: GoverningTokenType; + reserved: Uint8Array; + }) { + this.voterWeightAddin = args.voterWeightAddin; + this.maxVoterWeightAddin = args.maxVoterWeightAddin; + this.tokenType = args.tokenType; + this.reserved = args.reserved; + } +} + export class RealmConfigAccount { accountType = GovernanceAccountType.RealmConfig; realm: PublicKey; - communityVoterWeightAddin: PublicKey | undefined; - maxCommunityVoterWeightAddin: PublicKey | undefined; + communityTokenConfig: GoverningTokenConfig; + councilTokenConfig: GoverningTokenConfig; + + reserved: Uint8Array; constructor(args: { realm: PublicKey; - communityVoterWeightAddin: PublicKey | undefined; - maxCommunityVoterWeightAddin: PublicKey | undefined; + communityTokenConfig: GoverningTokenConfig; + councilTokenConfig: GoverningTokenConfig; + reserved: Uint8Array; }) { this.realm = args.realm; - this.communityVoterWeightAddin = args.communityVoterWeightAddin; - this.maxCommunityVoterWeightAddin = args.maxCommunityVoterWeightAddin; + this.communityTokenConfig = args.communityTokenConfig; + this.councilTokenConfig = args.councilTokenConfig; + this.reserved = args.reserved; } } @@ -362,6 +437,7 @@ export class GovernanceConfig { // VERSION >= 3 councilVoteThreshold: VoteThreshold; + councilVetoVoteThreshold: VoteThreshold; reserved = [0, 0]; constructor(args: { @@ -375,6 +451,7 @@ export class GovernanceConfig { // VERSION >= 3 // For versions < 3 must be set to YesVotePercentage(0) councilVoteThreshold: VoteThreshold; + councilVetoVoteThreshold: VoteThreshold; }) { this.communityVoteThreshold = args.communityVoteThreshold; this.minCommunityTokensToCreateProposal = @@ -387,6 +464,7 @@ export class GovernanceConfig { // VERSION >= 3 this.councilVoteThreshold = args.councilVoteThreshold; + this.councilVetoVoteThreshold = args.councilVetoVoteThreshold; } } @@ -527,6 +605,8 @@ export enum ProposalState { Defeated, ExecutingWithErrors, + + Vetoed, } export enum OptionVoteResult { @@ -588,7 +668,7 @@ export class Proposal { voteType: VoteType; options: ProposalOption[]; denyVoteWeight: BN | undefined; - vetoVoteWeight: BN | undefined; + reserved1: number; abstainVoteWeight: BN | undefined; startVotingAt: BN | null; maxVotingTime: number | null; @@ -617,6 +697,9 @@ export class Proposal { descriptionLink: string; + // V3 + vetoVoteWeight: BN; + constructor(args: { accountType: GovernanceAccountType; governance: PublicKey; @@ -639,7 +722,7 @@ export class Proposal { voteType: VoteType; options: ProposalOption[]; denyVoteWeight: BN | undefined; - vetoVoteWeight: BN | undefined; + reserved1: number; abstainVoteWeight: BN | undefined; startVotingAt: BN | null; maxVotingTime: number | null; @@ -656,6 +739,9 @@ export class Proposal { executionFlags: InstructionExecutionFlags; maxVoteWeight: BN | null; voteThreshold: VoteThreshold | null; + + // V3 + vetoVoteWeight: BN; }) { this.accountType = args.accountType; this.governance = args.governance; @@ -679,7 +765,7 @@ export class Proposal { this.voteType = args.voteType; this.options = args.options; this.denyVoteWeight = args.denyVoteWeight; - this.vetoVoteWeight = args.vetoVoteWeight; + this.reserved1 = args.reserved1; this.abstainVoteWeight = args.abstainVoteWeight; this.startVotingAt = args.startVotingAt; @@ -696,6 +782,9 @@ export class Proposal { this.executionFlags = args.executionFlags; this.maxVoteWeight = args.maxVoteWeight; this.voteThreshold = args.voteThreshold; + + // V3 + this.vetoVoteWeight = args.vetoVoteWeight; } /// Returns true if Proposal is in state when no voting can happen any longer @@ -707,6 +796,7 @@ export class Proposal { case ProposalState.Cancelled: case ProposalState.Defeated: case ProposalState.ExecutingWithErrors: + case ProposalState.Vetoed: return true; case ProposalState.Draft: case ProposalState.SigningOff: @@ -725,6 +815,7 @@ export class Proposal { case ProposalState.Cancelled: case ProposalState.Defeated: case ProposalState.ExecutingWithErrors: + case ProposalState.Vetoed: return true; case ProposalState.Succeeded: return this.instructionsCount === 0; @@ -740,6 +831,7 @@ export class Proposal { switch (this.state) { case ProposalState.Succeeded: case ProposalState.Defeated: + case ProposalState.Vetoed: return this.votingCompletedAt ? this.votingCompletedAt.toNumber() : 0; case ProposalState.Completed: case ProposalState.Cancelled: @@ -1161,3 +1253,20 @@ export async function getNativeTreasuryAddress( return signatoryRecordAddress; } + +export async function getGoverningTokenHoldingAddress( + programId: PublicKey, + realm: PublicKey, + governingTokenMint: PublicKey, +) { + const [governingTokenHoldingAddress] = await PublicKey.findProgramAddress( + [ + Buffer.from(GOVERNANCE_PROGRAM_SEED), + realm.toBuffer(), + governingTokenMint.toBuffer(), + ], + programId, + ); + + return governingTokenHoldingAddress; +} diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index b75c1f50..d6ba4f26 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -46,8 +46,22 @@ export async function tryGetRealmConfig( return getGovernanceAccount(connection, realmConfigPk, RealmConfigAccount); } +export async function getRealmConfig( + connection: Connection, + realmConfigPk: PublicKey, +) { + return getGovernanceAccount(connection, realmConfigPk, RealmConfigAccount); +} + // VoteRecords +export async function getVoteRecord( + connection: Connection, + voteRecordPk: PublicKey, +) { + return getGovernanceAccount(connection, voteRecordPk, VoteRecord); +} + export async function getVoteRecordsByVoter( connection: Connection, programId: PublicKey, diff --git a/packages/governance-sdk/src/governance/createSetRealmAuthority.ts b/packages/governance-sdk/src/governance/createSetRealmAuthority.ts index a1f032eb..826a26d3 100644 --- a/packages/governance-sdk/src/governance/createSetRealmAuthority.ts +++ b/packages/governance-sdk/src/governance/createSetRealmAuthority.ts @@ -1,5 +1,6 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { SetRealmAuthorityAction, withSetRealmAuthority } from '.'; +import { SetRealmAuthorityAction } from './instructions'; +import { withSetRealmAuthority } from './withSetRealmAuthority'; export function createSetRealmAuthority( programId: PublicKey, diff --git a/packages/governance-sdk/src/governance/createSetRealmConfig.ts b/packages/governance-sdk/src/governance/createSetRealmConfig.ts index d0764ac2..41000366 100644 --- a/packages/governance-sdk/src/governance/createSetRealmConfig.ts +++ b/packages/governance-sdk/src/governance/createSetRealmConfig.ts @@ -1,5 +1,8 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { MintMaxVoteWeightSource } from './accounts'; +import { + GoverningTokenConfigAccountArgs, + MintMaxVoteWeightSource, +} from './accounts'; import BN from 'bn.js'; import { withSetRealmConfig } from './withSetRealmConfig'; @@ -11,9 +14,9 @@ export async function createSetRealmConfig( councilMint: PublicKey | undefined, communityMintMaxVoteWeightSource: MintMaxVoteWeightSource, minCommunityTokensToCreateGovernance: BN, - communityVoterWeightAddin: PublicKey | undefined, - maxCommunityVoterWeightAddin: PublicKey | undefined, - payer: PublicKey, + communityTokenConfig: GoverningTokenConfigAccountArgs | undefined, + councilTokenConfig: GoverningTokenConfigAccountArgs | undefined, + payer: PublicKey | undefined, ) { const instructions: TransactionInstruction[] = []; await withSetRealmConfig( @@ -25,8 +28,8 @@ export async function createSetRealmConfig( councilMint, communityMintMaxVoteWeightSource, minCommunityTokensToCreateGovernance, - communityVoterWeightAddin, - maxCommunityVoterWeightAddin, + communityTokenConfig, + councilTokenConfig, payer, ); diff --git a/packages/governance-sdk/src/governance/enums.ts b/packages/governance-sdk/src/governance/enums.ts index b0019749..627b1fa5 100644 --- a/packages/governance-sdk/src/governance/enums.ts +++ b/packages/governance-sdk/src/governance/enums.ts @@ -1,4 +1,4 @@ -export enum GoverningTokenType { +export enum GovernananceTokenKind { Community, Council, } diff --git a/packages/governance-sdk/src/governance/errors.ts b/packages/governance-sdk/src/governance/errors.ts index b285bf73..d221bcf2 100644 --- a/packages/governance-sdk/src/governance/errors.ts +++ b/packages/governance-sdk/src/governance/errors.ts @@ -98,6 +98,16 @@ export const GovernanceError = [ 'RealmConfig change not allowed', // RealmConfigChangeNotAllowed 'At least one VoteThreshold is required', // AtLeastOneVoteThresholdRequired 'Reserved buffer must be empty', // ReservedBufferMustBeEmpty + + 'Cannot Relinquish in Finalizing state', // CannotRelinquishInFinalizingState + + 'Invalid RealmConfig account address', // InvalidRealmConfigAddress + 'Cannot deposit dormant tokens', // CannotDepositDormantTokens + 'Cannot withdraw membership tokens', // CannotWithdrawMembershipTokens + 'Cannot revoke GoverningTokens', // CannotRevokeGoverningTokens + 'Invalid Revoke amount', // InvalidRevokeAmount + 'Invalid GoverningToken source', // InvalidGoverningTokenSource + 'Cannot change community TokenType to Memebership', // CannotChangeCommunityTokenTypeToMemebership ] as const; export const TokenError = [ diff --git a/packages/governance-sdk/src/governance/index.ts b/packages/governance-sdk/src/governance/index.ts index 8942647d..efdba425 100644 --- a/packages/governance-sdk/src/governance/index.ts +++ b/packages/governance-sdk/src/governance/index.ts @@ -7,6 +7,7 @@ export * from './enums'; export * from './errors'; export * from './instructions'; export * from './serialisation'; +export * from './tools'; export * from './withAddSignatory'; export * from './version'; export * from './withCancelProposal'; @@ -26,6 +27,7 @@ export * from './withFlagTransactionError'; export * from './withInsertTransaction'; export * from './withRelinquishVote'; export * from './withRemoveTransaction'; +export * from './withRevokeGoverningTokens'; export * from './withSetRealmAuthority'; export * from './withSetGovernanceDelegate'; export * from './withSignOffProposal'; diff --git a/packages/governance-sdk/src/governance/instructions.ts b/packages/governance-sdk/src/governance/instructions.ts index 8b4ab26b..845b1f92 100644 --- a/packages/governance-sdk/src/governance/instructions.ts +++ b/packages/governance-sdk/src/governance/instructions.ts @@ -38,6 +38,7 @@ export enum GovernanceInstruction { CreateTokenOwnerRecord = 23, UpdateProgramMetadata = 24, CreateNativeTreasury = 25, + RevokeGoverningTokens = 26, } export class CreateRealmArgs { @@ -194,21 +195,26 @@ export class VoteChoice { export enum VoteKind { Approve, Deny, + Abstain, + Veto, } export class Vote { voteType: VoteKind; approveChoices: VoteChoice[] | undefined; deny: boolean | undefined; + veto: boolean | undefined; constructor(args: { voteType: VoteKind; approveChoices: VoteChoice[] | undefined; deny: boolean | undefined; + veto: boolean | undefined; }) { this.voteType = args.voteType; this.approveChoices = args.approveChoices; this.deny = args.deny; + this.veto = args.veto; } toYesNoVote() { @@ -229,6 +235,7 @@ export class Vote { voteType: VoteKind.Approve, approveChoices: [new VoteChoice({ rank: 0, weightPercentage: 100 })], deny: undefined, + veto: undefined, }); } case YesNoVote.No: { @@ -236,6 +243,7 @@ export class Vote { voteType: VoteKind.Deny, approveChoices: undefined, deny: true, + veto: undefined, }); } } @@ -373,3 +381,13 @@ export class SetGovernanceDelegateArgs { this.newGovernanceDelegate = args.newGovernanceDelegate; } } + +export class RevokeGoverningTokensArgs { + instruction: GovernanceInstruction = + GovernanceInstruction.RevokeGoverningTokens; + amount: BN; + + constructor(args: { amount: BN }) { + this.amount = args.amount; + } +} diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 605bd9c3..1dbee948 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -20,6 +20,7 @@ import { InsertTransactionArgs, RelinquishVoteArgs, RemoveTransactionArgs, + RevokeGoverningTokensArgs, SetGovernanceConfigArgs, SetGovernanceDelegateArgs, SetRealmAuthorityArgs, @@ -56,10 +57,16 @@ import { getAccountProgramVersion, ProgramMetadata, VoteThresholdType, + GoverningTokenConfigArgs, + GoverningTokenConfig, } from './accounts'; import { serialize } from 'borsh'; import { BorshAccountParser } from '../core/serialisation'; -import { PROGRAM_VERSION_V1 } from '../registry/constants'; +import { + PROGRAM_VERSION_V1, + PROGRAM_VERSION_V2, + PROGRAM_VERSION_V3, +} from '../registry/constants'; import { deserializeBorsh } from '../tools/borsh'; // ------------ u16 ------------ @@ -115,7 +122,21 @@ import { deserializeBorsh } from '../tools/borsh'; reader.offset += 1; if (value === VoteKind.Deny) { - return new Vote({ voteType: value, approveChoices: undefined, deny: true }); + return new Vote({ + voteType: value, + approveChoices: undefined, + deny: true, + veto: false, + }); + } + + if (value === VoteKind.Veto) { + return new Vote({ + voteType: value, + approveChoices: undefined, + deny: false, + veto: true, + }); } let approveChoices: VoteChoice[] = []; @@ -135,6 +156,7 @@ import { deserializeBorsh } from '../tools/borsh'; voteType: value, approveChoices: approveChoices, deny: undefined, + veto: undefined, }); }; @@ -226,9 +248,7 @@ export const createInstructionData = (instruction: TransactionInstruction) => { export const GOVERNANCE_SCHEMA_V1 = createGovernanceSchema(1); export const GOVERNANCE_SCHEMA_V2 = createGovernanceSchema(2); - -// V3 schema is backward compatible with V2 -export const GOVERNANCE_SCHEMA_V3 = GOVERNANCE_SCHEMA_V2; +export const GOVERNANCE_SCHEMA_V3 = createGovernanceSchema(3); // The most recent version of spl-gov export const GOVERNANCE_SCHEMA = GOVERNANCE_SCHEMA_V3; @@ -237,6 +257,10 @@ export function getGovernanceSchema(programVersion: number) { switch (programVersion) { case 1: return GOVERNANCE_SCHEMA_V1; + case 2: + return GOVERNANCE_SCHEMA_V2; + case 3: + return GOVERNANCE_SCHEMA_V3; default: return GOVERNANCE_SCHEMA; } @@ -253,11 +277,16 @@ function createGovernanceSchema(programVersion: number) { ['minCommunityTokensToCreateGovernance', 'u64'], ['communityMintMaxVoteWeightSource', MintMaxVoteWeightSource], // V1 of the program used restrictive instruction deserialisation which didn't allow additional data - ...(programVersion > PROGRAM_VERSION_V1 + ...(programVersion == PROGRAM_VERSION_V2 ? [ ['useCommunityVoterWeightAddin', 'u8'], ['useMaxCommunityVoterWeightAddin', 'u8'], ] + : programVersion >= PROGRAM_VERSION_V3 + ? [ + ['communityTokenConfigArgs', GoverningTokenConfigArgs], + ['councilTokenConfigArgs', GoverningTokenConfigArgs], + ] : []), ], }, @@ -273,6 +302,17 @@ function createGovernanceSchema(programVersion: number) { ], }, ], + [ + GoverningTokenConfigArgs, + { + kind: 'struct', + fields: [ + ['useVoterWeightAddin', 'u8'], + ['useMaxVoterWeightAddin', 'u8'], + ['tokenType', 'u8'], + ], + }, + ], [ DepositGoverningTokensArgs, { @@ -284,6 +324,16 @@ function createGovernanceSchema(programVersion: number) { ].filter(Boolean), }, ], + [ + RevokeGoverningTokensArgs, + { + kind: 'struct', + fields: [ + ['instruction', 'u8'], + ['amount', 'u64'], + ], + }, + ], [ WithdrawGoverningTokensArgs, { @@ -585,8 +635,21 @@ function createGovernanceSchema(programVersion: number) { fields: [ ['accountType', 'u8'], ['realm', 'pubkey'], - ['communityVoterWeightAddin', { kind: 'option', type: 'pubkey' }], - ['maxCommunityVoterWeightAddin', { kind: 'option', type: 'pubkey' }], + ['communityTokenConfig', GoverningTokenConfig], + ['councilTokenConfig', GoverningTokenConfig], + ['reserved', [110]], + ], + }, + ], + [ + GoverningTokenConfig, + { + kind: 'struct', + fields: [ + ['voterWeightAddin', { kind: 'option', type: 'pubkey' }], + ['maxVoterWeightAddin', { kind: 'option', type: 'pubkey' }], + ['tokenType', 'u8'], + ['reserved', [8]], ], }, ], @@ -616,7 +679,7 @@ function createGovernanceSchema(programVersion: number) { ['maxVotingTime', 'u32'], ['voteTipping', 'u8'], ['councilVoteThreshold', 'VoteThreshold'], - ['reserved', [2]], + ['councilVetoVoteThreshold', 'VoteThreshold'], ['minCouncilTokensToCreateProposal', 'u64'], ], }, @@ -678,7 +741,7 @@ function createGovernanceSchema(programVersion: number) { ['voteType', 'voteType'], ['options', [ProposalOption]], ['denyVoteWeight', { kind: 'option', type: 'u64' }], - ['vetoVoteWeight', { kind: 'option', type: 'u64' }], + ['reserved1', 'u8'], ['abstainVoteWeight', { kind: 'option', type: 'u64' }], ['startVotingAt', { kind: 'option', type: 'u64' }], ]), @@ -705,6 +768,7 @@ function createGovernanceSchema(programVersion: number) { ['name', 'string'], ['descriptionLink', 'string'], + ['vetoVoteWeight', 'u64'], ], }, ], diff --git a/packages/governance-sdk/src/governance/tools.ts b/packages/governance-sdk/src/governance/tools.ts new file mode 100644 index 00000000..2b20cd6e --- /dev/null +++ b/packages/governance-sdk/src/governance/tools.ts @@ -0,0 +1,139 @@ +import { AccountMeta, PublicKey } from '@solana/web3.js'; +import BN from 'bn.js'; +import { PROGRAM_VERSION_V2, PROGRAM_VERSION_V3 } from '../registry/constants'; +import { + getRealmConfigAddress, + GoverningTokenConfigAccountArgs, + GoverningTokenConfigArgs, + GoverningTokenType, + MintMaxVoteWeightSource, + RealmConfigArgs, +} from './accounts'; +import { GovernananceTokenKind } from './enums'; + +function assertValidTokenConfigArgs( + programVersion: number, + tokenConfigArgs: GoverningTokenConfigAccountArgs | undefined, + tokenKind: GovernananceTokenKind, +) { + if (tokenConfigArgs) { + if (programVersion < PROGRAM_VERSION_V2) { + throw new Error( + `Governing token config is not supported in version ${programVersion}`, + ); + } else if (programVersion == PROGRAM_VERSION_V2) { + if (tokenKind == GovernananceTokenKind.Council) { + throw new Error( + `Council token config is not supported in version ${programVersion}`, + ); + } + + if (tokenConfigArgs.tokenType != GoverningTokenType.Liquid) { + throw new Error( + `Community token type ${tokenConfigArgs.tokenType} is not supported in veriosn ${programVersion}`, + ); + } + } + } +} + +export function createRealmConfigArgs( + programVersion: number, + councilMint: PublicKey | undefined, + communityMintMaxVoteWeightSource: MintMaxVoteWeightSource, + minCommunityWeightToCreateGovernance: BN, + communityTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + councilTokenConfig?: GoverningTokenConfigAccountArgs | undefined, +) { + assertValidTokenConfigArgs( + programVersion, + communityTokenConfig, + GovernananceTokenKind.Community, + ); + assertValidTokenConfigArgs( + programVersion, + councilTokenConfig, + GovernananceTokenKind.Council, + ); + + return new RealmConfigArgs({ + useCouncilMint: councilMint !== undefined, + minCommunityTokensToCreateGovernance: minCommunityWeightToCreateGovernance, + communityMintMaxVoteWeightSource, + + // VERSION == 2 + useCommunityVoterWeightAddin: + communityTokenConfig?.voterWeightAddin !== undefined, + useMaxCommunityVoterWeightAddin: + communityTokenConfig?.maxVoterWeightAddin !== undefined, + + // VERSION >= 3 + communityTokenConfigArgs: new GoverningTokenConfigArgs({ + useVoterWeightAddin: communityTokenConfig?.voterWeightAddin !== undefined, + useMaxVoterWeightAddin: + communityTokenConfig?.maxVoterWeightAddin !== undefined, + tokenType: communityTokenConfig?.tokenType ?? GoverningTokenType.Liquid, + }), + councilTokenConfigArgs: new GoverningTokenConfigArgs({ + useVoterWeightAddin: councilTokenConfig?.voterWeightAddin !== undefined, + useMaxVoterWeightAddin: + councilTokenConfig?.maxVoterWeightAddin !== undefined, + tokenType: councilTokenConfig?.tokenType ?? GoverningTokenType.Liquid, + }), + }); +} + +export function withTokenConfigAccounts( + keys: Array, + communityTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + councilTokenConfig?: GoverningTokenConfigAccountArgs | undefined, +) { + if (communityTokenConfig?.voterWeightAddin) { + keys.push({ + pubkey: communityTokenConfig.voterWeightAddin, + isWritable: false, + isSigner: false, + }); + } + + if (communityTokenConfig?.maxVoterWeightAddin) { + keys.push({ + pubkey: communityTokenConfig.maxVoterWeightAddin, + isWritable: false, + isSigner: false, + }); + } + + if (councilTokenConfig?.voterWeightAddin) { + keys.push({ + pubkey: councilTokenConfig.voterWeightAddin, + isWritable: false, + isSigner: false, + }); + } + + if (councilTokenConfig?.maxVoterWeightAddin) { + keys.push({ + pubkey: councilTokenConfig.maxVoterWeightAddin, + isWritable: false, + isSigner: false, + }); + } +} + +export async function withV3RealmConfigAccount( + keys: Array, + programId: PublicKey, + programVersion: number, + realm: PublicKey, +) { + if (programVersion >= PROGRAM_VERSION_V3) { + const realmConfigMeta = { + pubkey: await getRealmConfigAddress(programId, realm), + isSigner: false, + isWritable: true, + }; + + keys.push(realmConfigMeta); + } +} diff --git a/packages/governance-sdk/src/governance/version.ts b/packages/governance-sdk/src/governance/version.ts index 43cb2388..4783070a 100644 --- a/packages/governance-sdk/src/governance/version.ts +++ b/packages/governance-sdk/src/governance/version.ts @@ -5,7 +5,11 @@ import { TransactionInstruction, } from '@solana/web3.js'; import BN from 'bn.js'; -import { PROGRAM_VERSION, PROGRAM_VERSION_V1 } from '../registry/constants'; +import { + PROGRAM_VERSION, + PROGRAM_VERSION_V1, + PROGRAM_VERSION_V2, +} from '../registry/constants'; import { BN_ZERO } from '../tools/numbers'; import { getProgramDataAccount } from '../tools/sdk/bpfUpgradeableLoader'; import { ProgramAccount, simulateTransaction } from '../tools/sdk/runtime'; @@ -105,6 +109,6 @@ export async function getGovernanceProgramVersion( return PROGRAM_VERSION; } - // Default to V1 because it's not possible to detect its version - return PROGRAM_VERSION_V1; + // Default to V2 which is the most common version being used + return PROGRAM_VERSION_V2; } diff --git a/packages/governance-sdk/src/governance/withCastVote.ts b/packages/governance-sdk/src/governance/withCastVote.ts index fb77dacf..fbf92a0c 100644 --- a/packages/governance-sdk/src/governance/withCastVote.ts +++ b/packages/governance-sdk/src/governance/withCastVote.ts @@ -10,7 +10,7 @@ import { CastVoteArgs, Vote } from './instructions'; import { getVoteRecordAddress } from './accounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; -import { withRealmConfigAccounts } from './withRealmConfigAccounts'; +import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; export const withCastVote = async ( instructions: TransactionInstruction[], @@ -22,7 +22,7 @@ export const withCastVote = async ( proposalOwnerRecord: PublicKey, tokenOwnerRecord: PublicKey, governanceAuthority: PublicKey, - governingTokenMint: PublicKey, + voteGoverningTokenMint: PublicKey, vote: Vote, payer: PublicKey, voterWeightRecord?: PublicKey, @@ -83,7 +83,7 @@ export const withCastVote = async ( isSigner: false, }, { - pubkey: governingTokenMint, + pubkey: voteGoverningTokenMint, isWritable: false, isSigner: false, }, @@ -114,7 +114,7 @@ export const withCastVote = async ( ); } - await withRealmConfigAccounts( + await withRealmConfigPluginAccounts( keys, programId, realm, diff --git a/packages/governance-sdk/src/governance/withCreateGovernance.ts b/packages/governance-sdk/src/governance/withCreateGovernance.ts index 332beb57..c58054b7 100644 --- a/packages/governance-sdk/src/governance/withCreateGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateGovernance.ts @@ -9,7 +9,7 @@ import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateGovernanceArgs } from './instructions'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; -import { withRealmConfigAccounts } from './withRealmConfigAccounts'; +import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; export const withCreateGovernance = async ( @@ -85,7 +85,12 @@ export const withCreateGovernance = async ( isSigner: true, }); - await withRealmConfigAccounts(keys, programId, realm, voterWeightRecord); + await withRealmConfigPluginAccounts( + keys, + programId, + realm, + voterWeightRecord, + ); instructions.push( new TransactionInstruction({ diff --git a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts index be5d115e..a403644d 100644 --- a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts @@ -9,7 +9,7 @@ import { GovernanceConfig } from './accounts'; import { CreateMintGovernanceArgs } from './instructions'; import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; -import { withRealmConfigAccounts } from './withRealmConfigAccounts'; +import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; export const withCreateMintGovernance = async ( @@ -94,7 +94,12 @@ export const withCreateMintGovernance = async ( isSigner: true, }); - await withRealmConfigAccounts(keys, programId, realm, voterWeightRecord); + await withRealmConfigPluginAccounts( + keys, + programId, + realm, + voterWeightRecord, + ); instructions.push( new TransactionInstruction({ diff --git a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts index 812947d8..919de647 100644 --- a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts @@ -9,7 +9,7 @@ import { GovernanceConfig } from './accounts'; import { CreateProgramGovernanceArgs } from './instructions'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; import { BPF_UPGRADE_LOADER_ID } from '../tools/sdk/bpfUpgradeableLoader'; -import { withRealmConfigAccounts } from './withRealmConfigAccounts'; +import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; export const withCreateProgramGovernance = async ( @@ -108,7 +108,12 @@ export const withCreateProgramGovernance = async ( isSigner: true, }); - await withRealmConfigAccounts(keys, programId, realm, voterWeightRecord); + await withRealmConfigPluginAccounts( + keys, + programId, + realm, + voterWeightRecord, + ); instructions.push( new TransactionInstruction({ diff --git a/packages/governance-sdk/src/governance/withCreateProposal.ts b/packages/governance-sdk/src/governance/withCreateProposal.ts index 3df56005..4cccc332 100644 --- a/packages/governance-sdk/src/governance/withCreateProposal.ts +++ b/packages/governance-sdk/src/governance/withCreateProposal.ts @@ -14,7 +14,7 @@ import { } from './accounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; -import { withRealmConfigAccounts } from './withRealmConfigAccounts'; +import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; export const withCreateProposal = async ( instructions: TransactionInstruction[], @@ -119,7 +119,12 @@ export const withCreateProposal = async ( }); } - await withRealmConfigAccounts(keys, programId, realm, voterWeightRecord); + await withRealmConfigPluginAccounts( + keys, + programId, + realm, + voterWeightRecord, + ); instructions.push( new TransactionInstruction({ diff --git a/packages/governance-sdk/src/governance/withCreateRealm.ts b/packages/governance-sdk/src/governance/withCreateRealm.ts index 06ba6c67..ea08dcfa 100644 --- a/packages/governance-sdk/src/governance/withCreateRealm.ts +++ b/packages/governance-sdk/src/governance/withCreateRealm.ts @@ -12,10 +12,14 @@ import { MintMaxVoteWeightSource, getTokenHoldingAddress, getRealmConfigAddress, + GoverningTokenConfigArgs, + GoverningTokenType, + GoverningTokenConfigAccountArgs, } from './accounts'; import BN from 'bn.js'; -import { PROGRAM_VERSION_V2 } from '../registry/constants'; +import { PROGRAM_VERSION_V2, PROGRAM_VERSION_V3 } from '../registry/constants'; import { SYSTEM_PROGRAM_ID, TOKEN_PROGRAM_ID } from '../tools/sdk'; +import { createRealmConfigArgs, withTokenConfigAccounts } from './tools'; export async function withCreateRealm( instructions: TransactionInstruction[], @@ -28,22 +32,17 @@ export async function withCreateRealm( councilMint: PublicKey | undefined, communityMintMaxVoteWeightSource: MintMaxVoteWeightSource, minCommunityWeightToCreateGovernance: BN, - communityVoterWeightAddin?: PublicKey | undefined, - maxCommunityVoterWeightAddin?: PublicKey | undefined, + communityTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + councilTokenConfig?: GoverningTokenConfigAccountArgs | undefined, ) { - if (communityVoterWeightAddin && programVersion < PROGRAM_VERSION_V2) { - throw new Error( - `Voter weight addin is not supported in version ${programVersion}`, - ); - } - - const configArgs = new RealmConfigArgs({ - useCouncilMint: councilMint !== undefined, - minCommunityTokensToCreateGovernance: minCommunityWeightToCreateGovernance, + const configArgs = createRealmConfigArgs( + programVersion, + councilMint, communityMintMaxVoteWeightSource, - useCommunityVoterWeightAddin: communityVoterWeightAddin !== undefined, - useMaxCommunityVoterWeightAddin: maxCommunityVoterWeightAddin !== undefined, - }); + minCommunityWeightToCreateGovernance, + communityTokenConfig, + councilTokenConfig, + ); const args = new CreateRealmArgs({ configArgs, @@ -129,33 +128,24 @@ export async function withCreateRealm( ]; } - if (communityVoterWeightAddin) { - keys.push({ - pubkey: communityVoterWeightAddin, - isWritable: false, - isSigner: false, - }); - } + const realmConfigMeta = { + pubkey: await getRealmConfigAddress(programId, realmAddress), + isSigner: false, + isWritable: true, + }; - if (maxCommunityVoterWeightAddin) { - keys.push({ - pubkey: maxCommunityVoterWeightAddin, - isWritable: false, - isSigner: false, - }); + if (programVersion >= PROGRAM_VERSION_V3) { + keys.push(realmConfigMeta); } - if (communityVoterWeightAddin || maxCommunityVoterWeightAddin) { - const realmConfigAddress = await getRealmConfigAddress( - programId, - realmAddress, - ); + withTokenConfigAccounts(keys, communityTokenConfig, councilTokenConfig); - keys.push({ - pubkey: realmConfigAddress, - isSigner: false, - isWritable: true, - }); + if ( + programVersion == PROGRAM_VERSION_V2 && + (communityTokenConfig?.voterWeightAddin || + communityTokenConfig?.maxVoterWeightAddin) + ) { + keys.push(realmConfigMeta); } instructions.push( diff --git a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts index 49f1a161..1ab7e3f1 100644 --- a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts @@ -9,7 +9,7 @@ import { GovernanceConfig } from './accounts'; import { CreateTokenGovernanceArgs } from './instructions'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken'; -import { withRealmConfigAccounts } from './withRealmConfigAccounts'; +import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; export const withCreateTokenGovernance = async ( @@ -98,7 +98,12 @@ export const withCreateTokenGovernance = async ( isSigner: true, }); - await withRealmConfigAccounts(keys, programId, realm, voterWeightRecord); + await withRealmConfigPluginAccounts( + keys, + programId, + realm, + voterWeightRecord, + ); instructions.push( new TransactionInstruction({ diff --git a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts index 88d0ba24..04f8e639 100644 --- a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts @@ -14,6 +14,7 @@ import BN from 'bn.js'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; +import { withV3RealmConfigAccount } from './tools'; export const withDepositGoverningTokens = async ( instructions: TransactionInstruction[], @@ -23,7 +24,7 @@ export const withDepositGoverningTokens = async ( governingTokenSource: PublicKey, governingTokenMint: PublicKey, governingTokenOwner: PublicKey, - transferAuthority: PublicKey, + governingTokenSourceAuthority: PublicKey, payer: PublicKey, amount: BN, ) => { @@ -70,7 +71,7 @@ export const withDepositGoverningTokens = async ( isSigner: true, }, { - pubkey: transferAuthority, + pubkey: governingTokenSourceAuthority, isWritable: false, isSigner: true, }, @@ -104,6 +105,8 @@ export const withDepositGoverningTokens = async ( }); } + await withV3RealmConfigAccount(keys, programId, programVersion, realm); + instructions.push( new TransactionInstruction({ keys, diff --git a/packages/governance-sdk/src/governance/withFinalizeVote.ts b/packages/governance-sdk/src/governance/withFinalizeVote.ts index 77158039..39e4bfdb 100644 --- a/packages/governance-sdk/src/governance/withFinalizeVote.ts +++ b/packages/governance-sdk/src/governance/withFinalizeVote.ts @@ -7,7 +7,7 @@ import { GOVERNANCE_SCHEMA } from './serialisation'; import { serialize } from 'borsh'; import { FinalizeVoteArgs } from './instructions'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; -import { withRealmConfigAccounts } from './withRealmConfigAccounts'; +import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; export const withFinalizeVote = async ( instructions: TransactionInstruction[], @@ -61,7 +61,7 @@ export const withFinalizeVote = async ( }); } - await withRealmConfigAccounts( + await withRealmConfigPluginAccounts( keys, programId, realm, diff --git a/packages/governance-sdk/src/governance/withRealmConfigAccounts.ts b/packages/governance-sdk/src/governance/withRealmConfigPluginAccounts.ts similarity index 93% rename from packages/governance-sdk/src/governance/withRealmConfigAccounts.ts rename to packages/governance-sdk/src/governance/withRealmConfigPluginAccounts.ts index 94266e77..657f7a4d 100644 --- a/packages/governance-sdk/src/governance/withRealmConfigAccounts.ts +++ b/packages/governance-sdk/src/governance/withRealmConfigPluginAccounts.ts @@ -1,7 +1,7 @@ import { AccountMeta, PublicKey } from '@solana/web3.js'; import { getRealmConfigAddress } from './accounts'; -export async function withRealmConfigAccounts( +export async function withRealmConfigPluginAccounts( keys: AccountMeta[], programId: PublicKey, realm: PublicKey, diff --git a/packages/governance-sdk/src/governance/withRelinquishVote.ts b/packages/governance-sdk/src/governance/withRelinquishVote.ts index d5ac9117..003a8863 100644 --- a/packages/governance-sdk/src/governance/withRelinquishVote.ts +++ b/packages/governance-sdk/src/governance/withRelinquishVote.ts @@ -2,10 +2,13 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import { GOVERNANCE_SCHEMA } from './serialisation'; import { serialize } from 'borsh'; import { RelinquishVoteArgs } from './instructions'; +import { PROGRAM_VERSION_V3 } from '../registry/constants'; export const withRelinquishVote = async ( instructions: TransactionInstruction[], programId: PublicKey, + programVersion: number, + realm: PublicKey, governance: PublicKey, proposal: PublicKey, tokenOwnerRecord: PublicKey, @@ -17,6 +20,17 @@ export const withRelinquishVote = async ( const args = new RelinquishVoteArgs(); const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + let v3Keys = + programVersion >= PROGRAM_VERSION_V3 + ? [ + { + pubkey: realm, + isWritable: false, + isSigner: false, + }, + ] + : []; + let keys = [ { pubkey: governance, @@ -63,7 +77,7 @@ export const withRelinquishVote = async ( instructions.push( new TransactionInstruction({ - keys: [...keys, ...existingVoteKeys], + keys: [...v3Keys, ...keys, ...existingVoteKeys], programId, data, }), diff --git a/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts b/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts new file mode 100644 index 00000000..6e526395 --- /dev/null +++ b/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts @@ -0,0 +1,101 @@ +import { + PublicKey, + SYSVAR_RENT_PUBKEY, + TransactionInstruction, +} from '@solana/web3.js'; +import { getGovernanceSchema } from './serialisation'; +import { serialize } from 'borsh'; +import { RevokeGoverningTokensArgs } from './instructions'; +import { + getGoverningTokenHoldingAddress, + getRealmConfigAddress, + getTokenOwnerRecordAddress, +} from './accounts'; +import BN from 'bn.js'; +import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken'; +import { PROGRAM_VERSION_V1 } from '../registry/constants'; + +export const withRevokeGoverningTokens = async ( + instructions: TransactionInstruction[], + programId: PublicKey, + programVersion: number, + realm: PublicKey, + realmAuthority: PublicKey, + governingTokenMint: PublicKey, + governingTokenOwner: PublicKey, + amount: BN, +) => { + const args = new RevokeGoverningTokensArgs({ amount }); + const data = Buffer.from( + serialize(getGovernanceSchema(programVersion), args), + ); + + const tokenOwnerRecordAddress = await getTokenOwnerRecordAddress( + programId, + realm, + governingTokenMint, + governingTokenOwner, + ); + + const governingTokenHoldingAddress = await getGoverningTokenHoldingAddress( + programId, + realm, + governingTokenMint, + ); + + const realmConfigAddress = await getRealmConfigAddress(programId, realm); + + const keys = [ + { + pubkey: realm, + isWritable: false, + isSigner: false, + }, + { + pubkey: realmAuthority, + isWritable: false, + isSigner: true, + }, + { + pubkey: governingTokenHoldingAddress, + isWritable: true, + isSigner: false, + }, + { + pubkey: tokenOwnerRecordAddress, + isWritable: true, + isSigner: false, + }, + { + pubkey: governingTokenMint, + isWritable: true, + isSigner: false, + }, + { + pubkey: realmConfigAddress, + isSigner: false, + isWritable: false, + }, + { + pubkey: TOKEN_PROGRAM_ID, + isWritable: false, + isSigner: false, + }, + ]; + + if (programVersion === PROGRAM_VERSION_V1) { + keys.push({ + pubkey: SYSVAR_RENT_PUBKEY, + isWritable: false, + isSigner: false, + }); + } + + instructions.push( + new TransactionInstruction({ + keys, + programId, + data, + }), + ); +}; diff --git a/packages/governance-sdk/src/governance/withSetRealmConfig.ts b/packages/governance-sdk/src/governance/withSetRealmConfig.ts index 7c1c065a..6d4a701b 100644 --- a/packages/governance-sdk/src/governance/withSetRealmConfig.ts +++ b/packages/governance-sdk/src/governance/withSetRealmConfig.ts @@ -2,6 +2,9 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import { getRealmConfigAddress, getTokenHoldingAddress, + GoverningTokenConfigAccountArgs, + GoverningTokenConfigArgs, + GoverningTokenType, MintMaxVoteWeightSource, RealmConfigArgs, } from './accounts'; @@ -10,7 +13,8 @@ import { getGovernanceSchema } from './serialisation'; import { serialize } from 'borsh'; import BN from 'bn.js'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; -import { PROGRAM_VERSION_V1 } from '../registry/constants'; +import { PROGRAM_VERSION_V1, PROGRAM_VERSION_V3 } from '../registry/constants'; +import { createRealmConfigArgs, withTokenConfigAccounts } from './tools'; export async function withSetRealmConfig( instructions: TransactionInstruction[], @@ -20,18 +24,19 @@ export async function withSetRealmConfig( realmAuthority: PublicKey, councilMint: PublicKey | undefined, communityMintMaxVoteWeightSource: MintMaxVoteWeightSource, - minCommunityTokensToCreateGovernance: BN, - communityVoterWeightAddin: PublicKey | undefined, - maxCommunityVoterWeightAddin: PublicKey | undefined, - payer: PublicKey, + minCommunityWeightToCreateGovernance: BN, + communityTokenConfig: GoverningTokenConfigAccountArgs | undefined, + councilTokenConfig: GoverningTokenConfigAccountArgs | undefined, + payer: PublicKey | undefined, ) { - const configArgs = new RealmConfigArgs({ - useCouncilMint: councilMint !== undefined, + const configArgs = createRealmConfigArgs( + programVersion, + councilMint, communityMintMaxVoteWeightSource, - minCommunityTokensToCreateGovernance, - useCommunityVoterWeightAddin: communityVoterWeightAddin !== undefined, - useMaxCommunityVoterWeightAddin: maxCommunityVoterWeightAddin !== undefined, - }); + minCommunityWeightToCreateGovernance, + communityTokenConfig, + councilTokenConfig, + ); const args = new SetRealmConfigArgs({ configArgs }); const data = Buffer.from( @@ -89,23 +94,14 @@ export async function withSetRealmConfig( isWritable: true, }); - if (communityVoterWeightAddin) { - keys.push({ - pubkey: communityVoterWeightAddin, - isWritable: false, - isSigner: false, - }); - } - - if (maxCommunityVoterWeightAddin) { - keys.push({ - pubkey: maxCommunityVoterWeightAddin, - isWritable: false, - isSigner: false, - }); - } + withTokenConfigAccounts(keys, communityTokenConfig, councilTokenConfig); - if (communityVoterWeightAddin || maxCommunityVoterWeightAddin) { + if ( + payer && + (programVersion >= PROGRAM_VERSION_V3 || + communityTokenConfig?.voterWeightAddin || + communityTokenConfig?.maxVoterWeightAddin) + ) { keys.push({ pubkey: payer, isSigner: true, diff --git a/packages/governance-sdk/src/governance/withWithdrawGoverningTokens.ts b/packages/governance-sdk/src/governance/withWithdrawGoverningTokens.ts index 034f2060..cdbdeec4 100644 --- a/packages/governance-sdk/src/governance/withWithdrawGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withWithdrawGoverningTokens.ts @@ -4,10 +4,12 @@ import { serialize } from 'borsh'; import { WithdrawGoverningTokensArgs } from './instructions'; import { GOVERNANCE_PROGRAM_SEED } from './accounts'; import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken'; +import { withV3RealmConfigAccount } from './tools'; export const withWithdrawGoverningTokens = async ( instructions: TransactionInstruction[], programId: PublicKey, + programVersion: number, realm: PublicKey, governingTokenDestination: PublicKey, governingTokenMint: PublicKey, @@ -57,7 +59,6 @@ export const withWithdrawGoverningTokens = async ( isWritable: true, isSigner: false, }, - { pubkey: TOKEN_PROGRAM_ID, isWritable: false, @@ -65,6 +66,8 @@ export const withWithdrawGoverningTokens = async ( }, ]; + await withV3RealmConfigAccount(keys, programId, programVersion, realm); + instructions.push( new TransactionInstruction({ keys, diff --git a/packages/governance-sdk/tests/governance/api.smoke.test.ts b/packages/governance-sdk/tests/governance/api.smoke.test.ts index dfce9336..3cc53bcb 100644 --- a/packages/governance-sdk/tests/governance/api.smoke.test.ts +++ b/packages/governance-sdk/tests/governance/api.smoke.test.ts @@ -1,6 +1,5 @@ import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { - Connection, Keypair, PublicKey, @@ -52,7 +51,6 @@ import { withCreateAssociatedTokenAccount } from '../tools/withCreateAssociatedT import { withCreateMint } from '../tools/withCreateMint'; import { withMintTo } from '../tools/withMintTo'; - const connection = new Connection(rpcEndpoint, 'recent'); test('setupRealm', async () => { @@ -61,7 +59,6 @@ test('setupRealm', async () => { const walletPk = wallet.publicKey; await requestAirdrop(connection, walletPk); - await new Promise(f => setTimeout(f, 1000)); // options @@ -74,6 +71,8 @@ test('setupRealm', async () => { programId, ); + console.log('SETUP', { programVersion, walletPk: walletPk.toBase58() }); + let instructions: TransactionInstruction[] = []; let signers: Keypair[] = []; @@ -150,20 +149,33 @@ test('setupRealm', async () => { signers = []; // Crate governance over the the governance token mint + + let communityVoteThreshold = new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 60, + }); + + let councilVoteThreshold = new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + // For VERSION < 3 we have to pass 0 + value: programVersion >= 3 ? 10 : 0, + }); + + let councilVetoVoteThreshold = new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + // For VERSION < 3 we have to pass 0 + value: programVersion >= 3 ? 10 : 0, + }); + const config = new GovernanceConfig({ - communityVoteThreshold: new VoteThreshold({ - type: VoteThresholdType.YesVotePercentage, - value: 60, - }), + communityVoteThreshold: communityVoteThreshold, minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), voteTipping: VoteTipping.Strict, - councilVoteThreshold: new VoteThreshold({ - type: VoteThresholdType.YesVotePercentage, - value: 60, - }), minCouncilTokensToCreateProposal: new BN(1), + councilVoteThreshold: councilVoteThreshold, + councilVetoVoteThreshold: councilVetoVoteThreshold, }); const governancePk = await withCreateMintGovernance( @@ -355,6 +367,8 @@ test('setupRealm', async () => { withRelinquishVote( instructions, programId, + programVersion, + realmPk, governancePk, proposalPk, tokenOwnerRecordPk, @@ -398,6 +412,7 @@ test('setupRealm', async () => { withWithdrawGoverningTokens( instructions, programId, + programVersion, realmPk, ataPk, mintPk, @@ -416,57 +431,55 @@ test('setupRealm', async () => { test('getAllGovernances', async () => { // Arrange - const realmPk = new PublicKey("9BrZiMXAVocFj7wgUaAbt1sMcKUEzHKbMmhgrojUvM9G") + const realmPk = new PublicKey('9BrZiMXAVocFj7wgUaAbt1sMcKUEzHKbMmhgrojUvM9G'); // Act const governances = await getAllGovernances(connection, programId, realmPk); // Arrange expect(governances.length).toBeGreaterThan(0); - - }); test('getAllProposals', async () => { // Arrange - const realmPk = new PublicKey("EDJ6Uc1U51x1SemSygLEjkvtzNMUWMm1wMf4tANQz9Qu") + const realmPk = new PublicKey('EDJ6Uc1U51x1SemSygLEjkvtzNMUWMm1wMf4tANQz9Qu'); // Act const proposals = await getAllProposals(connection, programId, realmPk); // Arrange expect(proposals.length).toBeGreaterThan(0); - - }); test('getAllTokenOwnerRecords', async () => { // Arrange - const realmPk = new PublicKey("EDJ6Uc1U51x1SemSygLEjkvtzNMUWMm1wMf4tANQz9Qu") + const realmPk = new PublicKey('EDJ6Uc1U51x1SemSygLEjkvtzNMUWMm1wMf4tANQz9Qu'); // Act - const tokenOwnerRecords = await getAllTokenOwnerRecords(connection, programId, realmPk); + const tokenOwnerRecords = await getAllTokenOwnerRecords( + connection, + programId, + realmPk, + ); // Arrange expect(tokenOwnerRecords.length).toBeGreaterThan(0); - - }); test('tryGetRealmConfig', async () => { // Arrange - const realmPk = new PublicKey("A98TAf9KwCMMd9GmXogc9D3Lj9diYGkAZctUZZPXEf41") - const programId = new PublicKey("AuetJrDq4USDLibT83abUB9pniWFQuPsZa3YNYtrqUWP") + const realmPk = new PublicKey('A98TAf9KwCMMd9GmXogc9D3Lj9diYGkAZctUZZPXEf41'); + const programId = new PublicKey( + 'AuetJrDq4USDLibT83abUB9pniWFQuPsZa3YNYtrqUWP', + ); // Act - const realmConfig = await tryGetRealmConfig(connection,programId,realmPk); + const realmConfig = await tryGetRealmConfig(connection, programId, realmPk); // Assert expect(realmConfig.account.realm).toEqual(realmPk); - }); - test('setGovernanceDelegate', async () => { // Arrange const wallet = Keypair.generate(); @@ -486,7 +499,7 @@ test('setGovernanceDelegate', async () => { let signers: Keypair[] = []; // Create and mint governance token - let mintPk = await withCreateMint( + let communityMintPk = await withCreateMint( connection, instructions, signers, @@ -498,11 +511,11 @@ test('setGovernanceDelegate', async () => { let ataPk = await withCreateAssociatedTokenAccount( instructions, - mintPk, + communityMintPk, walletPk, walletPk, ); - await withMintTo(instructions, mintPk, ataPk, walletPk, 1); + await withMintTo(instructions, communityMintPk, ataPk, walletPk, 1); // Create Realm const name = `Realm-${new Keypair().publicKey.toBase58().slice(0, 6)}`; @@ -517,7 +530,7 @@ test('setGovernanceDelegate', async () => { programVersion, name, realmAuthorityPk, - mintPk, + communityMintPk, walletPk, councilMintPk, communityMintMaxVoteWeightSource, @@ -531,7 +544,7 @@ test('setGovernanceDelegate', async () => { programVersion, realmPk, ataPk, - mintPk, + communityMintPk, walletPk, walletPk, walletPk, @@ -542,18 +555,26 @@ test('setGovernanceDelegate', async () => { instructions = []; signers = []; - const delegatePk = Keypair.generate().publicKey; // Act - await withSetGovernanceDelegate(instructions,programId,programVersion,realmPk,mintPk,walletPk,walletPk,delegatePk); + await withSetGovernanceDelegate( + instructions, + programId, + programVersion, + realmPk, + communityMintPk, + walletPk, + walletPk, + delegatePk, + ); await sendTransaction(connection, instructions, signers, wallet); // Assert - let tokenOwnerRecord = await getTokenOwnerRecord(connection,tokenOwnerRecordPk) + let tokenOwnerRecord = await getTokenOwnerRecord( + connection, + tokenOwnerRecordPk, + ); expect(tokenOwnerRecord.account.governanceDelegate).toEqual(delegatePk); - }); - - diff --git a/packages/governance-sdk/tests/governance/api.test.ts b/packages/governance-sdk/tests/governance/api.test.ts index b9076e42..447ca2f9 100644 --- a/packages/governance-sdk/tests/governance/api.test.ts +++ b/packages/governance-sdk/tests/governance/api.test.ts @@ -105,19 +105,33 @@ test('createRealmWithGovernanceAndProposal', async () => { ); // Crate governance over the the governance token mint + + let communityVoteThreshold = new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 60, + }); + + let councilVoteThreshold = new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + // For VERSION < 3 we have to pass 0 + value: programVersion >= 3 ? 10 : 0, + }); + + let councilVetoVoteThreshold = new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + // For VERSION < 3 we have to pass 0 + value: programVersion >= 3 ? 10 : 0, + }); + const config = new GovernanceConfig({ - communityVoteThreshold: new VoteThreshold({ - type: VoteThresholdType.YesVotePercentage, - value: 60, - }), + communityVoteThreshold: communityVoteThreshold, minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), voteTipping: VoteTipping.Strict, - councilVoteThreshold: new VoteThreshold({ - type: VoteThresholdType.Disabled, - }), minCouncilTokensToCreateProposal: new BN(1), + councilVoteThreshold: councilVoteThreshold, + councilVetoVoteThreshold: councilVetoVoteThreshold, }); const governancePk = await withCreateMintGovernance( @@ -217,13 +231,13 @@ test('createRealmWithGovernanceAndProposal', async () => { expect(results.length).toBe(1); expect(results[0].account.governingTokenOwner).toEqual(walletPk); - // check governance - const governance = await getGovernance(connection,governancePk); - expect(governance.account.config.communityVoteThreshold).toEqual(config.communityVoteThreshold); + // check governance + const governance = await getGovernance(connection, governancePk); + expect(governance.account.config.communityVoteThreshold).toEqual( + config.communityVoteThreshold, + ); // expect(governance.account.config.councilVoteThreshold).toEqual(config.councilVoteThreshold); - // check proposal - const proposal = await getProposal(connection,proposalPk); + // check proposal + const proposal = await getProposal(connection, proposalPk); }); - - diff --git a/packages/governance-sdk/tests/governance/api.v2.test.ts b/packages/governance-sdk/tests/governance/api.v2.test.ts new file mode 100644 index 00000000..499a187d --- /dev/null +++ b/packages/governance-sdk/tests/governance/api.v2.test.ts @@ -0,0 +1,58 @@ +import BN from 'bn.js'; +import { PROGRAM_VERSION_V2 } from '../../src'; +import { + GovernanceConfig, + VoteThreshold, + VoteThresholdType, + VoteTipping, +} from '../../src/governance/accounts'; +import { BenchBuilder } from '../tools/builders'; +import { programId } from '../tools/setup'; +import { getTimestampFromDays } from '../tools/units'; + +test('createGovernanceWithConfig', async () => { + // Arrange + const realm = await BenchBuilder.withConnection(PROGRAM_VERSION_V2) + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.sendTx()); + + const config = new GovernanceConfig({ + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 20, + }), + minCommunityTokensToCreateProposal: new BN(1), + minInstructionHoldUpTime: 0, + maxVotingTime: getTimestampFromDays(3), + voteTipping: VoteTipping.Strict, + minCouncilTokensToCreateProposal: new BN(1), + councilVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 0, + }), + councilVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 0, + }), + }); + + // Act + const governancePk = await realm.createGovernance(config); + + // Assert + const governance = await realm.getGovernance(governancePk); + + expect(governance.account.config.communityVoteThreshold).toEqual( + config.communityVoteThreshold, + ); + + expect(governance.account.config.councilVoteThreshold).toEqual( + config.councilVoteThreshold, + ); + + expect(governance.account.config.councilVetoVoteThreshold).toEqual( + config.councilVetoVoteThreshold, + ); +}); diff --git a/packages/governance-sdk/tests/governance/api.v2.v3.test.ts b/packages/governance-sdk/tests/governance/api.v2.v3.test.ts new file mode 100644 index 00000000..6bca0023 --- /dev/null +++ b/packages/governance-sdk/tests/governance/api.v2.v3.test.ts @@ -0,0 +1,129 @@ +import { Keypair } from '@solana/web3.js'; +import { GoverningTokenConfigAccountArgs, GoverningTokenType } from '../../src'; +import { BenchBuilder } from '../tools/builders'; + +test('setRealmConfig', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.sendTx()); + + const communityTokenConfig = new GoverningTokenConfigAccountArgs({ + voterWeightAddin: Keypair.generate().publicKey, + maxVoterWeightAddin: Keypair.generate().publicKey, + tokenType: GoverningTokenType.Liquid, + }); + + // Act + await realm.setRealmConfig(communityTokenConfig); + + // Assert + const realmConfig = await realm.getRealmConfig(); + + expect(realmConfig.account.realm).toEqual(realm.realmPk); + + // communityTokenConfig + expect(realmConfig.account.communityTokenConfig.tokenType).toEqual( + communityTokenConfig.tokenType, + ); + expect(realmConfig.account.communityTokenConfig.voterWeightAddin).toEqual( + communityTokenConfig.voterWeightAddin, + ); + expect(realmConfig.account.communityTokenConfig.maxVoterWeightAddin).toEqual( + communityTokenConfig.maxVoterWeightAddin, + ); + + // councilTokenConfig + expect(realmConfig.account.councilTokenConfig.tokenType).toEqual( + GoverningTokenType.Liquid, + ); + expect(realmConfig.account.councilTokenConfig.voterWeightAddin).toEqual( + undefined, + ); + expect(realmConfig.account.councilTokenConfig.maxVoterWeightAddin).toEqual( + undefined, + ); +}); + +test('withdrawGoverningTokens', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.sendTx()); + + // Act + await realm.withdrawGoverningTokens(); + + // Assert + const tokenOwnerRecord = await realm.getTokenOwnerRecord( + realm.communityOwnerRecordPk, + ); + + expect( + tokenOwnerRecord.account.governingTokenDepositAmount.toNumber(), + ).toEqual(0); +}); + +test('createProposal', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.withGovernance()) + .then(b => b.sendTx()); + + // Act + const proposalPk = await realm.createProposal('proposal 1'); + + // Assert + const proposal = await realm.getProposal(proposalPk); + + expect(proposal.account.name).toEqual('proposal 1'); + expect(proposal.account.vetoVoteWeight.toNumber()).toEqual(0); +}); + +test('castVote', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.withGovernance()) + .then(b => b.withProposal()) + .then(b => b.sendTx()) + .then(b => b.withProposalSignOff()); + + // Act + const voteRecordPk = await realm.castVote(); + + // Assert + const voteRecord = await realm.getVoteRecord(voteRecordPk); + + expect(voteRecord.account.proposal).toEqual(realm.proposalPk); +}); + +test('relinquishVote', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.withGovernance()) + .then(b => b.withProposal()) + .then(b => b.sendTx()) + .then(b => b.withProposalSignOff()) + .then(b => b.withCastVote()) + .then(b => b.sendTx()); + + // Act + await realm.relinquishVote(); + + // Assert + const voteRecord = await realm.getVoteRecord(realm.voteRecordPk); + + expect(voteRecord.account.isRelinquished).toBe(true); +}); diff --git a/packages/governance-sdk/tests/governance/api.v3.test.ts b/packages/governance-sdk/tests/governance/api.v3.test.ts new file mode 100644 index 00000000..79be2974 --- /dev/null +++ b/packages/governance-sdk/tests/governance/api.v3.test.ts @@ -0,0 +1,187 @@ +import { Keypair } from '@solana/web3.js'; +import BN from 'bn.js'; +import { + GovernanceConfig, + GoverningTokenConfigAccountArgs, + GoverningTokenType, + VoteThreshold, + VoteThresholdType, + VoteTipping, +} from '../../src/governance/accounts'; +import { PROGRAM_VERSION_V3 } from '../../src/registry/constants'; +import { BenchBuilder } from '../tools/builders'; +import { getTimestampFromDays } from '../tools/units'; + +test('createRealmWithTokenConfigs', async () => { + // Arrange + const bench = await BenchBuilder.withConnection(PROGRAM_VERSION_V3).then(b => + b.withWallet(), + ); + + const communityTokenConfig = new GoverningTokenConfigAccountArgs({ + voterWeightAddin: Keypair.generate().publicKey, + maxVoterWeightAddin: Keypair.generate().publicKey, + tokenType: GoverningTokenType.Dormant, + }); + const councilTokenConfig = new GoverningTokenConfigAccountArgs({ + voterWeightAddin: Keypair.generate().publicKey, + maxVoterWeightAddin: Keypair.generate().publicKey, + tokenType: GoverningTokenType.Membership, + }); + + // Act + const realm = await bench + .withRealm(communityTokenConfig, councilTokenConfig) + .then(b => b.sendTx()); + + // Assert + const realmConfig = await realm.getRealmConfig(); + + expect(realmConfig.account.realm).toEqual(realm.realmPk); + + // communityTokenConfig + expect(realmConfig.account.communityTokenConfig.tokenType).toEqual( + communityTokenConfig.tokenType, + ); + expect(realmConfig.account.communityTokenConfig.voterWeightAddin).toEqual( + communityTokenConfig.voterWeightAddin, + ); + expect(realmConfig.account.communityTokenConfig.maxVoterWeightAddin).toEqual( + communityTokenConfig.maxVoterWeightAddin, + ); + + // councilTokenConfig + expect(realmConfig.account.councilTokenConfig.tokenType).toEqual( + GoverningTokenType.Membership, + ); + expect(realmConfig.account.councilTokenConfig.voterWeightAddin).toEqual( + councilTokenConfig.voterWeightAddin, + ); + expect(realmConfig.account.councilTokenConfig.maxVoterWeightAddin).toEqual( + councilTokenConfig.maxVoterWeightAddin, + ); +}); + +test('createGovernanceWithCouncilThresholds', async () => { + // Arrange + const realm = await BenchBuilder.withConnection(PROGRAM_VERSION_V3) + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.sendTx()); + + const config = new GovernanceConfig({ + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 20, + }), + minCommunityTokensToCreateProposal: new BN(1), + minInstructionHoldUpTime: 0, + maxVotingTime: getTimestampFromDays(3), + voteTipping: VoteTipping.Strict, + minCouncilTokensToCreateProposal: new BN(1), + councilVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 60, + }), + councilVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 80, + }), + }); + + // Act + const governancePk = await realm.createGovernance(config); + + // Assert + const governance = await realm.getGovernance(governancePk); + + expect(governance.account.config.communityVoteThreshold).toEqual( + config.communityVoteThreshold, + ); + + expect(governance.account.config.councilVoteThreshold).toEqual( + config.councilVoteThreshold, + ); + + expect(governance.account.config.councilVetoVoteThreshold).toEqual( + config.councilVetoVoteThreshold, + ); +}); + +test('setRealmConfigWithTokenConfigs', async () => { + // Arrange + const realm = await BenchBuilder.withConnection(PROGRAM_VERSION_V3) + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.sendTx()); + + const communityTokenConfig = new GoverningTokenConfigAccountArgs({ + voterWeightAddin: Keypair.generate().publicKey, + maxVoterWeightAddin: Keypair.generate().publicKey, + tokenType: GoverningTokenType.Dormant, + }); + const councilTokenConfig = new GoverningTokenConfigAccountArgs({ + voterWeightAddin: Keypair.generate().publicKey, + maxVoterWeightAddin: Keypair.generate().publicKey, + tokenType: GoverningTokenType.Membership, + }); + + // Act + await realm.setRealmConfig(communityTokenConfig, councilTokenConfig); + + // Assert + const realmConfig = await realm.getRealmConfig(); + + expect(realmConfig.account.realm).toEqual(realm.realmPk); + + // communityTokenConfig + expect(realmConfig.account.communityTokenConfig.tokenType).toEqual( + communityTokenConfig.tokenType, + ); + expect(realmConfig.account.communityTokenConfig.voterWeightAddin).toEqual( + communityTokenConfig.voterWeightAddin, + ); + expect(realmConfig.account.communityTokenConfig.maxVoterWeightAddin).toEqual( + communityTokenConfig.maxVoterWeightAddin, + ); + + // councilTokenConfig + expect(realmConfig.account.councilTokenConfig.tokenType).toEqual( + GoverningTokenType.Membership, + ); + expect(realmConfig.account.councilTokenConfig.voterWeightAddin).toEqual( + councilTokenConfig.voterWeightAddin, + ); + expect(realmConfig.account.councilTokenConfig.maxVoterWeightAddin).toEqual( + councilTokenConfig.maxVoterWeightAddin, + ); +}); + +test('revokeGoverningToken', async () => { + // Arrange + + const communityTokenConfig = new GoverningTokenConfigAccountArgs({ + voterWeightAddin: undefined, + maxVoterWeightAddin: undefined, + tokenType: GoverningTokenType.Membership, + }); + + const realm = await BenchBuilder.withConnection(PROGRAM_VERSION_V3) + .then(b => b.withWallet()) + .then(b => b.withRealm(communityTokenConfig)) + .then(b => b.withCommunityMember()) + .then(b => b.sendTx()); + + // Act + await realm.revokeGoverningTokens(); + + // Assert + const tokenOwnerRecord = await realm.getTokenOwnerRecord( + realm.communityOwnerRecordPk, + ); + + expect( + tokenOwnerRecord.account.governingTokenDepositAmount.toNumber(), + ).toEqual(0); +}); diff --git a/packages/governance-sdk/tests/tools/builders.ts b/packages/governance-sdk/tests/tools/builders.ts new file mode 100644 index 00000000..b8de839d --- /dev/null +++ b/packages/governance-sdk/tests/tools/builders.ts @@ -0,0 +1,486 @@ +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + Token, + TOKEN_PROGRAM_ID, +} from '@solana/spl-token'; +import { + Connection, + Keypair, + PublicKey, + TransactionInstruction, +} from '@solana/web3.js'; +import BN from 'bn.js'; +import { + getGovernance, + getProposal, + getRealm, + getRealmConfig, + getTokenOwnerRecord, + getVoteRecord, + Vote, + withCastVote, + withCreateGovernance, + withCreateProposal, + withDepositGoverningTokens, + withRelinquishVote, + withRevokeGoverningTokens, + withSignOffProposal, + withWithdrawGoverningTokens, + YesNoVote, +} from '../../src'; +import { + getRealmConfigAddress, + GovernanceConfig, + GoverningTokenConfigAccountArgs, + GoverningTokenType, + MintMaxVoteWeightSource, + VoteThreshold, + VoteThresholdType, + VoteTipping, + VoteType, +} from '../../src/governance/accounts'; +import { getGovernanceProgramVersion } from '../../src/governance/version'; +import { withCreateRealm } from '../../src/governance/withCreateRealm'; +import { withSetRealmConfig } from '../../src/governance/withSetRealmConfig'; +import { requestAirdrop, sendTransaction } from './sdk'; +import { rpcEndpoint, rpcProgramId } from './setup'; +import { getTimestampFromDays } from './units'; +import { withCreateAssociatedTokenAccount } from './withCreateAssociatedTokenAccount'; +import { withCreateMint } from './withCreateMint'; +import { withMintTo } from './withMintTo'; + +export class BenchBuilder { + connection: Connection; + programId: PublicKey; + programVersion: number; + + wallet: Keypair; + walletPk: PublicKey; + + instructions: TransactionInstruction[] = []; + signers: Keypair[] = []; + + constructor( + connection: Connection, + programId: PublicKey, + programVersion: number, + ) { + this.connection = connection; + this.programId = programId; + this.programVersion = programVersion; + } + + static async withConnection( + requiredProgramVersion?: number | undefined, + connection?: Connection | undefined, + programId?: PublicKey | undefined, + ) { + connection = connection ?? new Connection(rpcEndpoint, 'recent'); + programId = programId ?? rpcProgramId; + + const programVersion = await getGovernanceProgramVersion( + connection, + programId, + ); + + if (requiredProgramVersion && programVersion != requiredProgramVersion) { + throw new Error( + `Program VERSION: ${programVersion} detected while VERSION: ${requiredProgramVersion} is required for the test`, + ); + } + + return new BenchBuilder(connection, programId, programVersion); + } + + async withWallet() { + this.wallet = Keypair.generate(); + this.walletPk = this.wallet.publicKey; + + await requestAirdrop(this.connection, this.walletPk); + await new Promise(f => setTimeout(f, 1000)); + + return this; + } + + async sendTx() { + await sendTransaction( + this.connection, + this.instructions, + this.signers, + this.wallet, + ); + this.instructions = []; + this.signers = []; + + return this; + } + + async withRealm( + communityTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + councilTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + ) { + return new RealmBuilder(this).withRealm( + communityTokenConfig, + councilTokenConfig, + ); + } +} + +export class RealmBuilder { + bench: BenchBuilder; + + realmPk: PublicKey; + realmAuthorityPk: PublicKey; + communityMintPk: PublicKey; + councilMintPk: PublicKey; + + communityOwnerRecordPk: PublicKey; + governancePk: PublicKey; + proposalPk: PublicKey; + voteRecordPk: PublicKey; + + constructor(bench: BenchBuilder) { + this.bench = bench; + } + + async withRealm( + communityTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + councilTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + ) { + const name = `Realm-${new Keypair().publicKey.toBase58().slice(0, 6)}`; + this.realmAuthorityPk = this.bench.walletPk; + + // Create community token + this.communityMintPk = await withCreateMint( + this.bench.connection, + this.bench.instructions, + this.bench.signers, + this.bench.walletPk, + this.bench.walletPk, + 0, + this.bench.walletPk, + ); + + // Create council + this.councilMintPk = await withCreateMint( + this.bench.connection, + this.bench.instructions, + this.bench.signers, + this.bench.walletPk, + this.bench.walletPk, + 0, + this.bench.walletPk, + ); + + const communityMintMaxVoteWeightSource = + MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION; + + this.realmPk = await withCreateRealm( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + name, + this.realmAuthorityPk, + this.communityMintPk, + this.bench.walletPk, + this.councilMintPk, + communityMintMaxVoteWeightSource, + new BN(1), + communityTokenConfig, + councilTokenConfig, + ); + + return this; + } + + async getRealm() { + return getRealm(this.bench.connection, this.realmPk); + } + + async setRealmConfig( + communityTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + councilTokenConfig?: GoverningTokenConfigAccountArgs | undefined, + ) { + const communityMintMaxVoteWeightSource = + MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION; + + communityTokenConfig = + communityTokenConfig ?? + new GoverningTokenConfigAccountArgs({ + voterWeightAddin: Keypair.generate().publicKey, + maxVoterWeightAddin: Keypair.generate().publicKey, + tokenType: GoverningTokenType.Liquid, + }); + + await withSetRealmConfig( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.realmPk, + this.bench.walletPk, + this.councilMintPk, + communityMintMaxVoteWeightSource, + new BN(1), + communityTokenConfig, + councilTokenConfig, + this.bench.walletPk, + ); + + await this.sendTx(); + } + + async getRealmConfig() { + const realmConfigPk = await getRealmConfigAddress( + this.bench.programId, + this.realmPk, + ); + return getRealmConfig(this.bench.connection, realmConfigPk); + } + + async withCommunityMember() { + let ataPk = await withCreateAssociatedTokenAccount( + this.bench.instructions, + this.communityMintPk, + this.bench.walletPk, + this.bench.walletPk, + ); + await withMintTo( + this.bench.instructions, + this.communityMintPk, + ataPk, + this.bench.walletPk, + 1, + ); + + this.communityOwnerRecordPk = await withDepositGoverningTokens( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.realmPk, + ataPk, + this.communityMintPk, + this.bench.walletPk, + this.bench.walletPk, + this.bench.walletPk, + new BN(1), + ); + + return this; + } + + async withdrawGoverningTokens() { + const ataPk = await Token.getAssociatedTokenAddress( + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + this.communityMintPk, + this.bench.walletPk, + ); + + await withWithdrawGoverningTokens( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.realmPk, + ataPk, + this.communityMintPk, + this.bench.walletPk, + ); + + await this.sendTx(); + } + + async revokeGoverningTokens() { + await withRevokeGoverningTokens( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + + this.realmPk, + this.bench.walletPk, + this.communityMintPk, + this.bench.walletPk, + new BN(1), + ); + + await this.sendTx(); + } + + async getTokenOwnerRecord(tokenOwnerRecordPk: PublicKey) { + return getTokenOwnerRecord(this.bench.connection, tokenOwnerRecordPk); + } + + async withGovernance(config?: GovernanceConfig | undefined) { + await this._createGovernance(config); + return this; + } + + async createGovernance(config?: GovernanceConfig | undefined) { + const governancePk = await this._createGovernance(config); + await this.sendTx(); + return governancePk; + } + + async _createGovernance(config?: GovernanceConfig | undefined) { + config = + config ?? + new GovernanceConfig({ + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 60, + }), + minCommunityTokensToCreateProposal: new BN(1), + minInstructionHoldUpTime: 0, + maxVotingTime: getTimestampFromDays(3), + voteTipping: VoteTipping.Strict, + minCouncilTokensToCreateProposal: new BN(1), + councilVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + // For VERSION < 3 we have to pass 0 + value: this.bench.programVersion >= 3 ? 10 : 0, + }), + councilVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + // For VERSION < 3 we have to pass 0 + value: this.bench.programVersion >= 3 ? 10 : 0, + }), + }); + + const governedAccountPk = Keypair.generate().publicKey; + + this.governancePk = await withCreateGovernance( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.realmPk, + governedAccountPk, + config, + this.communityOwnerRecordPk, + this.bench.walletPk, + this.bench.walletPk, + undefined, + ); + + return this.governancePk; + } + + async getGovernance(governancePk: PublicKey) { + return getGovernance(this.bench.connection, governancePk); + } + + async withProposal(name?: string) { + await this._createProposal(name); + return this; + } + + async createProposal(name?: string) { + const proposalPk = await this._createProposal(name); + await this.sendTx(); + return proposalPk; + } + + async _createProposal(name?: string) { + // Create single choice Approve/Deny proposal with instruction to mint more governance tokens + const voteType = VoteType.SINGLE_CHOICE; + const options = ['Approve']; + const useDenyOption = true; + + this.proposalPk = await withCreateProposal( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.realmPk, + this.governancePk, + this.communityOwnerRecordPk, + name ?? 'proposal 1', + '', + this.communityMintPk, + this.bench.walletPk, + 0, + voteType, + options, + useDenyOption, + this.bench.walletPk, + ); + + return this.proposalPk; + } + + async getProposal(proposalPk: PublicKey) { + return getProposal(this.bench.connection, proposalPk); + } + + async withProposalSignOff() { + withSignOffProposal( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.realmPk, + this.governancePk, + this.proposalPk, + this.bench.walletPk, + undefined, + this.communityOwnerRecordPk, + ); + + return this; + } + + async withCastVote() { + await this._castVote(); + return this; + } + + async castVote() { + const voteRecordPk = await this._castVote(); + await this.sendTx(); + return voteRecordPk; + } + + async _castVote() { + const vote = Vote.fromYesNoVote(YesNoVote.Yes); + + this.voteRecordPk = await withCastVote( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.realmPk, + this.governancePk, + this.proposalPk, + this.communityOwnerRecordPk, + this.communityOwnerRecordPk, + this.bench.walletPk, + this.communityMintPk, + vote, + this.bench.walletPk, + ); + + return this.voteRecordPk; + } + + async getVoteRecord(proposalPk: PublicKey) { + return getVoteRecord(this.bench.connection, proposalPk); + } + + async relinquishVote() { + withRelinquishVote( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.realmPk, + this.governancePk, + this.proposalPk, + this.communityOwnerRecordPk, + this.communityMintPk, + this.voteRecordPk, + this.bench.walletPk, + this.bench.walletPk, + ); + + await this.sendTx(); + } + + async sendTx() { + await this.bench.sendTx(); + return this; + } +} diff --git a/packages/governance-sdk/tests/tools/setup.ts b/packages/governance-sdk/tests/tools/setup.ts index 4ca0d02a..30e06ad0 100644 --- a/packages/governance-sdk/tests/tools/setup.ts +++ b/packages/governance-sdk/tests/tools/setup.ts @@ -1,9 +1,11 @@ +import { PublicKey } from '@solana/web3.js'; +export const programId = new PublicKey( + 'GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw', +); -import { PublicKey } from "@solana/web3.js"; +export const rpcProgramId = programId; +export const rpcEndpoint = 'http://127.0.0.1:8899'; -// const programId = new PublicKey('GTesTBiEWE32WHXXE2S4XbZvA5CrEc4xs6ZgRe895dP'); -// const rpcEndpoint = clusterApiUrl('devnet'); - -export const programId = new PublicKey('GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw'); -export const rpcEndpoint = 'http://127.0.0.1:8899'; \ No newline at end of file +// Run local validator given the path to spl_governance.so +// solana-test-validator --bpf-program GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw target/deploy/spl_governance.so --reset --clone ENmcpFCpxN1CqyUjuog9yyUVfdXBKF3LVCwLr7grJZpk -u devnet diff --git a/packages/governance/src/actions/registerRealm.ts b/packages/governance/src/actions/registerRealm.ts index f6430913..342f876e 100644 --- a/packages/governance/src/actions/registerRealm.ts +++ b/packages/governance/src/actions/registerRealm.ts @@ -1,6 +1,10 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import BN from 'bn.js'; -import { MintMaxVoteWeightSource } from '@solana/spl-governance'; +import { + GoverningTokenConfigAccountArgs, + GoverningTokenType, + MintMaxVoteWeightSource, +} from '@solana/spl-governance'; import { RpcContext } from '@solana/spl-governance'; import { withCreateRealm } from '@solana/spl-governance'; @@ -17,6 +21,14 @@ export async function registerRealm( ) { let instructions: TransactionInstruction[] = []; + const communityTokenConfig = communityVoterWeightAddin + ? new GoverningTokenConfigAccountArgs({ + voterWeightAddin: communityVoterWeightAddin, + maxVoterWeightAddin: undefined, + tokenType: GoverningTokenType.Liquid, + }) + : undefined; + const realmAddress = await withCreateRealm( instructions, programId, @@ -28,7 +40,7 @@ export async function registerRealm( councilMint, communityMintMaxVoteWeightSource, minCommunityTokensToCreateGovernance, - communityVoterWeightAddin, + communityTokenConfig, ); await sendTransactionWithNotifications( diff --git a/packages/governance/src/actions/relinquishVote.ts b/packages/governance/src/actions/relinquishVote.ts index 1f380b6c..4e28111e 100644 --- a/packages/governance/src/actions/relinquishVote.ts +++ b/packages/governance/src/actions/relinquishVote.ts @@ -7,7 +7,8 @@ import { RpcContext } from '@solana/spl-governance'; import { ProgramAccount } from '@solana/spl-governance'; export const relinquishVote = async ( - { connection, wallet, programId, walletPubkey }: RpcContext, + { connection, wallet, programId, programVersion, walletPubkey }: RpcContext, + realm: PublicKey, proposal: ProgramAccount, tokenOwnerRecord: PublicKey, voteRecord: PublicKey, @@ -22,6 +23,8 @@ export const relinquishVote = async ( withRelinquishVote( instructions, programId, + programVersion, + realm, proposal.account.governance, proposal.pubkey, tokenOwnerRecord, diff --git a/packages/governance/src/actions/withdrawGoverningTokens.ts b/packages/governance/src/actions/withdrawGoverningTokens.ts index 59b06430..5b88bbc1 100644 --- a/packages/governance/src/actions/withdrawGoverningTokens.ts +++ b/packages/governance/src/actions/withdrawGoverningTokens.ts @@ -5,7 +5,7 @@ import { RpcContext } from '@solana/spl-governance'; import { sendTransactionWithNotifications } from '../tools/transactions'; export const withdrawGoverningTokens = async ( - { connection, wallet, programId, walletPubkey }: RpcContext, + { connection, wallet, programId, programVersion, walletPubkey }: RpcContext, realm: PublicKey, governingTokenDestination: PublicKey, governingTokenMint: PublicKey, @@ -15,6 +15,7 @@ export const withdrawGoverningTokens = async ( await withWithdrawGoverningTokens( instructions, programId, + programVersion, realm, governingTokenDestination, governingTokenMint, diff --git a/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx b/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx index 381b56c9..0306ca54 100644 --- a/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx +++ b/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx @@ -53,7 +53,7 @@ export function getGovernanceConfig(programVersion: number, values: GovernanceCo const councilVoteThreshold = programVersion >= PROGRAM_VERSION_V3 - // For VERSION >-3 use the same threshold as for community (until supported in the UI) + // For VERSION >=3 use the same threshold as for community (until supported in the UI) ? communityVoteThreshold // For older versions set to 0 : new VoteThreshold({ @@ -61,6 +61,14 @@ export function getGovernanceConfig(programVersion: number, values: GovernanceCo value: 0, }); + // + const councilVetoVoteThreshold = programVersion >= PROGRAM_VERSION_V3 + ? councilVoteThreshold + : new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 0, + }); + return new GovernanceConfig({ communityVoteThreshold: communityVoteThreshold, minCommunityTokensToCreateProposal: new BN( @@ -76,6 +84,7 @@ export function getGovernanceConfig(programVersion: number, values: GovernanceCo minCouncilTokensToCreateProposal: new BN(1), voteTipping: values.voteTipping, councilVoteThreshold:councilVoteThreshold, + councilVetoVoteThreshold:councilVetoVoteThreshold, }); } @@ -142,6 +151,10 @@ export function GovernanceConfigFormItem({ type: VoteThresholdType.YesVotePercentage, value: 60, }), + councilVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 60, + }), }); } else { minTokensToCreateProposal = getMintDecimalAmountFromNatural( diff --git a/packages/governance/src/views/governance/buttons/newProposalButton.tsx b/packages/governance/src/views/governance/buttons/newProposalButton.tsx index 1a17077d..22064ac4 100644 --- a/packages/governance/src/views/governance/buttons/newProposalButton.tsx +++ b/packages/governance/src/views/governance/buttons/newProposalButton.tsx @@ -8,7 +8,7 @@ import { useMint } from '@oyster/common'; import { createProposal } from '../../../actions/createProposal'; import { Redirect } from 'react-router'; -import { GoverningTokenType } from '@solana/spl-governance'; +import { GovernananceTokenKind } from '@solana/spl-governance'; import { Governance, Realm } from '@solana/spl-governance'; import { useWalletTokenOwnerRecord } from '../../../hooks/apiHooks'; @@ -63,8 +63,8 @@ export function NewProposalButton({ canCreateProposalUsingCouncilTokens; const defaultGoverningTokenType = !communityMint.supply.isZero() - ? GoverningTokenType.Community - : GoverningTokenType.Council; + ? GovernananceTokenKind.Community + : GovernananceTokenKind.Council; const showTokenChoice = !communityMint.supply.isZero() && realm?.account.config.councilMint; @@ -72,13 +72,13 @@ export function NewProposalButton({ const onSubmit = async (values: { name: string; descriptionLink: string; - governingTokenType: GoverningTokenType; + governingTokenType: GovernananceTokenKind; }) => { const governingTokenType = values.governingTokenType ?? defaultGoverningTokenType; const governingTokenMint = - governingTokenType === GoverningTokenType.Community + governingTokenType === GovernananceTokenKind.Community ? realm!.account.communityMint : realm!.account.config.councilMint!; const proposalIndex = governance.account.proposalCount; @@ -135,12 +135,12 @@ export function NewProposalButton({ rules={[{ required: true }]} > - + {LABELS.COMMUNITY_TOKEN_HOLDERS} {realm.account.config.councilMint && ( - + {LABELS.COUNCIL} )} diff --git a/packages/governance/src/views/proposal/components/buttons/relinquishVoteButton.tsx b/packages/governance/src/views/proposal/components/buttons/relinquishVoteButton.tsx index ced7d031..a2f50ce6 100644 --- a/packages/governance/src/views/proposal/components/buttons/relinquishVoteButton.tsx +++ b/packages/governance/src/views/proposal/components/buttons/relinquishVoteButton.tsx @@ -54,6 +54,7 @@ export function RelinquishVoteButton({ try { await relinquishVote( rpcContext, + tokenOwnerRecord.account.realm, proposal, tokenOwnerRecord.pubkey, voteRecord!.pubkey, @@ -82,6 +83,7 @@ export function RelinquishVoteButton({ try { await relinquishVote( rpcContext, + tokenOwnerRecord.account.realm, proposal, tokenOwnerRecord.pubkey, voteRecord!.pubkey, diff --git a/packages/governance/src/views/proposal/components/instructionInput/realmConfigForm.tsx b/packages/governance/src/views/proposal/components/instructionInput/realmConfigForm.tsx index 0a1e4869..aaea38d7 100644 --- a/packages/governance/src/views/proposal/components/instructionInput/realmConfigForm.tsx +++ b/packages/governance/src/views/proposal/components/instructionInput/realmConfigForm.tsx @@ -1,6 +1,6 @@ import { Form, FormInstance, Input, InputNumber } from 'antd'; import { ExplorerLink, useMint, useWallet } from '@oyster/common'; -import { Governance, PROGRAM_VERSION_V1, Realm } from '@solana/spl-governance'; +import { Governance, GoverningTokenConfigAccountArgs, GoverningTokenType, PROGRAM_VERSION_V1, Realm } from '@solana/spl-governance'; import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import React from 'react'; @@ -78,9 +78,13 @@ export const RealmConfigForm = ({ values.communityMintDecimals, ); - const communityVoterWeightAddin = values.communityVoterWeightAddin - ? new PublicKey(values.communityVoterWeightAddin) - : undefined; + const communityTokenConfig = values.communityVoterWeightAddin + ? new GoverningTokenConfigAccountArgs({ + voterWeightAddin: new PublicKey(values.communityVoterWeightAddin), + maxVoterWeightAddin: undefined, + tokenType: GoverningTokenType.Liquid + }) + : undefined; const setRealmConfigIx = await createSetRealmConfig( programId, @@ -93,7 +97,7 @@ export const RealmConfigForm = ({ parseMintSupplyFraction(values.communityMintMaxVoteWeightFraction), // Use minCommunityTokensToCreateGovernance.toString() in case the number is larger than number new BN(minCommunityTokensToCreateGovernance.toString()), - communityVoterWeightAddin, + communityTokenConfig, undefined, // TODO: Once current wallet placeholder is supported to execute instruction using the wallet which executes the instruction replace it with the placeholder wallet.publicKey!, From de304ddfe2ba1f28a637f458b1971934f7efb1eb Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Thu, 18 Aug 2022 21:01:43 +0200 Subject: [PATCH 44/88] chore: Fix GovernananceTokenKind name (#549) --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/enums.ts | 2 +- packages/governance-sdk/src/governance/index.ts | 1 + packages/governance-sdk/src/governance/tools.ts | 10 +++++----- packages/governance/package.json | 2 +- .../views/governance/buttons/newProposalButton.tsx | 14 +++++++------- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 13e13f65..a491805a 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.0", + "version": "0.3.1", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/enums.ts b/packages/governance-sdk/src/governance/enums.ts index 627b1fa5..259a6cc3 100644 --- a/packages/governance-sdk/src/governance/enums.ts +++ b/packages/governance-sdk/src/governance/enums.ts @@ -1,4 +1,4 @@ -export enum GovernananceTokenKind { +export enum GovernanceTokenKind { Community, Council, } diff --git a/packages/governance-sdk/src/governance/index.ts b/packages/governance-sdk/src/governance/index.ts index efdba425..beeb7599 100644 --- a/packages/governance-sdk/src/governance/index.ts +++ b/packages/governance-sdk/src/governance/index.ts @@ -29,6 +29,7 @@ export * from './withRelinquishVote'; export * from './withRemoveTransaction'; export * from './withRevokeGoverningTokens'; export * from './withSetRealmAuthority'; +export * from './withSetRealmConfig'; export * from './withSetGovernanceDelegate'; export * from './withSignOffProposal'; export * from './withUpdateProgramMetadata'; diff --git a/packages/governance-sdk/src/governance/tools.ts b/packages/governance-sdk/src/governance/tools.ts index 2b20cd6e..687d427a 100644 --- a/packages/governance-sdk/src/governance/tools.ts +++ b/packages/governance-sdk/src/governance/tools.ts @@ -9,12 +9,12 @@ import { MintMaxVoteWeightSource, RealmConfigArgs, } from './accounts'; -import { GovernananceTokenKind } from './enums'; +import { GovernanceTokenKind } from './enums'; function assertValidTokenConfigArgs( programVersion: number, tokenConfigArgs: GoverningTokenConfigAccountArgs | undefined, - tokenKind: GovernananceTokenKind, + tokenKind: GovernanceTokenKind, ) { if (tokenConfigArgs) { if (programVersion < PROGRAM_VERSION_V2) { @@ -22,7 +22,7 @@ function assertValidTokenConfigArgs( `Governing token config is not supported in version ${programVersion}`, ); } else if (programVersion == PROGRAM_VERSION_V2) { - if (tokenKind == GovernananceTokenKind.Council) { + if (tokenKind == GovernanceTokenKind.Council) { throw new Error( `Council token config is not supported in version ${programVersion}`, ); @@ -48,12 +48,12 @@ export function createRealmConfigArgs( assertValidTokenConfigArgs( programVersion, communityTokenConfig, - GovernananceTokenKind.Community, + GovernanceTokenKind.Community, ); assertValidTokenConfigArgs( programVersion, councilTokenConfig, - GovernananceTokenKind.Council, + GovernanceTokenKind.Council, ); return new RealmConfigArgs({ diff --git a/packages/governance/package.json b/packages/governance/package.json index 7dab76d0..5c68ec45 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.0", + "@solana/spl-governance": "0.3.1", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", diff --git a/packages/governance/src/views/governance/buttons/newProposalButton.tsx b/packages/governance/src/views/governance/buttons/newProposalButton.tsx index 22064ac4..9501d445 100644 --- a/packages/governance/src/views/governance/buttons/newProposalButton.tsx +++ b/packages/governance/src/views/governance/buttons/newProposalButton.tsx @@ -8,7 +8,7 @@ import { useMint } from '@oyster/common'; import { createProposal } from '../../../actions/createProposal'; import { Redirect } from 'react-router'; -import { GovernananceTokenKind } from '@solana/spl-governance'; +import { GovernanceTokenKind } from '@solana/spl-governance'; import { Governance, Realm } from '@solana/spl-governance'; import { useWalletTokenOwnerRecord } from '../../../hooks/apiHooks'; @@ -63,8 +63,8 @@ export function NewProposalButton({ canCreateProposalUsingCouncilTokens; const defaultGoverningTokenType = !communityMint.supply.isZero() - ? GovernananceTokenKind.Community - : GovernananceTokenKind.Council; + ? GovernanceTokenKind.Community + : GovernanceTokenKind.Council; const showTokenChoice = !communityMint.supply.isZero() && realm?.account.config.councilMint; @@ -72,13 +72,13 @@ export function NewProposalButton({ const onSubmit = async (values: { name: string; descriptionLink: string; - governingTokenType: GovernananceTokenKind; + governingTokenType: GovernanceTokenKind; }) => { const governingTokenType = values.governingTokenType ?? defaultGoverningTokenType; const governingTokenMint = - governingTokenType === GovernananceTokenKind.Community + governingTokenType === GovernanceTokenKind.Community ? realm!.account.communityMint : realm!.account.config.councilMint!; const proposalIndex = governance.account.proposalCount; @@ -135,12 +135,12 @@ export function NewProposalButton({ rules={[{ required: true }]} > - + {LABELS.COMMUNITY_TOKEN_HOLDERS} {realm.account.config.councilMint && ( - + {LABELS.COUNCIL} )} From daac6c587c090826b7b4629e8ebda1a012b3973e Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Fri, 19 Aug 2022 15:55:36 +0200 Subject: [PATCH 45/88] Governance: Rename GovernanceTokenKind (#550) --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/enums.ts | 2 +- packages/governance-sdk/src/governance/tools.ts | 10 +++++----- packages/governance/package.json | 2 +- .../views/governance/buttons/newProposalButton.tsx | 14 +++++++------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index a491805a..1d20263b 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.1", + "version": "0.3.2", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/enums.ts b/packages/governance-sdk/src/governance/enums.ts index 259a6cc3..9f490f1d 100644 --- a/packages/governance-sdk/src/governance/enums.ts +++ b/packages/governance-sdk/src/governance/enums.ts @@ -1,4 +1,4 @@ -export enum GovernanceTokenKind { +export enum GoverningTokenRole { Community, Council, } diff --git a/packages/governance-sdk/src/governance/tools.ts b/packages/governance-sdk/src/governance/tools.ts index 687d427a..7c187e3c 100644 --- a/packages/governance-sdk/src/governance/tools.ts +++ b/packages/governance-sdk/src/governance/tools.ts @@ -9,12 +9,12 @@ import { MintMaxVoteWeightSource, RealmConfigArgs, } from './accounts'; -import { GovernanceTokenKind } from './enums'; +import { GoverningTokenRole } from './enums'; function assertValidTokenConfigArgs( programVersion: number, tokenConfigArgs: GoverningTokenConfigAccountArgs | undefined, - tokenKind: GovernanceTokenKind, + tokenKind: GoverningTokenRole, ) { if (tokenConfigArgs) { if (programVersion < PROGRAM_VERSION_V2) { @@ -22,7 +22,7 @@ function assertValidTokenConfigArgs( `Governing token config is not supported in version ${programVersion}`, ); } else if (programVersion == PROGRAM_VERSION_V2) { - if (tokenKind == GovernanceTokenKind.Council) { + if (tokenKind == GoverningTokenRole.Council) { throw new Error( `Council token config is not supported in version ${programVersion}`, ); @@ -48,12 +48,12 @@ export function createRealmConfigArgs( assertValidTokenConfigArgs( programVersion, communityTokenConfig, - GovernanceTokenKind.Community, + GoverningTokenRole.Community, ); assertValidTokenConfigArgs( programVersion, councilTokenConfig, - GovernanceTokenKind.Council, + GoverningTokenRole.Council, ); return new RealmConfigArgs({ diff --git a/packages/governance/package.json b/packages/governance/package.json index 5c68ec45..d91ceb92 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.1", + "@solana/spl-governance": "0.3.2", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", diff --git a/packages/governance/src/views/governance/buttons/newProposalButton.tsx b/packages/governance/src/views/governance/buttons/newProposalButton.tsx index 9501d445..800ec3b5 100644 --- a/packages/governance/src/views/governance/buttons/newProposalButton.tsx +++ b/packages/governance/src/views/governance/buttons/newProposalButton.tsx @@ -8,7 +8,7 @@ import { useMint } from '@oyster/common'; import { createProposal } from '../../../actions/createProposal'; import { Redirect } from 'react-router'; -import { GovernanceTokenKind } from '@solana/spl-governance'; +import { GoverningTokenRole } from '@solana/spl-governance'; import { Governance, Realm } from '@solana/spl-governance'; import { useWalletTokenOwnerRecord } from '../../../hooks/apiHooks'; @@ -63,8 +63,8 @@ export function NewProposalButton({ canCreateProposalUsingCouncilTokens; const defaultGoverningTokenType = !communityMint.supply.isZero() - ? GovernanceTokenKind.Community - : GovernanceTokenKind.Council; + ? GoverningTokenRole.Community + : GoverningTokenRole.Council; const showTokenChoice = !communityMint.supply.isZero() && realm?.account.config.councilMint; @@ -72,13 +72,13 @@ export function NewProposalButton({ const onSubmit = async (values: { name: string; descriptionLink: string; - governingTokenType: GovernanceTokenKind; + governingTokenType: GoverningTokenRole; }) => { const governingTokenType = values.governingTokenType ?? defaultGoverningTokenType; const governingTokenMint = - governingTokenType === GovernanceTokenKind.Community + governingTokenType === GoverningTokenRole.Community ? realm!.account.communityMint : realm!.account.config.councilMint!; const proposalIndex = governance.account.proposalCount; @@ -135,12 +135,12 @@ export function NewProposalButton({ rules={[{ required: true }]} > - + {LABELS.COMMUNITY_TOKEN_HOLDERS} {realm.account.config.councilMint && ( - + {LABELS.COUNCIL} )} From b4d4903143a7695c5cde753847272e0fa6273ffb Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Sat, 20 Aug 2022 00:24:33 +0200 Subject: [PATCH 46/88] fix: Rollback default version to V1 (#551) --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/version.ts | 4 ++-- packages/governance/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 1d20263b..cd064c91 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.2", + "version": "0.3.3", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/version.ts b/packages/governance-sdk/src/governance/version.ts index 4783070a..1fdeb022 100644 --- a/packages/governance-sdk/src/governance/version.ts +++ b/packages/governance-sdk/src/governance/version.ts @@ -109,6 +109,6 @@ export async function getGovernanceProgramVersion( return PROGRAM_VERSION; } - // Default to V2 which is the most common version being used - return PROGRAM_VERSION_V2; + // Default to V1 which doesn't support ProgramMetadata + return PROGRAM_VERSION_V1; } diff --git a/packages/governance/package.json b/packages/governance/package.json index d91ceb92..673abf5f 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.2", + "@solana/spl-governance": "0.3.3", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From 854f49cf76da72f9fd73faa7b84435c3d06841be Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Sat, 20 Aug 2022 00:41:16 +0200 Subject: [PATCH 47/88] fix: Make vetoVoteWeight conditional to version >= V2 --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/serialisation.ts | 7 ++++++- packages/governance/package.json | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index cd064c91..42a43464 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.3", + "version": "0.3.4", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 1dbee948..495cb0e2 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -768,7 +768,12 @@ function createGovernanceSchema(programVersion: number) { ['name', 'string'], ['descriptionLink', 'string'], - ['vetoVoteWeight', 'u64'], + + ...(programVersion === PROGRAM_VERSION_V1 + ? [] + : [['vetoVoteWeight', 'u64']]), + + , ], }, ], diff --git a/packages/governance/package.json b/packages/governance/package.json index 673abf5f..5d555556 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.3", + "@solana/spl-governance": "0.3.4", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From 865df9ac0eb71466311654d03258153103456943 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Sat, 20 Aug 2022 00:51:51 +0200 Subject: [PATCH 48/88] Governance: Fix Proposal serialisation --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/serialisation.ts | 2 -- packages/governance/package.json | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 42a43464..05f934dd 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.4", + "version": "0.3.5", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 495cb0e2..0ee136de 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -772,8 +772,6 @@ function createGovernanceSchema(programVersion: number) { ...(programVersion === PROGRAM_VERSION_V1 ? [] : [['vetoVoteWeight', 'u64']]), - - , ], }, ], diff --git a/packages/governance/package.json b/packages/governance/package.json index 5d555556..4bdf1696 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.4", + "@solana/spl-governance": "0.3.5", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From 2e5fc9efb5d5b89e847e4dd1188e8c6a03d77217 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Sat, 20 Aug 2022 01:05:46 +0200 Subject: [PATCH 49/88] Governance: Publish npm 0.3.6 --- packages/governance-sdk/package.json | 2 +- packages/governance/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 05f934dd..ba821db4 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.5", + "version": "0.3.6", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance/package.json b/packages/governance/package.json index 4bdf1696..b04ca371 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.5", + "@solana/spl-governance": "0.3.6", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From c239366c8b758f80d87b6112873de794baaded05 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Sat, 20 Aug 2022 12:35:56 +0200 Subject: [PATCH 50/88] chore: Add vote example --- .../tests/governance/api.test.ts | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/governance-sdk/tests/governance/api.test.ts b/packages/governance-sdk/tests/governance/api.test.ts index 447ca2f9..7656913e 100644 --- a/packages/governance-sdk/tests/governance/api.test.ts +++ b/packages/governance-sdk/tests/governance/api.test.ts @@ -17,16 +17,20 @@ import { GovernanceConfig, MintMaxVoteWeightSource, SetRealmAuthorityAction, + Vote, VoteThreshold, VoteThresholdType, VoteTipping, VoteType, + withCastVote, withCreateMintGovernance, withCreateProposal, withCreateRealm, withDepositGoverningTokens, withInsertTransaction, withSetRealmAuthority, + withSignOffProposal, + YesNoVote, } from '../../src'; import { requestAirdrop, sendTransaction } from '../tools/sdk'; import { programId, rpcEndpoint } from '../tools/setup'; @@ -215,9 +219,45 @@ test('createRealmWithGovernanceAndProposal', async () => { walletPk, ); - // Act + withSignOffProposal( + instructions, + programId, + programVersion, + realmPk, + governancePk, + proposalPk, + walletPk, + undefined, + tokenOwnerRecordPk, + ); + + await sendTransaction(connection, instructions, signers, wallet); + + // Cast Vote + instructions = []; + signers = []; + + const vote = Vote.fromYesNoVote(YesNoVote.Yes); + + const votePk = await withCastVote( + instructions, + programId, + programVersion, + realmPk, + governancePk, + proposalPk, + tokenOwnerRecordPk, // Proposal owner TokenOwnerRecord + tokenOwnerRecordPk, // Voter TokenOwnerRecord + walletPk, // Voter wallet or delegate + mintPk, + vote, + walletPk, + ); + await sendTransaction(connection, instructions, signers, wallet); + // Act + // Assert const realm = await getRealm(connection, realmPk); expect(realm.account.name).toBe(name); From 7ca73d60c93bdb87a04bc6f4661c036922841555 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 22 Aug 2022 17:31:19 +0200 Subject: [PATCH 51/88] Governance: Do not throw errors in tryGetRealmConfig --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/api.ts | 12 ++++++++++-- packages/governance/package.json | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index ba821db4..e27d0f3a 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.6", + "version": "0.3.8", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index d6ba4f26..e15ae0b1 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -42,8 +42,16 @@ export async function tryGetRealmConfig( programId: PublicKey, realmPk: PublicKey, ) { - const realmConfigPk = await getRealmConfigAddress(programId, realmPk); - return getGovernanceAccount(connection, realmConfigPk, RealmConfigAccount); + try { + const realmConfigPk = await getRealmConfigAddress(programId, realmPk); + return await getGovernanceAccount( + connection, + realmConfigPk, + RealmConfigAccount, + ); + } catch { + // RealmConfigAccount didn't exist in V1 and was optional in V2 and hence it doesn't have to exist + } } export async function getRealmConfig( diff --git a/packages/governance/package.json b/packages/governance/package.json index b04ca371..e9125479 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.6", + "@solana/spl-governance": "0.3.8", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From 4177a79a6cdcfb83b82f6b3a21c1dc9a7c8f0750 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Tue, 23 Aug 2022 13:12:24 +0200 Subject: [PATCH 52/88] feat: Update sdk to latest spl-gov V3 0.3.9 (#552) --- packages/governance-sdk/package.json | 2 +- .../governance-sdk/src/governance/accounts.ts | 24 +++++++++++++---- .../src/governance/serialisation.ts | 12 +++++++-- .../governance/withRevokeGoverningTokens.ts | 27 +++++-------------- .../tests/governance/api.v2.v3.test.ts | 17 ++++++++++++ .../tests/governance/api.v3.test.ts | 7 ++++- .../governance-sdk/tests/tools/builders.ts | 9 +++++-- packages/governance/package.json | 2 +- 8 files changed, 68 insertions(+), 32 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index e27d0f3a..fc65384b 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.8", + "version": "0.3.9", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index c20e7841..c1293223 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -432,12 +432,15 @@ export class GovernanceConfig { minCommunityTokensToCreateProposal: BN; minInstructionHoldUpTime: number; maxVotingTime: number; - voteTipping: VoteTipping; + communityVoteTipping: VoteTipping; minCouncilTokensToCreateProposal: BN; // VERSION >= 3 councilVoteThreshold: VoteThreshold; councilVetoVoteThreshold: VoteThreshold; + communityVetoVoteThreshold: VoteThreshold; + councilVoteTipping: VoteTipping; + reserved = [0, 0]; constructor(args: { @@ -445,26 +448,37 @@ export class GovernanceConfig { minCommunityTokensToCreateProposal: BN; minInstructionHoldUpTime: number; maxVotingTime: number; - voteTipping?: VoteTipping; + communityVoteTipping?: VoteTipping; minCouncilTokensToCreateProposal: BN; // VERSION >= 3 // For versions < 3 must be set to YesVotePercentage(0) councilVoteThreshold: VoteThreshold; councilVetoVoteThreshold: VoteThreshold; + communityVetoVoteThreshold: VoteThreshold; + councilVoteTipping: VoteTipping; }) { this.communityVoteThreshold = args.communityVoteThreshold; this.minCommunityTokensToCreateProposal = args.minCommunityTokensToCreateProposal; this.minInstructionHoldUpTime = args.minInstructionHoldUpTime; this.maxVotingTime = args.maxVotingTime; - this.voteTipping = args.voteTipping ?? VoteTipping.Strict; + this.communityVoteTipping = args.communityVoteTipping ?? VoteTipping.Strict; this.minCouncilTokensToCreateProposal = args.minCouncilTokensToCreateProposal; // VERSION >= 3 - this.councilVoteThreshold = args.councilVoteThreshold; - this.councilVetoVoteThreshold = args.councilVetoVoteThreshold; + this.councilVoteThreshold = + args.councilVoteThreshold ?? args.communityVoteThreshold; + this.councilVetoVoteThreshold = + args.councilVetoVoteThreshold ?? args.communityVoteThreshold; + + this.communityVetoVoteThreshold = + args.communityVetoVoteThreshold ?? + new VoteThreshold({ type: VoteThresholdType.Disabled }); + + this.councilVoteTipping = + args.councilVoteTipping ?? this.communityVoteTipping; } } diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 0ee136de..dfff2269 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -663,7 +663,9 @@ function createGovernanceSchema(programVersion: number) { ['governedAccount', 'pubkey'], ['proposalCount', 'u32'], ['config', GovernanceConfig], - ['reserved', [6]], + ...(programVersion >= PROGRAM_VERSION_V2 + ? [['reserved', [3]]] + : [['reserved', [6]]]), ['votingProposalCount', 'u16'], ], }, @@ -677,10 +679,16 @@ function createGovernanceSchema(programVersion: number) { ['minCommunityTokensToCreateProposal', 'u64'], ['minInstructionHoldUpTime', 'u32'], ['maxVotingTime', 'u32'], - ['voteTipping', 'u8'], + ['communityVoteTipping', 'u8'], ['councilVoteThreshold', 'VoteThreshold'], ['councilVetoVoteThreshold', 'VoteThreshold'], ['minCouncilTokensToCreateProposal', 'u64'], + ...(programVersion >= PROGRAM_VERSION_V2 + ? [ + ['councilVoteTipping', 'u8'], + ['communityVetoVoteThreshold', 'VoteThreshold'], + ] + : []), ], }, ], diff --git a/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts b/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts index 6e526395..64cdc977 100644 --- a/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts @@ -1,8 +1,4 @@ -import { - PublicKey, - SYSVAR_RENT_PUBKEY, - TransactionInstruction, -} from '@solana/web3.js'; +import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import { getGovernanceSchema } from './serialisation'; import { serialize } from 'borsh'; import { RevokeGoverningTokensArgs } from './instructions'; @@ -13,15 +9,14 @@ import { } from './accounts'; import BN from 'bn.js'; import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken'; -import { PROGRAM_VERSION_V1 } from '../registry/constants'; export const withRevokeGoverningTokens = async ( instructions: TransactionInstruction[], programId: PublicKey, programVersion: number, realm: PublicKey, - realmAuthority: PublicKey, governingTokenMint: PublicKey, + governingTokenMintAuthrority: PublicKey, governingTokenOwner: PublicKey, amount: BN, ) => { @@ -51,11 +46,6 @@ export const withRevokeGoverningTokens = async ( isWritable: false, isSigner: false, }, - { - pubkey: realmAuthority, - isWritable: false, - isSigner: true, - }, { pubkey: governingTokenHoldingAddress, isWritable: true, @@ -71,6 +61,11 @@ export const withRevokeGoverningTokens = async ( isWritable: true, isSigner: false, }, + { + pubkey: governingTokenMintAuthrority, + isWritable: false, + isSigner: true, + }, { pubkey: realmConfigAddress, isSigner: false, @@ -83,14 +78,6 @@ export const withRevokeGoverningTokens = async ( }, ]; - if (programVersion === PROGRAM_VERSION_V1) { - keys.push({ - pubkey: SYSVAR_RENT_PUBKEY, - isWritable: false, - isSigner: false, - }); - } - instructions.push( new TransactionInstruction({ keys, diff --git a/packages/governance-sdk/tests/governance/api.v2.v3.test.ts b/packages/governance-sdk/tests/governance/api.v2.v3.test.ts index 6bca0023..604349c7 100644 --- a/packages/governance-sdk/tests/governance/api.v2.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v2.v3.test.ts @@ -67,6 +67,23 @@ test('withdrawGoverningTokens', async () => { ).toEqual(0); }); +test('createGovernance', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.sendTx()); + + // Act + const governancePk = await realm.createGovernance(); + + // // Assert + const governance = await realm.getGovernance(governancePk); + + expect(governance.account.realm).toEqual(realm.realmPk); +}); + test('createProposal', async () => { // Arrange const realm = await BenchBuilder.withConnection() diff --git a/packages/governance-sdk/tests/governance/api.v3.test.ts b/packages/governance-sdk/tests/governance/api.v3.test.ts index 79be2974..9448747b 100644 --- a/packages/governance-sdk/tests/governance/api.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v3.test.ts @@ -78,7 +78,8 @@ test('createGovernanceWithCouncilThresholds', async () => { minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), - voteTipping: VoteTipping.Strict, + communityVoteTipping: VoteTipping.Strict, + councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), councilVoteThreshold: new VoteThreshold({ type: VoteThresholdType.YesVotePercentage, @@ -88,6 +89,10 @@ test('createGovernanceWithCouncilThresholds', async () => { type: VoteThresholdType.YesVotePercentage, value: 80, }), + communityVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 80, + }), }); // Act diff --git a/packages/governance-sdk/tests/tools/builders.ts b/packages/governance-sdk/tests/tools/builders.ts index b8de839d..308600f3 100644 --- a/packages/governance-sdk/tests/tools/builders.ts +++ b/packages/governance-sdk/tests/tools/builders.ts @@ -296,9 +296,9 @@ export class RealmBuilder { this.bench.programVersion, this.realmPk, - this.bench.walletPk, this.communityMintPk, this.bench.walletPk, + this.bench.walletPk, new BN(1), ); @@ -331,7 +331,8 @@ export class RealmBuilder { minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), - voteTipping: VoteTipping.Strict, + communityVoteTipping: VoteTipping.Strict, + councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), councilVoteThreshold: new VoteThreshold({ type: VoteThresholdType.YesVotePercentage, @@ -343,6 +344,10 @@ export class RealmBuilder { // For VERSION < 3 we have to pass 0 value: this.bench.programVersion >= 3 ? 10 : 0, }), + communityVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 80, + }), }); const governedAccountPk = Keypair.generate().publicKey; diff --git a/packages/governance/package.json b/packages/governance/package.json index e9125479..dbca946a 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.8", + "@solana/spl-governance": "0.3.9", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From b7ba289d2ea31be3e8ae36f303cea7a16ed29995 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Tue, 23 Aug 2022 13:17:38 +0200 Subject: [PATCH 53/88] fix: Realms-explorer spl-gov v3 defaults --- .../governanceConfigFormItem.tsx | 67 ++++++++++++------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx b/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx index 0306ca54..27656f3a 100644 --- a/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx +++ b/packages/governance/src/components/governanceConfigFormItem/governanceConfigFormItem.tsx @@ -40,7 +40,10 @@ export interface GovernanceConfigValues { voteTipping: VoteTipping; } -export function getGovernanceConfig(programVersion: number, values: GovernanceConfigValues) { +export function getGovernanceConfig( + programVersion: number, + values: GovernanceConfigValues, +) { const minTokensToCreateProposal = parseMinTokensToCreate( values.minTokensToCreateProposal, values.mintDecimals, @@ -51,23 +54,24 @@ export function getGovernanceConfig(programVersion: number, values: GovernanceCo value: values.voteThresholdPercentage, }); - - const councilVoteThreshold = programVersion >= PROGRAM_VERSION_V3 - // For VERSION >=3 use the same threshold as for community (until supported in the UI) - ? communityVoteThreshold - // For older versions set to 0 - : new VoteThreshold({ - type: VoteThresholdType.YesVotePercentage, - value: 0, - }); + const councilVoteThreshold = + programVersion >= PROGRAM_VERSION_V3 + ? // For VERSION >=3 use the same threshold as for community (until supported in the UI) + communityVoteThreshold + : // For older versions set to 0 + new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 0, + }); - // - const councilVetoVoteThreshold = programVersion >= PROGRAM_VERSION_V3 - ? councilVoteThreshold - : new VoteThreshold({ - type: VoteThresholdType.YesVotePercentage, - value: 0, - }); + // + const councilVetoVoteThreshold = + programVersion >= PROGRAM_VERSION_V3 + ? councilVoteThreshold + : new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 0, + }); return new GovernanceConfig({ communityVoteThreshold: communityVoteThreshold, @@ -82,9 +86,13 @@ export function getGovernanceConfig(programVersion: number, values: GovernanceCo // Council tokens are rare and possession of any amount of council tokens should be sufficient to be allowed to create proposals // If it turns to be a wrong assumption then it should be exposed in the UI minCouncilTokensToCreateProposal: new BN(1), - voteTipping: values.voteTipping, - councilVoteThreshold:councilVoteThreshold, - councilVetoVoteThreshold:councilVetoVoteThreshold, + communityVoteTipping: values.voteTipping, + councilVoteTipping: values.voteTipping, + councilVoteThreshold: councilVoteThreshold, + councilVetoVoteThreshold: councilVetoVoteThreshold, + communityVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.Disabled, + }), }); } @@ -145,7 +153,8 @@ export function GovernanceConfigFormItem({ minCommunityTokensToCreateProposal: ZERO, minInstructionHoldUpTime: getTimestampFromDays(0), maxVotingTime: getTimestampFromDays(3), - voteTipping: VoteTipping.Strict, + communityVoteTipping: VoteTipping.Strict, + councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: ZERO, councilVoteThreshold: new VoteThreshold({ type: VoteThresholdType.YesVotePercentage, @@ -155,6 +164,9 @@ export function GovernanceConfigFormItem({ type: VoteThresholdType.YesVotePercentage, value: 60, }), + communityVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.Disabled, + }), }); } else { minTokensToCreateProposal = getMintDecimalAmountFromNatural( @@ -237,11 +249,16 @@ export function GovernanceConfigFormItem({ name={configNameOf('voteTipping')} label={LABELS.VOTE_TIPPING} rules={[{ required: true }]} - initialValue={VoteTipping[governanceConfig.voteTipping]} + initialValue={VoteTipping[governanceConfig.communityVoteTipping]} > - + {Object.keys(VoteTipping) + .filter(vt => typeof VoteTipping[vt as any] === 'string') + .map(vt => ( + + {VoteTipping[vt as any]}{' '} + + ))} From f2471505abb8c3d349789973117a318e5a1c0001 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Tue, 23 Aug 2022 14:15:33 +0200 Subject: [PATCH 54/88] Governance: Fix V1 Governance account creation (#553) --- packages/governance-sdk/package.json | 2 +- .../governance-sdk/src/governance/version.ts | 8 +- .../src/governance/withCreateGovernance.ts | 7 +- .../governance/withCreateMintGovernance.ts | 7 +- .../governance/withCreateProgramGovernance.ts | 7 +- .../governance/withCreateTokenGovernance.ts | 7 +- .../tests/governance/api.test.ts | 4 +- .../tests/governance/api.v1.test.ts | 75 +++++++++++++++++++ .../tests/governance/api.v2.test.ts | 8 +- .../governance-sdk/tests/tools/builders.ts | 19 ++++- packages/governance/package.json | 2 +- 11 files changed, 129 insertions(+), 17 deletions(-) create mode 100644 packages/governance-sdk/tests/governance/api.v1.test.ts diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index fc65384b..4b64caa8 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.9", + "version": "0.3.10", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/version.ts b/packages/governance-sdk/src/governance/version.ts index 1fdeb022..8e9128fd 100644 --- a/packages/governance-sdk/src/governance/version.ts +++ b/packages/governance-sdk/src/governance/version.ts @@ -96,9 +96,10 @@ export async function getGovernanceProgramVersion( ); })[0]; - console.log('Program version (simulation)', simVersion); - - return simVersion.major; + if (simVersion) { + console.log('Program version (simulation)', simVersion); + return simVersion.major; + } } } catch (ex) { console.log("Can't determine program version", ex); @@ -110,5 +111,6 @@ export async function getGovernanceProgramVersion( } // Default to V1 which doesn't support ProgramMetadata + console.log('Program version (default)', PROGRAM_VERSION_V1); return PROGRAM_VERSION_V1; } diff --git a/packages/governance-sdk/src/governance/withCreateGovernance.ts b/packages/governance-sdk/src/governance/withCreateGovernance.ts index c58054b7..45e8ce6c 100644 --- a/packages/governance-sdk/src/governance/withCreateGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateGovernance.ts @@ -4,7 +4,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceSchema } from './serialisation'; import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateGovernanceArgs } from './instructions'; @@ -25,7 +25,10 @@ export const withCreateGovernance = async ( voterWeightRecord?: PublicKey, ) => { const args = new CreateGovernanceArgs({ config }); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + + const data = Buffer.from( + serialize(getGovernanceSchema(programVersion), args), + ); governedAccount = governedAccount ?? new Keypair().publicKey; diff --git a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts index a403644d..e639199c 100644 --- a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceSchema } from './serialisation'; import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateMintGovernanceArgs } from './instructions'; @@ -30,7 +30,10 @@ export const withCreateMintGovernance = async ( config, transferMintAuthorities: transferMintAuthorities, }); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + + const data = Buffer.from( + serialize(getGovernanceSchema(programVersion), args), + ); const [governanceAddress] = await PublicKey.findProgramAddress( [Buffer.from('mint-governance'), realm.toBuffer(), governedMint.toBuffer()], diff --git a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts index 919de647..ed1549b1 100644 --- a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceSchema } from './serialisation'; import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateProgramGovernanceArgs } from './instructions'; @@ -30,7 +30,10 @@ export const withCreateProgramGovernance = async ( config, transferUpgradeAuthority, }); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + + const data = Buffer.from( + serialize(getGovernanceSchema(programVersion), args), + ); const [governanceAddress] = await PublicKey.findProgramAddress( [ diff --git a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts index 1ab7e3f1..8acc72d9 100644 --- a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceSchema } from './serialisation'; import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateTokenGovernanceArgs } from './instructions'; @@ -30,7 +30,10 @@ export const withCreateTokenGovernance = async ( config, transferTokenOwner: transferAccountAuthorities, }); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + + const data = Buffer.from( + serialize(getGovernanceSchema(programVersion), args), + ); const [governanceAddress] = await PublicKey.findProgramAddress( [ diff --git a/packages/governance-sdk/tests/governance/api.test.ts b/packages/governance-sdk/tests/governance/api.test.ts index 7656913e..f9c4f11e 100644 --- a/packages/governance-sdk/tests/governance/api.test.ts +++ b/packages/governance-sdk/tests/governance/api.test.ts @@ -132,10 +132,12 @@ test('createRealmWithGovernanceAndProposal', async () => { minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), - voteTipping: VoteTipping.Strict, + communityVoteTipping: VoteTipping.Strict, + councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), councilVoteThreshold: councilVoteThreshold, councilVetoVoteThreshold: councilVetoVoteThreshold, + communityVetoVoteThreshold: councilVetoVoteThreshold, }); const governancePk = await withCreateMintGovernance( diff --git a/packages/governance-sdk/tests/governance/api.v1.test.ts b/packages/governance-sdk/tests/governance/api.v1.test.ts new file mode 100644 index 00000000..0dbed9ff --- /dev/null +++ b/packages/governance-sdk/tests/governance/api.v1.test.ts @@ -0,0 +1,75 @@ +import { PROGRAM_VERSION_V1 } from '../../src'; + +import { BenchBuilder } from '../tools/builders'; + +test('createRealm', async () => { + // Arrange + const bench = await BenchBuilder.withConnection(PROGRAM_VERSION_V1).then(b => + b.withWallet(), + ); + + // Act + const realm = await bench.withRealm().then(b => b.sendTx()); + + // Assert + const realmAccount = await realm.getRealm(); + + expect(realmAccount.pubkey).toEqual(realm.realmPk); +}); + +test('createGovernance', async () => { + // Arrange + const realm = await BenchBuilder.withConnection(PROGRAM_VERSION_V1) + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.sendTx()); + + // Act + const governancePk = await realm.createGovernance(); + + // Assert + const governance = await realm.getGovernance(governancePk); + + expect(governance.account.realm).toEqual(realm.realmPk); +}); + +test('createProposal', async () => { + // Arrange + const realm = await BenchBuilder.withConnection(PROGRAM_VERSION_V1) + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.withGovernance()) + .then(b => b.sendTx()); + + // Act + const proposalPk = await realm.createProposal('proposal 1'); + + // // Assert + const proposal = await realm.getProposal(proposalPk); + + expect(proposal.account.name).toEqual('proposal 1'); +}); + +test('castVote', async () => { + // Arrange + const realm = await BenchBuilder.withConnection(PROGRAM_VERSION_V1) + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.withGovernance()) + .then(b => b.sendTx()) + .then(b => b.withProposal()) + .then(b => b.withSignatory()) + .then(b => b.withProposalSignOff()) + .then(b => b.sendTx()); + + // Act + const voteRecordPk = await realm.castVote(); + + // Assert + const voteRecord = await realm.getVoteRecord(voteRecordPk); + + expect(voteRecord.account.proposal).toEqual(realm.proposalPk); +}); diff --git a/packages/governance-sdk/tests/governance/api.v2.test.ts b/packages/governance-sdk/tests/governance/api.v2.test.ts index 499a187d..9bcfebff 100644 --- a/packages/governance-sdk/tests/governance/api.v2.test.ts +++ b/packages/governance-sdk/tests/governance/api.v2.test.ts @@ -7,7 +7,6 @@ import { VoteTipping, } from '../../src/governance/accounts'; import { BenchBuilder } from '../tools/builders'; -import { programId } from '../tools/setup'; import { getTimestampFromDays } from '../tools/units'; test('createGovernanceWithConfig', async () => { @@ -26,7 +25,8 @@ test('createGovernanceWithConfig', async () => { minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), - voteTipping: VoteTipping.Strict, + communityVoteTipping: VoteTipping.Strict, + councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), councilVoteThreshold: new VoteThreshold({ type: VoteThresholdType.YesVotePercentage, @@ -36,6 +36,10 @@ test('createGovernanceWithConfig', async () => { type: VoteThresholdType.YesVotePercentage, value: 0, }), + communityVetoVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: 0, + }), }); // Act diff --git a/packages/governance-sdk/tests/tools/builders.ts b/packages/governance-sdk/tests/tools/builders.ts index 308600f3..abc91139 100644 --- a/packages/governance-sdk/tests/tools/builders.ts +++ b/packages/governance-sdk/tests/tools/builders.ts @@ -18,6 +18,7 @@ import { getTokenOwnerRecord, getVoteRecord, Vote, + withAddSignatory, withCastVote, withCreateGovernance, withCreateProposal, @@ -137,6 +138,7 @@ export class RealmBuilder { communityOwnerRecordPk: PublicKey; governancePk: PublicKey; proposalPk: PublicKey; + signatoryPk: PublicKey | undefined; voteRecordPk: PublicKey; constructor(bench: BenchBuilder) { @@ -414,6 +416,21 @@ export class RealmBuilder { return getProposal(this.bench.connection, proposalPk); } + async withSignatory() { + this.signatoryPk = await withAddSignatory( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.proposalPk, + this.communityOwnerRecordPk, + this.bench.walletPk, + this.bench.walletPk, + this.bench.walletPk, + ); + + return this; + } + async withProposalSignOff() { withSignOffProposal( this.bench.instructions, @@ -423,7 +440,7 @@ export class RealmBuilder { this.governancePk, this.proposalPk, this.bench.walletPk, - undefined, + this.signatoryPk, this.communityOwnerRecordPk, ); diff --git a/packages/governance/package.json b/packages/governance/package.json index dbca946a..1337adb0 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.9", + "@solana/spl-governance": "0.3.10", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From a58b9591345e73deeff6efdf2b271e824bbcbf21 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Thu, 25 Aug 2022 15:05:24 +0200 Subject: [PATCH 55/88] Governance: Fix GovernanceConfig serialisation for V2 args --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/serialisation.ts | 2 +- packages/governance/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 4b64caa8..4a21e3e1 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.10", + "version": "0.3.12", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index dfff2269..3ce7e136 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -683,7 +683,7 @@ function createGovernanceSchema(programVersion: number) { ['councilVoteThreshold', 'VoteThreshold'], ['councilVetoVoteThreshold', 'VoteThreshold'], ['minCouncilTokensToCreateProposal', 'u64'], - ...(programVersion >= PROGRAM_VERSION_V2 + ...(programVersion >= PROGRAM_VERSION_V3 ? [ ['councilVoteTipping', 'u8'], ['communityVetoVoteThreshold', 'VoteThreshold'], diff --git a/packages/governance/package.json b/packages/governance/package.json index 1337adb0..48ef82cd 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.10", + "@solana/spl-governance": "0.3.12", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From c44fc3b80ebed92e406115d1d2b4aa1ce565429d Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Thu, 25 Aug 2022 21:54:38 +0200 Subject: [PATCH 56/88] Governance: Split instruction and account schemas (#554) * chore: Rename schema to instruction schema * wip: Remove args schema from account schema * wip: Remove accounts from instruction schema * wip: Create shared struct schema * chore: Use programVersion for all instruction creators --- packages/governance-sdk/package.json | 2 +- .../governance-sdk/src/governance/accounts.ts | 15 +- .../governance/createSetGovernanceConfig.ts | 7 +- .../src/governance/serialisation.ts | 232 +++++++++++------- .../governance-sdk/src/governance/version.ts | 2 +- .../src/governance/withAddSignatory.ts | 6 +- .../src/governance/withCancelProposal.ts | 6 +- .../src/governance/withCastVote.ts | 4 +- .../src/governance/withCreateGovernance.ts | 4 +- .../governance/withCreateMintGovernance.ts | 4 +- .../governance/withCreateNativeTreasury.ts | 7 +- .../governance/withCreateProgramGovernance.ts | 4 +- .../src/governance/withCreateProposal.ts | 4 +- .../src/governance/withCreateRealm.ts | 4 +- .../governance/withCreateTokenGovernance.ts | 4 +- .../governance/withCreateTokenOwnerRecord.ts | 7 +- .../governance/withDepositGoverningTokens.ts | 4 +- .../src/governance/withExecuteTransaction.ts | 6 +- .../src/governance/withFinalizeVote.ts | 6 +- .../governance/withFlagTransactionError.ts | 6 +- .../src/governance/withInsertTransaction.ts | 4 +- .../src/governance/withRelinquishVote.ts | 6 +- .../src/governance/withRemoveTransaction.ts | 7 +- .../governance/withRevokeGoverningTokens.ts | 4 +- .../governance/withSetGovernanceDelegate.ts | 4 +- .../src/governance/withSetRealmAuthority.ts | 4 +- .../src/governance/withSetRealmConfig.ts | 7 +- .../src/governance/withSignOffProposal.ts | 6 +- .../governance/withUpdateProgramMetadata.ts | 7 +- .../governance/withWithdrawGoverningTokens.ts | 6 +- .../governance-sdk/src/registry/constants.ts | 3 + packages/governance/package.json | 2 +- .../src/actions/createNativeTreasury.ts | 3 +- .../src/actions/removeInstruction.ts | 3 +- .../src/actions/updateProgramMetadata.ts | 8 +- .../instruction/instructionCard.tsx | 6 +- .../instruction/newInstructionCard.tsx | 5 +- .../instructionInput/governanceConfigForm.tsx | 3 +- 38 files changed, 258 insertions(+), 164 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 4a21e3e1..a9cae4fb 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.12", + "version": "0.3.13", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index c1293223..5ddf106d 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -2,7 +2,11 @@ import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; import BigNumber from 'bignumber.js'; import { Vote, VoteKind } from './instructions'; -import { PROGRAM_VERSION_V1, PROGRAM_VERSION_V2 } from '../registry/constants'; +import { + ACCOUNT_VERSION_V1, + ACCOUNT_VERSION_V2, + PROGRAM_VERSION_V1, +} from '../registry/constants'; /// Seed prefix for Governance Program PDAs export const GOVERNANCE_PROGRAM_SEED = 'governance'; @@ -97,14 +101,17 @@ export function getAccountTypes(accountClass: GovernanceAccountClass) { } } -export function getAccountProgramVersion(accountType: GovernanceAccountType) { +export function getGovernanceAccountVersion( + accountType: GovernanceAccountType, +) { switch (accountType) { + case GovernanceAccountType.GovernanceV2: case GovernanceAccountType.VoteRecordV2: case GovernanceAccountType.ProposalTransactionV2: case GovernanceAccountType.ProposalV2: - return PROGRAM_VERSION_V2; + return ACCOUNT_VERSION_V2; default: - return PROGRAM_VERSION_V1; + return ACCOUNT_VERSION_V1; } } diff --git a/packages/governance-sdk/src/governance/createSetGovernanceConfig.ts b/packages/governance-sdk/src/governance/createSetGovernanceConfig.ts index 83b17e0a..28006e6b 100644 --- a/packages/governance-sdk/src/governance/createSetGovernanceConfig.ts +++ b/packages/governance-sdk/src/governance/createSetGovernanceConfig.ts @@ -1,16 +1,19 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import { GovernanceConfig } from './accounts'; import { SetGovernanceConfigArgs } from './instructions'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; export function createSetGovernanceConfig( programId: PublicKey, + programVersion: number, governance: PublicKey, governanceConfig: GovernanceConfig, ) { const args = new SetGovernanceConfigArgs({ config: governanceConfig }); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const keys = [ { diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 3ce7e136..311e5c4f 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -54,7 +54,7 @@ import { VoteTypeKind, ProposalOption, GovernanceAccountType, - getAccountProgramVersion, + getGovernanceAccountVersion, ProgramMetadata, VoteThresholdType, GoverningTokenConfigArgs, @@ -63,6 +63,8 @@ import { import { serialize } from 'borsh'; import { BorshAccountParser } from '../core/serialisation'; import { + ACCOUNT_VERSION_V1, + ACCOUNT_VERSION_V2, PROGRAM_VERSION_V1, PROGRAM_VERSION_V2, PROGRAM_VERSION_V3, @@ -227,7 +229,9 @@ export const serializeInstructionToBase64 = ( ) => { let data = createInstructionData(instruction); - return Buffer.from(serialize(GOVERNANCE_SCHEMA, data)).toString('base64'); + return Buffer.from( + serialize(GOVERNANCE_INSTRUCTION_SCHEMA_V1, data), + ).toString('base64'); }; // Converts TransactionInstruction to InstructionData format @@ -246,27 +250,112 @@ export const createInstructionData = (instruction: TransactionInstruction) => { }); }; -export const GOVERNANCE_SCHEMA_V1 = createGovernanceSchema(1); -export const GOVERNANCE_SCHEMA_V2 = createGovernanceSchema(2); -export const GOVERNANCE_SCHEMA_V3 = createGovernanceSchema(3); - -// The most recent version of spl-gov -export const GOVERNANCE_SCHEMA = GOVERNANCE_SCHEMA_V3; - -export function getGovernanceSchema(programVersion: number) { +// Instruction schemas +export const GOVERNANCE_INSTRUCTION_SCHEMA_V1 = createGovernanceInstructionSchema( + 1, +); +export const GOVERNANCE_INSTRUCTION_SCHEMA_V2 = createGovernanceInstructionSchema( + 2, +); +export const GOVERNANCE_INSTRUCTION_SCHEMA_V3 = createGovernanceInstructionSchema( + 3, +); + +export function getGovernanceInstructionSchema(programVersion: number) { switch (programVersion) { case 1: - return GOVERNANCE_SCHEMA_V1; + return GOVERNANCE_INSTRUCTION_SCHEMA_V1; case 2: - return GOVERNANCE_SCHEMA_V2; + return GOVERNANCE_INSTRUCTION_SCHEMA_V2; case 3: - return GOVERNANCE_SCHEMA_V3; + return GOVERNANCE_INSTRUCTION_SCHEMA_V3; default: - return GOVERNANCE_SCHEMA; + throw new Error( + `Account schema for program version: ${programVersion} doesn't exist`, + ); } } -function createGovernanceSchema(programVersion: number) { +/// Creates serialisation schema for spl-gov structs used for instructions and accounts +function createGovernanceStructSchema( + programVersion: number | undefined, + accountVersion: number | undefined, +) { + return new Map([ + [ + VoteChoice, + { + kind: 'struct', + fields: [ + ['rank', 'u8'], + ['weightPercentage', 'u8'], + ], + }, + ], + [ + InstructionData, + { + kind: 'struct', + fields: [ + ['programId', 'pubkey'], + ['accounts', [AccountMetaData]], + ['data', ['u8']], + ], + }, + ], + [ + AccountMetaData, + { + kind: 'struct', + fields: [ + ['pubkey', 'pubkey'], + ['isSigner', 'u8'], + ['isWritable', 'u8'], + ], + }, + ], + [ + MintMaxVoteWeightSource, + { + kind: 'struct', + fields: [ + ['type', 'u8'], + ['value', 'u64'], + ], + }, + ], + [ + GovernanceConfig, + { + kind: 'struct', + fields: [ + ['communityVoteThreshold', 'VoteThreshold'], + ['minCommunityTokensToCreateProposal', 'u64'], + ['minInstructionHoldUpTime', 'u32'], + ['maxVotingTime', 'u32'], + ['communityVoteTipping', 'u8'], + ['councilVoteThreshold', 'VoteThreshold'], + ['councilVetoVoteThreshold', 'VoteThreshold'], + ['minCouncilTokensToCreateProposal', 'u64'], + // Pass the extra fields to instruction if programVersion >= 3 + // The additional fields can't be passed to instructions for programVersion <= 2 because they were added in V3 + // and would override the transferAuhtority param which follows it + ...((programVersion && programVersion >= PROGRAM_VERSION_V3) || + // The account layout is backward compatible and we can read the extra fields for accountVersion >= 2 + (accountVersion && accountVersion >= ACCOUNT_VERSION_V2) + ? [ + ['councilVoteTipping', 'u8'], + ['communityVetoVoteThreshold', 'VoteThreshold'], + ] + : []), + ], + }, + ], + ]); +} + +/// Creates serialisation schema for spl-gov instructions for the given program version number +function createGovernanceInstructionSchema(programVersion: number) { return new Map([ [ RealmConfigArgs, @@ -320,7 +409,7 @@ function createGovernanceSchema(programVersion: number) { fields: [ ['instruction', 'u8'], // V1 of the program used restrictive instruction deserialisation which didn't allow additional data - programVersion > PROGRAM_VERSION_V1 ? ['amount', 'u64'] : undefined, + programVersion >= PROGRAM_VERSION_V2 ? ['amount', 'u64'] : undefined, ].filter(Boolean), }, ], @@ -461,16 +550,6 @@ function createGovernanceSchema(programVersion: number) { fields: [['instruction', 'u8']], }, ], - [ - VoteChoice, - { - kind: 'struct', - fields: [ - ['rank', 'u8'], - ['weightPercentage', 'u8'], - ], - }, - ], [ CastVoteArgs, { @@ -489,13 +568,13 @@ function createGovernanceSchema(programVersion: number) { kind: 'struct', fields: [ ['instruction', 'u8'], - programVersion > PROGRAM_VERSION_V1 + programVersion >= PROGRAM_VERSION_V2 ? ['optionIndex', 'u8'] : undefined, ['index', 'u16'], ['holdUpTime', 'u32'], - programVersion > PROGRAM_VERSION_V1 + programVersion >= PROGRAM_VERSION_V2 ? ['instructions', [InstructionData]] : ['instructionData', InstructionData], ].filter(Boolean), @@ -565,40 +644,30 @@ function createGovernanceSchema(programVersion: number) { fields: [['instruction', 'u8']], }, ], - [ - InstructionData, - { - kind: 'struct', - fields: [ - ['programId', 'pubkey'], - ['accounts', [AccountMetaData]], - ['data', ['u8']], - ], - }, - ], - [ - AccountMetaData, - { - kind: 'struct', - fields: [ - ['pubkey', 'pubkey'], - ['isSigner', 'u8'], - ['isWritable', 'u8'], - ], - }, - ], + ...createGovernanceStructSchema(programVersion, undefined), + ]); +} - [ - MintMaxVoteWeightSource, - { - kind: 'struct', - fields: [ - ['type', 'u8'], - ['value', 'u64'], - ], - }, - ], +// Accounts schemas +export const GOVERNANCE_ACCOUNT_SCHEMA_V1 = createGovernanceAccountSchema(1); +export const GOVERNANCE_ACCOUNT_SCHEMA_V2 = createGovernanceAccountSchema(2); + +export function getGovernanceAccountSchema(accountVersion: number) { + switch (accountVersion) { + case 1: + return GOVERNANCE_ACCOUNT_SCHEMA_V1; + case 2: + return GOVERNANCE_ACCOUNT_SCHEMA_V2; + default: + throw new Error( + `Account schema for account version: ${accountVersion} doesn't exist`, + ); + } +} +/// Creates serialisation schema for spl-gov accounts for the given account version number +function createGovernanceAccountSchema(accountVersion: number) { + return new Map([ [ RealmConfig, { @@ -663,35 +732,13 @@ function createGovernanceSchema(programVersion: number) { ['governedAccount', 'pubkey'], ['proposalCount', 'u32'], ['config', GovernanceConfig], - ...(programVersion >= PROGRAM_VERSION_V2 + ...(accountVersion >= ACCOUNT_VERSION_V2 ? [['reserved', [3]]] : [['reserved', [6]]]), ['votingProposalCount', 'u16'], ], }, ], - [ - GovernanceConfig, - { - kind: 'struct', - fields: [ - ['communityVoteThreshold', 'VoteThreshold'], - ['minCommunityTokensToCreateProposal', 'u64'], - ['minInstructionHoldUpTime', 'u32'], - ['maxVotingTime', 'u32'], - ['communityVoteTipping', 'u8'], - ['councilVoteThreshold', 'VoteThreshold'], - ['councilVetoVoteThreshold', 'VoteThreshold'], - ['minCouncilTokensToCreateProposal', 'u64'], - ...(programVersion >= PROGRAM_VERSION_V3 - ? [ - ['councilVoteTipping', 'u8'], - ['communityVetoVoteThreshold', 'VoteThreshold'], - ] - : []), - ], - }, - ], [ TokenOwnerRecord, { @@ -737,7 +784,7 @@ function createGovernanceSchema(programVersion: number) { ['signatoriesCount', 'u8'], ['signatoriesSignedOffCount', 'u8'], - ...(programVersion === PROGRAM_VERSION_V1 + ...(accountVersion === ACCOUNT_VERSION_V1 ? [ ['yesVotesCount', 'u64'], ['noVotesCount', 'u64'], @@ -764,20 +811,20 @@ function createGovernanceSchema(programVersion: number) { ['executionFlags', 'u8'], ['maxVoteWeight', { kind: 'option', type: 'u64' }], - ...(programVersion === PROGRAM_VERSION_V1 + ...(accountVersion === ACCOUNT_VERSION_V1 ? [] : [['maxVotingTime', { kind: 'option', type: 'u32' }]]), ['voteThreshold', { kind: 'option', type: 'VoteThreshold' }], - ...(programVersion === PROGRAM_VERSION_V1 + ...(accountVersion === ACCOUNT_VERSION_V1 ? [] : [['reserved', [64]]]), ['name', 'string'], ['descriptionLink', 'string'], - ...(programVersion === PROGRAM_VERSION_V1 + ...(accountVersion === ACCOUNT_VERSION_V1 ? [] : [['vetoVoteWeight', 'u64']]), ], @@ -815,7 +862,7 @@ function createGovernanceSchema(programVersion: number) { ['governingTokenOwner', 'pubkey'], ['isRelinquished', 'u8'], - ...(programVersion === PROGRAM_VERSION_V1 + ...(accountVersion === ACCOUNT_VERSION_V1 ? [['voteWeight', VoteWeight]] : [ ['voterWeight', 'u64'], @@ -831,12 +878,12 @@ function createGovernanceSchema(programVersion: number) { fields: [ ['accountType', 'u8'], ['proposal', 'pubkey'], - programVersion > PROGRAM_VERSION_V1 + accountVersion >= ACCOUNT_VERSION_V2 ? ['optionIndex', 'u8'] : undefined, ['instructionIndex', 'u16'], ['holdUpTime', 'u32'], - programVersion > PROGRAM_VERSION_V1 + accountVersion >= ACCOUNT_VERSION_V2 ? ['instructions', [InstructionData]] : ['instruction', InstructionData], ['executedAt', { kind: 'option', type: 'u64' }], @@ -856,13 +903,14 @@ function createGovernanceSchema(programVersion: number) { ], }, ], + ...createGovernanceStructSchema(undefined, accountVersion), ]); } export function getGovernanceSchemaForAccount( accountType: GovernanceAccountType, ) { - return getGovernanceSchema(getAccountProgramVersion(accountType)); + return getGovernanceAccountSchema(getGovernanceAccountVersion(accountType)); } export const GovernanceAccountParser = (classType: GovernanceAccountClass) => @@ -873,7 +921,7 @@ export const GovernanceAccountParser = (classType: GovernanceAccountClass) => export function getInstructionDataFromBase64(instructionDataBase64: string) { const instructionDataBin = Buffer.from(instructionDataBase64, 'base64'); const instructionData: InstructionData = deserializeBorsh( - GOVERNANCE_SCHEMA, + GOVERNANCE_INSTRUCTION_SCHEMA_V1, InstructionData, instructionDataBin, ); diff --git a/packages/governance-sdk/src/governance/version.ts b/packages/governance-sdk/src/governance/version.ts index 8e9128fd..c85be3cb 100644 --- a/packages/governance-sdk/src/governance/version.ts +++ b/packages/governance-sdk/src/governance/version.ts @@ -71,7 +71,7 @@ export async function getGovernanceProgramVersion( 'ENmcpFCpxN1CqyUjuog9yyUVfdXBKF3LVCwLr7grJZpk', ); - await withUpdateProgramMetadata(instructions, programId, walletPk); + await withUpdateProgramMetadata(instructions, programId, 2, walletPk); const transaction = new Transaction({ feePayer: walletPk }); transaction.add(...instructions); diff --git a/packages/governance-sdk/src/governance/withAddSignatory.ts b/packages/governance-sdk/src/governance/withAddSignatory.ts index f6e19da0..76595402 100644 --- a/packages/governance-sdk/src/governance/withAddSignatory.ts +++ b/packages/governance-sdk/src/governance/withAddSignatory.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { AddSignatoryArgs } from './instructions'; import { getSignatoryRecordAddress } from './accounts'; @@ -21,7 +21,9 @@ export const withAddSignatory = async ( payer: PublicKey, ) => { const args = new AddSignatoryArgs({ signatory }); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const signatoryRecordAddress = await getSignatoryRecordAddress( programId, diff --git a/packages/governance-sdk/src/governance/withCancelProposal.ts b/packages/governance-sdk/src/governance/withCancelProposal.ts index db5317b2..2396e969 100644 --- a/packages/governance-sdk/src/governance/withCancelProposal.ts +++ b/packages/governance-sdk/src/governance/withCancelProposal.ts @@ -4,7 +4,7 @@ import { SYSVAR_CLOCK_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { CancelProposalArgs } from './instructions'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; @@ -20,7 +20,9 @@ export const withCancelProposal = ( governanceAuthority: PublicKey, ) => { const args = new CancelProposalArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); let keys: AccountMeta[] = []; diff --git a/packages/governance-sdk/src/governance/withCastVote.ts b/packages/governance-sdk/src/governance/withCastVote.ts index fbf92a0c..68e5a281 100644 --- a/packages/governance-sdk/src/governance/withCastVote.ts +++ b/packages/governance-sdk/src/governance/withCastVote.ts @@ -4,7 +4,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { CastVoteArgs, Vote } from './instructions'; import { getVoteRecordAddress } from './accounts'; @@ -34,7 +34,7 @@ export const withCastVote = async ( : { yesNoVote: undefined, vote: vote }, ); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const voteRecordAddress = await getVoteRecordAddress( diff --git a/packages/governance-sdk/src/governance/withCreateGovernance.ts b/packages/governance-sdk/src/governance/withCreateGovernance.ts index 45e8ce6c..33c9dc10 100644 --- a/packages/governance-sdk/src/governance/withCreateGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateGovernance.ts @@ -4,7 +4,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateGovernanceArgs } from './instructions'; @@ -27,7 +27,7 @@ export const withCreateGovernance = async ( const args = new CreateGovernanceArgs({ config }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); governedAccount = governedAccount ?? new Keypair().publicKey; diff --git a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts index e639199c..7ec6909d 100644 --- a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateMintGovernanceArgs } from './instructions'; @@ -32,7 +32,7 @@ export const withCreateMintGovernance = async ( }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const [governanceAddress] = await PublicKey.findProgramAddress( diff --git a/packages/governance-sdk/src/governance/withCreateNativeTreasury.ts b/packages/governance-sdk/src/governance/withCreateNativeTreasury.ts index e4645d3d..af9628c8 100644 --- a/packages/governance-sdk/src/governance/withCreateNativeTreasury.ts +++ b/packages/governance-sdk/src/governance/withCreateNativeTreasury.ts @@ -1,5 +1,5 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { CreateNativeTreasuryArgs } from './instructions'; import { getNativeTreasuryAddress } from './accounts'; @@ -8,11 +8,14 @@ import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; export const withCreateNativeTreasury = async ( instructions: TransactionInstruction[], programId: PublicKey, + programVersion: number, governancePk: PublicKey, payer: PublicKey, ) => { const args = new CreateNativeTreasuryArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const nativeTreasuryAddress = await getNativeTreasuryAddress( programId, diff --git a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts index ed1549b1..9656635d 100644 --- a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateProgramGovernanceArgs } from './instructions'; @@ -32,7 +32,7 @@ export const withCreateProgramGovernance = async ( }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const [governanceAddress] = await PublicKey.findProgramAddress( diff --git a/packages/governance-sdk/src/governance/withCreateProposal.ts b/packages/governance-sdk/src/governance/withCreateProposal.ts index 4cccc332..ee367123 100644 --- a/packages/governance-sdk/src/governance/withCreateProposal.ts +++ b/packages/governance-sdk/src/governance/withCreateProposal.ts @@ -4,7 +4,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { CreateProposalArgs } from './instructions'; import { @@ -43,7 +43,7 @@ export const withCreateProposal = async ( useDenyOption, }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); let proposalIndexBuffer = Buffer.alloc(4); diff --git a/packages/governance-sdk/src/governance/withCreateRealm.ts b/packages/governance-sdk/src/governance/withCreateRealm.ts index ea08dcfa..f7254b7b 100644 --- a/packages/governance-sdk/src/governance/withCreateRealm.ts +++ b/packages/governance-sdk/src/governance/withCreateRealm.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { CreateRealmArgs } from './instructions'; import { @@ -49,7 +49,7 @@ export async function withCreateRealm( name, }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const [realmAddress] = await PublicKey.findProgramAddress( diff --git a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts index 8acc72d9..b86c759b 100644 --- a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { GovernanceConfig } from './accounts'; import { CreateTokenGovernanceArgs } from './instructions'; @@ -32,7 +32,7 @@ export const withCreateTokenGovernance = async ( }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const [governanceAddress] = await PublicKey.findProgramAddress( diff --git a/packages/governance-sdk/src/governance/withCreateTokenOwnerRecord.ts b/packages/governance-sdk/src/governance/withCreateTokenOwnerRecord.ts index aff560d5..20dcd28d 100644 --- a/packages/governance-sdk/src/governance/withCreateTokenOwnerRecord.ts +++ b/packages/governance-sdk/src/governance/withCreateTokenOwnerRecord.ts @@ -1,5 +1,5 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { CreateTokenOwnerRecordArgs } from './instructions'; import { getTokenOwnerRecordAddress } from './accounts'; @@ -8,13 +8,16 @@ import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; export const withCreateTokenOwnerRecord = async ( instructions: TransactionInstruction[], programId: PublicKey, + programVersion: number, realm: PublicKey, governingTokenOwner: PublicKey, governingTokenMint: PublicKey, payer: PublicKey, ) => { const args = new CreateTokenOwnerRecordArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const tokenOwnerRecordAddress = await getTokenOwnerRecordAddress( programId, diff --git a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts index 04f8e639..f11507a0 100644 --- a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { DepositGoverningTokensArgs } from './instructions'; import { @@ -30,7 +30,7 @@ export const withDepositGoverningTokens = async ( ) => { const args = new DepositGoverningTokensArgs({ amount }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const tokenOwnerRecordAddress = await getTokenOwnerRecordAddress( diff --git a/packages/governance-sdk/src/governance/withExecuteTransaction.ts b/packages/governance-sdk/src/governance/withExecuteTransaction.ts index 7a8f7150..19926da7 100644 --- a/packages/governance-sdk/src/governance/withExecuteTransaction.ts +++ b/packages/governance-sdk/src/governance/withExecuteTransaction.ts @@ -3,7 +3,7 @@ import { SYSVAR_CLOCK_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { ExecuteTransactionArgs } from './instructions'; import { @@ -23,7 +23,9 @@ export const withExecuteTransaction = async ( transactionInstructions: InstructionData[], ) => { const args = new ExecuteTransactionArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const nativeTreasury = await getNativeTreasuryAddress(programId, governance); diff --git a/packages/governance-sdk/src/governance/withFinalizeVote.ts b/packages/governance-sdk/src/governance/withFinalizeVote.ts index 39e4bfdb..d045401c 100644 --- a/packages/governance-sdk/src/governance/withFinalizeVote.ts +++ b/packages/governance-sdk/src/governance/withFinalizeVote.ts @@ -3,7 +3,7 @@ import { SYSVAR_CLOCK_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { FinalizeVoteArgs } from './instructions'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; @@ -21,7 +21,9 @@ export const withFinalizeVote = async ( maxVoterWeightRecord?: PublicKey, ) => { const args = new FinalizeVoteArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const [realmIsWritable, governanceIsWritable] = programVersion === PROGRAM_VERSION_V1 ? [false, false] : [true, true]; diff --git a/packages/governance-sdk/src/governance/withFlagTransactionError.ts b/packages/governance-sdk/src/governance/withFlagTransactionError.ts index 726755d6..30d11b88 100644 --- a/packages/governance-sdk/src/governance/withFlagTransactionError.ts +++ b/packages/governance-sdk/src/governance/withFlagTransactionError.ts @@ -3,7 +3,7 @@ import { SYSVAR_CLOCK_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { FlagTransactionErrorArgs } from './instructions'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; @@ -18,7 +18,9 @@ export const withFlagTransactionError = ( proposalTransaction: PublicKey, ) => { const args = new FlagTransactionErrorArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const keys = [ { diff --git a/packages/governance-sdk/src/governance/withInsertTransaction.ts b/packages/governance-sdk/src/governance/withInsertTransaction.ts index efa27060..b7ba1e32 100644 --- a/packages/governance-sdk/src/governance/withInsertTransaction.ts +++ b/packages/governance-sdk/src/governance/withInsertTransaction.ts @@ -3,7 +3,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { InsertTransactionArgs } from './instructions'; import { getProposalTransactionAddress, InstructionData } from './accounts'; @@ -38,7 +38,7 @@ export const withInsertTransaction = async ( : undefined, }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const proposalTransactionAddress = await getProposalTransactionAddress( diff --git a/packages/governance-sdk/src/governance/withRelinquishVote.ts b/packages/governance-sdk/src/governance/withRelinquishVote.ts index 003a8863..de4ee72e 100644 --- a/packages/governance-sdk/src/governance/withRelinquishVote.ts +++ b/packages/governance-sdk/src/governance/withRelinquishVote.ts @@ -1,5 +1,5 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { RelinquishVoteArgs } from './instructions'; import { PROGRAM_VERSION_V3 } from '../registry/constants'; @@ -18,7 +18,9 @@ export const withRelinquishVote = async ( beneficiary: PublicKey | undefined, ) => { const args = new RelinquishVoteArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); let v3Keys = programVersion >= PROGRAM_VERSION_V3 diff --git a/packages/governance-sdk/src/governance/withRemoveTransaction.ts b/packages/governance-sdk/src/governance/withRemoveTransaction.ts index 8bf307e2..8ce90ed0 100644 --- a/packages/governance-sdk/src/governance/withRemoveTransaction.ts +++ b/packages/governance-sdk/src/governance/withRemoveTransaction.ts @@ -1,11 +1,12 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { RemoveTransactionArgs } from './instructions'; export const withRemoveTransaction = async ( instructions: TransactionInstruction[], programId: PublicKey, + programVersion: number, proposal: PublicKey, tokenOwnerRecord: PublicKey, governanceAuthority: PublicKey, @@ -13,7 +14,9 @@ export const withRemoveTransaction = async ( beneficiary: PublicKey, ) => { const args = new RemoveTransactionArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const keys = [ { diff --git a/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts b/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts index 64cdc977..472b1297 100644 --- a/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts @@ -1,5 +1,5 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { RevokeGoverningTokensArgs } from './instructions'; import { @@ -22,7 +22,7 @@ export const withRevokeGoverningTokens = async ( ) => { const args = new RevokeGoverningTokensArgs({ amount }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const tokenOwnerRecordAddress = await getTokenOwnerRecordAddress( diff --git a/packages/governance-sdk/src/governance/withSetGovernanceDelegate.ts b/packages/governance-sdk/src/governance/withSetGovernanceDelegate.ts index 1e6da0dc..3f7fefd5 100644 --- a/packages/governance-sdk/src/governance/withSetGovernanceDelegate.ts +++ b/packages/governance-sdk/src/governance/withSetGovernanceDelegate.ts @@ -1,5 +1,5 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { SetGovernanceDelegateArgs } from './instructions'; import { getTokenOwnerRecordAddress } from './accounts'; @@ -18,7 +18,7 @@ export const withSetGovernanceDelegate = async ( newGovernanceDelegate: newGovernanceDelegate, }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); const tokenOwnerRecordAddress = await getTokenOwnerRecordAddress( diff --git a/packages/governance-sdk/src/governance/withSetRealmAuthority.ts b/packages/governance-sdk/src/governance/withSetRealmAuthority.ts index 2225eb76..971f1bb7 100644 --- a/packages/governance-sdk/src/governance/withSetRealmAuthority.ts +++ b/packages/governance-sdk/src/governance/withSetRealmAuthority.ts @@ -1,5 +1,5 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { SetRealmAuthorityAction, SetRealmAuthorityArgs } from './instructions'; import { PROGRAM_VERSION_V1 } from '../registry'; @@ -18,7 +18,7 @@ export const withSetRealmAuthority = ( action: action, // V2 }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); let keys = [ diff --git a/packages/governance-sdk/src/governance/withSetRealmConfig.ts b/packages/governance-sdk/src/governance/withSetRealmConfig.ts index 6d4a701b..4358adfe 100644 --- a/packages/governance-sdk/src/governance/withSetRealmConfig.ts +++ b/packages/governance-sdk/src/governance/withSetRealmConfig.ts @@ -3,13 +3,10 @@ import { getRealmConfigAddress, getTokenHoldingAddress, GoverningTokenConfigAccountArgs, - GoverningTokenConfigArgs, - GoverningTokenType, MintMaxVoteWeightSource, - RealmConfigArgs, } from './accounts'; import { SetRealmConfigArgs } from './instructions'; -import { getGovernanceSchema } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import BN from 'bn.js'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; @@ -40,7 +37,7 @@ export async function withSetRealmConfig( const args = new SetRealmConfigArgs({ configArgs }); const data = Buffer.from( - serialize(getGovernanceSchema(programVersion), args), + serialize(getGovernanceInstructionSchema(programVersion), args), ); let keys = [ diff --git a/packages/governance-sdk/src/governance/withSignOffProposal.ts b/packages/governance-sdk/src/governance/withSignOffProposal.ts index 63626cc8..fe824a2a 100644 --- a/packages/governance-sdk/src/governance/withSignOffProposal.ts +++ b/packages/governance-sdk/src/governance/withSignOffProposal.ts @@ -4,7 +4,7 @@ import { SYSVAR_CLOCK_PUBKEY, TransactionInstruction, } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { SignOffProposalArgs } from './instructions'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; @@ -21,7 +21,9 @@ export const withSignOffProposal = ( proposalOwnerRecord: PublicKey | undefined, ) => { const args = new SignOffProposalArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); let keys: AccountMeta[] = []; diff --git a/packages/governance-sdk/src/governance/withUpdateProgramMetadata.ts b/packages/governance-sdk/src/governance/withUpdateProgramMetadata.ts index 84e43eb1..a9419909 100644 --- a/packages/governance-sdk/src/governance/withUpdateProgramMetadata.ts +++ b/packages/governance-sdk/src/governance/withUpdateProgramMetadata.ts @@ -1,5 +1,5 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { UpdateProgramMetadataArgs } from './instructions'; import { getProgramMetadataAddress } from './accounts'; @@ -8,11 +8,14 @@ import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; export const withUpdateProgramMetadata = async ( instructions: TransactionInstruction[], programId: PublicKey, + programVersion: number, payer: PublicKey, ) => { const args = new UpdateProgramMetadataArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const programMetadataAddress = await getProgramMetadataAddress(programId); diff --git a/packages/governance-sdk/src/governance/withWithdrawGoverningTokens.ts b/packages/governance-sdk/src/governance/withWithdrawGoverningTokens.ts index cdbdeec4..cb5bd2f6 100644 --- a/packages/governance-sdk/src/governance/withWithdrawGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withWithdrawGoverningTokens.ts @@ -1,5 +1,5 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { GOVERNANCE_SCHEMA } from './serialisation'; +import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { WithdrawGoverningTokensArgs } from './instructions'; import { GOVERNANCE_PROGRAM_SEED } from './accounts'; @@ -16,7 +16,9 @@ export const withWithdrawGoverningTokens = async ( governingTokenOwner: PublicKey, ) => { const args = new WithdrawGoverningTokensArgs(); - const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args)); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); const [tokenOwnerRecordAddress] = await PublicKey.findProgramAddress( [ diff --git a/packages/governance-sdk/src/registry/constants.ts b/packages/governance-sdk/src/registry/constants.ts index 4ecd57da..b7714656 100644 --- a/packages/governance-sdk/src/registry/constants.ts +++ b/packages/governance-sdk/src/registry/constants.ts @@ -4,3 +4,6 @@ export const PROGRAM_VERSION_V3 = 3; // The most up to date program version export const PROGRAM_VERSION = PROGRAM_VERSION_V3; + +export const ACCOUNT_VERSION_V1 = 1; +export const ACCOUNT_VERSION_V2 = 2; diff --git a/packages/governance/package.json b/packages/governance/package.json index 48ef82cd..1914ccb2 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.12", + "@solana/spl-governance": "0.3.13", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", diff --git a/packages/governance/src/actions/createNativeTreasury.ts b/packages/governance/src/actions/createNativeTreasury.ts index fad25edf..38ffd50d 100644 --- a/packages/governance/src/actions/createNativeTreasury.ts +++ b/packages/governance/src/actions/createNativeTreasury.ts @@ -9,7 +9,7 @@ import { withCreateNativeTreasury } from '@solana/spl-governance'; import { ProgramAccount } from '@solana/spl-governance'; export const createNativeTreasury = async ( - { connection, wallet, programId, walletPubkey }: RpcContext, + { connection, wallet, programId, programVersion, walletPubkey }: RpcContext, governance: ProgramAccount, ) => { @@ -19,6 +19,7 @@ export const createNativeTreasury = async ( await withCreateNativeTreasury( instructions, programId, + programVersion, governance.pubkey, walletPubkey, ); diff --git a/packages/governance/src/actions/removeInstruction.ts b/packages/governance/src/actions/removeInstruction.ts index 354577dc..fb94b787 100644 --- a/packages/governance/src/actions/removeInstruction.ts +++ b/packages/governance/src/actions/removeInstruction.ts @@ -8,7 +8,7 @@ import { RpcContext } from '@solana/spl-governance'; import { ProgramAccount } from '@solana/spl-governance'; export const removeInstruction = async ( - { connection, wallet, programId, walletPubkey }: RpcContext, + { connection, wallet, programId, programVersion, walletPubkey }: RpcContext, proposal: ProgramAccount, proposalInstruction: PublicKey, ) => { @@ -21,6 +21,7 @@ export const removeInstruction = async ( await withRemoveTransaction( instructions, programId, + programVersion, proposal.pubkey, proposal.account.tokenOwnerRecord, governanceAuthority, diff --git a/packages/governance/src/actions/updateProgramMetadata.ts b/packages/governance/src/actions/updateProgramMetadata.ts index add04140..1a8823c8 100644 --- a/packages/governance/src/actions/updateProgramMetadata.ts +++ b/packages/governance/src/actions/updateProgramMetadata.ts @@ -9,12 +9,18 @@ export const updateProgramMetadata = async ({ connection, wallet, programId, + programVersion, walletPubkey, }: RpcContext) => { let signers: Keypair[] = []; let instructions: TransactionInstruction[] = []; - await withUpdateProgramMetadata(instructions, programId, walletPubkey); + await withUpdateProgramMetadata( + instructions, + programId, + programVersion, + walletPubkey, + ); await sendTransactionWithNotifications( connection, diff --git a/packages/governance/src/views/proposal/components/instruction/instructionCard.tsx b/packages/governance/src/views/proposal/components/instruction/instructionCard.tsx index 80635d81..45507c9d 100644 --- a/packages/governance/src/views/proposal/components/instruction/instructionCard.tsx +++ b/packages/governance/src/views/proposal/components/instruction/instructionCard.tsx @@ -9,8 +9,8 @@ import { Proposal, ProposalTransaction, ProposalState, + getGovernanceInstructionSchema, } from '@solana/spl-governance'; -import { GOVERNANCE_SCHEMA } from '@solana/spl-governance'; import { serialize } from 'borsh'; import '../style.less'; @@ -54,7 +54,7 @@ export function InstructionCard({ const instructionDetails = useMemo(() => { const dataBase64 = Buffer.from( serialize( - GOVERNANCE_SCHEMA, + getGovernanceInstructionSchema(rpcContext.programVersion), proposalInstruction.account.getSingleInstruction(), ), ).toString('base64'); @@ -63,7 +63,7 @@ export function InstructionCard({ programId: proposalInstruction.account.getSingleInstruction().programId, dataBase64: dataBase64, }; - }, [proposalInstruction]); + }, [proposalInstruction, rpcContext.programVersion]); const contentList: Record = { info: ( diff --git a/packages/governance/src/views/proposal/components/instruction/newInstructionCard.tsx b/packages/governance/src/views/proposal/components/instruction/newInstructionCard.tsx index 814f9503..250bdfa8 100644 --- a/packages/governance/src/views/proposal/components/instruction/newInstructionCard.tsx +++ b/packages/governance/src/views/proposal/components/instruction/newInstructionCard.tsx @@ -50,12 +50,11 @@ export function NewInstructionCard({ instruction: string; holdUpTime: number; }) => { - - let optionIndex = 0; // default to first option // If instructionsNextIndex exists then we have V1 account and otherwise V2 - let index = proposal.account.instructionsNextIndex ?? + let index = + proposal.account.instructionsNextIndex ?? proposal.account.options[optionIndex].instructionsNextIndex; try { diff --git a/packages/governance/src/views/proposal/components/instructionInput/governanceConfigForm.tsx b/packages/governance/src/views/proposal/components/instructionInput/governanceConfigForm.tsx index d74a8f78..c92124c9 100644 --- a/packages/governance/src/views/proposal/components/instructionInput/governanceConfigForm.tsx +++ b/packages/governance/src/views/proposal/components/instructionInput/governanceConfigForm.tsx @@ -31,10 +31,11 @@ export const GovernanceConfigForm = ({ const realm = useRealm(governance.account.realm); const onCreate = async (values: GovernanceConfigValues) => { - const config = getGovernanceConfig(programVersion,values); + const config = getGovernanceConfig(programVersion, values); const setGovernanceConfigIx = createSetGovernanceConfig( programId, + programVersion, governance.pubkey, config, ); From ab8be6d8fa1c9840b6830e32ae1042a5b61c9969 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Thu, 25 Aug 2022 22:00:06 +0200 Subject: [PATCH 57/88] Governance: Fix setupRealm test --- .../tests/governance/api.smoke.test.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/governance-sdk/tests/governance/api.smoke.test.ts b/packages/governance-sdk/tests/governance/api.smoke.test.ts index 3cc53bcb..e5d7f4af 100644 --- a/packages/governance-sdk/tests/governance/api.smoke.test.ts +++ b/packages/governance-sdk/tests/governance/api.smoke.test.ts @@ -167,15 +167,23 @@ test('setupRealm', async () => { value: programVersion >= 3 ? 10 : 0, }); + let communityVetoVoteThreshold = new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + // For VERSION < 3 we have to pass 0 + value: programVersion >= 3 ? 10 : 0, + }); + const config = new GovernanceConfig({ communityVoteThreshold: communityVoteThreshold, minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, maxVotingTime: getTimestampFromDays(3), - voteTipping: VoteTipping.Strict, + communityVoteTipping: VoteTipping.Strict, + councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), councilVoteThreshold: councilVoteThreshold, councilVetoVoteThreshold: councilVetoVoteThreshold, + communityVetoVoteThreshold: communityVetoVoteThreshold, }); const governancePk = await withCreateMintGovernance( @@ -264,6 +272,7 @@ test('setupRealm', async () => { await withRemoveTransaction( instructions, programId, + programVersion, proposalPk, tokenOwnerRecordPk, walletPk, @@ -419,7 +428,12 @@ test('setupRealm', async () => { tokenOwnerRecordPk, ); - await withUpdateProgramMetadata(instructions, programId, walletPk); + await withUpdateProgramMetadata( + instructions, + programId, + programVersion, + walletPk, + ); // Act await sendTransaction(connection, instructions, signers, wallet); From 19cf21e3fe0704311f0b6bf58457aa48970bb328 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Wed, 21 Sep 2022 16:09:03 -0400 Subject: [PATCH 58/88] feat: Support Absolute max voter weight source (#558) --- packages/governance-sdk/package.json | 2 +- packages/governance-sdk/src/governance/accounts.ts | 6 ++++-- packages/governance/package.json | 2 +- .../realmMintSupplyConfigFormItem.tsx | 6 ++++-- .../src/views/home/buttons/registerRealmButton.tsx | 2 ++ 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index a9cae4fb..75f71f6f 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.13", + "version": "0.3.14", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 5ddf106d..5935e4e6 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -158,10 +158,11 @@ export enum MintMaxVoteWeightSourceType { } export class MintMaxVoteWeightSource { - type = MintMaxVoteWeightSourceType.SupplyFraction; + type: MintMaxVoteWeightSourceType; value: BN; - constructor(args: { value: BN }) { + constructor(args: { type: MintMaxVoteWeightSourceType; value: BN }) { + this.type = args.type; this.value = args.value; } @@ -169,6 +170,7 @@ export class MintMaxVoteWeightSource { static SUPPLY_FRACTION_DECIMALS = 10; static FULL_SUPPLY_FRACTION = new MintMaxVoteWeightSource({ + type: MintMaxVoteWeightSourceType.SupplyFraction, value: MintMaxVoteWeightSource.SUPPLY_FRACTION_BASE, }); diff --git a/packages/governance/package.json b/packages/governance/package.json index 1914ccb2..aa007489 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.13", + "@solana/spl-governance": "0.3.14", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", diff --git a/packages/governance/src/components/realmMintSupplyConfigFormItem/realmMintSupplyConfigFormItem.tsx b/packages/governance/src/components/realmMintSupplyConfigFormItem/realmMintSupplyConfigFormItem.tsx index 4dbf18a2..3f71c726 100644 --- a/packages/governance/src/components/realmMintSupplyConfigFormItem/realmMintSupplyConfigFormItem.tsx +++ b/packages/governance/src/components/realmMintSupplyConfigFormItem/realmMintSupplyConfigFormItem.tsx @@ -64,6 +64,7 @@ export const parseMintSupplyFraction = (fraction: string) => { .toNumber(); return new MintMaxVoteWeightSource({ + type: MintMaxVoteWeightSourceType.SupplyFraction, value: new BN(fractionValue), }); }; @@ -120,10 +121,11 @@ export function RealmMintSupplyConfigFormItem({ {supplyFraction && ( - {`${communityMint + {`${ + communityMint ? formatMintSupplyFraction(communityMint, supplyFraction) : '' - } (${formatMintSupplyPercentage(supplyFraction)})`} + } (${formatMintSupplyPercentage(supplyFraction)})`} )} diff --git a/packages/governance/src/views/home/buttons/registerRealmButton.tsx b/packages/governance/src/views/home/buttons/registerRealmButton.tsx index be2fbf3f..fbc1524a 100644 --- a/packages/governance/src/views/home/buttons/registerRealmButton.tsx +++ b/packages/governance/src/views/home/buttons/registerRealmButton.tsx @@ -15,6 +15,7 @@ import { useRpcContext } from '../../../hooks/useRpcContext'; import { getRealmUrl } from '../../../tools/routeTools'; import { MintMaxVoteWeightSource, + MintMaxVoteWeightSourceType, PROGRAM_VERSION_V1, } from '@solana/spl-governance'; @@ -43,6 +44,7 @@ const parseMintSupplyFraction = (fraction: string) => { .toNumber(); return new MintMaxVoteWeightSource({ + type: MintMaxVoteWeightSourceType.SupplyFraction, value: new BN(fractionValue), }); }; From dfe0a8c3bd05e6e324a6c42391dabe6b9a0a6c7f Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Thu, 6 Oct 2022 11:00:16 +0100 Subject: [PATCH 59/88] fix: move reserved[3] to GovernanceConfig --- packages/governance-sdk/src/governance/accounts.ts | 5 ++++- packages/governance-sdk/src/governance/serialisation.ts | 5 ++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 5935e4e6..0587abbb 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -450,7 +450,7 @@ export class GovernanceConfig { communityVetoVoteThreshold: VoteThreshold; councilVoteTipping: VoteTipping; - reserved = [0, 0]; + reserved?: Uint8Array; constructor(args: { communityVoteThreshold: VoteThreshold; @@ -466,6 +466,7 @@ export class GovernanceConfig { councilVetoVoteThreshold: VoteThreshold; communityVetoVoteThreshold: VoteThreshold; councilVoteTipping: VoteTipping; + reserved?: Uint8Array; }) { this.communityVoteThreshold = args.communityVoteThreshold; this.minCommunityTokensToCreateProposal = @@ -488,6 +489,8 @@ export class GovernanceConfig { this.councilVoteTipping = args.councilVoteTipping ?? this.communityVoteTipping; + + this.reserved = args.reserved ?? new Uint8Array(3); } } diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 311e5c4f..48f01f9a 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -346,6 +346,7 @@ function createGovernanceStructSchema( ? [ ['councilVoteTipping', 'u8'], ['communityVetoVoteThreshold', 'VoteThreshold'], + ['reserved', [3]], ] : []), ], @@ -732,9 +733,7 @@ function createGovernanceAccountSchema(accountVersion: number) { ['governedAccount', 'pubkey'], ['proposalCount', 'u32'], ['config', GovernanceConfig], - ...(accountVersion >= ACCOUNT_VERSION_V2 - ? [['reserved', [3]]] - : [['reserved', [6]]]), + ...(accountVersion >= ACCOUNT_VERSION_V2 ? [] : [['reserved', [6]]]), ['votingProposalCount', 'u16'], ], }, From 1baaa1c55025f80f5a0e98944f3fcb6d62e3d89d Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Thu, 6 Oct 2022 11:01:30 +0100 Subject: [PATCH 60/88] chore: Update version to 0.3.15 --- packages/governance-sdk/package.json | 2 +- packages/governance/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 75f71f6f..8ec74cee 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.14", + "version": "0.3.15", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", diff --git a/packages/governance/package.json b/packages/governance/package.json index aa007489..85410ce1 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.14", + "@solana/spl-governance": "0.3.15", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", From 3bbb3ccdf413af39b0ef3951e6340dc506a638e5 Mon Sep 17 00:00:00 2001 From: Sayantan Karmakar <40912636+sayantank@users.noreply.github.com> Date: Wed, 19 Oct 2022 11:55:13 -0400 Subject: [PATCH 61/88] FIX: payer accounts not writable (#559) * fixed payer not being writable * chore: update version to 0.3.16 --- packages/governance-sdk/package.json | 4 ++-- packages/governance-sdk/src/governance/withAddSignatory.ts | 2 +- packages/governance-sdk/src/governance/withCastVote.ts | 2 +- .../governance-sdk/src/governance/withCreateGovernance.ts | 2 +- .../governance-sdk/src/governance/withCreateMintGovernance.ts | 2 +- packages/governance/package.json | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 8ec74cee..33087add 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.15", + "version": "0.3.16", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", @@ -48,4 +48,4 @@ "^.+\\.tsx?$": "esbuild-jest" } } -} \ No newline at end of file +} diff --git a/packages/governance-sdk/src/governance/withAddSignatory.ts b/packages/governance-sdk/src/governance/withAddSignatory.ts index 76595402..5d49deb6 100644 --- a/packages/governance-sdk/src/governance/withAddSignatory.ts +++ b/packages/governance-sdk/src/governance/withAddSignatory.ts @@ -54,7 +54,7 @@ export const withAddSignatory = async ( }, { pubkey: payer, - isWritable: false, + isWritable: true, isSigner: true, }, { diff --git a/packages/governance-sdk/src/governance/withCastVote.ts b/packages/governance-sdk/src/governance/withCastVote.ts index 68e5a281..fd05c9b4 100644 --- a/packages/governance-sdk/src/governance/withCastVote.ts +++ b/packages/governance-sdk/src/governance/withCastVote.ts @@ -89,7 +89,7 @@ export const withCastVote = async ( }, { pubkey: payer, - isWritable: false, + isWritable: true, isSigner: true, }, { diff --git a/packages/governance-sdk/src/governance/withCreateGovernance.ts b/packages/governance-sdk/src/governance/withCreateGovernance.ts index 33c9dc10..178c42e7 100644 --- a/packages/governance-sdk/src/governance/withCreateGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateGovernance.ts @@ -64,7 +64,7 @@ export const withCreateGovernance = async ( }, { pubkey: payer, - isWritable: false, + isWritable: true, isSigner: true, }, { diff --git a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts index 7ec6909d..c3019d72 100644 --- a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts @@ -68,7 +68,7 @@ export const withCreateMintGovernance = async ( }, { pubkey: payer, // 5 - isWritable: false, + isWritable: true, isSigner: true, }, { diff --git a/packages/governance/package.json b/packages/governance/package.json index 85410ce1..61b1a7e2 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.15", + "@solana/spl-governance": "0.3.16", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", @@ -83,4 +83,4 @@ "react": "16.13.1", "react-dom": "16.13.1" } -} \ No newline at end of file +} From 11def6ca80fdef7b083a721884069d816698d64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Brzezi=C5=84ski?= Date: Sun, 30 Oct 2022 10:16:26 +0100 Subject: [PATCH 62/88] batch realm request + fix recentblockhash (#562) * batch realm request + fix recentblockhash * fixes * fixes * fix * fix * fix: Use signe getRealms function * chore: bump version to 0.3.17 Co-authored-by: Sebastian Bor --- packages/governance-sdk/package.json | 5 +- packages/governance-sdk/src/core/api.ts | 2 +- packages/governance-sdk/src/governance/api.ts | 94 ++++++++++++++++++- packages/governance-sdk/src/tools/borsh.ts | 4 +- .../governance-sdk/src/tools/sdk/runtime.ts | 9 +- .../tests/governance/api.v2.v3.test.ts | 23 ++++- packages/governance/package.json | 2 +- yarn.lock | 28 ++++++ 8 files changed, 150 insertions(+), 17 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 33087add..31a04114 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.16", + "version": "0.3.17", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", @@ -33,7 +33,8 @@ "bn.js": "^5.1.3", "borsh": "^0.3.1", "bs58": "^4.0.1", - "superstruct": "^0.15.2" + "superstruct": "^0.15.2", + "axios": "^1.1.3" }, "devDependencies": { "esbuild": "^0.14.11", diff --git a/packages/governance-sdk/src/core/api.ts b/packages/governance-sdk/src/core/api.ts index 2bc9ebb2..cfd2b70d 100644 --- a/packages/governance-sdk/src/core/api.ts +++ b/packages/governance-sdk/src/core/api.ts @@ -76,7 +76,7 @@ export const booleanFilter = (offset: number, value: boolean) => new MemcmpFilter(offset, Buffer.from(value ? [1] : [0])); export async function getBorshProgramAccounts< - TAccount extends ProgramAccountWithType + TAccount extends ProgramAccountWithType, >( connection: Connection, programId: PublicKey, diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index e15ae0b1..9d0004e4 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -23,17 +23,101 @@ import { MemcmpFilter, pubkeyFilter, } from '../core/api'; - import { ProgramAccount } from '../tools/sdk/runtime'; - -// Realms +import bs58 from 'bs58'; +import axios from 'axios'; +import { deserializeBorsh } from '../tools/borsh'; +import { getErrorMessage } from '../tools'; export async function getRealm(connection: Connection, realm: PublicKey) { return getGovernanceAccount(connection, realm, Realm); } -export async function getRealms(connection: Connection, programId: PublicKey) { - return getGovernanceAccounts(connection, programId, Realm); +export async function getRealms( + connection: Connection, + programIds: PublicKey | PublicKey[], +) { + if (programIds instanceof PublicKey) { + return getGovernanceAccounts(connection, programIds, Realm); + } + + return _getRealms(connection, programIds); +} + +async function _getRealms(connection: Connection, programIds: PublicKey[]) { + const accountTypes = getAccountTypes( + (Realm as any) as GovernanceAccountClass, + ); + const rpcEndpoint = (connection as any)._rpcEndpoint; + + const rawProgramAccounts = []; + + for (const accountType of accountTypes) { + const programAccountsJson = await axios.request({ + url: rpcEndpoint, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + data: JSON.stringify([ + ...programIds.map(x => { + return { + jsonrpc: '2.0', + id: x.toBase58(), + method: 'getProgramAccounts', + params: [ + x.toBase58(), + { + commitment: connection.commitment, + encoding: 'base64', + filters: [ + { + memcmp: { + offset: 0, + bytes: bs58.encode([accountType]), + }, + }, + ], + }, + ], + }; + }), + ]), + }); + + rawProgramAccounts.push( + ...programAccountsJson?.data + ?.filter((x: any) => x.result) + .flatMap((x: any) => x.result), + ); + } + + let accounts: ProgramAccount[] = []; + + for (let rawAccount of rawProgramAccounts) { + try { + const data = Buffer.from(rawAccount.account.data[0], 'base64'); + const accountType = data[0]; + + const account: ProgramAccount = { + pubkey: new PublicKey(rawAccount.pubkey), + account: deserializeBorsh( + getGovernanceSchemaForAccount(accountType), + Realm, + data, + ), + owner: rawAccount.account.owner, + }; + + accounts.push(account); + } catch (ex) { + console.info( + `Can't deserialize Realm @ ${rawAccount.pubkey}.`, + getErrorMessage(ex), + ); + } + } + return accounts; } // Realm config diff --git a/packages/governance-sdk/src/tools/borsh.ts b/packages/governance-sdk/src/tools/borsh.ts index 27a664e2..24cb7bf0 100644 --- a/packages/governance-sdk/src/tools/borsh.ts +++ b/packages/governance-sdk/src/tools/borsh.ts @@ -2,13 +2,13 @@ import { PublicKey } from '@solana/web3.js'; import { BinaryReader, Schema, BorshError, BinaryWriter } from 'borsh'; (BinaryReader.prototype as any).readPubkey = function () { - const reader = (this as unknown) as BinaryReader; + const reader = this as unknown as BinaryReader; const array = reader.readFixedArray(32); return new PublicKey(array); }; (BinaryWriter.prototype as any).writePubkey = function (value: PublicKey) { - const writer = (this as unknown) as BinaryWriter; + const writer = this as unknown as BinaryWriter; writer.writeFixedArray(value.toBuffer()); }; diff --git a/packages/governance-sdk/src/tools/sdk/runtime.ts b/packages/governance-sdk/src/tools/sdk/runtime.ts index d92c5ddd..922fc5e3 100644 --- a/packages/governance-sdk/src/tools/sdk/runtime.ts +++ b/packages/governance-sdk/src/tools/sdk/runtime.ts @@ -23,11 +23,10 @@ export async function simulateTransaction( transaction: Transaction, commitment: Commitment, ): Promise> { - // @ts-ignore - transaction.recentBlockhash = await connection._recentBlockhash( - // @ts-ignore - connection._disableBlockhashCaching, - ); + const latestBlockhash = await connection.getRecentBlockhash(); + //@ts-ignore + transaction.lastValidBlockHeight = latestBlockhash.lastValidBlockHeight; + transaction.recentBlockhash = latestBlockhash.blockhash; const signData = transaction.serializeMessage(); // @ts-ignore diff --git a/packages/governance-sdk/tests/governance/api.v2.v3.test.ts b/packages/governance-sdk/tests/governance/api.v2.v3.test.ts index 604349c7..a1642140 100644 --- a/packages/governance-sdk/tests/governance/api.v2.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v2.v3.test.ts @@ -1,5 +1,9 @@ import { Keypair } from '@solana/web3.js'; -import { GoverningTokenConfigAccountArgs, GoverningTokenType } from '../../src'; +import { + getRealms, + GoverningTokenConfigAccountArgs, + GoverningTokenType, +} from '../../src'; import { BenchBuilder } from '../tools/builders'; test('setRealmConfig', async () => { @@ -144,3 +148,20 @@ test('relinquishVote', async () => { expect(voteRecord.account.isRelinquished).toBe(true); }); + +test('getRealmsForMultiplePrograms', async () => { + // Arrange + const bench = await BenchBuilder.withConnection().then(b => b.withWallet()); + + const realm = await bench.withRealm().then(b => b.sendTx()); + + // Act + + const realms = await getRealms(bench.connection, [bench.programId]); + + // Assert + + expect(realms.map(r => r.pubkey.toBase58())).toContainEqual( + realm.realmPk.toBase58(), + ); +}); diff --git a/packages/governance/package.json b/packages/governance/package.json index 61b1a7e2..6591e5b4 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -6,7 +6,7 @@ "@blockworks-foundation/voter-stake-registry-client": "^0.1.6", "@oyster/common": "0.0.2", "@project-serum/borsh": "^0.2.2", - "@solana/spl-governance": "0.3.16", + "@solana/spl-governance": "0.3.17", "@solana/spl-token": "0.1.3", "@solana/web3.js": "^1.22.0", "antd": "^4.6.6", diff --git a/yarn.lock b/yarn.lock index e82918bd..b73f494e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6181,6 +6181,15 @@ axios@^0.21.1: dependencies: follow-redirects "^1.10.0" +axios@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.1.3.tgz#8274250dada2edf53814ed7db644b9c2866c1e35" + integrity sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^2.0.2: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -11634,6 +11643,11 @@ follow-redirects@^1.14.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379" integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g== +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + for-each@^0.3.3, for-each@~0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -11691,6 +11705,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +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" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -18448,6 +18471,11 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.1" +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== + proxyquire@^2.1.0: version "2.1.3" resolved "https://registry.yarnpkg.com/proxyquire/-/proxyquire-2.1.3.tgz#2049a7eefa10a9a953346a18e54aab2b4268df39" From 2a53d6d7ef75d09f185a9db3a62fe07fde195bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Brzezi=C5=84ski?= Date: Mon, 31 Oct 2022 23:48:18 +0100 Subject: [PATCH 63/88] test infra fix (#563) --- packages/governance-sdk/package.json | 16 +- packages/governance-sdk/tsconfig.json | 16 +- yarn.lock | 1046 ++++++++++++++++++++++++- 3 files changed, 1059 insertions(+), 19 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 31a04114..4db74417 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -39,14 +39,24 @@ "devDependencies": { "esbuild": "^0.14.11", "esbuild-jest": "^0.5.0", - "jest": "^27.4.7", + "jest": "^29.2.0", "typescript": "^4.5.4", - "@solana/spl-token": "0.1.3" + "@solana/spl-token": "0.1.3", + "ts-jest": "29.0.3", + "@types/jest": "29.2.0" }, "jest": { "testTimeout": 20000, "transform": { "^.+\\.tsx?$": "esbuild-jest" - } + }, + "moduleFileExtensions": [ + "ts", + "tsx", + "js", + "jsx", + "json", + "node" + ] } } diff --git a/packages/governance-sdk/tsconfig.json b/packages/governance-sdk/tsconfig.json index 60e1a5d4..82a16617 100644 --- a/packages/governance-sdk/tsconfig.json +++ b/packages/governance-sdk/tsconfig.json @@ -4,10 +4,7 @@ "declarationMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "target": "es6", - "lib": [ - "es2019" - ], + "target": "ES5", "module": "commonjs", "noFallthroughCasesInSwitch": true, "noImplicitAny": true, @@ -18,11 +15,8 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, + "downlevelIteration": true }, - "include": [ - "src" - ], - "exclude": [ - "node_modules", - ] -} \ No newline at end of file + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/yarn.lock b/yarn.lock index b73f494e..932ca1e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,6 +16,14 @@ resolved "https://registry.yarnpkg.com/@alloc/types/-/types-1.3.0.tgz#904245b8d3260a4b7d8a801c12501968f64fac08" integrity sha512-mH7LiFiq9g6rX2tvt1LtwsclfG5hnsmtIfkZiauAGrm1AwXhoRS0sF2WrN9JGN7eV5vFXqNaB0eXZ3IvMsVi9g== +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@ant-design/colors@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@ant-design/colors/-/colors-6.0.0.tgz#9b9366257cffcc47db42b9d0203bb592c13c0298" @@ -120,6 +128,13 @@ dependencies: "@babel/highlight" "^7.16.7" +"@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + "@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.12", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.9.0": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1" @@ -130,6 +145,11 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== +"@babel/compat-data@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.0.tgz#9b61938c5f688212c7b9ae363a819df7d29d4093" + integrity sha512-Gt9jszFJYq7qzXVK4slhc6NzJXnOVmRECWcVjF/T23rNXD9NtWQ0W3qxdg+p9wWIB+VQw3GYV/U2Ha9bRTfs4w== + "@babel/core@7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" @@ -173,6 +193,27 @@ semver "^6.3.0" source-map "^0.5.0" +"@babel/core@^7.11.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.6.tgz#7122ae4f5c5a37c0946c066149abd8e75f81540f" + integrity sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.19.6" + "@babel/helper-compilation-targets" "^7.19.3" + "@babel/helper-module-transforms" "^7.19.6" + "@babel/helpers" "^7.19.4" + "@babel/parser" "^7.19.6" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.6" + "@babel/types" "^7.19.4" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + "@babel/core@^7.12.17", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf" @@ -212,6 +253,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.19.6", "@babel/generator@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.0.tgz#0bfc5379e0efb05ca6092091261fcdf7ec36249d" + integrity sha512-GUPcXxWibClgmYJuIwC2Bc2Lg+8b9VjaJ+HlNdACEVt+Wlr1eoU1OPZjZRm7Hzl0gaTsUZNQfeihvZJhG7oc3w== + dependencies: + "@babel/types" "^7.20.0" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" @@ -247,6 +297,16 @@ browserslist "^4.17.5" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.19.3": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" + integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== + dependencies: + "@babel/compat-data" "^7.20.0" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + semver "^6.3.0" + "@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.8.3": version "7.13.11" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6" @@ -287,6 +347,11 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + "@babel/helper-explode-assignable-expression@^7.12.13": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" @@ -312,6 +377,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" + "@babel/helper-get-function-arity@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" @@ -341,6 +414,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-member-expression-to-functions@^7.13.0", "@babel/helper-member-expression-to-functions@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" @@ -362,6 +442,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.13.14", "@babel/helper-module-transforms@^7.9.0": version "7.13.14" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef" @@ -390,6 +477,20 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-module-transforms@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz#6c52cc3ac63b70952d33ee987cbee1c9368b533f" + integrity sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.19.4" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.6" + "@babel/types" "^7.19.4" + "@babel/helper-optimise-call-expression@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" @@ -407,6 +508,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== +"@babel/helper-plugin-utils@^7.18.6": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" + integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== + "@babel/helper-remap-async-to-generator@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" @@ -440,6 +546,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-simple-access@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz#be553f4951ac6352df2567f7daa19a0ee15668e7" + integrity sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg== + dependencies: + "@babel/types" "^7.19.4" + "@babel/helper-skip-transparent-expression-wrappers@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" @@ -461,6 +574,18 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/helper-validator-identifier@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" @@ -471,6 +596,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + "@babel/helper-validator-option@^7.12.17": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" @@ -481,6 +611,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + "@babel/helper-wrap-function@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" @@ -509,6 +644,15 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helpers@^7.19.4": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.0.tgz#27c8ffa8cc32a2ed3762fba48886e7654dbcf77f" + integrity sha512-aGMjYraN0zosCEthoGLdqot1oRsmxVTQRHadsUPz5QM44Zej2PYRz7XiDE7GqnkZnNtLbOuxqoZw42vkU7+XEQ== + dependencies: + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.0" + "@babel/types" "^7.20.0" + "@babel/highlight@^7.12.13", "@babel/highlight@^7.8.3": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" @@ -527,6 +671,15 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.13.13", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": version "7.13.13" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df" @@ -537,6 +690,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== +"@babel/parser@^7.18.10", "@babel/parser@^7.19.6", "@babel/parser@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.0.tgz#b26133c888da4d79b0d3edcf42677bcadc783046" + integrity sha512-G9VgAhEaICnz8iiJeGJQyVl6J2nTjbW0xeisva0PK6XcKsga7BIaqm4ZF8Rg1Wbaqmy6znspNqhPaPkyukujzg== + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" @@ -766,6 +924,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -1427,6 +1592,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + "@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0": version "7.13.13" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d" @@ -1457,6 +1631,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.19.6", "@babel/traverse@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.0.tgz#538c4c6ce6255f5666eba02252a7b59fc2d5ed98" + integrity sha512-5+cAXQNARgjRUK0JWu2UBwja4JLSO/rBMPJzpsKb+oBF5xlUuCfljQepS4XypBQoiigL0VQjTZy6WiONtUdScQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.0" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.0" + "@babel/types" "^7.20.0" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.13", "@babel/types@^7.13.14", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0": version "7.13.14" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.14.tgz#c35a4abb15c7cd45a2746d78ab328e362cbace0d" @@ -1474,6 +1664,15 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.19.4", "@babel/types@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.0.tgz#52c94cf8a7e24e89d2a194c25c35b17a64871479" + integrity sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -2117,6 +2316,18 @@ jest-util "^27.4.2" slash "^3.0.0" +"@jest/console@^29.2.1": + version "29.2.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.2.1.tgz#5f2c62dcdd5ce66e94b6d6729e021758bceea090" + integrity sha512-MF8Adcw+WPLZGBiNxn76DOuczG3BhODTcMlDCA4+cFi41OkaY/lyI0XUUhi73F88Y+7IHoGmD80pN5CtxQUdSw== + dependencies: + "@jest/types" "^29.2.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.2.1" + jest-util "^29.2.1" + slash "^3.0.0" + "@jest/core@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" @@ -2185,6 +2396,40 @@ slash "^3.0.0" strip-ansi "^6.0.0" +"@jest/core@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.2.2.tgz#207aa8973d9de8769f9518732bc5f781efc3ffa7" + integrity sha512-susVl8o2KYLcZhhkvSB+b7xX575CX3TmSvxfeDjpRko7KmT89rHkXj6XkDkNpSeFMBzIENw5qIchO9HC9Sem+A== + dependencies: + "@jest/console" "^29.2.1" + "@jest/reporters" "^29.2.2" + "@jest/test-result" "^29.2.1" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.2.0" + jest-config "^29.2.2" + jest-haste-map "^29.2.1" + jest-message-util "^29.2.1" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.2" + jest-resolve-dependencies "^29.2.2" + jest-runner "^29.2.2" + jest-runtime "^29.2.2" + jest-snapshot "^29.2.2" + jest-util "^29.2.1" + jest-validate "^29.2.2" + jest-watcher "^29.2.2" + micromatch "^4.0.4" + pretty-format "^29.2.1" + slash "^3.0.0" + strip-ansi "^6.0.0" + "@jest/environment@^24.3.0", "@jest/environment@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" @@ -2205,6 +2450,31 @@ "@types/node" "*" jest-mock "^27.4.6" +"@jest/environment@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.2.2.tgz#481e729048d42e87d04842c38aa4d09c507f53b0" + integrity sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A== + dependencies: + "@jest/fake-timers" "^29.2.2" + "@jest/types" "^29.2.1" + "@types/node" "*" + jest-mock "^29.2.2" + +"@jest/expect-utils@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.2.2.tgz#460a5b5a3caf84d4feb2668677393dd66ff98665" + integrity sha512-vwnVmrVhTmGgQzyvcpze08br91OL61t9O0lJMDyb6Y/D8EKQ9V7rGUb/p7PDt0GPzK0zFYqXWFo4EO2legXmkg== + dependencies: + jest-get-type "^29.2.0" + +"@jest/expect@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.2.2.tgz#81edbd33afbde7795ca07ff6b4753d15205032e4" + integrity sha512-zwblIZnrIVt8z/SiEeJ7Q9wKKuB+/GS4yZe9zw7gMqfGf4C5hBLGrVyxu1SzDbVSqyMSlprKl3WL1r80cBNkgg== + dependencies: + expect "^29.2.2" + jest-snapshot "^29.2.2" + "@jest/fake-timers@^24.3.0", "@jest/fake-timers@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" @@ -2226,6 +2496,18 @@ jest-mock "^27.4.6" jest-util "^27.4.2" +"@jest/fake-timers@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.2.2.tgz#d8332e6e3cfa99cde4bc87d04a17d6b699deb340" + integrity sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA== + dependencies: + "@jest/types" "^29.2.1" + "@sinonjs/fake-timers" "^9.1.2" + "@types/node" "*" + jest-message-util "^29.2.1" + jest-mock "^29.2.2" + jest-util "^29.2.1" + "@jest/globals@^27.4.6": version "27.4.6" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.4.6.tgz#3f09bed64b0fd7f5f996920258bd4be8f52f060a" @@ -2235,6 +2517,16 @@ "@jest/types" "^27.4.2" expect "^27.4.6" +"@jest/globals@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.2.2.tgz#205ff1e795aa774301c2c0ba0be182558471b845" + integrity sha512-/nt+5YMh65kYcfBhj38B3Hm0Trk4IsuMXNDGKE/swp36yydBWfz3OXkLqkSvoAtPW8IJMSJDFCbTM2oj5SNprw== + dependencies: + "@jest/environment" "^29.2.2" + "@jest/expect" "^29.2.2" + "@jest/types" "^29.2.1" + jest-mock "^29.2.2" + "@jest/reporters@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" @@ -2293,6 +2585,43 @@ terminal-link "^2.0.0" v8-to-istanbul "^8.1.0" +"@jest/reporters@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.2.2.tgz#69b395f79c3a97ce969ce05ccf1a482e5d6de290" + integrity sha512-AzjL2rl2zJC0njIzcooBvjA4sJjvdoq98sDuuNs4aNugtLPSQ+91nysGKRF0uY1to5k0MdGMdOBggUsPqvBcpA== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.2.1" + "@jest/test-result" "^29.2.1" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" + "@jridgewell/trace-mapping" "^0.3.15" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.2.1" + jest-util "^29.2.1" + jest-worker "^29.2.1" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.0.0": + version "29.0.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" + integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== + dependencies: + "@sinclair/typebox" "^0.24.1" + "@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" @@ -2311,6 +2640,15 @@ graceful-fs "^4.2.4" source-map "^0.6.0" +"@jest/source-map@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" + integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.15" + callsites "^3.0.0" + graceful-fs "^4.2.9" + "@jest/test-result@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" @@ -2330,6 +2668,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^29.2.1": + version "29.2.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.2.1.tgz#f42dbf7b9ae465d0a93eee6131473b8bb3bd2edb" + integrity sha512-lS4+H+VkhbX6z64tZP7PAUwPqhwj3kbuEHcaLuaBuB+riyaX7oa1txe0tXgrFj5hRWvZKvqO7LZDlNWeJ7VTPA== + dependencies: + "@jest/console" "^29.2.1" + "@jest/types" "^29.2.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" @@ -2350,6 +2698,16 @@ jest-haste-map "^27.4.6" jest-runtime "^27.4.6" +"@jest/test-sequencer@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.2.2.tgz#4ac7487b237e517a1f55e7866fb5553f6e0168b9" + integrity sha512-Cuc1znc1pl4v9REgmmLf0jBd3Y65UXJpioGYtMr/JNpQEIGEzkmHhy6W6DLbSsXeUA13TDzymPv0ZGZ9jH3eIw== + dependencies: + "@jest/test-result" "^29.2.1" + graceful-fs "^4.2.9" + jest-haste-map "^29.2.1" + slash "^3.0.0" + "@jest/transform@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" @@ -2414,6 +2772,27 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/transform@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.2.2.tgz#dfc03fc092b31ffea0c55917728e75bfcf8b5de6" + integrity sha512-aPe6rrletyuEIt2axxgdtxljmzH8O/nrov4byy6pDw9S8inIrTV+2PnjyP/oFHMSynzGxJ2s6OHowBNMXp/Jzg== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.2.1" + "@jridgewell/trace-mapping" "^0.3.15" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.2.1" + jest-regex-util "^29.2.0" + jest-util "^29.2.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.1" + "@jest/types@^24.3.0", "@jest/types@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" @@ -2455,6 +2834,58 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jest/types@^29.2.1": + version "29.2.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.2.1.tgz#ec9c683094d4eb754e41e2119d8bdaef01cf6da0" + integrity sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw== + dependencies: + "@jest/schemas" "^29.0.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@json-rpc-tools/provider@^1.5.5": version "1.7.6" resolved "https://registry.yarnpkg.com/@json-rpc-tools/provider/-/provider-1.7.6.tgz#8a17c34c493fa892632e278fd9331104e8491ec6" @@ -3590,6 +4021,11 @@ resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25" integrity sha512-DetpxZw1fzPD5xUBrIAoplLChO2VB8DlL5Gg+I1IR9b2wPqYIca2WSUxL5g1vLeR4MsQq1NeWriXAVffV+U1Fw== +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -3616,6 +4052,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sinonjs/samsam@^5.3.1": version "5.3.1" resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f" @@ -4575,7 +5018,7 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/graceful-fs@^4.1.2": +"@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== @@ -4637,6 +5080,14 @@ resolved "https://registry.yarnpkg.com/@types/javascript-time-ago/-/javascript-time-ago-2.0.2.tgz#875569ced6fa170dea36e6b6efe3c9f498e3d553" integrity sha512-uBUXwIG8YzPuWw5c6yV5RGvskkNOxnR+9hctOv8cptyMlB0IgfzeqFo0jkK+Ich8zGchvWghOT3Ryqr3bZmH3A== +"@types/jest@29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.0.tgz#fa98e08b46ab119f1a74a9552c48c589f5378a96" + integrity sha512-KO7bPV21d65PKwv3LLsD8Jn3E05pjNjRZvkm+YTacWhVmykAb07wW6IkZUmQAltwQafNcDUEUrMO2h3jeBSisg== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + "@types/jest@^24.0.0", "@types/jest@^24.9.1": version "24.9.1" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.9.1.tgz#02baf9573c78f1b9974a5f36778b366aa77bd534" @@ -4894,6 +5345,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^17.0.8": + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76" + integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg== + dependencies: + "@types/yargs-parser" "*" + "@types/zrender@*": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/zrender/-/zrender-4.0.0.tgz#a6806f12ec4eccaaebd9b0d816f049aca6188fbd" @@ -6416,6 +6874,19 @@ babel-jest@^27.4.6: graceful-fs "^4.2.4" slash "^3.0.0" +babel-jest@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.2.2.tgz#2c15abd8c2081293c9c3f4f80a4ed1d51542fee5" + integrity sha512-kkq2QSDIuvpgfoac3WZ1OOcHsQQDU5xYk2Ql7tLdJ8BVAYbefEXal+NfS45Y5LVZA7cxC8KYcQMObpCt1J025w== + dependencies: + "@jest/transform" "^29.2.2" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.2.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + babel-loader@8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" @@ -6496,6 +6967,16 @@ babel-plugin-jest-hoist@^27.4.0: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz#23ee99c37390a98cfddf3ef4a78674180d823094" + integrity sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + babel-plugin-macros@2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" @@ -6877,6 +7358,14 @@ babel-preset-jest@^27.4.0: babel-plugin-jest-hoist "^27.4.0" babel-preset-current-node-syntax "^1.0.0" +babel-preset-jest@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz#3048bea3a1af222e3505e4a767a974c95a7620dc" + integrity sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA== + dependencies: + babel-plugin-jest-hoist "^29.2.0" + babel-preset-current-node-syntax "^1.0.0" + babel-preset-react-app@^9.1.2: version "9.1.2" resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz#54775d976588a8a6d1a99201a702befecaf48030" @@ -7318,6 +7807,16 @@ browserslist@^4.17.5: node-releases "^2.0.1" picocolors "^1.0.0" +browserslist@^4.21.3: + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -7677,6 +8176,11 @@ caniuse-lite@^1.0.30001286: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001299.tgz#d753bf6444ed401eb503cbbe17aa3e1451b5a68c" integrity sha512-iujN4+x7QzqA2NCSrS5VUy+4gLmRd4xv6vbBBsmfVqTx8bLAD8097euLqQgKxSVLvxjSDcvF1T/i9ocgnUFexw== +caniuse-lite@^1.0.30001400: + version "1.0.30001427" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz#d3a749f74be7ae0671fbec3a4eea18576e8ad646" + integrity sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -7974,6 +8478,15 @@ 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-deep@^0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6" @@ -9547,6 +10060,11 @@ diff-sequences@^27.4.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== +diff-sequences@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.2.0.tgz#4c55b5b40706c7b5d2c5c75999a50c56d214e8f6" + integrity sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw== + diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" @@ -9904,6 +10422,11 @@ electron-to-chromium@^1.4.17: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.45.tgz#cf1144091d6683cbd45a231954a745f02fb24598" integrity sha512-czF9eYVuOmlY/vxyMQz2rGlNSjZpxNQYBe1gmQv7al171qOIhgyO9k7D5AKlgeTCSPKk+LHhj5ZyIdmEub9oNg== +electron-to-chromium@^1.4.251: + version "1.4.284" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== + elliptic@6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" @@ -9948,6 +10471,11 @@ email-addresses@^3.0.1: resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-3.1.0.tgz#cabf7e085cbdb63008a70319a74e6136188812fb" integrity sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg== +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + emittery@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" @@ -11191,6 +11719,17 @@ expect@^27.4.6: jest-matcher-utils "^27.4.6" jest-message-util "^27.4.6" +expect@^29.0.0, expect@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.2.2.tgz#ba2dd0d7e818727710324a6e7f13dd0e6d086106" + integrity sha512-hE09QerxZ5wXiOhqkXy5d2G9ar+EqOyifnCXCpMNu+vZ6DG9TJ6CO2c2kPDSLqERTTWrO7OZj8EkYHQqSd78Yw== + dependencies: + "@jest/expect-utils" "^29.2.2" + jest-get-type "^29.2.0" + jest-matcher-utils "^29.2.2" + jest-message-util "^29.2.1" + jest-util "^29.2.1" + express@^4.14.0, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -11328,7 +11867,7 @@ fast-glob@^3.1.1: micromatch "^4.0.2" picomatch "^2.2.1" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -12287,6 +12826,11 @@ graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -13796,6 +14340,14 @@ jest-changed-files@^27.4.2: execa "^5.0.0" throat "^6.0.1" +jest-changed-files@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.2.0.tgz#b6598daa9803ea6a4dce7968e20ab380ddbee289" + integrity sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + jest-circus@^27.4.6: version "27.4.6" resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.4.6.tgz#d3af34c0eb742a967b1919fbb351430727bcea6c" @@ -13821,6 +14373,31 @@ jest-circus@^27.4.6: stack-utils "^2.0.3" throat "^6.0.1" +jest-circus@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.2.2.tgz#1dc4d35fd49bf5e64d3cc505fb2db396237a6dfa" + integrity sha512-upSdWxx+Mh4DV7oueuZndJ1NVdgtTsqM4YgywHEx05UMH5nxxA2Qu9T9T9XVuR021XxqSoaKvSmmpAbjwwwxMw== + dependencies: + "@jest/environment" "^29.2.2" + "@jest/expect" "^29.2.2" + "@jest/test-result" "^29.2.1" + "@jest/types" "^29.2.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^29.2.1" + jest-matcher-utils "^29.2.2" + jest-message-util "^29.2.1" + jest-runtime "^29.2.2" + jest-snapshot "^29.2.2" + jest-util "^29.2.1" + p-limit "^3.1.0" + pretty-format "^29.2.1" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-cli@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" @@ -13858,6 +14435,24 @@ jest-cli@^27.4.7: prompts "^2.0.1" yargs "^16.2.0" +jest-cli@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.2.2.tgz#feaf0aa57d327e80d4f2f18d5f8cd2e77cac5371" + integrity sha512-R45ygnnb2CQOfd8rTPFR+/fls0d+1zXS6JPYTBBrnLPrhr58SSuPTiA5Tplv8/PXpz4zXR/AYNxmwIj6J6nrvg== + dependencies: + "@jest/core" "^29.2.2" + "@jest/test-result" "^29.2.1" + "@jest/types" "^29.2.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^29.2.2" + jest-util "^29.2.1" + jest-validate "^29.2.2" + prompts "^2.0.1" + yargs "^17.3.1" + jest-config@24.9.0, jest-config@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" @@ -13909,6 +14504,34 @@ jest-config@^27.4.7: pretty-format "^27.4.6" slash "^3.0.0" +jest-config@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.2.2.tgz#bf98623a46454d644630c1f0de8bba3f495c2d59" + integrity sha512-Q0JX54a5g1lP63keRfKR8EuC7n7wwny2HoTRDb8cx78IwQOiaYUVZAdjViY3WcTxpR02rPUpvNVmZ1fkIlZPcw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.2.2" + "@jest/types" "^29.2.1" + babel-jest "^29.2.2" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.2.2" + jest-environment-node "^29.2.2" + jest-get-type "^29.2.0" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.2" + jest-runner "^29.2.2" + jest-util "^29.2.1" + jest-validate "^29.2.2" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.2.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + jest-diff@^24.0.0, jest-diff@^24.3.0, jest-diff@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" @@ -13929,6 +14552,16 @@ jest-diff@^27.4.6: jest-get-type "^27.4.0" pretty-format "^27.4.6" +jest-diff@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.2.1.tgz#027e42f5a18b693fb2e88f81b0ccab533c08faee" + integrity sha512-gfh/SMNlQmP3MOUgdzxPOd4XETDJifADpT937fN1iUGz+9DgOu2eUPHH25JDkLVcLwwqxv3GzVyK4VBUr9fjfA== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.2.0" + jest-get-type "^29.2.0" + pretty-format "^29.2.1" + jest-docblock@^24.3.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" @@ -13943,6 +14576,13 @@ jest-docblock@^27.4.0: dependencies: detect-newline "^3.0.0" +jest-docblock@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" + integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== + dependencies: + detect-newline "^3.0.0" + jest-each@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" @@ -13965,6 +14605,17 @@ jest-each@^27.4.6: jest-util "^27.4.2" pretty-format "^27.4.6" +jest-each@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.2.1.tgz#6b0a88ee85c2ba27b571a6010c2e0c674f5c9b29" + integrity sha512-sGP86H/CpWHMyK3qGIGFCgP6mt+o5tu9qG4+tobl0LNdgny0aitLXs9/EBacLy3Bwqy+v4uXClqJgASJWcruYw== + dependencies: + "@jest/types" "^29.2.1" + chalk "^4.0.0" + jest-get-type "^29.2.0" + jest-util "^29.2.1" + pretty-format "^29.2.1" + jest-environment-jsdom-fourteen@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz#4cd0042f58b4ab666950d96532ecb2fc188f96fb" @@ -14025,6 +14676,18 @@ jest-environment-node@^27.4.6: jest-mock "^27.4.6" jest-util "^27.4.2" +jest-environment-node@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.2.2.tgz#a64b272773870c3a947cd338c25fd34938390bc2" + integrity sha512-B7qDxQjkIakQf+YyrqV5dICNs7tlCO55WJ4OMSXsqz1lpI/0PmeuXdx2F7eU8rnPbRkUR/fItSSUh0jvE2y/tw== + dependencies: + "@jest/environment" "^29.2.2" + "@jest/fake-timers" "^29.2.2" + "@jest/types" "^29.2.1" + "@types/node" "*" + jest-mock "^29.2.2" + jest-util "^29.2.1" + jest-get-type@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" @@ -14035,6 +14698,11 @@ jest-get-type@^27.4.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== +jest-get-type@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" + integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== + jest-haste-map@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" @@ -14095,6 +14763,25 @@ jest-haste-map@^27.4.6: optionalDependencies: fsevents "^2.3.2" +jest-haste-map@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.2.1.tgz#f803fec57f8075e6c55fb5cd551f99a72471c699" + integrity sha512-wF460rAFmYc6ARcCFNw4MbGYQjYkvjovb9GBT+W10Um8q5nHq98jD6fHZMDMO3tA56S8XnmNkM8GcA8diSZfnA== + dependencies: + "@jest/types" "^29.2.1" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.2.0" + jest-util "^29.2.1" + jest-worker "^29.2.1" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + jest-jasmine2@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" @@ -14156,6 +14843,14 @@ jest-leak-detector@^27.4.6: jest-get-type "^27.4.0" pretty-format "^27.4.6" +jest-leak-detector@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.2.1.tgz#ec551686b7d512ec875616c2c3534298b1ffe2fc" + integrity sha512-1YvSqYoiurxKOJtySc+CGVmw/e1v4yNY27BjWTVzp0aTduQeA7pdieLiW05wTYG/twlKOp2xS/pWuikQEmklug== + dependencies: + jest-get-type "^29.2.0" + pretty-format "^29.2.1" + jest-matcher-utils@^24.0.0, jest-matcher-utils@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" @@ -14176,6 +14871,16 @@ jest-matcher-utils@^27.4.6: jest-get-type "^27.4.0" pretty-format "^27.4.6" +jest-matcher-utils@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.2.2.tgz#9202f8e8d3a54733266784ce7763e9a08688269c" + integrity sha512-4DkJ1sDPT+UX2MR7Y3od6KtvRi9Im1ZGLGgdLFLm4lPexbTaCgJW5NN3IOXlQHF7NSHY/VHhflQ+WoKtD/vyCw== + dependencies: + chalk "^4.0.0" + jest-diff "^29.2.1" + jest-get-type "^29.2.0" + pretty-format "^29.2.1" + jest-message-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" @@ -14205,6 +14910,21 @@ jest-message-util@^27.4.6: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.2.1.tgz#3a51357fbbe0cc34236f17a90d772746cf8d9193" + integrity sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.2.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.2.1" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^24.0.0, jest-mock@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" @@ -14220,6 +14940,15 @@ jest-mock@^27.4.6: "@jest/types" "^27.4.2" "@types/node" "*" +jest-mock@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.2.2.tgz#9045618b3f9d27074bbcf2d55bdca6a5e2e8bca7" + integrity sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ== + dependencies: + "@jest/types" "^29.2.1" + "@types/node" "*" + jest-util "^29.2.1" + jest-pnp-resolver@^1.2.1, jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" @@ -14240,6 +14969,11 @@ jest-regex-util@^27.4.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== +jest-regex-util@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" + integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== + jest-resolve-dependencies@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" @@ -14258,6 +14992,14 @@ jest-resolve-dependencies@^27.4.6: jest-regex-util "^27.4.0" jest-snapshot "^27.4.6" +jest-resolve-dependencies@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.2.2.tgz#1f444766f37a25f1490b5137408b6ff746a05d64" + integrity sha512-wWOmgbkbIC2NmFsq8Lb+3EkHuW5oZfctffTGvwsA4JcJ1IRk8b2tg+hz44f0lngvRTeHvp3Kyix9ACgudHH9aQ== + dependencies: + jest-regex-util "^29.2.0" + jest-snapshot "^29.2.2" + jest-resolve@24.9.0, jest-resolve@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" @@ -14285,6 +15027,21 @@ jest-resolve@^27.4.6: resolve.exports "^1.1.0" slash "^3.0.0" +jest-resolve@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.2.2.tgz#ad6436053b0638b41e12bbddde2b66e1397b35b5" + integrity sha512-3gaLpiC3kr14rJR3w7vWh0CBX2QAhfpfiQTwrFPvVrcHe5VUBtIXaR004aWE/X9B2CFrITOQAp5gxLONGrk6GA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.2.1" + jest-pnp-resolver "^1.2.2" + jest-util "^29.2.1" + jest-validate "^29.2.2" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + jest-runner@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" @@ -14338,6 +15095,33 @@ jest-runner@^27.4.6: source-map-support "^0.5.6" throat "^6.0.1" +jest-runner@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.2.2.tgz#6b5302ed15eba8bf05e6b14d40f1e8d469564da3" + integrity sha512-1CpUxXDrbsfy9Hr9/1zCUUhT813kGGK//58HeIw/t8fa/DmkecEwZSWlb1N/xDKXg3uCFHQp1GCvlSClfImMxg== + dependencies: + "@jest/console" "^29.2.1" + "@jest/environment" "^29.2.2" + "@jest/test-result" "^29.2.1" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.2.0" + jest-environment-node "^29.2.2" + jest-haste-map "^29.2.1" + jest-leak-detector "^29.2.1" + jest-message-util "^29.2.1" + jest-resolve "^29.2.2" + jest-runtime "^29.2.2" + jest-util "^29.2.1" + jest-watcher "^29.2.2" + jest-worker "^29.2.1" + p-limit "^3.1.0" + source-map-support "0.5.13" + jest-runtime@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" @@ -14395,6 +15179,34 @@ jest-runtime@^27.4.6: slash "^3.0.0" strip-bom "^4.0.0" +jest-runtime@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.2.2.tgz#4068ee82423769a481460efd21d45a8efaa5c179" + integrity sha512-TpR1V6zRdLynckKDIQaY41od4o0xWL+KOPUCZvJK2bu5P1UXhjobt5nJ2ICNeIxgyj9NGkO0aWgDqYPVhDNKjA== + dependencies: + "@jest/environment" "^29.2.2" + "@jest/fake-timers" "^29.2.2" + "@jest/globals" "^29.2.2" + "@jest/source-map" "^29.2.0" + "@jest/test-result" "^29.2.1" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.2.1" + jest-message-util "^29.2.1" + jest-mock "^29.2.2" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.2" + jest-snapshot "^29.2.2" + jest-util "^29.2.1" + slash "^3.0.0" + strip-bom "^4.0.0" + jest-serializer@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" @@ -14463,6 +15275,36 @@ jest-snapshot@^27.4.6: pretty-format "^27.4.6" semver "^7.3.2" +jest-snapshot@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.2.2.tgz#1016ce60297b77382386bad561107174604690c2" + integrity sha512-GfKJrpZ5SMqhli3NJ+mOspDqtZfJBryGA8RIBxF+G+WbDoC7HCqKaeAss4Z/Sab6bAW11ffasx8/vGsj83jyjA== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.2.2" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.2.2" + graceful-fs "^4.2.9" + jest-diff "^29.2.1" + jest-get-type "^29.2.0" + jest-haste-map "^29.2.1" + jest-matcher-utils "^29.2.2" + jest-message-util "^29.2.1" + jest-util "^29.2.1" + natural-compare "^1.4.0" + pretty-format "^29.2.1" + semver "^7.3.5" + jest-util@^24.0.0, jest-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" @@ -14505,6 +15347,18 @@ jest-util@^27.4.2: graceful-fs "^4.2.4" picomatch "^2.2.3" +jest-util@^29.0.0, jest-util@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.2.1.tgz#f26872ba0dc8cbefaba32c34f98935f6cf5fc747" + integrity sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g== + dependencies: + "@jest/types" "^29.2.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" @@ -14529,6 +15383,18 @@ jest-validate@^27.4.6: leven "^3.1.0" pretty-format "^27.4.6" +jest-validate@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.2.2.tgz#e43ce1931292dfc052562a11bc681af3805eadce" + integrity sha512-eJXATaKaSnOuxNfs8CLHgdABFgUrd0TtWS8QckiJ4L/QVDF4KVbZFBBOwCBZHOS0Rc5fOxqngXeGXE3nGQkpQA== + dependencies: + "@jest/types" "^29.2.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.2.0" + leven "^3.1.0" + pretty-format "^29.2.1" + jest-watch-typeahead@0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz#e5be959698a7fa2302229a5082c488c3c8780a4a" @@ -14568,6 +15434,20 @@ jest-watcher@^27.4.6: jest-util "^27.4.2" string-length "^4.0.1" +jest-watcher@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.2.2.tgz#7093d4ea8177e0a0da87681a9e7b09a258b9daf7" + integrity sha512-j2otfqh7mOvMgN2WlJ0n7gIx9XCMWntheYGlBK7+5g3b1Su13/UAK7pdKGyd4kDlrLwtH2QPvRv5oNIxWvsJ1w== + dependencies: + "@jest/test-result" "^29.2.1" + "@jest/types" "^29.2.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.2.1" + string-length "^4.0.1" + jest-worker@^24.6.0, jest-worker@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" @@ -14602,6 +15482,16 @@ jest-worker@^27.4.6: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.2.1.tgz#8ba68255438252e1674f990f0180c54dfa26a3b1" + integrity sha512-ROHTZ+oj7sBrgtv46zZ84uWky71AoYi0vEV9CdEtc1FQunsoAGe5HbQmW76nI5QWdvECVPrSi1MCVUmizSavMg== + dependencies: + "@types/node" "*" + jest-util "^29.2.1" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest@24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" @@ -14619,6 +15509,16 @@ jest@^27.4.7: import-local "^3.0.2" jest-cli "^27.4.7" +jest@^29.2.0: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.2.2.tgz#24da83cbbce514718acd698926b7679109630476" + integrity sha512-r+0zCN9kUqoON6IjDdjbrsWobXM/09Nd45kIPRD8kloaRh1z5ZCMdVsgLXGxmlL7UpAJsvCYOQNO+NjvG/gqiQ== + dependencies: + "@jest/core" "^29.2.2" + "@jest/types" "^29.2.1" + import-local "^3.0.2" + jest-cli "^29.2.2" + js-sha256@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" @@ -14917,6 +15817,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -15689,6 +16594,13 @@ make-fetch-happen@^5.0.0: socks-proxy-agent "^4.0.0" ssri "^6.0.0" +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -16567,6 +17479,11 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + nopt@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" @@ -17085,7 +18002,7 @@ p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.3.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.1, p-limit@^3.0.2: +p-limit@^3.0.1, p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -17276,7 +18193,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -18374,6 +19291,15 @@ pretty-format@^27.4.6: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^29.0.0, pretty-format@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.2.1.tgz#86e7748fe8bbc96a6a4e04fa99172630907a9611" + integrity sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA== + dependencies: + "@jest/schemas" "^29.0.0" + ansi-styles "^5.0.0" + react-is "^18.0.0" + private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -19170,6 +20096,11 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + react-layout-effect@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/react-layout-effect/-/react-layout-effect-1.0.5.tgz#0dc4e24452aee5de66c93c166f0ec512dfb1be80" @@ -20296,6 +21227,13 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@7.x: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -20507,6 +21445,11 @@ signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== +signal-exit@^3.0.7: + 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== + simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -20707,6 +21650,14 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-support@^0.4.15: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" @@ -21065,6 +22016,15 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string-width@^4.2.3: + 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== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string.prototype.matchall@^4.0.2: version "4.0.4" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz#608f255e93e072107f5de066f81a2dfb78cf6b29" @@ -21168,6 +22128,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -21229,7 +22196,7 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@3.1.1, strip-json-comments@^3.0.1: +strip-json-comments@3.1.1, strip-json-comments@^3.0.1, 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== @@ -21656,6 +22623,11 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -21851,6 +22823,20 @@ ts-generator@^0.1.1: resolve "^1.8.1" ts-essentials "^1.0.0" +ts-jest@29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.0.3.tgz#63ea93c5401ab73595440733cefdba31fcf9cb77" + integrity sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.1" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "^21.0.1" + ts-jest@^24.0.0: version "24.3.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" @@ -22223,6 +23209,14 @@ upath@^1.1.1, upath@^1.2.0: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== +update-browserslist-db@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -22464,6 +23458,15 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" +v8-to-istanbul@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -22566,6 +23569,13 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + walletlink@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/walletlink/-/walletlink-2.0.3.tgz#8905deed6ba9a07d5dd49d709db359df571b0cc4" @@ -23442,6 +24452,14 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +write-file-atomic@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + write-json-file@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" @@ -23670,6 +24688,11 @@ yargs-parser@^20.2.2, yargs-parser@^20.2.3: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== +yargs-parser@^21.0.0, yargs-parser@^21.0.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" @@ -23726,6 +24749,19 @@ yargs@^14.2.2: y18n "^4.0.0" yargs-parser "^15.0.1" +yargs@^17.3.1: + version "17.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.0.tgz#e134900fc1f218bc230192bdec06a0a5f973e46c" + integrity sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g== + 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.0.0" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" From 9f269c97db6c3f4d18e86f04078ba9a660549651 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 12 Dec 2022 10:17:45 +0000 Subject: [PATCH 64/88] Governance: sdk v3 1 (#567) * feat: coolOffTime, proposal seed, proposal deposit * fix: Update activeProposalCount * fix: Update errors * fix: Rename maxVotingTime to baseVotingTime * chore: Update votingProposalCount comments * feat: Add version to TokenOwnerRecord * chore: Update package version * fix: Fix proposal creation for V2 * fix: Rename baseVotingTime to maxVotingTime * fix: Add all V2 Program accounts * fix: Update errors --- packages/governance-sdk/package.json | 4 +- .../governance-sdk/src/governance/accounts.ts | 51 ++++++++++++++++--- .../governance-sdk/src/governance/errors.ts | 16 ++++-- .../src/governance/instructions.ts | 5 ++ .../src/governance/serialisation.ts | 23 ++++++--- .../src/governance/withCreateProposal.ts | 42 +++++++++++++-- .../tests/governance/api.v2.test.ts | 2 + .../tests/governance/api.v2.v3.test.ts | 12 ++--- .../tests/governance/api.v3.test.ts | 34 ++++++++++++- .../governance-sdk/tests/tools/builders.ts | 2 + 10 files changed, 159 insertions(+), 32 deletions(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 4db74417..c2bb9e00 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.17", + "version": "0.3.18", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", @@ -59,4 +59,4 @@ "node" ] } -} +} \ No newline at end of file diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 0587abbb..3f94d331 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -105,10 +105,16 @@ export function getGovernanceAccountVersion( accountType: GovernanceAccountType, ) { switch (accountType) { - case GovernanceAccountType.GovernanceV2: case GovernanceAccountType.VoteRecordV2: case GovernanceAccountType.ProposalTransactionV2: case GovernanceAccountType.ProposalV2: + case GovernanceAccountType.RealmV2: + case GovernanceAccountType.TokenOwnerRecordV2: + case GovernanceAccountType.GovernanceV2: + case GovernanceAccountType.ProgramGovernanceV2: + case GovernanceAccountType.MintGovernanceV2: + case GovernanceAccountType.TokenGovernanceV2: + case GovernanceAccountType.SignatoryRecordV2: return ACCOUNT_VERSION_V2; default: return ACCOUNT_VERSION_V1; @@ -342,6 +348,7 @@ export class Realm { reserved: Uint8Array; + // Not used in versions >= V3 / legacy1 votingProposalCount: number; authority: PublicKey | undefined; @@ -449,8 +456,8 @@ export class GovernanceConfig { councilVetoVoteThreshold: VoteThreshold; communityVetoVoteThreshold: VoteThreshold; councilVoteTipping: VoteTipping; - - reserved?: Uint8Array; + votingCoolOffTime: number; + depositExemptProposalCount: number; constructor(args: { communityVoteThreshold: VoteThreshold; @@ -466,7 +473,8 @@ export class GovernanceConfig { councilVetoVoteThreshold: VoteThreshold; communityVetoVoteThreshold: VoteThreshold; councilVoteTipping: VoteTipping; - reserved?: Uint8Array; + votingCoolOffTime: number; + depositExemptProposalCount: number; }) { this.communityVoteThreshold = args.communityVoteThreshold; this.minCommunityTokensToCreateProposal = @@ -490,7 +498,8 @@ export class GovernanceConfig { this.councilVoteTipping = args.councilVoteTipping ?? this.communityVoteTipping; - this.reserved = args.reserved ?? new Uint8Array(3); + this.votingCoolOffTime = args.votingCoolOffTime; + this.depositExemptProposalCount = args.depositExemptProposalCount; } } @@ -499,9 +508,12 @@ export class Governance { realm: PublicKey; governedAccount: PublicKey; config: GovernanceConfig; + // proposalCount is not used for >= V3 proposalCount: number; reserved?: Uint8Array; - votingProposalCount: number; + + // V3 + activeProposalCount: BN; constructor(args: { realm: PublicKey; @@ -510,7 +522,7 @@ export class Governance { config: GovernanceConfig; reserved?: Uint8Array; proposalCount: number; - votingProposalCount: number; + activeProposalCount: BN; }) { this.accountType = args.accountType; this.realm = args.realm; @@ -518,7 +530,7 @@ export class Governance { this.config = args.config; this.reserved = args.reserved; this.proposalCount = args.proposalCount; - this.votingProposalCount = args.votingProposalCount; + this.activeProposalCount = args.activeProposalCount; } isProgramGovernance() { @@ -563,6 +575,7 @@ export class TokenOwnerRecord { unrelinquishedVotesCount: number; + // Not used in versions >= V3 / I'ts the upper 4 bytes of unrelinquishedVotesCount totalVotesCount: number; outstandingProposalCount: number; @@ -571,6 +584,9 @@ export class TokenOwnerRecord { governanceDelegate?: PublicKey; + // V3 + version: number; + constructor(args: { realm: PublicKey; governingTokenMint: PublicKey; @@ -581,6 +597,7 @@ export class TokenOwnerRecord { outstandingProposalCount: number; reserved: Uint8Array; governanceDelegate: PublicKey | undefined; + version: number; }) { this.realm = args.realm; this.governingTokenMint = args.governingTokenMint; @@ -591,6 +608,7 @@ export class TokenOwnerRecord { this.outstandingProposalCount = args.outstandingProposalCount; this.reserved = args.reserved; this.governanceDelegate = args.governanceDelegate; + this.version = args.version; } } @@ -1296,3 +1314,20 @@ export async function getGoverningTokenHoldingAddress( return governingTokenHoldingAddress; } + +export async function getProposalDepositAddress( + programId: PublicKey, + proposal: PublicKey, + proposalDepositPayer: PublicKey, +) { + const [proposalDepositAddress] = await PublicKey.findProgramAddress( + [ + Buffer.from('proposal-deposit'), + proposal.toBuffer(), + proposalDepositPayer.toBuffer(), + ], + programId, + ); + + return proposalDepositAddress; +} diff --git a/packages/governance-sdk/src/governance/errors.ts b/packages/governance-sdk/src/governance/errors.ts index d221bcf2..f1e28b5e 100644 --- a/packages/governance-sdk/src/governance/errors.ts +++ b/packages/governance-sdk/src/governance/errors.ts @@ -61,7 +61,7 @@ export const GovernanceError = [ 'Current token owner must sign transaction', // TokenOwnerMustSign 'Given VoteThresholdType is not supported', //VoteThresholdTypeNotSupported 'Given VoteWeightSource is not supported', //VoteWeightSourceNotSupported - 'GoverningTokenMint not allowed to vote', // GoverningTokenMintNotAllowedToVote + 'Legacy1', // Legacy1 'Governance PDA must sign', // GovernancePdaMustSign 'Instruction already flagged with error', // InstructionAlreadyFlaggedWithError 'Invalid Realm for Governance', // InvalidRealmForGovernance @@ -107,7 +107,16 @@ export const GovernanceError = [ 'Cannot revoke GoverningTokens', // CannotRevokeGoverningTokens 'Invalid Revoke amount', // InvalidRevokeAmount 'Invalid GoverningToken source', // InvalidGoverningTokenSource - 'Cannot change community TokenType to Memebership', // CannotChangeCommunityTokenTypeToMemebership + 'Cannot change community TokenType to Membership', // CannotChangeCommunityTokenTypeToMembership + + 'Voter weight threshold disabled', // VoterWeightThresholdDisabled + 'Vote not allowed in cool off time', // VoteNotAllowedInCoolOffTime + 'Cannot refund ProposalDeposit', // CannotRefundProposalDeposit + + 'Invalid Proposal for ProposalDeposit', // InvalidProposalForProposalDeposit + 'Invalid deposit_exempt_proposal_count', // InvalidDepositExemptProposalCount + 'Invalid GoverningTokenMint not allowed to vote', // GoverningTokenMintNotAllowedToVote + 'Invalid deposit Payer for ProposalDeposit', // InvalidDepositPayerForProposalDeposit ] as const; export const TokenError = [ @@ -136,7 +145,8 @@ export const GovernanceToolsError = [ 'Account already initialized', // AccountAlreadyInitialized "Account doesn't exist", // AccountDoesNotExist 'Invalid account owner', // InvalidAccountOwner - 'Invalid Account type', // InvalidAccountType + 'Invalid account type', // InvalidAccountType + 'Invalid new account size', // InvalidNewAccountSize ] as const; const governanceErrorOffset = 500; diff --git a/packages/governance-sdk/src/governance/instructions.ts b/packages/governance-sdk/src/governance/instructions.ts index 845b1f92..ed1e8575 100644 --- a/packages/governance-sdk/src/governance/instructions.ts +++ b/packages/governance-sdk/src/governance/instructions.ts @@ -143,6 +143,9 @@ export class CreateProposalArgs { useDenyOption: boolean; // -------------------------------- + // V3 ----------------------------- + proposalSeed: PublicKey; + constructor(args: { name: string; descriptionLink: string; @@ -150,6 +153,7 @@ export class CreateProposalArgs { voteType: VoteType; options: string[]; useDenyOption: boolean; + proposalSeed: PublicKey; }) { this.name = args.name; this.descriptionLink = args.descriptionLink; @@ -157,6 +161,7 @@ export class CreateProposalArgs { this.voteType = args.voteType; this.options = args.options; this.useDenyOption = args.useDenyOption; + this.proposalSeed = args.proposalSeed; } } diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 48f01f9a..d9da03a4 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -339,14 +339,15 @@ function createGovernanceStructSchema( ['minCouncilTokensToCreateProposal', 'u64'], // Pass the extra fields to instruction if programVersion >= 3 // The additional fields can't be passed to instructions for programVersion <= 2 because they were added in V3 - // and would override the transferAuhtority param which follows it + // and would override the transferAuthority param which follows it ...((programVersion && programVersion >= PROGRAM_VERSION_V3) || // The account layout is backward compatible and we can read the extra fields for accountVersion >= 2 (accountVersion && accountVersion >= ACCOUNT_VERSION_V2) ? [ ['councilVoteTipping', 'u8'], ['communityVetoVoteThreshold', 'VoteThreshold'], - ['reserved', [3]], + ['votingCoolOffTime', 'u32'], + ['depositExemptProposalCount', 'u8'], ] : []), ], @@ -510,7 +511,11 @@ function createGovernanceInstructionSchema(programVersion: number) { ['options', ['string']], ['useDenyOption', 'u8'], ]), - ], + + programVersion >= PROGRAM_VERSION_V3 + ? ['proposalSeed', 'pubkey'] + : undefined, + ].filter(Boolean), }, ], [ @@ -733,8 +738,12 @@ function createGovernanceAccountSchema(accountVersion: number) { ['governedAccount', 'pubkey'], ['proposalCount', 'u32'], ['config', GovernanceConfig], - ...(accountVersion >= ACCOUNT_VERSION_V2 ? [] : [['reserved', [6]]]), - ['votingProposalCount', 'u16'], + ...(accountVersion >= ACCOUNT_VERSION_V2 + ? [ + ['reserved', [120]], + ['activeProposalCount', 'u64'], + ] + : []), ], }, ], @@ -748,10 +757,12 @@ function createGovernanceAccountSchema(accountVersion: number) { ['governingTokenMint', 'pubkey'], ['governingTokenOwner', 'pubkey'], ['governingTokenDepositAmount', 'u64'], + // unrelinquishedVotesCount is u64 in V3 but for backward compatibility the sdk reads it as u32 ['unrelinquishedVotesCount', 'u32'], ['totalVotesCount', 'u32'], ['outstandingProposalCount', 'u8'], - ['reserved', [7]], + ['version', 'u8'], + ['reserved', [6]], ['governanceDelegate', { kind: 'option', type: 'pubkey' }], ], }, diff --git a/packages/governance-sdk/src/governance/withCreateProposal.ts b/packages/governance-sdk/src/governance/withCreateProposal.ts index ee367123..a9d0374e 100644 --- a/packages/governance-sdk/src/governance/withCreateProposal.ts +++ b/packages/governance-sdk/src/governance/withCreateProposal.ts @@ -1,4 +1,5 @@ import { + Keypair, PublicKey, SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY, @@ -8,11 +9,16 @@ import { getGovernanceInstructionSchema } from './serialisation'; import { serialize } from 'borsh'; import { CreateProposalArgs } from './instructions'; import { + getProposalDepositAddress, getRealmConfigAddress, GOVERNANCE_PROGRAM_SEED, VoteType, } from './accounts'; -import { PROGRAM_VERSION_V1 } from '../registry/constants'; +import { + PROGRAM_VERSION_V1, + PROGRAM_VERSION_V2, + PROGRAM_VERSION_V3, +} from '../registry/constants'; import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; @@ -27,13 +33,16 @@ export const withCreateProposal = async ( descriptionLink: string, governingTokenMint: PublicKey, governanceAuthority: PublicKey, - proposalIndex: number, + // Proposal index is not used from V3 + proposalIndex: number | undefined, voteType: VoteType, options: string[], useDenyOption: boolean, payer: PublicKey, voterWeightRecord?: PublicKey, ) => { + const proposalSeed = new Keypair().publicKey; + const args = new CreateProposalArgs({ name, descriptionLink, @@ -41,20 +50,30 @@ export const withCreateProposal = async ( voteType, options, useDenyOption, + proposalSeed, }); const data = Buffer.from( serialize(getGovernanceInstructionSchema(programVersion), args), ); - let proposalIndexBuffer = Buffer.alloc(4); - proposalIndexBuffer.writeInt32LE(proposalIndex, 0); + let proposalSeedBuffer = proposalSeed.toBuffer(); + + if (programVersion <= PROGRAM_VERSION_V2) { + if (proposalIndex === undefined) { + throw new Error( + `proposalIndex is required for version: ${programVersion}`, + ); + } + proposalSeedBuffer = Buffer.alloc(4); + proposalSeedBuffer.writeInt32LE(proposalIndex, 0); + } const [proposalAddress] = await PublicKey.findProgramAddress( [ Buffer.from(GOVERNANCE_PROGRAM_SEED), governance.toBuffer(), governingTokenMint.toBuffer(), - proposalIndexBuffer, + proposalSeedBuffer, ], programId, ); @@ -126,6 +145,19 @@ export const withCreateProposal = async ( voterWeightRecord, ); + if (programVersion >= PROGRAM_VERSION_V3) { + const proposalDepositAddress = await getProposalDepositAddress( + programId, + proposalAddress, + payer, + ); + keys.push({ + pubkey: proposalDepositAddress, + isWritable: true, + isSigner: false, + }); + } + instructions.push( new TransactionInstruction({ keys, diff --git a/packages/governance-sdk/tests/governance/api.v2.test.ts b/packages/governance-sdk/tests/governance/api.v2.test.ts index 9bcfebff..8e4981bf 100644 --- a/packages/governance-sdk/tests/governance/api.v2.test.ts +++ b/packages/governance-sdk/tests/governance/api.v2.test.ts @@ -40,6 +40,8 @@ test('createGovernanceWithConfig', async () => { type: VoteThresholdType.YesVotePercentage, value: 0, }), + votingCoolOffTime: 0, + depositExemptProposalCount: 0, }); // Act diff --git a/packages/governance-sdk/tests/governance/api.v2.v3.test.ts b/packages/governance-sdk/tests/governance/api.v2.v3.test.ts index a1642140..31c89458 100644 --- a/packages/governance-sdk/tests/governance/api.v2.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v2.v3.test.ts @@ -78,13 +78,10 @@ test('createGovernance', async () => { .then(b => b.withRealm()) .then(b => b.withCommunityMember()) .then(b => b.sendTx()); - // Act const governancePk = await realm.createGovernance(); - - // // Assert + // Assert const governance = await realm.getGovernance(governancePk); - expect(governance.account.realm).toEqual(realm.realmPk); }); @@ -114,9 +111,10 @@ test('castVote', async () => { .then(b => b.withRealm()) .then(b => b.withCommunityMember()) .then(b => b.withGovernance()) - .then(b => b.withProposal()) .then(b => b.sendTx()) - .then(b => b.withProposalSignOff()); + .then(b => b.withProposal()) + .then(b => b.withProposalSignOff()) + .then(b => b.sendTx()); // Act const voteRecordPk = await realm.castVote(); @@ -134,8 +132,8 @@ test('relinquishVote', async () => { .then(b => b.withRealm()) .then(b => b.withCommunityMember()) .then(b => b.withGovernance()) - .then(b => b.withProposal()) .then(b => b.sendTx()) + .then(b => b.withProposal()) .then(b => b.withProposalSignOff()) .then(b => b.withCastVote()) .then(b => b.sendTx()); diff --git a/packages/governance-sdk/tests/governance/api.v3.test.ts b/packages/governance-sdk/tests/governance/api.v3.test.ts index 9448747b..3f17fb9d 100644 --- a/packages/governance-sdk/tests/governance/api.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v3.test.ts @@ -62,7 +62,7 @@ test('createRealmWithTokenConfigs', async () => { ); }); -test('createGovernanceWithCouncilThresholds', async () => { +test('createGovernanceWithConfig', async () => { // Arrange const realm = await BenchBuilder.withConnection(PROGRAM_VERSION_V3) .then(b => b.withWallet()) @@ -93,6 +93,8 @@ test('createGovernanceWithCouncilThresholds', async () => { type: VoteThresholdType.YesVotePercentage, value: 80, }), + votingCoolOffTime: 5000, + depositExemptProposalCount: 10, }); // Act @@ -112,6 +114,14 @@ test('createGovernanceWithCouncilThresholds', async () => { expect(governance.account.config.councilVetoVoteThreshold).toEqual( config.councilVetoVoteThreshold, ); + + expect(governance.account.config.maxVotingTime).toEqual( + getTimestampFromDays(3), + ); + + expect(governance.account.config.votingCoolOffTime).toEqual(5000); + + expect(governance.account.config.depositExemptProposalCount).toEqual(10); }); test('setRealmConfigWithTokenConfigs', async () => { @@ -190,3 +200,25 @@ test('revokeGoverningToken', async () => { tokenOwnerRecord.account.governingTokenDepositAmount.toNumber(), ).toEqual(0); }); + +test('createProposal', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.withGovernance()) + .then(b => b.sendTx()); + + // Act + const proposalPk = await realm.createProposal('proposal 1'); + + // Assert + const proposal = await realm.getProposal(proposalPk); + + expect(proposal.account.name).toEqual('proposal 1'); + expect(proposal.account.vetoVoteWeight.toNumber()).toEqual(0); + + const governance = await realm.getGovernance(proposal.account.governance); + expect(governance.account.activeProposalCount.toNumber()).toEqual(1); +}); diff --git a/packages/governance-sdk/tests/tools/builders.ts b/packages/governance-sdk/tests/tools/builders.ts index abc91139..08974d2c 100644 --- a/packages/governance-sdk/tests/tools/builders.ts +++ b/packages/governance-sdk/tests/tools/builders.ts @@ -350,6 +350,8 @@ export class RealmBuilder { type: VoteThresholdType.YesVotePercentage, value: 80, }), + votingCoolOffTime: 0, + depositExemptProposalCount: 0, }); const governedAccountPk = Keypair.generate().publicKey; From b874111120397a4ad7c3c08798577f7a8cba46d7 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 2 Jan 2023 16:20:09 +0000 Subject: [PATCH 65/88] Governance: Add ProposalDeposit api (#569) --- .../governance-sdk/src/governance/accounts.ts | 17 ++++++++++++++- packages/governance-sdk/src/governance/api.ts | 20 ++++++++++++++++++ .../src/governance/serialisation.ts | 12 +++++++++++ .../tests/governance/api.v3.test.ts | 21 +++++++++++++++++++ .../governance-sdk/tests/tools/builders.ts | 9 ++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 3f94d331..9d97b226 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -35,6 +35,7 @@ export enum GovernanceAccountType { MintGovernanceV2 = 20, TokenGovernanceV2 = 21, SignatoryRecordV2 = 22, + ProposalDeposit = 23, } export interface GovernanceAccount { @@ -50,7 +51,8 @@ export type GovernanceAccountClass = | typeof VoteRecord | typeof ProposalTransaction | typeof RealmConfigAccount - | typeof ProgramMetadata; + | typeof ProgramMetadata + | typeof ProposalDeposit; export function getAccountTypes(accountClass: GovernanceAccountClass) { switch (accountClass) { @@ -66,6 +68,8 @@ export function getAccountTypes(accountClass: GovernanceAccountClass) { GovernanceAccountType.ProposalV1, GovernanceAccountType.ProposalV2, ]; + case ProposalDeposit: + return [GovernanceAccountType.ProposalDeposit]; case SignatoryRecord: return [ GovernanceAccountType.SignatoryRecordV1, @@ -983,6 +987,17 @@ export class Proposal { } } +export class ProposalDeposit { + accountType: GovernanceAccountType = GovernanceAccountType.ProposalDeposit; + proposal: PublicKey; + depositPayer: PublicKey; + + constructor(args: { proposal: PublicKey; depositPayer: PublicKey }) { + this.proposal = args.proposal; + this.depositPayer = args.depositPayer; + } +} + export class SignatoryRecord { accountType: GovernanceAccountType = GovernanceAccountType.SignatoryRecordV1; proposal: PublicKey; diff --git a/packages/governance-sdk/src/governance/api.ts b/packages/governance-sdk/src/governance/api.ts index 9d0004e4..a28b7782 100644 --- a/packages/governance-sdk/src/governance/api.ts +++ b/packages/governance-sdk/src/governance/api.ts @@ -16,6 +16,7 @@ import { VoteRecord, RealmConfigAccount, getRealmConfigAddress, + ProposalDeposit, } from './accounts'; import { @@ -299,6 +300,25 @@ export async function getAllProposals( ); } +// ProposalDeposit api + +/** + * Returns all ProposalDeposits for the given deposit payer + * @param connection + * @param programId + * @param depositPayer + * @returns + */ +export async function getProposalDepositsByDepositPayer( + connection: Connection, + programId: PublicKey, + depositPayer: PublicKey, +) { + return getGovernanceAccounts(connection, programId, ProposalDeposit, [ + pubkeyFilter(1 + 32, depositPayer)!, + ]); +} + // Generic API export async function getGovernanceAccounts( diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index d9da03a4..b155643f 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -59,6 +59,7 @@ import { VoteThresholdType, GoverningTokenConfigArgs, GoverningTokenConfig, + ProposalDeposit, } from './accounts'; import { serialize } from 'borsh'; import { BorshAccountParser } from '../core/serialisation'; @@ -840,6 +841,17 @@ function createGovernanceAccountSchema(accountVersion: number) { ], }, ], + [ + ProposalDeposit, + { + kind: 'struct', + fields: [ + ['accountType', 'u8'], + ['proposal', 'pubkey'], + ['depositPayer', 'pubkey'], + ], + }, + ], [ SignatoryRecord, { diff --git a/packages/governance-sdk/tests/governance/api.v3.test.ts b/packages/governance-sdk/tests/governance/api.v3.test.ts index 3f17fb9d..098142a6 100644 --- a/packages/governance-sdk/tests/governance/api.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v3.test.ts @@ -222,3 +222,24 @@ test('createProposal', async () => { const governance = await realm.getGovernance(proposal.account.governance); expect(governance.account.activeProposalCount.toNumber()).toEqual(1); }); + +test('createProposalWithDeposit', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.withGovernance()) + .then(b => b.sendTx()); + + // Act + const proposalPk = await realm.createProposal('proposal 1'); + + // Assert + const proposalDeposit = ( + await realm.getProposalDeposits(realm.bench.walletPk) + )[0]; + + expect(proposalDeposit.account.proposal).toEqual(proposalPk); + expect(proposalDeposit.account.depositPayer).toEqual(realm.bench.walletPk); +}); diff --git a/packages/governance-sdk/tests/tools/builders.ts b/packages/governance-sdk/tests/tools/builders.ts index 08974d2c..39258b03 100644 --- a/packages/governance-sdk/tests/tools/builders.ts +++ b/packages/governance-sdk/tests/tools/builders.ts @@ -13,6 +13,7 @@ import BN from 'bn.js'; import { getGovernance, getProposal, + getProposalDepositsByDepositPayer, getRealm, getRealmConfig, getTokenOwnerRecord, @@ -418,6 +419,14 @@ export class RealmBuilder { return getProposal(this.bench.connection, proposalPk); } + async getProposalDeposits(depositPayerPk: PublicKey) { + return getProposalDepositsByDepositPayer( + this.bench.connection, + this.bench.programId, + depositPayerPk, + ); + } + async withSignatory() { this.signatoryPk = await withAddSignatory( this.bench.instructions, From 2f054dbcdf2ed64c8301419358c789419c07d9ae Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 2 Jan 2023 16:21:23 +0000 Subject: [PATCH 66/88] chore: Update spl-governance-sdk to 0.3.19 --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index c2bb9e00..8fd5384a 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.18", + "version": "0.3.19", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From 122d238da01085f143e5417f53db58865144503f Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 16 Jan 2023 18:37:53 +0000 Subject: [PATCH 67/88] Governance: Add createRevokeGoverningTokens (#572) * feat: Add createRevokeGoverningTokens * fix: revokeGoverningTokens fix test --- .../governance/createRevokeGoverningTokens.ts | 27 +++++++++++++++++++ .../governance-sdk/src/governance/index.ts | 1 + .../governance/withRevokeGoverningTokens.ts | 6 ++--- .../governance-sdk/tests/tools/builders.ts | 2 +- 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 packages/governance-sdk/src/governance/createRevokeGoverningTokens.ts diff --git a/packages/governance-sdk/src/governance/createRevokeGoverningTokens.ts b/packages/governance-sdk/src/governance/createRevokeGoverningTokens.ts new file mode 100644 index 00000000..e7ac0a9d --- /dev/null +++ b/packages/governance-sdk/src/governance/createRevokeGoverningTokens.ts @@ -0,0 +1,27 @@ +import { PublicKey, TransactionInstruction } from '@solana/web3.js'; +import BN from 'bn.js'; +import { withRevokeGoverningTokens } from './withRevokeGoverningTokens'; + +export async function createRevokeGoverningTokens( + programId: PublicKey, + programVersion: number, + realm: PublicKey, + governingTokenOwner: PublicKey, + governingTokenMint: PublicKey, + revokeAuthority: PublicKey, + amount: BN, +) { + const instructions: TransactionInstruction[] = []; + await withRevokeGoverningTokens( + instructions, + programId, + programVersion, + realm, + governingTokenOwner, + governingTokenMint, + revokeAuthority, + amount, + ); + + return instructions[0]; +} diff --git a/packages/governance-sdk/src/governance/index.ts b/packages/governance-sdk/src/governance/index.ts index beeb7599..08ea7c7e 100644 --- a/packages/governance-sdk/src/governance/index.ts +++ b/packages/governance-sdk/src/governance/index.ts @@ -1,5 +1,6 @@ export * from './accounts'; export * from './api'; +export * from './createRevokeGoverningTokens'; export * from './createSetGovernanceConfig'; export * from './createSetRealmConfig'; export * from './createSetRealmAuthority'; diff --git a/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts b/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts index 472b1297..6d5cf424 100644 --- a/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withRevokeGoverningTokens.ts @@ -15,9 +15,9 @@ export const withRevokeGoverningTokens = async ( programId: PublicKey, programVersion: number, realm: PublicKey, - governingTokenMint: PublicKey, - governingTokenMintAuthrority: PublicKey, governingTokenOwner: PublicKey, + governingTokenMint: PublicKey, + revokeAuthority: PublicKey, amount: BN, ) => { const args = new RevokeGoverningTokensArgs({ amount }); @@ -62,7 +62,7 @@ export const withRevokeGoverningTokens = async ( isSigner: false, }, { - pubkey: governingTokenMintAuthrority, + pubkey: revokeAuthority, isWritable: false, isSigner: true, }, diff --git a/packages/governance-sdk/tests/tools/builders.ts b/packages/governance-sdk/tests/tools/builders.ts index 39258b03..34a68247 100644 --- a/packages/governance-sdk/tests/tools/builders.ts +++ b/packages/governance-sdk/tests/tools/builders.ts @@ -299,8 +299,8 @@ export class RealmBuilder { this.bench.programVersion, this.realmPk, - this.communityMintPk, this.bench.walletPk, + this.communityMintPk, this.bench.walletPk, new BN(1), ); From e573b361958fa816175516947a0869acbfa22335 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 16 Jan 2023 18:38:58 +0000 Subject: [PATCH 68/88] chore: Bump spl-gov-sdk version to 0.3.20 --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 8fd5384a..6b321f59 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.19", + "version": "0.3.20", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From a17e1221383fe1a9aa05eda31c4b934e738a8253 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 30 Jan 2023 19:32:48 +0000 Subject: [PATCH 69/88] Governance: Add withRefundProposalDeposit (#573) * feat: Add withRefundProposalDeposit * chore: refundProposalDeposit test --- .../governance-sdk/src/governance/index.ts | 1 + .../src/governance/instructions.ts | 6 +++ .../src/governance/serialisation.ts | 8 +++ .../governance/withRefundProposalDeposit.ts | 50 +++++++++++++++++++ .../tests/governance/api.v3.test.ts | 24 +++++++++ .../governance-sdk/tests/tools/builders.ts | 16 ++++++ 6 files changed, 105 insertions(+) create mode 100644 packages/governance-sdk/src/governance/withRefundProposalDeposit.ts diff --git a/packages/governance-sdk/src/governance/index.ts b/packages/governance-sdk/src/governance/index.ts index 08ea7c7e..add5abc3 100644 --- a/packages/governance-sdk/src/governance/index.ts +++ b/packages/governance-sdk/src/governance/index.ts @@ -26,6 +26,7 @@ export * from './withExecuteTransaction'; export * from './withFinalizeVote'; export * from './withFlagTransactionError'; export * from './withInsertTransaction'; +export * from './withRefundProposalDeposit'; export * from './withRelinquishVote'; export * from './withRemoveTransaction'; export * from './withRevokeGoverningTokens'; diff --git a/packages/governance-sdk/src/governance/instructions.ts b/packages/governance-sdk/src/governance/instructions.ts index ed1e8575..ea5dcb29 100644 --- a/packages/governance-sdk/src/governance/instructions.ts +++ b/packages/governance-sdk/src/governance/instructions.ts @@ -39,6 +39,7 @@ export enum GovernanceInstruction { UpdateProgramMetadata = 24, CreateNativeTreasury = 25, RevokeGoverningTokens = 26, + RefundProposalDeposit = 27, } export class CreateRealmArgs { @@ -396,3 +397,8 @@ export class RevokeGoverningTokensArgs { this.amount = args.amount; } } + +export class RefundProposalDepositArgs { + instruction: GovernanceInstruction = + GovernanceInstruction.RefundProposalDeposit; +} diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index b155643f..85bf427f 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -18,6 +18,7 @@ import { FinalizeVoteArgs, FlagTransactionErrorArgs, InsertTransactionArgs, + RefundProposalDepositArgs, RelinquishVoteArgs, RemoveTransactionArgs, RevokeGoverningTokensArgs, @@ -651,6 +652,13 @@ function createGovernanceInstructionSchema(programVersion: number) { fields: [['instruction', 'u8']], }, ], + [ + RefundProposalDepositArgs, + { + kind: 'struct', + fields: [['instruction', 'u8']], + }, + ], ...createGovernanceStructSchema(programVersion, undefined), ]); } diff --git a/packages/governance-sdk/src/governance/withRefundProposalDeposit.ts b/packages/governance-sdk/src/governance/withRefundProposalDeposit.ts new file mode 100644 index 00000000..0555de09 --- /dev/null +++ b/packages/governance-sdk/src/governance/withRefundProposalDeposit.ts @@ -0,0 +1,50 @@ +import { PublicKey, TransactionInstruction } from '@solana/web3.js'; +import { getGovernanceInstructionSchema } from './serialisation'; +import { serialize } from 'borsh'; +import { RefundProposalDepositArgs } from './instructions'; +import { getProposalDepositAddress } from './accounts'; + +export const withRefundProposalDeposit = async ( + instructions: TransactionInstruction[], + programId: PublicKey, + programVersion: number, + proposalPk: PublicKey, + proposalDepositPayerPk: PublicKey, +) => { + const args = new RefundProposalDepositArgs(); + const data = Buffer.from( + serialize(getGovernanceInstructionSchema(programVersion), args), + ); + + const proposalDepositAddress = await getProposalDepositAddress( + programId, + proposalPk, + proposalDepositPayerPk, + ); + + const keys = [ + { + pubkey: proposalPk, + isWritable: false, + isSigner: false, + }, + { + pubkey: proposalDepositAddress, + isWritable: true, + isSigner: false, + }, + { + pubkey: proposalDepositPayerPk, + isWritable: true, + isSigner: false, + }, + ]; + + instructions.push( + new TransactionInstruction({ + keys, + programId, + data, + }), + ); +}; diff --git a/packages/governance-sdk/tests/governance/api.v3.test.ts b/packages/governance-sdk/tests/governance/api.v3.test.ts index 098142a6..86fc80a0 100644 --- a/packages/governance-sdk/tests/governance/api.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v3.test.ts @@ -243,3 +243,27 @@ test('createProposalWithDeposit', async () => { expect(proposalDeposit.account.proposal).toEqual(proposalPk); expect(proposalDeposit.account.depositPayer).toEqual(realm.bench.walletPk); }); + +test('refundProposalDeposit', async () => { + // Arrange + const realm = await BenchBuilder.withConnection() + .then(b => b.withWallet()) + .then(b => b.withRealm()) + .then(b => b.withCommunityMember()) + .then(b => b.withGovernance()) + .then(b => b.sendTx()) + .then(b => b.withProposal()) + .then(b => b.withProposalSignOff()) + .then(b => b.withCastVote()) + .then(b => b.sendTx()); + + // Act + await realm.refundProposalDeposit(); + + // Assert + const proposalDeposits = await realm.getProposalDeposits( + realm.bench.walletPk, + ); + + expect(proposalDeposits.length).toBe(0); +}); diff --git a/packages/governance-sdk/tests/tools/builders.ts b/packages/governance-sdk/tests/tools/builders.ts index 34a68247..91cec951 100644 --- a/packages/governance-sdk/tests/tools/builders.ts +++ b/packages/governance-sdk/tests/tools/builders.ts @@ -24,6 +24,7 @@ import { withCreateGovernance, withCreateProposal, withDepositGoverningTokens, + withRefundProposalDeposit, withRelinquishVote, withRevokeGoverningTokens, withSignOffProposal, @@ -427,6 +428,21 @@ export class RealmBuilder { ); } + async refundProposalDeposit() { + await this._refundProposalDeposit(); + await this.sendTx(); + } + + async _refundProposalDeposit() { + await withRefundProposalDeposit( + this.bench.instructions, + this.bench.programId, + this.bench.programVersion, + this.proposalPk, + this.bench.walletPk, + ); + } + async withSignatory() { this.signatoryPk = await withAddSignatory( this.bench.instructions, From 5bf3c498e07446f82563e282b77e4eabfbfedf7e Mon Sep 17 00:00:00 2001 From: "Sebastian.Bor" Date: Mon, 30 Jan 2023 19:35:29 +0000 Subject: [PATCH 70/88] chore: bump spl-gov sdk version to 0.3.21 --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 6b321f59..a6980840 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.20", + "version": "0.3.21", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From bddf486072bfab1c2f28f16a2981a160587ef137 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 30 Jan 2023 20:09:05 +0000 Subject: [PATCH 71/88] Governance: Add governingTokenOwnerIsSigner (#574) --- .../src/governance/withDepositGoverningTokens.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts index f11507a0..6e8ca0d8 100644 --- a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts @@ -27,6 +27,7 @@ export const withDepositGoverningTokens = async ( governingTokenSourceAuthority: PublicKey, payer: PublicKey, amount: BN, + governingTokenOwnerIsSigner = true, ) => { const args = new DepositGoverningTokensArgs({ amount }); const data = Buffer.from( @@ -68,7 +69,7 @@ export const withDepositGoverningTokens = async ( { pubkey: governingTokenOwner, isWritable: false, - isSigner: true, + isSigner: governingTokenOwnerIsSigner, }, { pubkey: governingTokenSourceAuthority, From b596c582f003524aa526094d30d8143b46070c30 Mon Sep 17 00:00:00 2001 From: "Sebastian.Bor" Date: Mon, 30 Jan 2023 20:10:48 +0000 Subject: [PATCH 72/88] chore: bump spl-gov sdk version to 0.3.22 --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index a6980840..ac41bcfe 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.21", + "version": "0.3.22", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From 5fd1bcff54ac02d87b04feaa9e8314039de0084b Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 30 Jan 2023 20:19:37 +0000 Subject: [PATCH 73/88] Governance: simplify withDepositGoverningTokens (#575) --- .../src/governance/withDepositGoverningTokens.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts index 6e8ca0d8..af2d5160 100644 --- a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts @@ -27,7 +27,6 @@ export const withDepositGoverningTokens = async ( governingTokenSourceAuthority: PublicKey, payer: PublicKey, amount: BN, - governingTokenOwnerIsSigner = true, ) => { const args = new DepositGoverningTokensArgs({ amount }); const data = Buffer.from( @@ -41,6 +40,11 @@ export const withDepositGoverningTokens = async ( governingTokenOwner, ); + // If we are minting the tokens directly into the DAO then governingTokenOwner doesn't have to sign the tx + const governingTokenOwnerIsSigner = governingTokenSource.equals( + governingTokenMint, + ); + const [governingTokenHoldingAddress] = await PublicKey.findProgramAddress( [ Buffer.from(GOVERNANCE_PROGRAM_SEED), From 5698d36311fb7fa4c4730b5d26d6bfb7b520445b Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 30 Jan 2023 20:20:48 +0000 Subject: [PATCH 74/88] chore: bump spl-gov sdk version to 0.3.23 --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index ac41bcfe..08220854 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.22", + "version": "0.3.23", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From 7885a6c860917f068ee6da8d1a1b0eb876f41e43 Mon Sep 17 00:00:00 2001 From: agrippa Date: Wed, 1 Feb 2023 15:12:12 -0500 Subject: [PATCH 75/88] Update withDepositGoverningTokens.ts (#576) --- .../governance-sdk/src/governance/withDepositGoverningTokens.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts index af2d5160..bc6510cb 100644 --- a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts @@ -41,7 +41,7 @@ export const withDepositGoverningTokens = async ( ); // If we are minting the tokens directly into the DAO then governingTokenOwner doesn't have to sign the tx - const governingTokenOwnerIsSigner = governingTokenSource.equals( + const governingTokenOwnerIsSigner = !governingTokenSource.equals( governingTokenMint, ); From fdd872804e10447c860bf6f56ed0545ad557aaeb Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Wed, 1 Feb 2023 20:13:35 +0000 Subject: [PATCH 76/88] chore: bump spl-gov sdk version to 0.3.24 --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 08220854..0f6deec2 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.23", + "version": "0.3.24", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From 6a698a058de324aed292fe30d78cf47eee347ff7 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Wed, 1 Feb 2023 20:52:33 +0000 Subject: [PATCH 77/88] feat: Add governingTokenOwnerIsSigner param (#577) --- .../src/governance/withDepositGoverningTokens.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts index bc6510cb..b542d85e 100644 --- a/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts +++ b/packages/governance-sdk/src/governance/withDepositGoverningTokens.ts @@ -27,6 +27,7 @@ export const withDepositGoverningTokens = async ( governingTokenSourceAuthority: PublicKey, payer: PublicKey, amount: BN, + governingTokenOwnerIsSigner?: boolean, ) => { const args = new DepositGoverningTokensArgs({ amount }); const data = Buffer.from( @@ -40,10 +41,10 @@ export const withDepositGoverningTokens = async ( governingTokenOwner, ); - // If we are minting the tokens directly into the DAO then governingTokenOwner doesn't have to sign the tx - const governingTokenOwnerIsSigner = !governingTokenSource.equals( - governingTokenMint, - ); + governingTokenOwnerIsSigner = + governingTokenOwnerIsSigner ?? + // If we are minting the tokens directly into the DAO then governingTokenOwner doesn't have to sign the tx + !governingTokenSource.equals(governingTokenMint); const [governingTokenHoldingAddress] = await PublicKey.findProgramAddress( [ From cb5b4e69fb95effbafdcfd429be1a598ed7a6fdd Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Wed, 1 Feb 2023 20:53:27 +0000 Subject: [PATCH 78/88] chore: bump spl-gov sdk version to 0.3.25 --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 0f6deec2..6ac432b2 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.24", + "version": "0.3.25", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From 7144ac002c45f7997f6b12db59e91857ea361797 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Tue, 14 Mar 2023 10:54:05 +0000 Subject: [PATCH 79/88] Governance: Add getGovernanceProgramVersion test (#580) --- .../governance-sdk/tests/governance/api.v3.test.ts | 9 +++++++++ yarn.lock | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/governance-sdk/tests/governance/api.v3.test.ts b/packages/governance-sdk/tests/governance/api.v3.test.ts index 86fc80a0..e8ffbc53 100644 --- a/packages/governance-sdk/tests/governance/api.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v3.test.ts @@ -12,6 +12,15 @@ import { PROGRAM_VERSION_V3 } from '../../src/registry/constants'; import { BenchBuilder } from '../tools/builders'; import { getTimestampFromDays } from '../tools/units'; +test('getGovernanceProgramVersion', async () => { + // Arrange + // Act + const builder = await BenchBuilder.withConnection(); + + // Assert + expect(builder.programVersion).toEqual(3); +}); + test('createRealmWithTokenConfigs', async () => { // Arrange const bench = await BenchBuilder.withConnection(PROGRAM_VERSION_V3).then(b => diff --git a/yarn.lock b/yarn.lock index 932ca1e1..8806f976 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4080,6 +4080,19 @@ dependencies: buffer "~6.0.3" +"@solana/spl-governance@0.3.17": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@solana/spl-governance/-/spl-governance-0.3.17.tgz#ec6fc9c3e3c2eb5de0c00ebc8c4d46f6e5a899e9" + integrity sha512-GdKBb9Hwzsu6X3Kn1SwKUuuo4cGG9cUCnlSE0JXeGOriFEVcQf3rcuUIOU7JbKcN1vIMyDyayE8p632EOgFprw== + dependencies: + "@solana/web3.js" "^1.22.0" + axios "^1.1.3" + bignumber.js "^9.0.1" + bn.js "^5.1.3" + borsh "^0.3.1" + bs58 "^4.0.1" + superstruct "^0.15.2" + "@solana/spl-token-registry@^0.2.0": version "0.2.51" resolved "https://registry.yarnpkg.com/@solana/spl-token-registry/-/spl-token-registry-0.2.51.tgz#a263c146575f1dbab2d3e2e1f379068a8a63706f" From 4cabfe64d9ab2b99a832bb3f668e0d1283e9111f Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Tue, 28 Mar 2023 15:09:37 +0100 Subject: [PATCH 80/88] Governance: Rename maxVotingTime to baseVotingTime (#581) --- .../governance-sdk/src/governance/accounts.ts | 16 +++++++++------- .../src/governance/serialisation.ts | 2 +- packages/governance-sdk/tests/chat/api.test.ts | 4 +++- .../tests/governance/api.smoke.test.ts | 4 +++- .../governance-sdk/tests/governance/api.test.ts | 4 +++- .../tests/governance/api.v2.test.ts | 2 +- .../tests/governance/api.v3.test.ts | 4 ++-- packages/governance-sdk/tests/tools/builders.ts | 2 +- 8 files changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 9d97b226..31faac8a 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -451,7 +451,7 @@ export class GovernanceConfig { minCommunityTokensToCreateProposal: BN; minInstructionHoldUpTime: number; - maxVotingTime: number; + baseVotingTime: number; communityVoteTipping: VoteTipping; minCouncilTokensToCreateProposal: BN; @@ -467,7 +467,7 @@ export class GovernanceConfig { communityVoteThreshold: VoteThreshold; minCommunityTokensToCreateProposal: BN; minInstructionHoldUpTime: number; - maxVotingTime: number; + baseVotingTime: number; communityVoteTipping?: VoteTipping; minCouncilTokensToCreateProposal: BN; @@ -484,7 +484,7 @@ export class GovernanceConfig { this.minCommunityTokensToCreateProposal = args.minCommunityTokensToCreateProposal; this.minInstructionHoldUpTime = args.minInstructionHoldUpTime; - this.maxVotingTime = args.maxVotingTime; + this.baseVotingTime = args.baseVotingTime; this.communityVoteTipping = args.communityVoteTipping ?? VoteTipping.Strict; this.minCouncilTokensToCreateProposal = args.minCouncilTokensToCreateProposal; @@ -943,11 +943,13 @@ export class Proposal { getTimeToVoteEnd(governance: Governance) { const unixTimestampInSeconds = Date.now() / 1000; - return this.isPreVotingState() - ? governance.config.maxVotingTime + const baseVotingTime = this.isPreVotingState() + ? governance.config.baseVotingTime : (this.votingAt?.toNumber() ?? 0) + - governance.config.maxVotingTime - - unixTimestampInSeconds; + governance.config.baseVotingTime - + unixTimestampInSeconds; + + return baseVotingTime + governance.config.votingCoolOffTime; } hasVoteTimeEnded(governance: Governance) { diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 85bf427f..0e26bede 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -334,7 +334,7 @@ function createGovernanceStructSchema( ['communityVoteThreshold', 'VoteThreshold'], ['minCommunityTokensToCreateProposal', 'u64'], ['minInstructionHoldUpTime', 'u32'], - ['maxVotingTime', 'u32'], + ['baseVotingTime', 'u32'], ['communityVoteTipping', 'u8'], ['councilVoteThreshold', 'VoteThreshold'], ['councilVetoVoteThreshold', 'VoteThreshold'], diff --git a/packages/governance-sdk/tests/chat/api.test.ts b/packages/governance-sdk/tests/chat/api.test.ts index 62a8ffec..860163d2 100644 --- a/packages/governance-sdk/tests/chat/api.test.ts +++ b/packages/governance-sdk/tests/chat/api.test.ts @@ -117,12 +117,14 @@ test('postProposalComment', async () => { }), minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, - maxVotingTime: getTimestampFromDays(3), + baseVotingTime: getTimestampFromDays(3), voteTipping: VoteTipping.Strict, councilVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled, }), minCouncilTokensToCreateProposal: new BN(1), + votingCoolOffTime: 0, + depositExemptProposalCount: 0, }); const governancePk = await withCreateMintGovernance( diff --git a/packages/governance-sdk/tests/governance/api.smoke.test.ts b/packages/governance-sdk/tests/governance/api.smoke.test.ts index e5d7f4af..03781bcb 100644 --- a/packages/governance-sdk/tests/governance/api.smoke.test.ts +++ b/packages/governance-sdk/tests/governance/api.smoke.test.ts @@ -177,13 +177,15 @@ test('setupRealm', async () => { communityVoteThreshold: communityVoteThreshold, minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, - maxVotingTime: getTimestampFromDays(3), + baseVotingTime: getTimestampFromDays(3), communityVoteTipping: VoteTipping.Strict, councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), councilVoteThreshold: councilVoteThreshold, councilVetoVoteThreshold: councilVetoVoteThreshold, communityVetoVoteThreshold: communityVetoVoteThreshold, + votingCoolOffTime: 0, + depositExemptProposalCount: 0, }); const governancePk = await withCreateMintGovernance( diff --git a/packages/governance-sdk/tests/governance/api.test.ts b/packages/governance-sdk/tests/governance/api.test.ts index f9c4f11e..22132b82 100644 --- a/packages/governance-sdk/tests/governance/api.test.ts +++ b/packages/governance-sdk/tests/governance/api.test.ts @@ -131,13 +131,15 @@ test('createRealmWithGovernanceAndProposal', async () => { communityVoteThreshold: communityVoteThreshold, minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, - maxVotingTime: getTimestampFromDays(3), + baseVotingTime: getTimestampFromDays(3), communityVoteTipping: VoteTipping.Strict, councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), councilVoteThreshold: councilVoteThreshold, councilVetoVoteThreshold: councilVetoVoteThreshold, communityVetoVoteThreshold: councilVetoVoteThreshold, + votingCoolOffTime: 0, + depositExemptProposalCount: 0, }); const governancePk = await withCreateMintGovernance( diff --git a/packages/governance-sdk/tests/governance/api.v2.test.ts b/packages/governance-sdk/tests/governance/api.v2.test.ts index 8e4981bf..bd6e8c6f 100644 --- a/packages/governance-sdk/tests/governance/api.v2.test.ts +++ b/packages/governance-sdk/tests/governance/api.v2.test.ts @@ -24,7 +24,7 @@ test('createGovernanceWithConfig', async () => { }), minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, - maxVotingTime: getTimestampFromDays(3), + baseVotingTime: getTimestampFromDays(3), communityVoteTipping: VoteTipping.Strict, councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), diff --git a/packages/governance-sdk/tests/governance/api.v3.test.ts b/packages/governance-sdk/tests/governance/api.v3.test.ts index e8ffbc53..65b9bff8 100644 --- a/packages/governance-sdk/tests/governance/api.v3.test.ts +++ b/packages/governance-sdk/tests/governance/api.v3.test.ts @@ -86,7 +86,7 @@ test('createGovernanceWithConfig', async () => { }), minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, - maxVotingTime: getTimestampFromDays(3), + baseVotingTime: getTimestampFromDays(3), communityVoteTipping: VoteTipping.Strict, councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), @@ -124,7 +124,7 @@ test('createGovernanceWithConfig', async () => { config.councilVetoVoteThreshold, ); - expect(governance.account.config.maxVotingTime).toEqual( + expect(governance.account.config.baseVotingTime).toEqual( getTimestampFromDays(3), ); diff --git a/packages/governance-sdk/tests/tools/builders.ts b/packages/governance-sdk/tests/tools/builders.ts index 91cec951..4a689718 100644 --- a/packages/governance-sdk/tests/tools/builders.ts +++ b/packages/governance-sdk/tests/tools/builders.ts @@ -334,7 +334,7 @@ export class RealmBuilder { }), minCommunityTokensToCreateProposal: new BN(1), minInstructionHoldUpTime: 0, - maxVotingTime: getTimestampFromDays(3), + baseVotingTime: getTimestampFromDays(3), communityVoteTipping: VoteTipping.Strict, councilVoteTipping: VoteTipping.Strict, minCouncilTokensToCreateProposal: new BN(1), From a4f4ddfcbdf5cc7ba36b613032ab0af7b5efddec Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Tue, 28 Mar 2023 15:11:57 +0100 Subject: [PATCH 81/88] chore: bump spl-gov sdk verion to 0.3.26 (#582) --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 6ac432b2..172e68d2 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.25", + "version": "0.3.26", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From 0560e7baeda79c472031eea8e548ee6baaea9428 Mon Sep 17 00:00:00 2001 From: agrippa Date: Mon, 17 Apr 2023 13:53:09 -0400 Subject: [PATCH 82/88] throw an error if writing governance config and baseVotingTime < 1hr (#583) * deprecate narrow governance types * error if basevotingtime is too low --- .../src/governance/createSetGovernanceConfig.ts | 4 ++++ .../governance-sdk/src/governance/withCreateGovernance.ts | 4 ++++ .../governance-sdk/src/governance/withCreateMintGovernance.ts | 1 + .../src/governance/withCreateProgramGovernance.ts | 1 + .../src/governance/withCreateTokenGovernance.ts | 1 + 5 files changed, 11 insertions(+) diff --git a/packages/governance-sdk/src/governance/createSetGovernanceConfig.ts b/packages/governance-sdk/src/governance/createSetGovernanceConfig.ts index 28006e6b..3e6fb61b 100644 --- a/packages/governance-sdk/src/governance/createSetGovernanceConfig.ts +++ b/packages/governance-sdk/src/governance/createSetGovernanceConfig.ts @@ -15,6 +15,10 @@ export function createSetGovernanceConfig( serialize(getGovernanceInstructionSchema(programVersion), args), ); + if (args.config.baseVotingTime < 3600) { + throw new Error('baseVotingTime should be at least 1 hour'); + } + const keys = [ { pubkey: governance, diff --git a/packages/governance-sdk/src/governance/withCreateGovernance.ts b/packages/governance-sdk/src/governance/withCreateGovernance.ts index 178c42e7..5ef87c45 100644 --- a/packages/governance-sdk/src/governance/withCreateGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateGovernance.ts @@ -26,6 +26,10 @@ export const withCreateGovernance = async ( ) => { const args = new CreateGovernanceArgs({ config }); + if (args.config.baseVotingTime < 3600) { + throw new Error('baseVotingTime should be at least 1 hour'); + } + const data = Buffer.from( serialize(getGovernanceInstructionSchema(programVersion), args), ); diff --git a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts index c3019d72..60194afe 100644 --- a/packages/governance-sdk/src/governance/withCreateMintGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateMintGovernance.ts @@ -12,6 +12,7 @@ import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime'; import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; +/** @deprecated */ export const withCreateMintGovernance = async ( instructions: TransactionInstruction[], programId: PublicKey, diff --git a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts index 9656635d..512229c6 100644 --- a/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateProgramGovernance.ts @@ -12,6 +12,7 @@ import { BPF_UPGRADE_LOADER_ID } from '../tools/sdk/bpfUpgradeableLoader'; import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; +/** @deprecated */ export const withCreateProgramGovernance = async ( instructions: TransactionInstruction[], programId: PublicKey, diff --git a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts index b86c759b..743dd1e5 100644 --- a/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts +++ b/packages/governance-sdk/src/governance/withCreateTokenGovernance.ts @@ -12,6 +12,7 @@ import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken'; import { withRealmConfigPluginAccounts } from './withRealmConfigPluginAccounts'; import { PROGRAM_VERSION_V1 } from '../registry/constants'; +/** @deprecated */ export const withCreateTokenGovernance = async ( instructions: TransactionInstruction[], programId: PublicKey, From 040b7c89f757846f64c2436dbb58ecc4db8c5837 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 17 Apr 2023 18:55:56 +0100 Subject: [PATCH 83/88] chore: Update spl-gov sdk version to 0.3.27 (#584) --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 172e68d2..44728ee8 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.26", + "version": "0.3.27", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From 16957c9ddf9cc1c2a068b170af7e49ed0f805013 Mon Sep 17 00:00:00 2001 From: 0xShuk <83659045+0xShuk@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:08:12 +0530 Subject: [PATCH 84/88] Governance: Fix VoteType enum (#590) --- .../governance-sdk/src/governance/accounts.ts | 40 ++++++++++++++++--- .../src/governance/serialisation.ts | 27 +++++++++++-- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/packages/governance-sdk/src/governance/accounts.ts b/packages/governance-sdk/src/governance/accounts.ts index 31faac8a..88c3040d 100644 --- a/packages/governance-sdk/src/governance/accounts.ts +++ b/packages/governance-sdk/src/governance/accounts.ts @@ -209,24 +209,52 @@ export enum VoteTypeKind { MultiChoice = 1, } +export enum MultiChoiceType { + FullWeight = 0, + Weighted = 1, +} + export class VoteType { type: VoteTypeKind; - choiceCount: number | undefined; + choiceType: MultiChoiceType | undefined; + minVoterOptions: number | undefined; + maxVoterOptions: number | undefined; + maxWinningOptions: number | undefined; - constructor(args: { type: VoteTypeKind; choiceCount: number | undefined }) { + constructor(args: { + type: VoteTypeKind; + choiceType: MultiChoiceType | undefined; + minVoterOptions: number | undefined; + maxVoterOptions: number | undefined; + maxWinningOptions: number | undefined; + }) { this.type = args.type; - this.choiceCount = args.choiceCount; + this.choiceType = args.choiceType; + this.minVoterOptions = args.minVoterOptions; + this.maxVoterOptions = args.maxVoterOptions; + this.maxWinningOptions = args.maxWinningOptions; } static SINGLE_CHOICE = new VoteType({ type: VoteTypeKind.SingleChoice, - choiceCount: undefined, + choiceType: undefined, + minVoterOptions: undefined, + maxVoterOptions: undefined, + maxWinningOptions: undefined, }); - static MULTI_CHOICE = (choiceCount: number) => + static MULTI_CHOICE = ( + choiceType: MultiChoiceType, + minVoterOptions: number, + maxVoterOptions: number, + maxWinningOptions: number, + ) => new VoteType({ type: VoteTypeKind.MultiChoice, - choiceCount: choiceCount, + choiceType, + minVoterOptions, + maxVoterOptions, + maxWinningOptions, }); isSingleChoice() { diff --git a/packages/governance-sdk/src/governance/serialisation.ts b/packages/governance-sdk/src/governance/serialisation.ts index 0e26bede..f3262247 100644 --- a/packages/governance-sdk/src/governance/serialisation.ts +++ b/packages/governance-sdk/src/governance/serialisation.ts @@ -102,8 +102,21 @@ import { deserializeBorsh } from '../tools/borsh'; return VoteType.SINGLE_CHOICE; } - const choiceCount = reader.buf.readUInt16LE(reader.offset); - return VoteType.MULTI_CHOICE(choiceCount); + const choiceType = reader.buf.readUInt8(reader.offset); + reader.offset += 1; + const minVoterOptions = reader.buf.readUInt8(reader.offset); + reader.offset += 1; + const maxVoterOptions = reader.buf.readUInt8(reader.offset); + reader.offset += 1; + const maxWinningOptions = reader.buf.readUInt8(reader.offset); + reader.offset += 1; + + return VoteType.MULTI_CHOICE( + choiceType, + minVoterOptions, + maxVoterOptions, + maxWinningOptions, + ); }; (BinaryWriter.prototype as any).writeVoteType = function (value: VoteType) { @@ -113,8 +126,14 @@ import { deserializeBorsh } from '../tools/borsh'; writer.length += 1; if (value.type === VoteTypeKind.MultiChoice) { - writer.buf.writeUInt16LE(value.choiceCount!, writer.length); - writer.length += 2; + writer.buf.writeUInt8(value.choiceType!, writer.length); + writer.length += 1; + writer.buf.writeUInt8(value.minVoterOptions!, writer.length); + writer.length += 1; + writer.buf.writeUInt8(value.maxVoterOptions!, writer.length); + writer.length += 1; + writer.buf.writeUInt8(value.maxWinningOptions!, writer.length); + writer.length += 1; } }; From 6a23631ad30fb7761107b8316479c14519217560 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Wed, 19 Jul 2023 17:40:40 +0100 Subject: [PATCH 85/88] chore: bump version to 0.3.28 (#591) --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index 44728ee8..fa33fff5 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.27", + "version": "0.3.28", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From c168fedce3d8270ae424c573373429f89fad43b7 Mon Sep 17 00:00:00 2001 From: Utkarsh <83659045+0xShuk@users.noreply.github.com> Date: Thu, 22 Aug 2024 22:42:03 +0530 Subject: [PATCH 86/88] Update simulate function (#598) --- packages/governance-sdk/src/governance/version.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/governance-sdk/src/governance/version.ts b/packages/governance-sdk/src/governance/version.ts index c85be3cb..97b506f9 100644 --- a/packages/governance-sdk/src/governance/version.ts +++ b/packages/governance-sdk/src/governance/version.ts @@ -77,10 +77,8 @@ export async function getGovernanceProgramVersion( transaction.add(...instructions); // TODO: Once return values are supported change the simulation call to the actual one - const getVersion = await simulateTransaction( - connection, + const getVersion = await connection.simulateTransaction( transaction, - 'recent', ); if (getVersion.value.logs) { From 82fbb391ec875e45d17dad98df000e2086c01670 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Mon, 26 Aug 2024 19:30:25 +0200 Subject: [PATCH 87/88] chore: bump version to 0.3.29 --- packages/governance-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/governance-sdk/package.json b/packages/governance-sdk/package.json index fa33fff5..80fe958d 100644 --- a/packages/governance-sdk/package.json +++ b/packages/governance-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-governance", - "version": "0.3.28", + "version": "0.3.29", "description": "SPL Governance Client API", "author": "Solana Maintainers ", "homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md", From 6505a1624f653dd4e4a431f405a6895597fd7133 Mon Sep 17 00:00:00 2001 From: Sebastian Bor Date: Thu, 27 Feb 2025 20:40:39 +0000 Subject: [PATCH 88/88] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index ea275636..ae5c92a9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# oyster + +This repo still exists in archived form, but the maintained version of `governance-sdk` package has now relocated to: https://github.com/Mythic-Project/oyster/tree/main/packages/governance-sdk + ## Setup Be sure to be running Node v12.16.2 and yarn version 1.22.10.