From 61c6a3208a30cc39de24798db149aefdeb49ca25 Mon Sep 17 00:00:00 2001 From: AidarKC Date: Fri, 15 May 2026 15:29:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D1=8B=20=D0=B2=D1=81=D0=B5=20=D1=82=D0=B5?= =?UTF-8?q?=D0=BA=D1=83=D1=89=D0=B8=D0=B5=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=BE=20=D1=80=D1=83=D1=81=D1=81=D0=BA=D0=B8=D1=85=20com?= =?UTF-8?q?mit=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 10 + .idea/gradle.xml | 18 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/shine-solana.iml | 9 + .idea/vcs.xml | 6 + shine/.gradle/8.14.4/checksums/checksums.lock | Bin 0 -> 17 bytes .../executionHistory/executionHistory.lock | Bin 0 -> 17 bytes .../.gradle/8.14.4/fileChanges/last-build.bin | Bin 0 -> 1 bytes .../.gradle/8.14.4/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes shine/.gradle/8.14.4/gc.properties | 0 .../buildOutputCleanup.lock | Bin 0 -> 17 bytes .../buildOutputCleanup/cache.properties | 2 + shine/.gradle/vcs-1/gc.properties | 0 shine/.vendor/pyth-crosschain | 1 + shine/AGENTS.md | 15 + shine/build.gradle | 45 + shine/keys/shine_payments-keypair.json | 1 + shine/keys/shine_users-keypair.json | 1 + shine/programs/common/src/utils.rs | 100 +- .../shine_payments/oracle_check/README.md | 19 + .../shine_payments/oracle_check/index.html | 255 +++++ .../shine_payments/web/buy_ticket.html | 6 +- .../shine_payments/web/dao_revoke_vote.html | 342 +++++++ shine/programs/shine_payments/web/index.html | 5 + .../shine_payments/web/track_ticket.html | 6 +- shine/programs/shine_users/src/settings.rs | 2 +- shine/programs/shine_users/src/users.rs | 73 +- shine/scripts/dao/README.md | 60 ++ .../dao/create_realm_dao_full_build_exec.js | 456 +++++++++ .../scripts/dao/create_realm_dao_full_test.sh | 106 +++ shine/scripts/dao/dao.config.env | 37 + .../execute_revoke_transaction_full_exec.js | 108 +++ .../propose_vote_execute_revoke_full_exec.js | 399 ++++++++ .../dao/revoke_member_token_full_exec.js | 112 +++ ...-53_Devnet_DAO_Full-1_2026-05-09_full.json | 31 + ...1-53_Devnet_DAO_Full-1_2026-05-09_full.txt | 26 + ...2026-05-09_02-24-43_revoke_FUc28vNixp.json | 23 + .../2026-05-09_02-24-43_revoke_FUc28vNixp.txt | 29 + shine/scripts/dao_legacy/README.md | 7 + .../dao_legacy/create_realm_dao_build_exec.js | 379 ++++++++ .../dao_legacy/create_realm_dao_test.sh | 106 +++ ...reate_realm_dao_without_burn_build_exec.js | 379 ++++++++ shine/scripts/devnet/README.md | 8 + ...26-05-15_15-20-22_vanity_grind_report.json | 16 + ...aykoMooghA5SURLYhkkU8NEhV5Y2T6fsXD7rn.json | 1 + ...26-05-15_15-20-09_vanity_grind_report.json | 16 + ...Rxa8Se5KFQmkBbxBJ3Fo8FeY8N9td6NGz38zu.json | 1 + shine/settings.gradle | 2 + shine/yarn.lock | 876 +++++++++++++----- КОШЕЛЬКИ_DEVNET_ТЕСТ.md | 51 +- 51 files changed, 3835 insertions(+), 325 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/shine-solana.iml create mode 100644 .idea/vcs.xml create mode 100644 shine/.gradle/8.14.4/checksums/checksums.lock create mode 100644 shine/.gradle/8.14.4/executionHistory/executionHistory.lock create mode 100644 shine/.gradle/8.14.4/fileChanges/last-build.bin create mode 100644 shine/.gradle/8.14.4/fileHashes/fileHashes.lock create mode 100644 shine/.gradle/8.14.4/gc.properties create mode 100644 shine/.gradle/buildOutputCleanup/buildOutputCleanup.lock create mode 100644 shine/.gradle/buildOutputCleanup/cache.properties create mode 100644 shine/.gradle/vcs-1/gc.properties create mode 160000 shine/.vendor/pyth-crosschain create mode 100644 shine/build.gradle create mode 100644 shine/keys/shine_payments-keypair.json create mode 100644 shine/keys/shine_users-keypair.json create mode 100644 shine/programs/shine_payments/oracle_check/README.md create mode 100644 shine/programs/shine_payments/oracle_check/index.html create mode 100644 shine/programs/shine_payments/web/dao_revoke_vote.html create mode 100644 shine/scripts/dao/README.md create mode 100755 shine/scripts/dao/create_realm_dao_full_build_exec.js create mode 100755 shine/scripts/dao/create_realm_dao_full_test.sh create mode 100644 shine/scripts/dao/dao.config.env create mode 100644 shine/scripts/dao/execute_revoke_transaction_full_exec.js create mode 100755 shine/scripts/dao/propose_vote_execute_revoke_full_exec.js create mode 100755 shine/scripts/dao/revoke_member_token_full_exec.js create mode 100644 shine/scripts/dao/runs/2026-05-09_02-21-53_Devnet_DAO_Full-1_2026-05-09_full.json create mode 100644 shine/scripts/dao/runs/2026-05-09_02-21-53_Devnet_DAO_Full-1_2026-05-09_full.txt create mode 100644 shine/scripts/dao/runs/2026-05-09_02-24-43_revoke_FUc28vNixp.json create mode 100644 shine/scripts/dao/runs/2026-05-09_02-24-43_revoke_FUc28vNixp.txt create mode 100644 shine/scripts/dao_legacy/README.md create mode 100755 shine/scripts/dao_legacy/create_realm_dao_build_exec.js create mode 100755 shine/scripts/dao_legacy/create_realm_dao_test.sh create mode 100755 shine/scripts/dao_legacy/create_realm_dao_without_burn_build_exec.js create mode 100644 shine/scripts/governance_token/runs/2026-05-15_15-20-22_vanity_grind_report.json create mode 100644 shine/scripts/governance_token/runs/DAou7SeaykoMooghA5SURLYhkkU8NEhV5Y2T6fsXD7rn.json create mode 100644 shine/scripts/governance_token/scripts/governance_token/runs/2026-05-15_15-20-09_vanity_grind_report.json create mode 100644 shine/scripts/governance_token/scripts/governance_token/runs/DAoxa7YRxa8Se5KFQmkBbxBJ3Fo8FeY8N9td6NGz38zu.json create mode 100644 shine/settings.gradle diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..30cf57e --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..30d78fe --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..a94cba3 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..07b2738 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/shine-solana.iml b/.idea/shine-solana.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/shine-solana.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/shine/.gradle/8.14.4/checksums/checksums.lock b/shine/.gradle/8.14.4/checksums/checksums.lock new file mode 100644 index 0000000000000000000000000000000000000000..9ab06d8af42629313ec5d61259e2cadb1908d95f GIT binary patch literal 17 TcmZSf7e3~r&U9)j0~7!NBn$%p literal 0 HcmV?d00001 diff --git a/shine/.gradle/8.14.4/executionHistory/executionHistory.lock b/shine/.gradle/8.14.4/executionHistory/executionHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..02b615f08542619fff224af9ccedf6dc2779fc09 GIT binary patch literal 17 TcmZQR<`DS7er01I0~7!NGaLj3 literal 0 HcmV?d00001 diff --git a/shine/.gradle/8.14.4/fileChanges/last-build.bin b/shine/.gradle/8.14.4/fileChanges/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/shine/.gradle/8.14.4/fileHashes/fileHashes.lock b/shine/.gradle/8.14.4/fileHashes/fileHashes.lock new file mode 100644 index 0000000000000000000000000000000000000000..e03d9f1483aaaf0064435285a191f9fa6b4433a4 GIT binary patch literal 17 ScmZQ($x@BX?#^pvfC2y^I|A7N literal 0 HcmV?d00001 diff --git a/shine/.gradle/8.14.4/gc.properties b/shine/.gradle/8.14.4/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/shine/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/shine/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000000000000000000000000000000000000..a60aa33e61b4ae1fe3e09a39e488df42ee2e02a2 GIT binary patch literal 17 UcmZSno$JLayrB3g0|YPv050?c#{d8T literal 0 HcmV?d00001 diff --git a/shine/.gradle/buildOutputCleanup/cache.properties b/shine/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..388b175 --- /dev/null +++ b/shine/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Mon May 11 16:21:48 MSK 2026 +gradle.version=8.14.4 diff --git a/shine/.gradle/vcs-1/gc.properties b/shine/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/shine/.vendor/pyth-crosschain b/shine/.vendor/pyth-crosschain new file mode 160000 index 0000000..3abc395 --- /dev/null +++ b/shine/.vendor/pyth-crosschain @@ -0,0 +1 @@ +Subproject commit 3abc3959fa56192511bdc977615f500a55022e88 diff --git a/shine/AGENTS.md b/shine/AGENTS.md index a2dc824..9c545ea 100644 --- a/shine/AGENTS.md +++ b/shine/AGENTS.md @@ -31,3 +31,18 @@ - `GITEA_TOKEN` Push выполнять через `http.extraHeader` (Authorization) без вывода токена в логи. + +## Rule: Commit Messages + +Текст commit message писать на русском языке. + +## Rule: UI Deploy + +Деплой UI Shine Payments выполнять через Gradle из папки `shine`: + +1. `gradle deployUi` +2. `gradle checkUiRemote` + +Где смотреть детали (пути деплоя, путь Caddy, рабочие URL): + +- комментарии в `build.gradle` (в корне `shine/`). diff --git a/shine/build.gradle b/shine/build.gradle new file mode 100644 index 0000000..6fd56db --- /dev/null +++ b/shine/build.gradle @@ -0,0 +1,45 @@ +/* + * Gradle-задачи для утилитного деплоя UI Shine Payments. + * + * Куда деплоим файлы UI: + * /home/player/sites/test-solana-tickets.shineup.me + * + * Где расположен Caddy-конфиг на сервере: + * /home/player/SHiNE/caddy/Caddyfile + * + * По каким URL должен работать UI: + * https://test-solana-tickets.shineup.me + * https://sol.shiningpeople.ru + */ + +tasks.register("deployUi", Exec) { + group = "deploy" + description = "Деплой HTML UI Shine Payments на 45.136.124.227 в /home/player/sites/test-solana-tickets.shineup.me (URL: test-solana-tickets.shineup.me, sol.shiningpeople.ru)" + + // Источник локальных UI-страниц: + // shine/programs/shine_payments/web/ + def localUiDir = "${projectDir}/programs/shine_payments/web/" + + // Целевая директория на сервере: + // /home/player/sites/test-solana-tickets.shineup.me + def remoteTarget = "player@45.136.124.227:/home/player/sites/test-solana-tickets.shineup.me/" + + commandLine "rsync", "-av", "--delete", localUiDir, remoteTarget +} + +tasks.register("checkUiRemote", Exec) { + group = "deploy" + description = "Проверка на сервере: Caddy-конфиг и наличие новых Program ID в UI" + + commandLine "ssh", "-o", "StrictHostKeyChecking=no", "player@45.136.124.227", + "set -e; " + + "echo 'Caddy file:'; " + + "ls -la /home/player/SHiNE/caddy/Caddyfile; " + + "echo; " + + "echo 'Домены в Caddy:'; " + + "grep -n 'test-solana-tickets.shineup.me\\|sol.shiningpeople.ru' /home/player/SHiNE/caddy/Caddyfile; " + + "echo; " + + "echo 'Program ID в загруженных html:'; " + + "grep -R -n 'm48pWRGWrMj3TEHjuU4zsp5Gju4e7ZaPovk8RcVt7kR' /home/player/sites/test-solana-tickets.shineup.me/*.html" +} + diff --git a/shine/keys/shine_payments-keypair.json b/shine/keys/shine_payments-keypair.json new file mode 100644 index 0000000..f228fcd --- /dev/null +++ b/shine/keys/shine_payments-keypair.json @@ -0,0 +1 @@ +[112,191,53,183,50,74,71,149,251,216,158,157,67,198,143,219,67,188,22,43,49,6,18,31,92,254,78,219,18,245,187,50,50,133,54,215,248,187,162,135,70,192,63,182,33,87,44,169,230,248,155,7,216,43,188,126,253,71,54,123,202,174,140,97] \ No newline at end of file diff --git a/shine/keys/shine_users-keypair.json b/shine/keys/shine_users-keypair.json new file mode 100644 index 0000000..c497472 --- /dev/null +++ b/shine/keys/shine_users-keypair.json @@ -0,0 +1 @@ +[78,57,36,25,42,130,147,16,232,65,139,10,4,54,133,0,204,50,65,112,18,99,223,142,226,60,119,36,253,192,185,121,112,54,249,197,203,152,82,234,162,32,176,193,110,19,217,20,149,116,215,16,153,121,28,243,143,248,181,55,186,250,95,103] \ No newline at end of file diff --git a/shine/programs/common/src/utils.rs b/shine/programs/common/src/utils.rs index 77eb884..ae8ce47 100644 --- a/shine/programs/common/src/utils.rs +++ b/shine/programs/common/src/utils.rs @@ -1,23 +1,14 @@ use anchor_lang::prelude::*; -use anchor_lang::solana_program::{ - program::invoke_signed, - system_instruction, - system_program -}; +use anchor_lang::solana_program::{program::invoke_signed, system_instruction, system_program}; - - - - - -/// сдесь коды всех ошибок +/// сдесь коды всех ошибок #[error_code] pub enum ErrCode { /// Система уже инициализирована и не может быть инициализирована повторно! #[msg("Система уже инициализирована и не может быть инициализирована повторно!")] SystemAlreadyInitialized = 1000, - + #[msg("PDA не содержит данных или не инициализирован")] EmptyPdaData = 1002, @@ -40,7 +31,6 @@ pub enum ErrCode { #[msg("PDA-аккаунт уже существует и не может быть создан повторно.")] PdaAlreadyExists = 1009, - #[msg("Подписавший не совпадает с ожидаемым пользователем (это потому что пока временно можно регистрировать пользователя с другово аккаунта")] InvalidSigner = 1005, @@ -86,29 +76,8 @@ pub enum ErrCode { #[msg("Невалидная magic-сигнатура записи")] InvalidRecordMagic = 1025, - - } - - - - - - - - - - - - - - - - - - - ///---------------------------------------------------------------------------------------------------------- /// Базовые функции для работы с PDA ///---------------------------------------------------------------------------------------------------------- @@ -137,7 +106,7 @@ pub fn create_and_write_pda<'info>( msg!("Создаём PDA с размером {} байт", space); let space = space; //+ 128; // Добавляется запас под метаданные - // Вычисляем необходимую арендную плату + // Вычисляем необходимую арендную плату let lamports = Rent::get()?.minimum_balance(space as usize); // Формируем инструкцию @@ -152,11 +121,7 @@ pub fn create_and_write_pda<'info>( // Выполняем инструкцию с подписью от PDA invoke_signed( &create_instr, - &[ - signer.clone(), - pda_account.clone(), - system_program.clone(), - ], + &[signer.clone(), pda_account.clone(), system_program.clone()], &[&seeds], )?; } @@ -177,9 +142,6 @@ pub fn create_and_write_pda<'info>( Ok(()) } - - - /// Создаёт PDA аккаунт (если его ещё нет). /// /// ⚠️ Если аккаунт уже существует, выбрасывается ошибка. @@ -221,22 +183,18 @@ pub fn create_pda<'info>( // ─────────────────────────────────────────────── // 3. Создаём инструкцию system_program для создания аккаунта let create_instr = system_instruction::create_account( - signer.key, // от имени кого - pda_account.key, // для какого PDA - lamports, // сколько лампортов перевести - full_space, // сколько байт выделить - program_id, // кто будет владельцем PDA + signer.key, // от имени кого + pda_account.key, // для какого PDA + lamports, // сколько лампортов перевести + full_space, // сколько байт выделить + program_id, // кто будет владельцем PDA ); // ─────────────────────────────────────────────── // 4. Выполняем инструкцию с подписью PDA (через сиды) invoke_signed( &create_instr, - &[ - signer.clone(), - pda_account.clone(), - system_program.clone(), - ], + &[signer.clone(), pda_account.clone(), system_program.clone()], &[&seeds], // PDA сиды → для подписи )?; @@ -251,10 +209,7 @@ pub fn create_pda<'info>( /// Аргументы: /// - `pda_account`: аккаунт, в который пишем (должен быть mut) /// - `data`: бинарный массив, который нужно записать -pub fn write_to_pda<'info>( - pda_account: &AccountInfo<'info>, - data: &[u8], -) -> Result<()> { +pub fn write_to_pda<'info>(pda_account: &AccountInfo<'info>, data: &[u8]) -> Result<()> { // ─────────────────────────────────────────────── // 1. Получаем доступ к данным PDA (на запись) let mut account_data = pda_account.try_borrow_mut_data()?; @@ -274,15 +229,6 @@ pub fn write_to_pda<'info>( Ok(()) } - - - - - - - - - /// ------------------------------------------------------------------------ /// safe_read_pda ‒ «безопасное чтение PDA» /// ------------------------------------------------------------------------ @@ -300,7 +246,7 @@ pub fn write_to_pda<'info>( /// - Успех → копируем их в Vec и возвращаем. /// - Ошибка (например, конфликт borrow) → логируем и возвращаем пустой Vec. /// -/// пример использования +/// пример использования /// let raw_bytes = safe_read_pda(&ctx.accounts.readonly_pda); /// require!(!raw_bytes.is_empty(), ErrCode::EmptyPdaData); /// msg!("Размер считанных данных: {}", raw_bytes.len()); @@ -333,17 +279,15 @@ pub fn safe_read_pda<'info>(pda_account: &AccountInfo<'info>) -> Vec { } Err(e) => { // Ошибка при borrow (например, уже есть активное мутабельное заимствование) - msg!("safe_read_pda: ошибка borrow_data ({:?}) ‒ возвращаем пустой массив", e); + msg!( + "safe_read_pda: ошибка borrow_data ({:?}) ‒ возвращаем пустой массив", + e + ); Vec::new() } } } - - - - - /// ------------------------------------------------------------------------ /// delete_pda_with_assign — закрыть PDA, вернуть ренту и освободить адрес /// ------------------------------------------------------------------------ @@ -373,7 +317,10 @@ pub fn delete_pda_return_rent<'info>( program_id: &Pubkey, ) -> Result<()> { // 0) проверки - require!(pda_account.owner != &Pubkey::default(), ErrCode::EmptyPdaData); + require!( + pda_account.owner != &Pubkey::default(), + ErrCode::EmptyPdaData + ); require!(pda_account.owner == program_id, ErrCode::InvalidPdaAddress); // 1) Переложить все лампорты с PDA на получателя (мы владелец, это разрешено) @@ -389,7 +336,9 @@ pub fn delete_pda_return_rent<'info>( // 2) Нулим данные (если были) if !pda_account.data_is_empty() { let mut data = pda_account.try_borrow_mut_data()?; - for b in data.iter_mut() { *b = 0; } + for b in data.iter_mut() { + *b = 0; + } } // 3) Сжать до 0 байт @@ -399,4 +348,3 @@ pub fn delete_pda_return_rent<'info>( msg!("PDA закрыт: рента отправлена на {}", recipient.key); Ok(()) } - diff --git a/shine/programs/shine_payments/oracle_check/README.md b/shine/programs/shine_payments/oracle_check/README.md new file mode 100644 index 0000000..ea92a44 --- /dev/null +++ b/shine/programs/shine_payments/oracle_check/README.md @@ -0,0 +1,19 @@ +# Oracle Check + +Мини-страница диагностики оракула Pyth для `SOL/USD`. + +Файл: + +- `index.html` + +Что проверяет: + +1. Чтение oracle account через RPC (`devnet`, `mainnet-beta`, `testnet`). +2. Парсинг по текущим оффсетам из UI (`74/90/94`). +3. Альтернативный парсинг (`73/89/93`) для проверки сдвига формата. +4. Сравнение с Hermes API (эталонный источник цены по feed id). + +Запуск: + +Открыть `index.html` в браузере и нажать кнопку «Проверить все сети». + diff --git a/shine/programs/shine_payments/oracle_check/index.html b/shine/programs/shine_payments/oracle_check/index.html new file mode 100644 index 0000000..06c18e8 --- /dev/null +++ b/shine/programs/shine_payments/oracle_check/index.html @@ -0,0 +1,255 @@ + + + + + + Проверка оракула Pyth (Devnet/Mainnet/Testnet) + + + +
+

Диагностика оракула Pyth (SOL/USD)

+
+
+ Страница нужна, чтобы проверить, что именно возвращает аккаунт оракула в разных сетях и где ломается парсинг. +
+
+ Проверяются три сети: devnet, mainnet-beta, testnet. +
+
+ +
+

Настройки

+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ Если для сети аккаунт не существует, это тоже покажется в отчёте. +
+
+ +
+

Результаты

+
Нажмите «Проверить все сети».
+
+
+ + + + + diff --git a/shine/programs/shine_payments/web/buy_ticket.html b/shine/programs/shine_payments/web/buy_ticket.html index d37f1a8..105086c 100644 --- a/shine/programs/shine_payments/web/buy_ticket.html +++ b/shine/programs/shine_payments/web/buy_ticket.html @@ -148,9 +148,9 @@ return BigInt(Math.round(v * 1_000_000_000)); } function parsePythPriceUpdateV2(data) { - const price = readI64(data, 74); - const exponent = readI32(data, 90); - const publishTime = readI64(data, 94); + const price = readI64(data, 73); + const exponent = readI32(data, 89); + const publishTime = readI64(data, 93); if (price <= 0n) throw new Error("Оракул вернул некорректную цену"); let num = price * 100n; let den = 1n; diff --git a/shine/programs/shine_payments/web/dao_revoke_vote.html b/shine/programs/shine_payments/web/dao_revoke_vote.html new file mode 100644 index 0000000..fe7b4e2 --- /dev/null +++ b/shine/programs/shine_payments/web/dao_revoke_vote.html @@ -0,0 +1,342 @@ + + + + + + DAO revoke vote — Shine Payments Devnet + + + +
+
← На главную
+

DAO: голосование на revoke/burn membership token (Devnet)

+
Governance program:
+ +
+
+ +
+
Кошелек: не подключен
+
+ +
+
+ + + +
+
+ + +
+
+ +
+
+
+ +
+
+ + +
+
+ +
+
Если получите hold-up (`0x20d`) — дождитесь конца voting window/hold-up и повторите execute.
+
+
+
+ + + + diff --git a/shine/programs/shine_payments/web/index.html b/shine/programs/shine_payments/web/index.html index a8c891f..857c80b 100644 --- a/shine/programs/shine_payments/web/index.html +++ b/shine/programs/shine_payments/web/index.html @@ -61,6 +61,11 @@
Выдача лимитов менеджерам в USD для добавления билетов в очередь 1/2.
+ +

DAO revoke governance token

+
UI для proposal/vote/execute на отзыв (burn/revoke) membership governance токенов.
+
+

Инструменты менеджера

Показ лимитов менеджера и создание билетов в очередь 1/2 в USD.
diff --git a/shine/programs/shine_payments/web/track_ticket.html b/shine/programs/shine_payments/web/track_ticket.html index ebb8792..f1c5390 100644 --- a/shine/programs/shine_payments/web/track_ticket.html +++ b/shine/programs/shine_payments/web/track_ticket.html @@ -142,9 +142,9 @@ return s.includes("notenoughinflowforstep") || s.includes("0x177a"); } function parsePythPriceUpdateV2(data) { - const price = readI64(data, 74); - const exponent = readI32(data, 90); - const publishTime = readI64(data, 94); + const price = readI64(data, 73); + const exponent = readI32(data, 89); + const publishTime = readI64(data, 93); if (price <= 0n) throw new Error("Оракул вернул некорректную цену"); let num = price * 100n; let den = 1n; diff --git a/shine/programs/shine_users/src/settings.rs b/shine/programs/shine_users/src/settings.rs index e1b8bfe..97e3ff9 100644 --- a/shine/programs/shine_users/src/settings.rs +++ b/shine/programs/shine_users/src/settings.rs @@ -3,7 +3,7 @@ pub const USER_PDA_SEED_PREFIX: &str = "login="; // (в частности, сценарии ротации root key с дополнительной подписью старого ключа). pub const USER_PDA_SPACE: usize = 768; -pub const REGISTRATION_FEE_RECEIVER: &str = "6bFc5Gz5qF172GQhK5HpDbWs8F6qcSxdHn5XqAstf1fY"; +pub const REGISTRATION_FEE_RECEIVER: &str = "9vXFoN9ngfN1gpqQ3HT5n3y9Wp2r7HnSQckirgwVwWwb"; pub const REGISTRATION_FEE_LAMPORTS: u64 = 10_000_000; // 0.01 SOL pub const LIMIT_STEP: u64 = 10_000; diff --git a/shine/programs/shine_users/src/users.rs b/shine/programs/shine_users/src/users.rs index 7178dd2..586a403 100644 --- a/shine/programs/shine_users/src/users.rs +++ b/shine/programs/shine_users/src/users.rs @@ -5,8 +5,8 @@ use anchor_lang::solana_program::{ hash::hashv, instruction::Instruction, program::invoke, - sysvar::instructions::{load_current_index_checked, load_instruction_at_checked}, system_instruction, + sysvar::instructions::{load_current_index_checked, load_instruction_at_checked}, }; use common::utils::{create_pda, safe_read_pda, write_to_pda, ErrCode}; use std::str::FromStr; @@ -221,7 +221,11 @@ pub fn update_user_pda(ctx: Context, args: UpdateUserPdaArgs) -> old_record.created_at_ms == args.created_at_ms, ErrCode::ImmutableFieldChanged ); - require_keys_eq!(old_record.root_key, args.root_key, ErrCode::ImmutableFieldChanged); + require_keys_eq!( + old_record.root_key, + args.root_key, + ErrCode::ImmutableFieldChanged + ); require!( args.version == old_record.version.saturating_add(1), ErrCode::InvalidVersion @@ -455,18 +459,18 @@ fn verify_record_signature( let provided_sig = vec_to_signature(signature)?; let msg_hash = hashv(&[unsigned]); - let current_ix_index = - load_current_index_checked(instructions_sysvar).map_err(|_| error!(ErrCode::InvalidSignature))?; + let current_ix_index = load_current_index_checked(instructions_sysvar) + .map_err(|_| error!(ErrCode::InvalidSignature))?; require!(current_ix_index > 0, ErrCode::InvalidSignature); - let ed_ix = load_instruction_at_checked( - (current_ix_index - 1) as usize, - instructions_sysvar, - ) - .map_err(|_| error!(ErrCode::InvalidSignature))?; + let ed_ix = load_instruction_at_checked((current_ix_index - 1) as usize, instructions_sysvar) + .map_err(|_| error!(ErrCode::InvalidSignature))?; let parsed = parse_ed25519_ix(&ed_ix)?; require_keys_eq!(parsed.pubkey, *root_key, ErrCode::InvalidSignature); - require!(parsed.message == msg_hash.as_ref(), ErrCode::InvalidSignature); + require!( + parsed.message == msg_hash.as_ref(), + ErrCode::InvalidSignature + ); require!(parsed.signature == provided_sig, ErrCode::InvalidSignature); Ok(parsed.signature) @@ -479,7 +483,11 @@ struct ParsedEd25519 { } fn parse_ed25519_ix(ix: &Instruction) -> Result { - require_keys_eq!(ix.program_id, ed25519_program::id(), ErrCode::InvalidSignature); + require_keys_eq!( + ix.program_id, + ed25519_program::id(), + ErrCode::InvalidSignature + ); let data = &ix.data; require!(data.len() >= 16, ErrCode::InvalidSignature); @@ -554,7 +562,10 @@ fn validate_login(login: &str) -> Result<()> { fn validate_fields(fields: &UserMutableFields) -> Result<()> { if fields.is_server { - require!(!fields.server_address.is_empty(), ErrCode::InvalidRecordData); + require!( + !fields.server_address.is_empty(), + ErrCode::InvalidRecordData + ); require!( fields.server_address.as_bytes().len() <= u8::MAX as usize, ErrCode::InvalidRecordData @@ -568,7 +579,10 @@ fn validate_fields(fields: &UserMutableFields) -> Result<()> { ); for login in &fields.connection_servers { require!(!login.is_empty(), ErrCode::InvalidRecordData); - require!(login.as_bytes().len() <= u8::MAX as usize, ErrCode::InvalidRecordData); + require!( + login.as_bytes().len() <= u8::MAX as usize, + ErrCode::InvalidRecordData + ); } Ok(()) } @@ -590,7 +604,10 @@ fn transfer_lamports<'info>( return Ok(()); } let ix = system_instruction::transfer(payer.key, recipient.key, lamports); - invoke(&ix, &[payer.clone(), recipient.clone(), system_program.clone()])?; + invoke( + &ix, + &[payer.clone(), recipient.clone(), system_program.clone()], + )?; Ok(()) } @@ -629,7 +646,9 @@ fn vec_to_hash32(input: &[u8]) -> Result<[u8; 32]> { } fn read_u8(data: &[u8], cursor: &mut usize) -> Result { - let v = *data.get(*cursor).ok_or(error!(ErrCode::InvalidRecordData))?; + let v = *data + .get(*cursor) + .ok_or(error!(ErrCode::InvalidRecordData))?; *cursor += 1; Ok(v) } @@ -638,7 +657,9 @@ fn read_u16(data: &[u8], cursor: &mut usize) -> Result { let end = cursor .checked_add(2) .ok_or(error!(ErrCode::InvalidRecordData))?; - let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?; + let slice = data + .get(*cursor..end) + .ok_or(error!(ErrCode::InvalidRecordData))?; *cursor = end; Ok(u16::from_le_bytes([slice[0], slice[1]])) } @@ -647,7 +668,9 @@ fn read_u32(data: &[u8], cursor: &mut usize) -> Result { let end = cursor .checked_add(4) .ok_or(error!(ErrCode::InvalidRecordData))?; - let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?; + let slice = data + .get(*cursor..end) + .ok_or(error!(ErrCode::InvalidRecordData))?; *cursor = end; Ok(u32::from_le_bytes([slice[0], slice[1], slice[2], slice[3]])) } @@ -656,7 +679,9 @@ fn read_u64(data: &[u8], cursor: &mut usize) -> Result { let end = cursor .checked_add(8) .ok_or(error!(ErrCode::InvalidRecordData))?; - let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?; + let slice = data + .get(*cursor..end) + .ok_or(error!(ErrCode::InvalidRecordData))?; *cursor = end; Ok(u64::from_le_bytes([ slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7], @@ -667,7 +692,9 @@ fn read_fixed_32(data: &[u8], cursor: &mut usize) -> Result<[u8; 32]> { let end = cursor .checked_add(32) .ok_or(error!(ErrCode::InvalidRecordData))?; - let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?; + let slice = data + .get(*cursor..end) + .ok_or(error!(ErrCode::InvalidRecordData))?; *cursor = end; let mut out = [0u8; 32]; out.copy_from_slice(slice); @@ -678,7 +705,9 @@ fn read_fixed_64(data: &[u8], cursor: &mut usize) -> Result<[u8; 64]> { let end = cursor .checked_add(64) .ok_or(error!(ErrCode::InvalidRecordData))?; - let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?; + let slice = data + .get(*cursor..end) + .ok_or(error!(ErrCode::InvalidRecordData))?; *cursor = end; let mut out = [0u8; 64]; out.copy_from_slice(slice); @@ -690,7 +719,9 @@ fn read_len_prefixed_string(data: &[u8], cursor: &mut usize) -> Result { let end = cursor .checked_add(len) .ok_or(error!(ErrCode::InvalidRecordData))?; - let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?; + let slice = data + .get(*cursor..end) + .ok_or(error!(ErrCode::InvalidRecordData))?; *cursor = end; let value = std::str::from_utf8(slice).map_err(|_| error!(ErrCode::InvalidRecordData))?; Ok(value.to_string()) diff --git a/shine/scripts/dao/README.md b/shine/scripts/dao/README.md new file mode 100644 index 0000000..5c46814 --- /dev/null +++ b/shine/scripts/dao/README.md @@ -0,0 +1,60 @@ +# DAO scripts (актуальные) + +## 1) Проверка конфигурации + +```bash +scripts/dao/create_realm_dao_full_test.sh scripts/dao/dao.config.env +``` + +## 2) Реальное создание FULL DAO + +```bash +node scripts/dao/create_realm_dao_full_build_exec.js scripts/dao/dao.config.env +``` + +Что делает: + +1. Создает governance mint (SPL, decimals=0, supply из конфига). +2. Добавляет on-chain metadata для mint (URI и картинка из Arweave). +3. Создает Realm / Governance / Native Treasury. +4. Депозитит governance токены в Realm. +5. Пишет отчеты в `scripts/dao/runs/*.json` и `*.txt`. + +## 3) Revoke/Burn membership токенов + +### Вариант A (рекомендуется): через DAO голосование + +```bash +node scripts/dao/propose_vote_execute_revoke_full_exec.js \ + scripts/dao/dao.config.env \ + \ + \ + \ + \ + [AMOUNT] +``` + +Скрипт делает полный цикл: + +1. `create proposal` +2. `insert revoke instruction` +3. `sign off` +4. `cast vote` +5. `execute` + +### Вариант B (технический/админский): прямой revoke + +```bash +node scripts/dao/revoke_member_token_full_exec.js \ + scripts/dao/dao.config.env \ + \ + \ + \ + [AMOUNT] +``` + +Важное: + +1. Для `RevokeGoverningTokens` токен должен быть membership-типом (в full-скрипте это уже так). +2. Для сценария “только DAO голосованием” используйте вариант A. +3. Вариант B оставлен как технический инструмент. diff --git a/shine/scripts/dao/create_realm_dao_full_build_exec.js b/shine/scripts/dao/create_realm_dao_full_build_exec.js new file mode 100755 index 0000000..be76ea1 --- /dev/null +++ b/shine/scripts/dao/create_realm_dao_full_build_exec.js @@ -0,0 +1,456 @@ +#!/usr/bin/env node +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const readline = require("readline"); +const BN = require("bn.js"); +const { + Connection, + Keypair, + PublicKey, + SystemProgram, + Transaction, + sendAndConfirmTransaction, + clusterApiUrl, +} = require("@solana/web3.js"); +const { + TOKEN_PROGRAM_ID, + AuthorityType, + getMintLen, + createInitializeMintInstruction, + getAssociatedTokenAddressSync, + createAssociatedTokenAccountIdempotentInstruction, + createMintToInstruction, + createSetAuthorityInstruction, +} = require("@solana/spl-token"); +const { + MintMaxVoteWeightSource, + VoteThreshold, + VoteThresholdType, + VoteTipping, + GovernanceConfig, + PROGRAM_VERSION_V3, + GoverningTokenConfigAccountArgs, + GoverningTokenType, + withCreateRealm, + withDepositGoverningTokens, + withCreateGovernance, + withCreateNativeTreasury, + withSetRealmAuthority, + SetRealmAuthorityAction, +} = require("@solana/spl-governance"); +const { createUmi } = require("@metaplex-foundation/umi-bundle-defaults"); +const { + createSignerFromKeypair, + signerIdentity, + percentAmount, + none, + some, +} = require("@metaplex-foundation/umi"); +const { fromWeb3JsKeypair, fromWeb3JsPublicKey } = require("@metaplex-foundation/umi-web3js-adapters"); +const { mplTokenMetadata, createV1, TokenStandard } = require("@metaplex-foundation/mpl-token-metadata"); + +function parseEnvConfig(configPath) { + const raw = fs.readFileSync(configPath, "utf8"); + const out = {}; + for (const line of raw.split("\n")) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) continue; + const eq = trimmed.indexOf("="); + if (eq === -1) continue; + const key = trimmed.slice(0, eq).trim(); + let val = trimmed.slice(eq + 1).trim(); + if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) { + val = val.slice(1, -1); + } + val = val.replace(/\$HOME/g, process.env.HOME || ""); + out[key] = val; + } + return out; +} + +function assertRequired(cfg, key) { + if (!cfg[key]) throw new Error(`В конфиге отсутствует обязательный параметр: ${key}`); +} + +function loadKeypair(filePath) { + const arr = JSON.parse(fs.readFileSync(filePath, "utf8")); + return Keypair.fromSecretKey(Uint8Array.from(arr)); +} + +function lamportsToSol(lamports) { + return Number(lamports) / 1_000_000_000; +} + +function nowStamp() { + const d = new Date(); + const p = (n) => String(n).padStart(2, "0"); + return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}_${p(d.getHours())}-${p( + d.getMinutes() + )}-${p(d.getSeconds())}`; +} + +async function askYes() { + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); + const answer = await new Promise((resolve) => + rl.question("Введите YES для реального создания ПОЛНОГО DAO: ", resolve) + ); + rl.close(); + return answer.trim() === "YES"; +} + +function ensureArweaveUri(name, uri) { + if (!uri) throw new Error(`${name} пустой`); + if (!(uri.startsWith("https://arweave.net/") || uri.startsWith("ar://"))) { + throw new Error(`${name} должен указывать на Arweave (https://arweave.net/... или ar://...)`); + } +} + +async function attachTokenMetadataViaUmi(cfg, cluster, issuer, mintPubkey, mintKeypair) { + ensureArweaveUri("DAO_GOV_TOKEN_METADATA_URI", cfg.DAO_GOV_TOKEN_METADATA_URI); + ensureArweaveUri("DAO_GOV_TOKEN_IMAGE_URL", cfg.DAO_GOV_TOKEN_IMAGE_URL); + + const umi = createUmi(clusterApiUrl(cluster)); + const umiSigner = createSignerFromKeypair(umi, fromWeb3JsKeypair(issuer)); + const umiMintSigner = createSignerFromKeypair(umi, fromWeb3JsKeypair(mintKeypair)); + umi.use(signerIdentity(umiSigner)); + umi.use(mplTokenMetadata()); + + const builder = createV1(umi, { + mint: umiMintSigner, + authority: umiSigner, + payer: umiSigner, + updateAuthority: umiSigner, + name: cfg.DAO_GOV_NFT_NAME, + symbol: cfg.DAO_GOV_NFT_SYMBOL, + uri: cfg.DAO_GOV_TOKEN_METADATA_URI, + sellerFeeBasisPoints: percentAmount(0), + tokenStandard: TokenStandard.Fungible, + decimals: some(0), + creators: none(), + collection: none(), + uses: none(), + collectionDetails: none(), + ruleSet: none(), + printSupply: none(), + primarySaleHappened: false, + isMutable: true, + isCollection: false, + splTokenProgram: fromWeb3JsPublicKey(TOKEN_PROGRAM_ID), + }); + + const res = await builder.sendAndConfirm(umi); + const sig = Buffer.from(res.signature).toString("base64"); + return sig; +} + +async function main() { + const configPath = process.argv[2] + ? path.resolve(process.argv[2]) + : path.resolve(__dirname, "dao.config.env"); + if (!fs.existsSync(configPath)) throw new Error(`Конфиг не найден: ${configPath}`); + + const cfg = parseEnvConfig(configPath); + [ + "DAO_CLUSTER", + "DAO_REALM_NAME", + "DAO_GOV_NFT_NAME", + "DAO_GOV_NFT_SYMBOL", + "DAO_GOV_NFT_SUPPLY", + "DAO_VOTING_TIME_SEC", + "DAO_APPROVAL_THRESHOLD_PERCENT", + "DAO_ISSUER_KEYPAIR", + "SPL_GOVERNANCE_PROGRAM_ID", + "DAO_GOV_TOKEN_METADATA_URI", + "DAO_GOV_TOKEN_IMAGE_URL", + ].forEach((k) => assertRequired(cfg, k)); + + const cluster = cfg.DAO_CLUSTER; + const connection = new Connection(clusterApiUrl(cluster), "confirmed"); + const issuer = loadKeypair(path.resolve(cfg.DAO_ISSUER_KEYPAIR)); + const governanceProgramId = new PublicKey(cfg.SPL_GOVERNANCE_PROGRAM_ID); + + const supply = Number(cfg.DAO_GOV_NFT_SUPPLY); + const votingTimeSec = Number(cfg.DAO_VOTING_TIME_SEC); + const thresholdPct = Number(cfg.DAO_APPROVAL_THRESHOLD_PERCENT); + if (!Number.isInteger(supply) || supply <= 0) throw new Error("DAO_GOV_NFT_SUPPLY должен быть целым > 0"); + if (!Number.isInteger(votingTimeSec) || votingTimeSec < 3600) + throw new Error("DAO_VOTING_TIME_SEC должен быть >= 3600 (ограничение Realms)"); + if (!Number.isInteger(thresholdPct) || thresholdPct < 51 || thresholdPct > 100) + throw new Error("DAO_APPROVAL_THRESHOLD_PERCENT должен быть в диапазоне 51..100"); + + const [realmPda] = PublicKey.findProgramAddressSync( + [Buffer.from("governance"), Buffer.from(cfg.DAO_REALM_NAME, "utf8")], + governanceProgramId + ); + const realmExists = (await connection.getAccountInfo(realmPda)) !== null; + if (realmExists) throw new Error(`Realm уже существует: ${realmPda.toBase58()}`); + + const startBalance = await connection.getBalance(issuer.publicKey, "confirmed"); + console.log("============================================================"); + console.log("СОЗДАНИЕ DAO (FULL)"); + console.log("------------------------------------------------------------"); + console.log("Сеть: ", cluster); + console.log("Realm name: ", cfg.DAO_REALM_NAME); + console.log("Realm PDA: ", realmPda.toBase58()); + console.log("Governance program: ", governanceProgramId.toBase58()); + console.log("Issuer: ", issuer.publicKey.toBase58()); + console.log("Баланс до старта: ", `${lamportsToSol(startBalance)} SOL`); + console.log("Token name/symbol: ", `${cfg.DAO_GOV_NFT_NAME} / ${cfg.DAO_GOV_NFT_SYMBOL}`); + console.log("Token supply: ", supply); + console.log("Voting time sec: ", votingTimeSec); + console.log("Threshold %: ", thresholdPct); + console.log("Arweave metadata URI:", cfg.DAO_GOV_TOKEN_METADATA_URI); + console.log("Arweave image URL: ", cfg.DAO_GOV_TOKEN_IMAGE_URL); + console.log("============================================================"); + + const ok = await askYes(); + if (!ok) { + console.log("Отменено пользователем."); + return; + } + + const mintKeypair = Keypair.generate(); + const mintLen = getMintLen([]); + const mintRent = await connection.getMinimumBalanceForRentExemption(mintLen); + const issuerAta = getAssociatedTokenAddressSync(mintKeypair.publicKey, issuer.publicKey, false, TOKEN_PROGRAM_ID); + + const txMint = new Transaction().add( + SystemProgram.createAccount({ + fromPubkey: issuer.publicKey, + newAccountPubkey: mintKeypair.publicKey, + space: mintLen, + lamports: mintRent, + programId: TOKEN_PROGRAM_ID, + }), + createInitializeMintInstruction(mintKeypair.publicKey, 0, issuer.publicKey, issuer.publicKey, TOKEN_PROGRAM_ID), + createAssociatedTokenAccountIdempotentInstruction( + issuer.publicKey, + issuerAta, + issuer.publicKey, + mintKeypair.publicKey, + TOKEN_PROGRAM_ID + ), + createMintToInstruction(mintKeypair.publicKey, issuerAta, issuer.publicKey, supply, [], TOKEN_PROGRAM_ID) + ); + const sigMint = await sendAndConfirmTransaction(connection, txMint, [issuer, mintKeypair], { + commitment: "confirmed", + }); + + const sigMetadata = await attachTokenMetadataViaUmi( + cfg, + cluster, + issuer, + mintKeypair.publicKey, + mintKeypair + ); + + const programVersion = PROGRAM_VERSION_V3; + const ixRealm = []; + const communityTokenConfig = new GoverningTokenConfigAccountArgs({ + voterWeightAddin: undefined, + maxVoterWeightAddin: undefined, + tokenType: GoverningTokenType.Membership, + }); + const realmPk = await withCreateRealm( + ixRealm, + governanceProgramId, + programVersion, + cfg.DAO_REALM_NAME, + issuer.publicKey, + mintKeypair.publicKey, + issuer.publicKey, + undefined, + MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION, + new BN(1), + communityTokenConfig, + undefined + ); + const sigRealm = await sendAndConfirmTransaction(connection, new Transaction().add(...ixRealm), [issuer], { + commitment: "confirmed", + }); + + const ixDeposit = []; + const tokenOwnerRecordPk = await withDepositGoverningTokens( + ixDeposit, + governanceProgramId, + programVersion, + realmPk, + issuerAta, + mintKeypair.publicKey, + issuer.publicKey, + issuer.publicKey, + issuer.publicKey, + new BN(supply), + true + ); + const sigDeposit = await sendAndConfirmTransaction(connection, new Transaction().add(...ixDeposit), [issuer], { + commitment: "confirmed", + }); + + const governanceConfig = new GovernanceConfig({ + communityVoteThreshold: new VoteThreshold({ type: VoteThresholdType.YesVotePercentage, value: thresholdPct }), + minCommunityTokensToCreateProposal: new BN(1), + minInstructionHoldUpTime: 0, + baseVotingTime: votingTimeSec, + communityVoteTipping: VoteTipping.Early, + minCouncilTokensToCreateProposal: new BN(0), + councilVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + councilVetoVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + communityVetoVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + councilVoteTipping: VoteTipping.Disabled, + votingCoolOffTime: 0, + depositExemptProposalCount: 0, + }); + + const ixGov = []; + const governancePk = await withCreateGovernance( + ixGov, + governanceProgramId, + programVersion, + realmPk, + realmPk, + governanceConfig, + tokenOwnerRecordPk, + issuer.publicKey, + issuer.publicKey + ); + const treasuryPk = await withCreateNativeTreasury(ixGov, governanceProgramId, programVersion, governancePk, issuer.publicKey); + const sigGov = await sendAndConfirmTransaction(connection, new Transaction().add(...ixGov), [issuer], { + commitment: "confirmed", + }); + + // Для DAO revoke governing tokens mint authority должен быть у governance PDA. + const ixSetMintAuthority = [ + createSetAuthorityInstruction( + mintKeypair.publicKey, + issuer.publicKey, + AuthorityType.MintTokens, + governancePk, + [], + TOKEN_PROGRAM_ID + ), + ]; + const sigSetMintAuthority = await sendAndConfirmTransaction( + connection, + new Transaction().add(...ixSetMintAuthority), + [issuer], + { commitment: "confirmed" } + ); + + const ixRealmAuthority = []; + withSetRealmAuthority( + ixRealmAuthority, + governanceProgramId, + programVersion, + realmPk, + issuer.publicKey, + governancePk, + SetRealmAuthorityAction.SetChecked + ); + const sigSetRealmAuthority = await sendAndConfirmTransaction( + connection, + new Transaction().add(...ixRealmAuthority), + [issuer], + { commitment: "confirmed" } + ); + + const endBalance = await connection.getBalance(issuer.publicKey, "confirmed"); + const spentLamports = startBalance - endBalance; + const report = { + createdAt: new Date().toISOString(), + cluster, + configPath, + realmName: cfg.DAO_REALM_NAME, + governanceProgramId: governanceProgramId.toBase58(), + issuer: issuer.publicKey.toBase58(), + communityMint: mintKeypair.publicKey.toBase58(), + issuerAta: issuerAta.toBase58(), + realm: realmPk.toBase58(), + tokenOwnerRecord: tokenOwnerRecordPk.toBase58(), + governance: governancePk.toBase58(), + nativeTreasury: treasuryPk.toBase58(), + metadataUri: cfg.DAO_GOV_TOKEN_METADATA_URI, + imageUrl: cfg.DAO_GOV_TOKEN_IMAGE_URL, + txMint: sigMint, + txMetadata: sigMetadata, + txRealm: sigRealm, + txDeposit: sigDeposit, + txGovernanceTreasury: sigGov, + txSetMintAuthorityToGovernance: sigSetMintAuthority, + txSetRealmAuthority: sigSetRealmAuthority, + votingTimeSec, + thresholdPercent: thresholdPct, + tokenSupply: supply, + startBalanceLamports: startBalance, + endBalanceLamports: endBalance, + spentLamports, + startBalanceSol: lamportsToSol(startBalance), + endBalanceSol: lamportsToSol(endBalance), + spentSol: lamportsToSol(spentLamports), + }; + const reportDir = path.resolve(__dirname, "runs"); + fs.mkdirSync(reportDir, { recursive: true }); + const reportBaseName = `${nowStamp()}_${cfg.DAO_REALM_NAME.replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 80)}_full`; + const reportJsonPath = path.join(reportDir, `${reportBaseName}.json`); + const reportTxtPath = path.join(reportDir, `${reportBaseName}.txt`); + fs.writeFileSync(reportJsonPath, JSON.stringify(report, null, 2)); + fs.writeFileSync( + reportTxtPath, + [ + `createdAt: ${report.createdAt}`, + `cluster: ${report.cluster}`, + `realmName: ${report.realmName}`, + `governanceProgramId: ${report.governanceProgramId}`, + `issuer: ${report.issuer}`, + `communityMint: ${report.communityMint}`, + `issuerAta: ${report.issuerAta}`, + `realm: ${report.realm}`, + `tokenOwnerRecord: ${report.tokenOwnerRecord}`, + `governance: ${report.governance}`, + `nativeTreasury: ${report.nativeTreasury}`, + `metadataUri: ${report.metadataUri}`, + `imageUrl: ${report.imageUrl}`, + `txMint: ${report.txMint}`, + `txMetadata: ${report.txMetadata}`, + `txRealm: ${report.txRealm}`, + `txDeposit: ${report.txDeposit}`, + `txGovernanceTreasury: ${report.txGovernanceTreasury}`, + `txSetMintAuthorityToGovernance: ${report.txSetMintAuthorityToGovernance}`, + `txSetRealmAuthority: ${report.txSetRealmAuthority}`, + `tokenSupply: ${report.tokenSupply}`, + `votingTimeSec: ${report.votingTimeSec}`, + `thresholdPercent: ${report.thresholdPercent}`, + `startBalanceSol: ${report.startBalanceSol}`, + `endBalanceSol: ${report.endBalanceSol}`, + `spentSol: ${report.spentSol}`, + `configPath: ${report.configPath}`, + ].join("\n") + "\n" + ); + + console.log("============================================================"); + console.log("DAO FULL СОЗДАНО"); + console.log("------------------------------------------------------------"); + console.log("Community mint (SPL + metadata): ", mintKeypair.publicKey.toBase58()); + console.log("Realm: ", realmPk.toBase58()); + console.log("Governance: ", governancePk.toBase58()); + console.log("Native treasury PDA: ", treasuryPk.toBase58()); + console.log("Tx mint: ", sigMint); + console.log("Tx metadata: ", sigMetadata); + console.log("Tx realm: ", sigRealm); + console.log("Tx deposit: ", sigDeposit); + console.log("Tx governance+treasury: ", sigGov); + console.log("Tx set mint authority -> governance: ", sigSetMintAuthority); + console.log("Tx set realm authority -> governance: ", sigSetRealmAuthority); + console.log("Баланс после: ", `${lamportsToSol(endBalance)} SOL`); + console.log("Потрачено: ", `${lamportsToSol(spentLamports)} SOL`); + console.log("Отчёт JSON: ", reportJsonPath); + console.log("Отчёт TXT: ", reportTxtPath); + console.log("============================================================"); +} + +main().catch((e) => { + console.error("Ошибка создания DAO FULL:", e?.message || e); + process.exit(1); +}); diff --git a/shine/scripts/dao/create_realm_dao_full_test.sh b/shine/scripts/dao/create_realm_dao_full_test.sh new file mode 100755 index 0000000..9248ce9 --- /dev/null +++ b/shine/scripts/dao/create_realm_dao_full_test.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG_PATH="${1:-$SCRIPT_DIR/dao.config.env}" + +if [[ ! -f "$CONFIG_PATH" ]]; then + echo "Ошибка: не найден конфиг $CONFIG_PATH" + exit 1 +fi + +# shellcheck disable=SC1090 +source "$CONFIG_PATH" + +require_cmd() { + if ! command -v "$1" >/dev/null 2>&1; then + echo "Ошибка: команда '$1' не найдена" + exit 1 + fi +} + +require_cmd solana +require_cmd solana-keygen +require_cmd node + +if [[ -z "${DAO_REALM_NAME:-}" || -z "${DAO_CLUSTER:-}" || -z "${DAO_ISSUER_KEYPAIR:-}" || -z "${SPL_GOVERNANCE_PROGRAM_ID:-}" ]]; then + echo "Ошибка: обязательные поля конфига пустые" + exit 1 +fi + +if [[ ! -f "$DAO_ISSUER_KEYPAIR" ]]; then + echo "Ошибка: keypair не найден: $DAO_ISSUER_KEYPAIR" + exit 1 +fi + +if [[ "${DAO_REALM_NAME}" == *"TEMPLATE"* || "${DAO_REALM_NAME}" == *"CHANGE_ME"* ]]; then + echo "Ошибка: похоже, не заменили тестовое имя DAO_REALM_NAME" + exit 1 +fi + +if ! [[ "${DAO_VOTING_TIME_SEC}" =~ ^[0-9]+$ ]] || ! [[ "${DAO_GOV_NFT_SUPPLY}" =~ ^[0-9]+$ ]] || ! [[ "${DAO_APPROVAL_THRESHOLD_PERCENT}" =~ ^[0-9]+$ ]]; then + echo "Ошибка: числовые параметры заданы некорректно" + exit 1 +fi + +if (( DAO_APPROVAL_THRESHOLD_PERCENT < 51 || DAO_APPROVAL_THRESHOLD_PERCENT > 100 )); then + echo "Ошибка: DAO_APPROVAL_THRESHOLD_PERCENT должен быть в диапазоне 51..100" + exit 1 +fi + +ISSUER_PUBKEY="$(solana-keygen pubkey "$DAO_ISSUER_KEYPAIR")" +ISSUER_BALANCE="$(solana balance "$ISSUER_PUBKEY" --url "$DAO_CLUSTER" 2>/dev/null || true)" + +REALM_PDA="$(node - "$DAO_REALM_NAME" "$SPL_GOVERNANCE_PROGRAM_ID" <<'NODE' +const { PublicKey } = require("@solana/web3.js"); +const realmName = process.argv[2]; +const programId = new PublicKey(process.argv[3]); +const [pda] = PublicKey.findProgramAddressSync( + [Buffer.from("governance"), Buffer.from(realmName, "utf8")], + programId +); +console.log(pda.toBase58()); +NODE +)" + +if [[ -z "$REALM_PDA" ]]; then + echo "Ошибка: не удалось вычислить PDA realm." + exit 1 +fi + +REALM_EXISTS="no" +if solana account "$REALM_PDA" --url "$DAO_CLUSTER" >/dev/null 2>&1; then + REALM_EXISTS="yes" +fi + +cat < + new AccountMetaData({ + pubkey: k.pubkey, + isSigner: !!k.isSigner, + isWritable: !!k.isWritable, + }) + ), + data: Uint8Array.from(ix.data), + }); +} + +async function main() { + const configPath = process.argv[2] ? path.resolve(process.argv[2]) : path.resolve(__dirname, "dao.config.env"); + const realm = new PublicKey(process.argv[3]); + const governance = new PublicKey(process.argv[4]); + const proposal = new PublicKey(process.argv[5]); + const proposalTx = new PublicKey(process.argv[6]); + const mint = new PublicKey(process.argv[7]); + const targetOwner = new PublicKey(process.argv[8]); + const amount = new BN(process.argv[9] || "1"); + if (!process.argv[8]) { + throw new Error( + "Использование: node scripts/dao/execute_revoke_transaction_full_exec.js [amount]" + ); + } + const cfg = parseEnvConfig(configPath); + const cluster = cfg.DAO_CLUSTER || "devnet"; + const governanceProgramId = new PublicKey(cfg.SPL_GOVERNANCE_PROGRAM_ID); + const signer = loadKeypair(path.resolve(cfg.DAO_ISSUER_KEYPAIR)); + const connection = new Connection(clusterApiUrl(cluster), "confirmed"); + + const ixRawRevoke = []; + await withRevokeGoverningTokens( + ixRawRevoke, + governanceProgramId, + PROGRAM_VERSION_V3, + realm, + targetOwner, + mint, + governance, + amount + ); + const revokeInstructionData = toGovernanceInstructionData(ixRawRevoke[0]); + + const ixExecute = []; + await withExecuteTransaction( + ixExecute, + governanceProgramId, + PROGRAM_VERSION_V3, + governance, + proposal, + proposalTx, + [revokeInstructionData] + ); + const sig = await sendAndConfirmTransaction(connection, new Transaction().add(...ixExecute), [signer], { + commitment: "confirmed", + }); + console.log("Execute success. Tx:", sig); +} + +main().catch((e) => { + console.error("Ошибка execute revoke:", e?.message || e); + process.exit(1); +}); + diff --git a/shine/scripts/dao/propose_vote_execute_revoke_full_exec.js b/shine/scripts/dao/propose_vote_execute_revoke_full_exec.js new file mode 100755 index 0000000..832b28a --- /dev/null +++ b/shine/scripts/dao/propose_vote_execute_revoke_full_exec.js @@ -0,0 +1,399 @@ +#!/usr/bin/env node +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const readline = require("readline"); +const BN = require("bn.js"); +const { + Connection, + Keypair, + PublicKey, + Transaction, + sendAndConfirmTransaction, + clusterApiUrl, +} = require("@solana/web3.js"); +const { + PROGRAM_VERSION_V3, + Vote, + YesNoVote, + VoteType, + InstructionData, + AccountMetaData, + withRevokeGoverningTokens, + withCreateProposal, + withInsertTransaction, + withSignOffProposal, + withCastVote, + withExecuteTransaction, + withFinalizeVote, + getTokenOwnerRecordAddress, + getProposalTransactionAddress, +} = require("@solana/spl-governance"); + +function parseEnvConfig(configPath) { + const raw = fs.readFileSync(configPath, "utf8"); + const out = {}; + for (const line of raw.split("\n")) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) continue; + const eq = trimmed.indexOf("="); + if (eq === -1) continue; + const key = trimmed.slice(0, eq).trim(); + let val = trimmed.slice(eq + 1).trim(); + if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) { + val = val.slice(1, -1); + } + val = val.replace(/\$HOME/g, process.env.HOME || ""); + out[key] = val; + } + return out; +} + +function loadKeypair(filePath) { + const arr = JSON.parse(fs.readFileSync(filePath, "utf8")); + return Keypair.fromSecretKey(Uint8Array.from(arr)); +} + +function nowStamp() { + const d = new Date(); + const p = (n) => String(n).padStart(2, "0"); + return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}_${p(d.getHours())}-${p( + d.getMinutes() + )}-${p(d.getSeconds())}`; +} + +async function askYes() { + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); + const answer = await new Promise((resolve) => + rl.question("Введите YES для proposal->vote->execute revoke: ", resolve) + ); + rl.close(); + return answer.trim() === "YES"; +} + +function toGovernanceInstructionData(ix) { + return new InstructionData({ + programId: ix.programId, + accounts: ix.keys.map( + (k) => + new AccountMetaData({ + pubkey: k.pubkey, + isSigner: !!k.isSigner, + isWritable: !!k.isWritable, + }) + ), + data: Uint8Array.from(ix.data), + }); +} + +function classifyExecuteError(msg) { + const s = String(msg || "").toLowerCase(); + if (s.includes("0x20d") || s.includes("hold up time")) { + return "HOLD_UP_TIME"; + } + if (s.includes("0x21d") || s.includes("invalid mint authority")) { + return "INVALID_MINT_AUTHORITY"; + } + return "OTHER"; +} + +async function main() { + const configPath = process.argv[2] + ? path.resolve(process.argv[2]) + : path.resolve(__dirname, "dao.config.env"); + const realmStr = process.argv[3]; + const governanceStr = process.argv[4]; + const mintStr = process.argv[5]; + const targetOwnerStr = process.argv[6]; + const amountStr = process.argv[7] || "1"; + if (!realmStr || !governanceStr || !mintStr || !targetOwnerStr) { + throw new Error( + "Использование: node scripts/dao/propose_vote_execute_revoke_full_exec.js [amount]" + ); + } + + const cfg = parseEnvConfig(configPath); + const cluster = cfg.DAO_CLUSTER || "devnet"; + const governanceProgramId = new PublicKey(cfg.SPL_GOVERNANCE_PROGRAM_ID); + const proposerKpPath = cfg.DAO_ISSUER_KEYPAIR; + if (!proposerKpPath) throw new Error("В конфиге нет DAO_ISSUER_KEYPAIR"); + const proposer = loadKeypair(path.resolve(proposerKpPath)); + + const realm = new PublicKey(realmStr); + const governance = new PublicKey(governanceStr); + const mint = new PublicKey(mintStr); + const targetOwner = new PublicKey(targetOwnerStr); + const amount = new BN(amountStr); + if (amount.lten(0)) throw new Error("amount должен быть > 0"); + + const connection = new Connection(clusterApiUrl(cluster), "confirmed"); + const proposerRecord = await getTokenOwnerRecordAddress( + governanceProgramId, + realm, + mint, + proposer.publicKey + ); + + console.log("============================================================"); + console.log("DAO REVOKE THROUGH VOTE"); + console.log("------------------------------------------------------------"); + console.log("Сеть: ", cluster); + console.log("Governance program: ", governanceProgramId.toBase58()); + console.log("Realm: ", realm.toBase58()); + console.log("Governance: ", governance.toBase58()); + console.log("Mint: ", mint.toBase58()); + console.log("Target owner: ", targetOwner.toBase58()); + console.log("Amount: ", amount.toString()); + console.log("Proposer: ", proposer.publicKey.toBase58()); + console.log("Proposer record: ", proposerRecord.toBase58()); + console.log("============================================================"); + + const ok = await askYes(); + if (!ok) { + console.log("Отменено пользователем."); + return; + } + + const proposalName = `Revoke ${amount.toString()} from ${targetOwner + .toBase58() + .slice(0, 8)}...`; + const proposalDescription = cfg.DAO_REVOKE_PROPOSAL_URI || cfg.DAO_GOV_TOKEN_METADATA_URI || "https://arweave.net/"; + + const ixCreateProposal = []; + const proposalPk = await withCreateProposal( + ixCreateProposal, + governanceProgramId, + PROGRAM_VERSION_V3, + realm, + governance, + proposerRecord, + proposalName, + proposalDescription, + mint, + proposer.publicKey, + undefined, + VoteType.SINGLE_CHOICE, + ["Approve"], + true, + proposer.publicKey + ); + const sigCreateProposal = await sendAndConfirmTransaction( + connection, + new Transaction().add(...ixCreateProposal), + [proposer], + { commitment: "confirmed" } + ); + + const ixRawRevoke = []; + await withRevokeGoverningTokens( + ixRawRevoke, + governanceProgramId, + PROGRAM_VERSION_V3, + realm, + targetOwner, + mint, + governance, + amount + ); + if (ixRawRevoke.length !== 1) throw new Error("Ожидалась одна инструкция revoke"); + const revokeInstructionData = toGovernanceInstructionData(ixRawRevoke[0]); + + const ixInsert = []; + const proposalTxPk = await withInsertTransaction( + ixInsert, + governanceProgramId, + PROGRAM_VERSION_V3, + governance, + proposalPk, + proposerRecord, + proposer.publicKey, + 0, + 0, + 0, + [revokeInstructionData], + proposer.publicKey + ); + const sigInsert = await sendAndConfirmTransaction(connection, new Transaction().add(...ixInsert), [proposer], { + commitment: "confirmed", + }); + + const ixSignOff = []; + withSignOffProposal( + ixSignOff, + governanceProgramId, + PROGRAM_VERSION_V3, + realm, + governance, + proposalPk, + proposer.publicKey, + undefined, + proposerRecord + ); + const sigSignOff = await sendAndConfirmTransaction(connection, new Transaction().add(...ixSignOff), [proposer], { + commitment: "confirmed", + }); + + const ixVote = []; + const vote = Vote.fromYesNoVote(YesNoVote.Yes); + const voteRecordPk = await withCastVote( + ixVote, + governanceProgramId, + PROGRAM_VERSION_V3, + realm, + governance, + proposalPk, + proposerRecord, + proposerRecord, + proposer.publicKey, + mint, + vote, + proposer.publicKey + ); + const sigVote = await sendAndConfirmTransaction(connection, new Transaction().add(...ixVote), [proposer], { + commitment: "confirmed", + }); + + const computedProposalTxPk = await getProposalTransactionAddress( + governanceProgramId, + PROGRAM_VERSION_V3, + proposalPk, + 0, + 0 + ); + if (!computedProposalTxPk.equals(proposalTxPk)) { + throw new Error("Несовпадение адреса proposal transaction"); + } + + let sigFinalize = null; + try { + const ixFinalize = []; + await withFinalizeVote( + ixFinalize, + governanceProgramId, + PROGRAM_VERSION_V3, + realm, + governance, + proposalPk, + proposerRecord, + mint + ); + sigFinalize = await sendAndConfirmTransaction(connection, new Transaction().add(...ixFinalize), [proposer], { + commitment: "confirmed", + }); + } catch (_) { + // Может быть уже tipped/succeeded без finalize. + } + + let sigExecute = null; + let executeError = null; + let executeErrorKind = null; + try { + const ixExecute = []; + await withExecuteTransaction( + ixExecute, + governanceProgramId, + PROGRAM_VERSION_V3, + governance, + proposalPk, + proposalTxPk, + [revokeInstructionData] + ); + sigExecute = await sendAndConfirmTransaction(connection, new Transaction().add(...ixExecute), [proposer], { + commitment: "confirmed", + }); + } catch (e) { + executeError = e?.message || String(e); + executeErrorKind = classifyExecuteError(executeError); + } + + const report = { + createdAt: new Date().toISOString(), + cluster, + configPath, + governanceProgramId: governanceProgramId.toBase58(), + realm: realm.toBase58(), + governance: governance.toBase58(), + mint: mint.toBase58(), + targetOwner: targetOwner.toBase58(), + amount: amount.toString(), + proposer: proposer.publicKey.toBase58(), + proposerRecord: proposerRecord.toBase58(), + proposal: proposalPk.toBase58(), + proposalTransaction: proposalTxPk.toBase58(), + voteRecord: voteRecordPk.toBase58(), + txCreateProposal: sigCreateProposal, + txInsertTransaction: sigInsert, + txSignOff: sigSignOff, + txVote: sigVote, + txFinalize: sigFinalize, + txExecute: sigExecute, + executeError, + executeErrorKind, + }; + + const reportDir = path.resolve(__dirname, "runs"); + fs.mkdirSync(reportDir, { recursive: true }); + const reportBaseName = `${nowStamp()}_revoke_${targetOwner.toBase58().slice(0, 10)}`; + const reportJsonPath = path.join(reportDir, `${reportBaseName}.json`); + const reportTxtPath = path.join(reportDir, `${reportBaseName}.txt`); + fs.writeFileSync(reportJsonPath, JSON.stringify(report, null, 2)); + fs.writeFileSync( + reportTxtPath, + [ + `createdAt: ${report.createdAt}`, + `cluster: ${report.cluster}`, + `realm: ${report.realm}`, + `governance: ${report.governance}`, + `mint: ${report.mint}`, + `targetOwner: ${report.targetOwner}`, + `amount: ${report.amount}`, + `proposer: ${report.proposer}`, + `proposal: ${report.proposal}`, + `proposalTransaction: ${report.proposalTransaction}`, + `voteRecord: ${report.voteRecord}`, + `txCreateProposal: ${report.txCreateProposal}`, + `txInsertTransaction: ${report.txInsertTransaction}`, + `txSignOff: ${report.txSignOff}`, + `txVote: ${report.txVote}`, + `txFinalize: ${report.txFinalize || "-"}`, + `txExecute: ${report.txExecute || "-"}`, + `executeError: ${report.executeError || "-"}`, + `executeErrorKind: ${report.executeErrorKind || "-"}`, + ].join("\n") + "\n" + ); + + console.log("============================================================"); + console.log("REVOKE ЧЕРЕЗ DAO ГОЛОСОВАНИЕ ВЫПОЛНЕН"); + console.log("------------------------------------------------------------"); + console.log("Proposal: ", proposalPk.toBase58()); + console.log("Proposal Tx: ", proposalTxPk.toBase58()); + console.log("Tx create proposal: ", sigCreateProposal); + console.log("Tx insert revoke instruction: ", sigInsert); + console.log("Tx sign off: ", sigSignOff); + console.log("Tx cast vote: ", sigVote); + if (sigFinalize) console.log("Tx finalize vote: ", sigFinalize); + if (sigExecute) { + console.log("Tx execute: ", sigExecute); + } else { + console.log("Execute сейчас не прошел (ожидание voting/hold-up):"); + console.log("Ошибка execute: ", executeError); + if (executeErrorKind === "HOLD_UP_TIME") { + console.log("Причина: ", "слишком рано для execute (hold-up / окно голосования еще не завершено)"); + } else if (executeErrorKind === "INVALID_MINT_AUTHORITY") { + console.log("Причина: ", "community mint authority не передан на governance PDA при создании DAO"); + } + console.log("Повтор execute через время этой командой:"); + console.log( + `node scripts/dao/execute_revoke_transaction_full_exec.js ${configPath} ${realm.toBase58()} ${governance.toBase58()} ${proposalPk.toBase58()} ${proposalTxPk.toBase58()} ${mint.toBase58()} ${targetOwner.toBase58()} ${amount.toString()}` + ); + } + console.log("Отчёт JSON: ", reportJsonPath); + console.log("Отчёт TXT: ", reportTxtPath); + console.log("============================================================"); +} + +main().catch((e) => { + console.error("Ошибка proposal/vote/execute revoke:", e?.message || e); + process.exit(1); +}); diff --git a/shine/scripts/dao/revoke_member_token_full_exec.js b/shine/scripts/dao/revoke_member_token_full_exec.js new file mode 100755 index 0000000..6e5a86d --- /dev/null +++ b/shine/scripts/dao/revoke_member_token_full_exec.js @@ -0,0 +1,112 @@ +#!/usr/bin/env node +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const readline = require("readline"); +const BN = require("bn.js"); +const { Connection, Keypair, PublicKey, Transaction, sendAndConfirmTransaction, clusterApiUrl } = require("@solana/web3.js"); +const { PROGRAM_VERSION_V3, withRevokeGoverningTokens } = require("@solana/spl-governance"); + +function parseEnvConfig(configPath) { + const raw = fs.readFileSync(configPath, "utf8"); + const out = {}; + for (const line of raw.split("\n")) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) continue; + const eq = trimmed.indexOf("="); + if (eq === -1) continue; + const key = trimmed.slice(0, eq).trim(); + let val = trimmed.slice(eq + 1).trim(); + if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) { + val = val.slice(1, -1); + } + val = val.replace(/\$HOME/g, process.env.HOME || ""); + out[key] = val; + } + return out; +} + +function loadKeypair(filePath) { + const arr = JSON.parse(fs.readFileSync(filePath, "utf8")); + return Keypair.fromSecretKey(Uint8Array.from(arr)); +} + +async function askYes() { + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); + const answer = await new Promise((resolve) => + rl.question("Введите YES для отзыва (burn/revoke) governance токенов: ", resolve) + ); + rl.close(); + return answer.trim() === "YES"; +} + +async function main() { + const configPath = process.argv[2] + ? path.resolve(process.argv[2]) + : path.resolve(__dirname, "dao.config.env"); + const realmStr = process.argv[3]; + const mintStr = process.argv[4]; + const targetOwnerStr = process.argv[5]; + const amountStr = process.argv[6] || "1"; + if (!realmStr || !mintStr || !targetOwnerStr) { + throw new Error( + "Использование: node scripts/dao/revoke_member_token_full_exec.js [amount]" + ); + } + + const cfg = parseEnvConfig(configPath); + const cluster = cfg.DAO_CLUSTER || "devnet"; + const governanceProgramId = new PublicKey(cfg.SPL_GOVERNANCE_PROGRAM_ID); + const revokeKpPath = cfg.DAO_REVOKE_AUTHORITY_KEYPAIR || cfg.DAO_ISSUER_KEYPAIR; + if (!revokeKpPath) throw new Error("В конфиге нет DAO_REVOKE_AUTHORITY_KEYPAIR и DAO_ISSUER_KEYPAIR"); + const revokeAuthority = loadKeypair(path.resolve(revokeKpPath)); + + const realm = new PublicKey(realmStr); + const mint = new PublicKey(mintStr); + const targetOwner = new PublicKey(targetOwnerStr); + const amount = new BN(amountStr); + if (amount.lten(0)) throw new Error("amount должен быть > 0"); + + console.log("============================================================"); + console.log("REVOKE/BURN GOVERNANCE TOKENS"); + console.log("------------------------------------------------------------"); + console.log("Сеть: ", cluster); + console.log("Governance program: ", governanceProgramId.toBase58()); + console.log("Realm: ", realm.toBase58()); + console.log("Mint: ", mint.toBase58()); + console.log("Target owner: ", targetOwner.toBase58()); + console.log("Amount: ", amount.toString()); + console.log("Revoke authority: ", revokeAuthority.publicKey.toBase58()); + console.log("============================================================"); + + const ok = await askYes(); + if (!ok) { + console.log("Отменено пользователем."); + return; + } + + const connection = new Connection(clusterApiUrl(cluster), "confirmed"); + const ix = []; + await withRevokeGoverningTokens( + ix, + governanceProgramId, + PROGRAM_VERSION_V3, + realm, + targetOwner, + mint, + revokeAuthority.publicKey, + amount + ); + + const sig = await sendAndConfirmTransaction(connection, new Transaction().add(...ix), [revokeAuthority], { + commitment: "confirmed", + }); + console.log("Готово. Tx:", sig); +} + +main().catch((e) => { + console.error("Ошибка revoke:", e?.message || e); + process.exit(1); +}); + diff --git a/shine/scripts/dao/runs/2026-05-09_02-21-53_Devnet_DAO_Full-1_2026-05-09_full.json b/shine/scripts/dao/runs/2026-05-09_02-21-53_Devnet_DAO_Full-1_2026-05-09_full.json new file mode 100644 index 0000000..d9e5f66 --- /dev/null +++ b/shine/scripts/dao/runs/2026-05-09_02-21-53_Devnet_DAO_Full-1_2026-05-09_full.json @@ -0,0 +1,31 @@ +{ + "createdAt": "2026-05-08T23:21:53.557Z", + "cluster": "devnet", + "configPath": "/home/ai/work/SOLANA/shine-solana/shine/scripts/dao/dao.config.env", + "realmName": "Devnet DAO Full-1 2026-05-09", + "governanceProgramId": "GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw", + "issuer": "FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P", + "communityMint": "AKKhTDHWbDZy39f3UKeiP2z1rFmbv5K4DvxVL7KTQy8b", + "issuerAta": "CHfjpcyHotgczBErH7CCW9QMp8AeaGGyJxAtgV7ZyEwA", + "realm": "4vPg3A7uPZ4gZkNGy6vbDwsqYLwPgeciYqRbfpfuRa7A", + "tokenOwnerRecord": "97anU7DvmdpsQUY8ScmxswSPaGmMMw2FnNESiDQwzMjr", + "governance": "3NS5DT83nxh88xcndCPNrziFMvZNAjCSRu5jF1SpPRRt", + "nativeTreasury": "9vXFoN9ngfN1gpqQ3HT5n3y9Wp2r7HnSQckirgwVwWwb", + "metadataUri": "https://arweave.net/6cMl-qV-7vpgXSdOR5MVnMEPMHgLkRdfgdO43I9z5ek", + "imageUrl": "https://arweave.net/6cMl-qV-7vpgXSdOR5MVnMEPMHgLkRdfgdO43I9z5ek", + "txMint": "47cWAoXbDHYpW74exnBRma9QBoa3NMVx7iEU9mZsn74NYy3AK4tPptM1oPbaW91Mw3nZBTgxQtzgKSKP2Gdr8Hyh", + "txMetadata": "50d05LiBAXFmbt+jGZpw5tzvvNPAgwy/SiSmzb9l/v73GDFc2eN6+udw0fd9HdjYlP6t4oKYcsZB/kTRzqzMBg==", + "txRealm": "4v22Zmsm5qkoDQaeNuzeziH7GjxiUDSDRVeXLDYwgrXF3Ltw5xSkZFrVwPAiTZRPXzrm5bhbtSHd2rA7xPq9v4kG", + "txDeposit": "2gvWE3iA4yXhx3z1yshRRQgNEHcQgskmEsHSCo2X5WnvyXMzx8jtfyWZosvH7GWMmmtQegdaaTdtrAWeLXjiHtLw", + "txGovernanceTreasury": "4mArdxprVHpFtLMwyxmz9E99J8jwrGSsYvFmjR1SCMeWPim3HMZZQai9zrwBBn461axx5QDWiN7c9YVP7hXFmBmi", + "txSetRealmAuthority": "39qz1J4R63hxQQRrJ1EgdFG45PofBmtguP8V9Xx35FtPoo4APe5kPXhqyMKRK2o61iYHG5zvFob9bgUuzwvYPzaG", + "votingTimeSec": 3600, + "thresholdPercent": 51, + "tokenSupply": 10, + "startBalanceLamports": 19996489120, + "endBalanceLamports": 19963662080, + "spentLamports": 32827040, + "startBalanceSol": 19.99648912, + "endBalanceSol": 19.96366208, + "spentSol": 0.03282704 +} \ No newline at end of file diff --git a/shine/scripts/dao/runs/2026-05-09_02-21-53_Devnet_DAO_Full-1_2026-05-09_full.txt b/shine/scripts/dao/runs/2026-05-09_02-21-53_Devnet_DAO_Full-1_2026-05-09_full.txt new file mode 100644 index 0000000..6395423 --- /dev/null +++ b/shine/scripts/dao/runs/2026-05-09_02-21-53_Devnet_DAO_Full-1_2026-05-09_full.txt @@ -0,0 +1,26 @@ +createdAt: 2026-05-08T23:21:53.557Z +cluster: devnet +realmName: Devnet DAO Full-1 2026-05-09 +governanceProgramId: GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw +issuer: FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P +communityMint: AKKhTDHWbDZy39f3UKeiP2z1rFmbv5K4DvxVL7KTQy8b +issuerAta: CHfjpcyHotgczBErH7CCW9QMp8AeaGGyJxAtgV7ZyEwA +realm: 4vPg3A7uPZ4gZkNGy6vbDwsqYLwPgeciYqRbfpfuRa7A +tokenOwnerRecord: 97anU7DvmdpsQUY8ScmxswSPaGmMMw2FnNESiDQwzMjr +governance: 3NS5DT83nxh88xcndCPNrziFMvZNAjCSRu5jF1SpPRRt +nativeTreasury: 9vXFoN9ngfN1gpqQ3HT5n3y9Wp2r7HnSQckirgwVwWwb +metadataUri: https://arweave.net/6cMl-qV-7vpgXSdOR5MVnMEPMHgLkRdfgdO43I9z5ek +imageUrl: https://arweave.net/6cMl-qV-7vpgXSdOR5MVnMEPMHgLkRdfgdO43I9z5ek +txMint: 47cWAoXbDHYpW74exnBRma9QBoa3NMVx7iEU9mZsn74NYy3AK4tPptM1oPbaW91Mw3nZBTgxQtzgKSKP2Gdr8Hyh +txMetadata: 50d05LiBAXFmbt+jGZpw5tzvvNPAgwy/SiSmzb9l/v73GDFc2eN6+udw0fd9HdjYlP6t4oKYcsZB/kTRzqzMBg== +txRealm: 4v22Zmsm5qkoDQaeNuzeziH7GjxiUDSDRVeXLDYwgrXF3Ltw5xSkZFrVwPAiTZRPXzrm5bhbtSHd2rA7xPq9v4kG +txDeposit: 2gvWE3iA4yXhx3z1yshRRQgNEHcQgskmEsHSCo2X5WnvyXMzx8jtfyWZosvH7GWMmmtQegdaaTdtrAWeLXjiHtLw +txGovernanceTreasury: 4mArdxprVHpFtLMwyxmz9E99J8jwrGSsYvFmjR1SCMeWPim3HMZZQai9zrwBBn461axx5QDWiN7c9YVP7hXFmBmi +txSetRealmAuthority: 39qz1J4R63hxQQRrJ1EgdFG45PofBmtguP8V9Xx35FtPoo4APe5kPXhqyMKRK2o61iYHG5zvFob9bgUuzwvYPzaG +tokenSupply: 10 +votingTimeSec: 3600 +thresholdPercent: 51 +startBalanceSol: 19.99648912 +endBalanceSol: 19.96366208 +spentSol: 0.03282704 +configPath: /home/ai/work/SOLANA/shine-solana/shine/scripts/dao/dao.config.env diff --git a/shine/scripts/dao/runs/2026-05-09_02-24-43_revoke_FUc28vNixp.json b/shine/scripts/dao/runs/2026-05-09_02-24-43_revoke_FUc28vNixp.json new file mode 100644 index 0000000..4178bfe --- /dev/null +++ b/shine/scripts/dao/runs/2026-05-09_02-24-43_revoke_FUc28vNixp.json @@ -0,0 +1,23 @@ +{ + "createdAt": "2026-05-08T23:24:43.905Z", + "cluster": "devnet", + "configPath": "/home/ai/work/SOLANA/shine-solana/shine/scripts/dao/dao.config.env", + "governanceProgramId": "GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw", + "realm": "4vPg3A7uPZ4gZkNGy6vbDwsqYLwPgeciYqRbfpfuRa7A", + "governance": "3NS5DT83nxh88xcndCPNrziFMvZNAjCSRu5jF1SpPRRt", + "mint": "AKKhTDHWbDZy39f3UKeiP2z1rFmbv5K4DvxVL7KTQy8b", + "targetOwner": "FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P", + "amount": "1", + "proposer": "FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P", + "proposerRecord": "97anU7DvmdpsQUY8ScmxswSPaGmMMw2FnNESiDQwzMjr", + "proposal": "8A9cthr1PG6t2xdUyC928KZVpTzZPW7YoJsYPYjw8o2E", + "proposalTransaction": "krWkKxVaQDd3C6pdcJmH7Wu1tgk6RtS2AcoJba4VZGq", + "voteRecord": "EyWuYWt5jhCoySPWvFcm7DBaCVM5v4Y9N8Kcd3LCf24D", + "txCreateProposal": "kt4vtQbwcXY4KF4SKCHkzv86qxYXaA5Wapjug4VtB6xi6WmwxURzn9az41gb9sYKrhZ1U9qdgePUr4jLt7iTCkZ", + "txInsertTransaction": "47KrAnsj7whE7GyeQZzKoc1ciUfy6r3YFZFsF7huorzewx1SSxCXCF2QaJCRXdBw87u53CLrS7JM1D4BDXUZWbsA", + "txSignOff": "5X69zNCHrQAcSR5guneKh7NG5qfMvaYtvH9vz4pvwY4B2zQs3NhnMk47X5xF25EV6Cf2fANkpjkNdkqSmVZU9U2E", + "txVote": "5Dwnp7568BaRQJ67FHJC46KT9Ym4RSNyZWSSSM9KyFx5U1fSwsejBkvEstQQ4wuoBtcpNgsTcwjdMPUMrw5N3Haf", + "txFinalize": null, + "txExecute": null, + "executeError": "Simulation failed. \nMessage: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x20d. \nLogs: \n[\n \"Program GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw invoke [1]\",\n \"Program log: VERSION:\\\"3.1.2\\\"\",\n \"Program log: GOVERNANCE-INSTRUCTION: ExecuteTransaction\",\n \"Program log: GOVERNANCE-ERROR: Can't execute transaction within its hold up time\",\n \"Program GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw consumed 10045 of 200000 compute units\",\n \"Program GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw failed: custom program error: 0x20d\"\n]. \nCatch the `SendTransactionError` and call `getLogs()` on it for full details." +} \ No newline at end of file diff --git a/shine/scripts/dao/runs/2026-05-09_02-24-43_revoke_FUc28vNixp.txt b/shine/scripts/dao/runs/2026-05-09_02-24-43_revoke_FUc28vNixp.txt new file mode 100644 index 0000000..88db9a0 --- /dev/null +++ b/shine/scripts/dao/runs/2026-05-09_02-24-43_revoke_FUc28vNixp.txt @@ -0,0 +1,29 @@ +createdAt: 2026-05-08T23:24:43.905Z +cluster: devnet +realm: 4vPg3A7uPZ4gZkNGy6vbDwsqYLwPgeciYqRbfpfuRa7A +governance: 3NS5DT83nxh88xcndCPNrziFMvZNAjCSRu5jF1SpPRRt +mint: AKKhTDHWbDZy39f3UKeiP2z1rFmbv5K4DvxVL7KTQy8b +targetOwner: FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P +amount: 1 +proposer: FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P +proposal: 8A9cthr1PG6t2xdUyC928KZVpTzZPW7YoJsYPYjw8o2E +proposalTransaction: krWkKxVaQDd3C6pdcJmH7Wu1tgk6RtS2AcoJba4VZGq +voteRecord: EyWuYWt5jhCoySPWvFcm7DBaCVM5v4Y9N8Kcd3LCf24D +txCreateProposal: kt4vtQbwcXY4KF4SKCHkzv86qxYXaA5Wapjug4VtB6xi6WmwxURzn9az41gb9sYKrhZ1U9qdgePUr4jLt7iTCkZ +txInsertTransaction: 47KrAnsj7whE7GyeQZzKoc1ciUfy6r3YFZFsF7huorzewx1SSxCXCF2QaJCRXdBw87u53CLrS7JM1D4BDXUZWbsA +txSignOff: 5X69zNCHrQAcSR5guneKh7NG5qfMvaYtvH9vz4pvwY4B2zQs3NhnMk47X5xF25EV6Cf2fANkpjkNdkqSmVZU9U2E +txVote: 5Dwnp7568BaRQJ67FHJC46KT9Ym4RSNyZWSSSM9KyFx5U1fSwsejBkvEstQQ4wuoBtcpNgsTcwjdMPUMrw5N3Haf +txFinalize: - +txExecute: - +executeError: Simulation failed. +Message: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x20d. +Logs: +[ + "Program GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw invoke [1]", + "Program log: VERSION:\"3.1.2\"", + "Program log: GOVERNANCE-INSTRUCTION: ExecuteTransaction", + "Program log: GOVERNANCE-ERROR: Can't execute transaction within its hold up time", + "Program GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw consumed 10045 of 200000 compute units", + "Program GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw failed: custom program error: 0x20d" +]. +Catch the `SendTransactionError` and call `getLogs()` on it for full details. diff --git a/shine/scripts/dao_legacy/README.md b/shine/scripts/dao_legacy/README.md new file mode 100644 index 0000000..9796f72 --- /dev/null +++ b/shine/scripts/dao_legacy/README.md @@ -0,0 +1,7 @@ +# LEGACY + +Эта папка содержит старые варианты скриптов создания DAO. + +Их оставили только для истории и сравнения. + +Актуальные скрипты находятся в `scripts/dao`. diff --git a/shine/scripts/dao_legacy/create_realm_dao_build_exec.js b/shine/scripts/dao_legacy/create_realm_dao_build_exec.js new file mode 100755 index 0000000..0f67621 --- /dev/null +++ b/shine/scripts/dao_legacy/create_realm_dao_build_exec.js @@ -0,0 +1,379 @@ +#!/usr/bin/env node +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const readline = require("readline"); +const BN = require("bn.js"); +const { + Connection, + Keypair, + PublicKey, + SystemProgram, + Transaction, + sendAndConfirmTransaction, + clusterApiUrl, +} = require("@solana/web3.js"); +const { + TOKEN_PROGRAM_ID, + getMintLen, + createInitializeMintInstruction, + getAssociatedTokenAddressSync, + createAssociatedTokenAccountIdempotentInstruction, + createMintToInstruction, +} = require("@solana/spl-token"); +const { + MintMaxVoteWeightSource, + VoteThreshold, + VoteThresholdType, + VoteTipping, + GovernanceConfig, + withCreateRealm, + withDepositGoverningTokens, + withCreateGovernance, + withCreateNativeTreasury, + PROGRAM_VERSION_V3, +} = require("@solana/spl-governance"); + +function parseEnvConfig(configPath) { + const raw = fs.readFileSync(configPath, "utf8"); + const out = {}; + for (const line of raw.split("\n")) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) continue; + const eq = trimmed.indexOf("="); + if (eq === -1) continue; + const key = trimmed.slice(0, eq).trim(); + let val = trimmed.slice(eq + 1).trim(); + if ( + (val.startsWith('"') && val.endsWith('"')) || + (val.startsWith("'") && val.endsWith("'")) + ) { + val = val.slice(1, -1); + } + val = val.replace(/\$HOME/g, process.env.HOME || ""); + out[key] = val; + } + return out; +} + +function assertRequired(cfg, key) { + if (!cfg[key]) { + throw new Error(`В конфиге отсутствует обязательный параметр: ${key}`); + } +} + +function loadKeypair(filePath) { + const arr = JSON.parse(fs.readFileSync(filePath, "utf8")); + return Keypair.fromSecretKey(Uint8Array.from(arr)); +} + +function lamportsToSol(lamports) { + return Number(lamports) / 1_000_000_000; +} + +function nowStamp() { + const d = new Date(); + const p = (n) => String(n).padStart(2, "0"); + return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}_${p(d.getHours())}-${p( + d.getMinutes() + )}-${p(d.getSeconds())}`; +} + +async function askYes() { + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); + const answer = await new Promise((resolve) => + rl.question("Введите YES для реального создания DAO: ", resolve) + ); + rl.close(); + return answer.trim() === "YES"; +} + +async function main() { + const configPath = process.argv[2] + ? path.resolve(process.argv[2]) + : path.resolve(__dirname, "dao.config.env"); + + if (!fs.existsSync(configPath)) { + throw new Error(`Конфиг не найден: ${configPath}`); + } + + const cfg = parseEnvConfig(configPath); + [ + "DAO_CLUSTER", + "DAO_REALM_NAME", + "DAO_GOV_NFT_NAME", + "DAO_GOV_NFT_SYMBOL", + "DAO_GOV_NFT_SUPPLY", + "DAO_VOTING_TIME_SEC", + "DAO_APPROVAL_THRESHOLD_PERCENT", + "DAO_ISSUER_KEYPAIR", + "SPL_GOVERNANCE_PROGRAM_ID", + ].forEach((k) => assertRequired(cfg, k)); + + const cluster = cfg.DAO_CLUSTER; + const connection = new Connection(clusterApiUrl(cluster), "confirmed"); + const issuer = loadKeypair(path.resolve(cfg.DAO_ISSUER_KEYPAIR)); + const governanceProgramId = new PublicKey(cfg.SPL_GOVERNANCE_PROGRAM_ID); + + const supply = Number(cfg.DAO_GOV_NFT_SUPPLY); + const votingTimeSec = Number(cfg.DAO_VOTING_TIME_SEC); + const thresholdPct = Number(cfg.DAO_APPROVAL_THRESHOLD_PERCENT); + if (!Number.isInteger(supply) || supply <= 0) { + throw new Error("DAO_GOV_NFT_SUPPLY должен быть целым > 0"); + } + if (!Number.isInteger(votingTimeSec) || votingTimeSec <= 0) { + throw new Error("DAO_VOTING_TIME_SEC должен быть целым > 0"); + } + if (!Number.isInteger(thresholdPct) || thresholdPct < 51 || thresholdPct > 100) { + throw new Error("DAO_APPROVAL_THRESHOLD_PERCENT должен быть в диапазоне 51..100"); + } + + const [realmPda] = PublicKey.findProgramAddressSync( + [Buffer.from("governance"), Buffer.from(cfg.DAO_REALM_NAME, "utf8")], + governanceProgramId + ); + const realmExists = (await connection.getAccountInfo(realmPda)) !== null; + if (realmExists) { + throw new Error( + `Realm уже существует для имени '${cfg.DAO_REALM_NAME}': ${realmPda.toBase58()}` + ); + } + + const startBalance = await connection.getBalance(issuer.publicKey, "confirmed"); + console.log("============================================================"); + console.log("СОЗДАНИЕ DAO (EXEC)"); + console.log("------------------------------------------------------------"); + console.log("Сеть: ", cluster); + console.log("Realm name: ", cfg.DAO_REALM_NAME); + console.log("Realm PDA: ", realmPda.toBase58()); + console.log("Governance program: ", governanceProgramId.toBase58()); + console.log("Issuer: ", issuer.publicKey.toBase58()); + console.log("Баланс до старта: ", `${lamportsToSol(startBalance)} SOL`); + console.log("NFT symbol/name: ", `${cfg.DAO_GOV_NFT_SYMBOL} / ${cfg.DAO_GOV_NFT_NAME}`); + console.log("NFT supply: ", supply); + console.log("Voting time sec: ", votingTimeSec); + console.log("Threshold %: ", thresholdPct); + console.log("Конфиг: ", configPath); + console.log("============================================================"); + + const ok = await askYes(); + if (!ok) { + console.log("Отменено пользователем."); + return; + } + + const mintKeypair = Keypair.generate(); + const mintLen = getMintLen([]); + const mintRent = await connection.getMinimumBalanceForRentExemption(mintLen); + const issuerAta = getAssociatedTokenAddressSync( + mintKeypair.publicKey, + issuer.publicKey, + false, + TOKEN_PROGRAM_ID + ); + + const txMint = new Transaction().add( + SystemProgram.createAccount({ + fromPubkey: issuer.publicKey, + newAccountPubkey: mintKeypair.publicKey, + space: mintLen, + lamports: mintRent, + programId: TOKEN_PROGRAM_ID, + }), + createInitializeMintInstruction( + mintKeypair.publicKey, + 0, + issuer.publicKey, + issuer.publicKey, + TOKEN_PROGRAM_ID + ), + createAssociatedTokenAccountIdempotentInstruction( + issuer.publicKey, + issuerAta, + issuer.publicKey, + mintKeypair.publicKey, + TOKEN_PROGRAM_ID + ), + createMintToInstruction( + mintKeypair.publicKey, + issuerAta, + issuer.publicKey, + supply, + [], + TOKEN_PROGRAM_ID + ) + ); + const sigMint = await sendAndConfirmTransaction(connection, txMint, [issuer, mintKeypair], { + commitment: "confirmed", + }); + + const programVersion = PROGRAM_VERSION_V3; + const ixRealm = []; + const realmPk = await withCreateRealm( + ixRealm, + governanceProgramId, + programVersion, + cfg.DAO_REALM_NAME, + issuer.publicKey, + mintKeypair.publicKey, + issuer.publicKey, + undefined, + MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION, + new BN(1) + ); + const txRealm = new Transaction().add(...ixRealm); + const sigRealm = await sendAndConfirmTransaction(connection, txRealm, [issuer], { + commitment: "confirmed", + }); + + const ixDeposit = []; + const tokenOwnerRecordPk = await withDepositGoverningTokens( + ixDeposit, + governanceProgramId, + programVersion, + realmPk, + issuerAta, + mintKeypair.publicKey, + issuer.publicKey, + issuer.publicKey, + issuer.publicKey, + new BN(supply), + true + ); + const txDeposit = new Transaction().add(...ixDeposit); + const sigDeposit = await sendAndConfirmTransaction(connection, txDeposit, [issuer], { + commitment: "confirmed", + }); + + const governanceConfig = new GovernanceConfig({ + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: thresholdPct, + }), + minCommunityTokensToCreateProposal: new BN(1), + minInstructionHoldUpTime: 0, + baseVotingTime: votingTimeSec, + communityVoteTipping: VoteTipping.Strict, + minCouncilTokensToCreateProposal: new BN(0), + councilVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + councilVetoVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + communityVetoVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + councilVoteTipping: VoteTipping.Disabled, + votingCoolOffTime: 0, + depositExemptProposalCount: 0, + }); + + const ixGov = []; + const governancePk = await withCreateGovernance( + ixGov, + governanceProgramId, + programVersion, + realmPk, + realmPk, + governanceConfig, + tokenOwnerRecordPk, + issuer.publicKey, + issuer.publicKey + ); + const treasuryPk = await withCreateNativeTreasury( + ixGov, + governanceProgramId, + programVersion, + governancePk, + issuer.publicKey + ); + const txGov = new Transaction().add(...ixGov); + const sigGov = await sendAndConfirmTransaction(connection, txGov, [issuer], { + commitment: "confirmed", + }); + + const endBalance = await connection.getBalance(issuer.publicKey, "confirmed"); + const spentLamports = startBalance - endBalance; + const report = { + createdAt: new Date().toISOString(), + cluster, + configPath, + realmName: cfg.DAO_REALM_NAME, + governanceProgramId: governanceProgramId.toBase58(), + issuer: issuer.publicKey.toBase58(), + communityMint: mintKeypair.publicKey.toBase58(), + issuerAta: issuerAta.toBase58(), + realm: realmPk.toBase58(), + tokenOwnerRecord: tokenOwnerRecordPk.toBase58(), + governance: governancePk.toBase58(), + nativeTreasury: treasuryPk.toBase58(), + txMint: sigMint, + txRealm: sigRealm, + txDeposit: sigDeposit, + txGovernanceTreasury: sigGov, + votingTimeSec, + thresholdPercent: thresholdPct, + nftSupply: supply, + startBalanceLamports: startBalance, + endBalanceLamports: endBalance, + spentLamports, + startBalanceSol: lamportsToSol(startBalance), + endBalanceSol: lamportsToSol(endBalance), + spentSol: lamportsToSol(spentLamports), + }; + const reportDir = path.resolve(__dirname, "runs"); + fs.mkdirSync(reportDir, { recursive: true }); + const reportBaseName = `${nowStamp()}_${cfg.DAO_REALM_NAME + .replace(/[^a-zA-Z0-9._-]+/g, "_") + .slice(0, 80)}`; + const reportJsonPath = path.join(reportDir, `${reportBaseName}.json`); + const reportTxtPath = path.join(reportDir, `${reportBaseName}.txt`); + fs.writeFileSync(reportJsonPath, JSON.stringify(report, null, 2)); + fs.writeFileSync( + reportTxtPath, + [ + `createdAt: ${report.createdAt}`, + `cluster: ${report.cluster}`, + `realmName: ${report.realmName}`, + `governanceProgramId: ${report.governanceProgramId}`, + `issuer: ${report.issuer}`, + `communityMint: ${report.communityMint}`, + `issuerAta: ${report.issuerAta}`, + `realm: ${report.realm}`, + `tokenOwnerRecord: ${report.tokenOwnerRecord}`, + `governance: ${report.governance}`, + `nativeTreasury: ${report.nativeTreasury}`, + `txMint: ${report.txMint}`, + `txRealm: ${report.txRealm}`, + `txDeposit: ${report.txDeposit}`, + `txGovernanceTreasury: ${report.txGovernanceTreasury}`, + `nftSupply: ${report.nftSupply}`, + `votingTimeSec: ${report.votingTimeSec}`, + `thresholdPercent: ${report.thresholdPercent}`, + `startBalanceSol: ${report.startBalanceSol}`, + `endBalanceSol: ${report.endBalanceSol}`, + `spentSol: ${report.spentSol}`, + `configPath: ${report.configPath}`, + ].join("\n") + "\n" + ); + + console.log("============================================================"); + console.log("DAO СОЗДАНО"); + console.log("------------------------------------------------------------"); + console.log("Community mint (SPL Token, transferable): ", mintKeypair.publicKey.toBase58()); + console.log("Issuer ATA: ", issuerAta.toBase58()); + console.log("Realm: ", realmPk.toBase58()); + console.log("TokenOwnerRecord: ", tokenOwnerRecordPk.toBase58()); + console.log("Governance: ", governancePk.toBase58()); + console.log("Native treasury PDA: ", treasuryPk.toBase58()); + console.log("Tx mint: ", sigMint); + console.log("Tx realm: ", sigRealm); + console.log("Tx deposit: ", sigDeposit); + console.log("Tx governance+treasury: ", sigGov); + console.log("Баланс после: ", `${lamportsToSol(endBalance)} SOL`); + console.log("Потрачено: ", `${lamportsToSol(spentLamports)} SOL`); + console.log("Отчёт JSON: ", reportJsonPath); + console.log("Отчёт TXT: ", reportTxtPath); + console.log("============================================================"); +} + +main().catch((e) => { + console.error("Ошибка создания DAO:", e?.message || e); + process.exit(1); +}); diff --git a/shine/scripts/dao_legacy/create_realm_dao_test.sh b/shine/scripts/dao_legacy/create_realm_dao_test.sh new file mode 100755 index 0000000..ea43ce9 --- /dev/null +++ b/shine/scripts/dao_legacy/create_realm_dao_test.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG_PATH="${1:-$SCRIPT_DIR/dao.config.env}" + +if [[ ! -f "$CONFIG_PATH" ]]; then + echo "Ошибка: не найден конфиг $CONFIG_PATH" + exit 1 +fi + +# shellcheck disable=SC1090 +source "$CONFIG_PATH" + +require_cmd() { + if ! command -v "$1" >/dev/null 2>&1; then + echo "Ошибка: команда '$1' не найдена" + exit 1 + fi +} + +require_cmd solana +require_cmd solana-keygen +require_cmd node + +if [[ -z "${DAO_REALM_NAME:-}" || -z "${DAO_CLUSTER:-}" || -z "${DAO_ISSUER_KEYPAIR:-}" || -z "${SPL_GOVERNANCE_PROGRAM_ID:-}" ]]; then + echo "Ошибка: обязательные поля конфига пустые" + exit 1 +fi + +if [[ ! -f "$DAO_ISSUER_KEYPAIR" ]]; then + echo "Ошибка: keypair не найден: $DAO_ISSUER_KEYPAIR" + exit 1 +fi + +if [[ "${DAO_REALM_NAME}" == *"TEMPLATE"* || "${DAO_REALM_NAME}" == *"CHANGE_ME"* ]]; then + echo "Ошибка: похоже, не заменили тестовое имя DAO_REALM_NAME" + exit 1 +fi + +if ! [[ "${DAO_VOTING_TIME_SEC}" =~ ^[0-9]+$ ]] || ! [[ "${DAO_GOV_NFT_SUPPLY}" =~ ^[0-9]+$ ]] || ! [[ "${DAO_APPROVAL_THRESHOLD_PERCENT}" =~ ^[0-9]+$ ]]; then + echo "Ошибка: числовые параметры заданы некорректно" + exit 1 +fi + +if (( DAO_APPROVAL_THRESHOLD_PERCENT < 51 || DAO_APPROVAL_THRESHOLD_PERCENT > 100 )); then + echo "Ошибка: DAO_APPROVAL_THRESHOLD_PERCENT должен быть в диапазоне 51..100" + exit 1 +fi + +ISSUER_PUBKEY="$(solana-keygen pubkey "$DAO_ISSUER_KEYPAIR")" +ISSUER_BALANCE="$(solana balance "$ISSUER_PUBKEY" --url "$DAO_CLUSTER" 2>/dev/null || true)" + +REALM_PDA="$(node - "$DAO_REALM_NAME" "$SPL_GOVERNANCE_PROGRAM_ID" <<'NODE' +const { PublicKey } = require("@solana/web3.js"); +const realmName = process.argv[2]; +const programId = new PublicKey(process.argv[3]); +const [pda] = PublicKey.findProgramAddressSync( + [Buffer.from("governance"), Buffer.from(realmName, "utf8")], + programId +); +console.log(pda.toBase58()); +NODE +)" + +if [[ -z "$REALM_PDA" ]]; then + echo "Ошибка: не удалось вычислить PDA realm." + exit 1 +fi + +REALM_EXISTS="no" +if solana account "$REALM_PDA" --url "$DAO_CLUSTER" >/dev/null 2>&1; then + REALM_EXISTS="yes" +fi + +cat < String(n).padStart(2, "0"); + return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}_${p(d.getHours())}-${p( + d.getMinutes() + )}-${p(d.getSeconds())}`; +} + +async function askYes() { + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); + const answer = await new Promise((resolve) => + rl.question("Введите YES для реального создания DAO: ", resolve) + ); + rl.close(); + return answer.trim() === "YES"; +} + +async function main() { + const configPath = process.argv[2] + ? path.resolve(process.argv[2]) + : path.resolve(__dirname, "dao.config.env"); + + if (!fs.existsSync(configPath)) { + throw new Error(`Конфиг не найден: ${configPath}`); + } + + const cfg = parseEnvConfig(configPath); + [ + "DAO_CLUSTER", + "DAO_REALM_NAME", + "DAO_GOV_NFT_NAME", + "DAO_GOV_NFT_SYMBOL", + "DAO_GOV_NFT_SUPPLY", + "DAO_VOTING_TIME_SEC", + "DAO_APPROVAL_THRESHOLD_PERCENT", + "DAO_ISSUER_KEYPAIR", + "SPL_GOVERNANCE_PROGRAM_ID", + ].forEach((k) => assertRequired(cfg, k)); + + const cluster = cfg.DAO_CLUSTER; + const connection = new Connection(clusterApiUrl(cluster), "confirmed"); + const issuer = loadKeypair(path.resolve(cfg.DAO_ISSUER_KEYPAIR)); + const governanceProgramId = new PublicKey(cfg.SPL_GOVERNANCE_PROGRAM_ID); + + const supply = Number(cfg.DAO_GOV_NFT_SUPPLY); + const votingTimeSec = Number(cfg.DAO_VOTING_TIME_SEC); + const thresholdPct = Number(cfg.DAO_APPROVAL_THRESHOLD_PERCENT); + if (!Number.isInteger(supply) || supply <= 0) { + throw new Error("DAO_GOV_NFT_SUPPLY должен быть целым > 0"); + } + if (!Number.isInteger(votingTimeSec) || votingTimeSec <= 0) { + throw new Error("DAO_VOTING_TIME_SEC должен быть целым > 0"); + } + if (!Number.isInteger(thresholdPct) || thresholdPct < 51 || thresholdPct > 100) { + throw new Error("DAO_APPROVAL_THRESHOLD_PERCENT должен быть в диапазоне 51..100"); + } + + const [realmPda] = PublicKey.findProgramAddressSync( + [Buffer.from("governance"), Buffer.from(cfg.DAO_REALM_NAME, "utf8")], + governanceProgramId + ); + const realmExists = (await connection.getAccountInfo(realmPda)) !== null; + if (realmExists) { + throw new Error( + `Realm уже существует для имени '${cfg.DAO_REALM_NAME}': ${realmPda.toBase58()}` + ); + } + + const startBalance = await connection.getBalance(issuer.publicKey, "confirmed"); + console.log("============================================================"); + console.log("СОЗДАНИЕ DAO (EXEC)"); + console.log("------------------------------------------------------------"); + console.log("Сеть: ", cluster); + console.log("Realm name: ", cfg.DAO_REALM_NAME); + console.log("Realm PDA: ", realmPda.toBase58()); + console.log("Governance program: ", governanceProgramId.toBase58()); + console.log("Issuer: ", issuer.publicKey.toBase58()); + console.log("Баланс до старта: ", `${lamportsToSol(startBalance)} SOL`); + console.log("NFT symbol/name: ", `${cfg.DAO_GOV_NFT_SYMBOL} / ${cfg.DAO_GOV_NFT_NAME}`); + console.log("NFT supply: ", supply); + console.log("Voting time sec: ", votingTimeSec); + console.log("Threshold %: ", thresholdPct); + console.log("Конфиг: ", configPath); + console.log("============================================================"); + + const ok = await askYes(); + if (!ok) { + console.log("Отменено пользователем."); + return; + } + + const mintKeypair = Keypair.generate(); + const mintLen = getMintLen([]); + const mintRent = await connection.getMinimumBalanceForRentExemption(mintLen); + const issuerAta = getAssociatedTokenAddressSync( + mintKeypair.publicKey, + issuer.publicKey, + false, + TOKEN_PROGRAM_ID + ); + + const txMint = new Transaction().add( + SystemProgram.createAccount({ + fromPubkey: issuer.publicKey, + newAccountPubkey: mintKeypair.publicKey, + space: mintLen, + lamports: mintRent, + programId: TOKEN_PROGRAM_ID, + }), + createInitializeMintInstruction( + mintKeypair.publicKey, + 0, + issuer.publicKey, + issuer.publicKey, + TOKEN_PROGRAM_ID + ), + createAssociatedTokenAccountIdempotentInstruction( + issuer.publicKey, + issuerAta, + issuer.publicKey, + mintKeypair.publicKey, + TOKEN_PROGRAM_ID + ), + createMintToInstruction( + mintKeypair.publicKey, + issuerAta, + issuer.publicKey, + supply, + [], + TOKEN_PROGRAM_ID + ) + ); + const sigMint = await sendAndConfirmTransaction(connection, txMint, [issuer, mintKeypair], { + commitment: "confirmed", + }); + + const programVersion = PROGRAM_VERSION_V3; + const ixRealm = []; + const realmPk = await withCreateRealm( + ixRealm, + governanceProgramId, + programVersion, + cfg.DAO_REALM_NAME, + issuer.publicKey, + mintKeypair.publicKey, + issuer.publicKey, + undefined, + MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION, + new BN(1) + ); + const txRealm = new Transaction().add(...ixRealm); + const sigRealm = await sendAndConfirmTransaction(connection, txRealm, [issuer], { + commitment: "confirmed", + }); + + const ixDeposit = []; + const tokenOwnerRecordPk = await withDepositGoverningTokens( + ixDeposit, + governanceProgramId, + programVersion, + realmPk, + issuerAta, + mintKeypair.publicKey, + issuer.publicKey, + issuer.publicKey, + issuer.publicKey, + new BN(supply), + true + ); + const txDeposit = new Transaction().add(...ixDeposit); + const sigDeposit = await sendAndConfirmTransaction(connection, txDeposit, [issuer], { + commitment: "confirmed", + }); + + const governanceConfig = new GovernanceConfig({ + communityVoteThreshold: new VoteThreshold({ + type: VoteThresholdType.YesVotePercentage, + value: thresholdPct, + }), + minCommunityTokensToCreateProposal: new BN(1), + minInstructionHoldUpTime: 0, + baseVotingTime: votingTimeSec, + communityVoteTipping: VoteTipping.Strict, + minCouncilTokensToCreateProposal: new BN(0), + councilVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + councilVetoVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + communityVetoVoteThreshold: new VoteThreshold({ type: VoteThresholdType.Disabled }), + councilVoteTipping: VoteTipping.Disabled, + votingCoolOffTime: 0, + depositExemptProposalCount: 0, + }); + + const ixGov = []; + const governancePk = await withCreateGovernance( + ixGov, + governanceProgramId, + programVersion, + realmPk, + realmPk, + governanceConfig, + tokenOwnerRecordPk, + issuer.publicKey, + issuer.publicKey + ); + const treasuryPk = await withCreateNativeTreasury( + ixGov, + governanceProgramId, + programVersion, + governancePk, + issuer.publicKey + ); + const txGov = new Transaction().add(...ixGov); + const sigGov = await sendAndConfirmTransaction(connection, txGov, [issuer], { + commitment: "confirmed", + }); + + const endBalance = await connection.getBalance(issuer.publicKey, "confirmed"); + const spentLamports = startBalance - endBalance; + const report = { + createdAt: new Date().toISOString(), + cluster, + configPath, + realmName: cfg.DAO_REALM_NAME, + governanceProgramId: governanceProgramId.toBase58(), + issuer: issuer.publicKey.toBase58(), + communityMint: mintKeypair.publicKey.toBase58(), + issuerAta: issuerAta.toBase58(), + realm: realmPk.toBase58(), + tokenOwnerRecord: tokenOwnerRecordPk.toBase58(), + governance: governancePk.toBase58(), + nativeTreasury: treasuryPk.toBase58(), + txMint: sigMint, + txRealm: sigRealm, + txDeposit: sigDeposit, + txGovernanceTreasury: sigGov, + votingTimeSec, + thresholdPercent: thresholdPct, + nftSupply: supply, + startBalanceLamports: startBalance, + endBalanceLamports: endBalance, + spentLamports, + startBalanceSol: lamportsToSol(startBalance), + endBalanceSol: lamportsToSol(endBalance), + spentSol: lamportsToSol(spentLamports), + }; + const reportDir = path.resolve(__dirname, "runs"); + fs.mkdirSync(reportDir, { recursive: true }); + const reportBaseName = `${nowStamp()}_${cfg.DAO_REALM_NAME + .replace(/[^a-zA-Z0-9._-]+/g, "_") + .slice(0, 80)}`; + const reportJsonPath = path.join(reportDir, `${reportBaseName}.json`); + const reportTxtPath = path.join(reportDir, `${reportBaseName}.txt`); + fs.writeFileSync(reportJsonPath, JSON.stringify(report, null, 2)); + fs.writeFileSync( + reportTxtPath, + [ + `createdAt: ${report.createdAt}`, + `cluster: ${report.cluster}`, + `realmName: ${report.realmName}`, + `governanceProgramId: ${report.governanceProgramId}`, + `issuer: ${report.issuer}`, + `communityMint: ${report.communityMint}`, + `issuerAta: ${report.issuerAta}`, + `realm: ${report.realm}`, + `tokenOwnerRecord: ${report.tokenOwnerRecord}`, + `governance: ${report.governance}`, + `nativeTreasury: ${report.nativeTreasury}`, + `txMint: ${report.txMint}`, + `txRealm: ${report.txRealm}`, + `txDeposit: ${report.txDeposit}`, + `txGovernanceTreasury: ${report.txGovernanceTreasury}`, + `nftSupply: ${report.nftSupply}`, + `votingTimeSec: ${report.votingTimeSec}`, + `thresholdPercent: ${report.thresholdPercent}`, + `startBalanceSol: ${report.startBalanceSol}`, + `endBalanceSol: ${report.endBalanceSol}`, + `spentSol: ${report.spentSol}`, + `configPath: ${report.configPath}`, + ].join("\n") + "\n" + ); + + console.log("============================================================"); + console.log("DAO СОЗДАНО"); + console.log("------------------------------------------------------------"); + console.log("Community mint (SPL Token, transferable): ", mintKeypair.publicKey.toBase58()); + console.log("Issuer ATA: ", issuerAta.toBase58()); + console.log("Realm: ", realmPk.toBase58()); + console.log("TokenOwnerRecord: ", tokenOwnerRecordPk.toBase58()); + console.log("Governance: ", governancePk.toBase58()); + console.log("Native treasury PDA: ", treasuryPk.toBase58()); + console.log("Tx mint: ", sigMint); + console.log("Tx realm: ", sigRealm); + console.log("Tx deposit: ", sigDeposit); + console.log("Tx governance+treasury: ", sigGov); + console.log("Баланс после: ", `${lamportsToSol(endBalance)} SOL`); + console.log("Потрачено: ", `${lamportsToSol(spentLamports)} SOL`); + console.log("Отчёт JSON: ", reportJsonPath); + console.log("Отчёт TXT: ", reportTxtPath); + console.log("============================================================"); +} + +main().catch((e) => { + console.error("Ошибка создания DAO:", e?.message || e); + process.exit(1); +}); diff --git a/shine/scripts/devnet/README.md b/shine/scripts/devnet/README.md index 96d6e02..5659aa8 100644 --- a/shine/scripts/devnet/README.md +++ b/shine/scripts/devnet/README.md @@ -1,3 +1,11 @@ +⚠️ УСТАРЕВШЕЕ (LEGACY) + +Папка `scripts/devnet` относится к старой логике (legacy) и для текущей версии `shine_payments` больше не используется. + +Актуальные скрипты по DAO и новой схеме находятся в `scripts/dao`. + +--- + Devnet E2E тест: NFT-модуль + add_bonus Ветка содержит скрипты для проверки (NFT + add_bonus) в devnet. diff --git a/shine/scripts/governance_token/runs/2026-05-15_15-20-22_vanity_grind_report.json b/shine/scripts/governance_token/runs/2026-05-15_15-20-22_vanity_grind_report.json new file mode 100644 index 0000000..bbc51a7 --- /dev/null +++ b/shine/scripts/governance_token/runs/2026-05-15_15-20-22_vanity_grind_report.json @@ -0,0 +1,16 @@ +{ + "createdAt": "2026-05-15T12:20:22.373Z", + "prefix": "DAo", + "count": 1, + "ignoreCase": false, + "runsDir": "/home/ai/work/SOLANA/shine-solana/shine/scripts/governance_token/runs", + "avgExpectedTriesPerMatch": 195112, + "attemptsObserved": 0, + "foundHintsInOutput": 1, + "command": "solana-keygen grind --starts-with DAo:1", + "outputLog": [ + "Searching with 16 threads for:", + "1 pubkey that starts with 'DAo' and ends with ''", + "Wrote keypair to DAou7SeaykoMooghA5SURLYhkkU8NEhV5Y2T6fsXD7rn.json" + ] +} \ No newline at end of file diff --git a/shine/scripts/governance_token/runs/DAou7SeaykoMooghA5SURLYhkkU8NEhV5Y2T6fsXD7rn.json b/shine/scripts/governance_token/runs/DAou7SeaykoMooghA5SURLYhkkU8NEhV5Y2T6fsXD7rn.json new file mode 100644 index 0000000..e8f47fb --- /dev/null +++ b/shine/scripts/governance_token/runs/DAou7SeaykoMooghA5SURLYhkkU8NEhV5Y2T6fsXD7rn.json @@ -0,0 +1 @@ +[115,67,66,30,87,145,246,163,61,151,201,124,183,214,51,151,22,218,111,91,138,240,184,170,169,117,123,68,99,10,100,161,180,207,127,168,102,124,209,83,46,144,109,253,200,122,20,82,223,74,69,105,53,218,226,231,88,238,93,98,54,161,167,31] \ No newline at end of file diff --git a/shine/scripts/governance_token/scripts/governance_token/runs/2026-05-15_15-20-09_vanity_grind_report.json b/shine/scripts/governance_token/scripts/governance_token/runs/2026-05-15_15-20-09_vanity_grind_report.json new file mode 100644 index 0000000..f1544cc --- /dev/null +++ b/shine/scripts/governance_token/scripts/governance_token/runs/2026-05-15_15-20-09_vanity_grind_report.json @@ -0,0 +1,16 @@ +{ + "createdAt": "2026-05-15T12:20:09.856Z", + "prefix": "DAo", + "count": 1, + "ignoreCase": false, + "runsDir": "/home/ai/work/SOLANA/shine-solana/shine/scripts/governance_token/scripts/governance_token/runs", + "avgExpectedTriesPerMatch": 195112, + "attemptsObserved": 0, + "foundHintsInOutput": 1, + "command": "solana-keygen grind --starts-with DAo:1", + "outputLog": [ + "Searching with 16 threads for:", + "1 pubkey that starts with 'DAo' and ends with ''", + "Wrote keypair to DAoxa7YRxa8Se5KFQmkBbxBJ3Fo8FeY8N9td6NGz38zu.json" + ] +} \ No newline at end of file diff --git a/shine/scripts/governance_token/scripts/governance_token/runs/DAoxa7YRxa8Se5KFQmkBbxBJ3Fo8FeY8N9td6NGz38zu.json b/shine/scripts/governance_token/scripts/governance_token/runs/DAoxa7YRxa8Se5KFQmkBbxBJ3Fo8FeY8N9td6NGz38zu.json new file mode 100644 index 0000000..c05ba78 --- /dev/null +++ b/shine/scripts/governance_token/scripts/governance_token/runs/DAoxa7YRxa8Se5KFQmkBbxBJ3Fo8FeY8N9td6NGz38zu.json @@ -0,0 +1 @@ +[127,127,232,76,177,128,31,8,169,68,116,117,202,252,44,203,63,250,250,210,30,186,201,66,110,211,193,137,111,186,165,157,180,207,144,236,191,129,155,243,98,167,69,154,219,76,79,141,228,101,60,132,255,6,252,105,99,29,143,220,127,120,236,26] \ No newline at end of file diff --git a/shine/settings.gradle b/shine/settings.gradle new file mode 100644 index 0000000..0fb3efa --- /dev/null +++ b/shine/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "shine-tools" + diff --git a/shine/yarn.lock b/shine/yarn.lock index 0b6fad0..d8c2843 100644 --- a/shine/yarn.lock +++ b/shine/yarn.lock @@ -4,17 +4,17 @@ "@babel/runtime@^7.25.0": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.1.tgz#9fce313d12c9a77507f264de74626e87fd0dc541" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz" integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog== "@coral-xyz/anchor-errors@^0.31.1": version "0.31.1" - resolved "https://registry.yarnpkg.com/@coral-xyz/anchor-errors/-/anchor-errors-0.31.1.tgz#d635cbac2533973ae6bfb5d3ba1de89ce5aece2d" + resolved "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.31.1.tgz" integrity sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ== "@coral-xyz/anchor@^0.31.1": version "0.31.1" - resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.31.1.tgz#0fdeebf45a3cb2e47e8ebbb815ca98542152962c" + resolved "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.31.1.tgz" integrity sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA== dependencies: "@coral-xyz/anchor-errors" "^0.31.1" @@ -33,57 +33,302 @@ "@coral-xyz/borsh@^0.31.1": version "0.31.1" - resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.31.1.tgz#5328e1e0921b75d7f4a62dd3f61885a938bc7241" + resolved "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.31.1.tgz" integrity sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw== dependencies: bn.js "^5.1.2" buffer-layout "^1.2.0" -"@noble/curves@^1.4.2": +"@metaplex-foundation/mpl-token-metadata@^3.4.0": + version "3.4.0" + resolved "https://registry.npmjs.org/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-3.4.0.tgz" + integrity sha512-AxBAYCK73JWxY3g9//z/C9krkR0t1orXZDknUPS4+GjwGH2vgPfsk04yfZ31Htka2AdS9YE/3wH7sMUBHKn9Rg== + dependencies: + "@metaplex-foundation/mpl-toolbox" "^0.10.0" + +"@metaplex-foundation/mpl-toolbox@^0.10.0": + version "0.10.0" + resolved "https://registry.npmjs.org/@metaplex-foundation/mpl-toolbox/-/mpl-toolbox-0.10.0.tgz" + integrity sha512-84KD1L5cFyw5xnntHwL4uPwfcrkKSiwuDeypiVr92qCUFuF3ZENa2zlFVPu+pQcjTlod2LmEX3MhBmNjRMpdKg== + +"@metaplex-foundation/umi-bundle-defaults@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-bundle-defaults/-/umi-bundle-defaults-1.5.1.tgz" + integrity sha512-7qoXenAkQbcj468HGAeLZDyg3eEhcS9rWAnGqjnKgWOlL1czL2Qwho0FEtqOv57IHwAJSTpbHbcvABmdpTjjdw== + dependencies: + "@metaplex-foundation/umi-downloader-http" "^1.5.1" + "@metaplex-foundation/umi-eddsa-web3js" "^1.5.1" + "@metaplex-foundation/umi-http-fetch" "^1.5.1" + "@metaplex-foundation/umi-program-repository" "^1.5.1" + "@metaplex-foundation/umi-rpc-chunk-get-accounts" "^1.5.1" + "@metaplex-foundation/umi-rpc-web3js" "^1.5.1" + "@metaplex-foundation/umi-serializer-data-view" "^1.5.1" + "@metaplex-foundation/umi-transaction-factory-web3js" "^1.5.1" + +"@metaplex-foundation/umi-downloader-http@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-downloader-http/-/umi-downloader-http-1.5.1.tgz" + integrity sha512-1s9gSTaDtwELyxBRE6Wmdr3xWeb4Z1uU04dj3Hg8VU+TN6/3wchh93+rIGZT5D3zzdh4+yPxdYV+4ZEr3T5glQ== + +"@metaplex-foundation/umi-eddsa-web3js@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-eddsa-web3js/-/umi-eddsa-web3js-1.5.1.tgz" + integrity sha512-ZlzmXXAa1Ujk00G5TmqXM81J25+k/8sqt0zxBUlLTUSOxzlhxhlUKdErIhpHazbKq+eGck+Onm17oAwVKdKAcw== + dependencies: + "@metaplex-foundation/umi-web3js-adapters" "^1.5.1" + "@noble/curves" "^1.0.0" + yaml "^2.7.0" + +"@metaplex-foundation/umi-http-fetch@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-http-fetch/-/umi-http-fetch-1.5.1.tgz" + integrity sha512-AOjZJo3Ua4a2FvgA85x5f0TkMSb+13Ao3uLIQ9FbScV42kqZnDox8KjJ7tKm1ZtYDlCYD0pSFMKPOC9NPDnHDg== + dependencies: + node-fetch "^2.6.7" + +"@metaplex-foundation/umi-options@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-options/-/umi-options-1.5.1.tgz" + integrity sha512-ZE6uXgFA3rElFq4gJxZM2diAqZdFqL65bOnAggwdnnei5XXRzFyNF16wYSqlHnPLvG6ohRHWiXww8d2Mb83xFg== + +"@metaplex-foundation/umi-program-repository@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-program-repository/-/umi-program-repository-1.5.1.tgz" + integrity sha512-E5W0IjwFgDGuBTshISbbEh/s8deqxcOzzEjOOlYdMXnevVsfNLwBBIAY4NPJg3v5vpFlKODwUGB5BxCUVthzJg== + +"@metaplex-foundation/umi-public-keys@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-public-keys/-/umi-public-keys-1.5.1.tgz" + integrity sha512-joTnI1mRtYRfIaTo98uaYRjBPszsdyHuq0vvd6QbSX+MPvu3enkWi+UicuykEc3VXd5tcGdNMiGSx4jgXG6pkw== + dependencies: + "@metaplex-foundation/umi-serializers-encodings" "^1.5.1" + +"@metaplex-foundation/umi-rpc-chunk-get-accounts@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-chunk-get-accounts/-/umi-rpc-chunk-get-accounts-1.5.1.tgz" + integrity sha512-3dnGobT1Xwul7fXzQr8660UHSnFOCWEed4T449oNekrVsHp2o00fdOqjXwo11DYhS1rjm+gbzRSazRKb62uF2Q== + +"@metaplex-foundation/umi-rpc-web3js@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-web3js/-/umi-rpc-web3js-1.5.1.tgz" + integrity sha512-CxHyruh2gW2b/ZOwHFFtooOgtu9hBrOJTd3HUMtD/jpaturApa3itsL/zNt4K34tELzVIUL7N78LDjNpzbu9Kw== + dependencies: + "@metaplex-foundation/umi-web3js-adapters" "^1.5.1" + +"@metaplex-foundation/umi-serializer-data-view@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-serializer-data-view/-/umi-serializer-data-view-1.5.1.tgz" + integrity sha512-9Wxqk3bGVJ0xNmHhHrOUhdu/90Q1IT3FZRZN4eGckb0sf7Bgls7kBTkFfgXFmUh2VBnE0GnnncXeHKtop5RSFA== + +"@metaplex-foundation/umi-serializers-core@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-core/-/umi-serializers-core-1.5.1.tgz" + integrity sha512-6nYsbTCLq421x7JT1B3/iNgPpSARj/wL9naoKbOreHrk2ip/4R7vQstVRMl0Gx+Hv2tHnEIbFo3JBtWyC377Qw== + +"@metaplex-foundation/umi-serializers-encodings@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-encodings/-/umi-serializers-encodings-1.5.1.tgz" + integrity sha512-cVvwWmREE/Pmvjvsd50F18P53HDT0vzZECD6uYWIVzxgwpOiRDFu6r/vGbweomHoWzfTvuU6hiKuKv2KsOoXQA== + dependencies: + "@metaplex-foundation/umi-serializers-core" "^1.5.1" + +"@metaplex-foundation/umi-serializers-numbers@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-numbers/-/umi-serializers-numbers-1.5.1.tgz" + integrity sha512-7DVF1VJIdT44Pe6qWKaqGu4YVgE10OeLMYpm7C16SujSBgQGB/I2bh8NBifyH2R3oHhoyfE9qgIKB3dgRazN6A== + dependencies: + "@metaplex-foundation/umi-serializers-core" "^1.5.1" + +"@metaplex-foundation/umi-serializers@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-serializers/-/umi-serializers-1.5.1.tgz" + integrity sha512-scXciBylbJ4iwfxOF1Xx2XiBzoYUD8fSKWTsMal5Rj1hMRDe6b2XZcsBOjio61iAr8aTtFPmKpqxeBdLwmQ0ZQ== + dependencies: + "@metaplex-foundation/umi-options" "^1.5.1" + "@metaplex-foundation/umi-public-keys" "^1.5.1" + "@metaplex-foundation/umi-serializers-core" "^1.5.1" + "@metaplex-foundation/umi-serializers-encodings" "^1.5.1" + "@metaplex-foundation/umi-serializers-numbers" "^1.5.1" + +"@metaplex-foundation/umi-transaction-factory-web3js@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-transaction-factory-web3js/-/umi-transaction-factory-web3js-1.5.1.tgz" + integrity sha512-g4NfvtnmXtH1Q/Y9LdCsFtDRHQZmZWW7uKz+N9a+IVsJTTvpWFALMHm66dFDQGa0ExAYxAj7j6uZH2qDn0zarA== + dependencies: + "@metaplex-foundation/umi-web3js-adapters" "^1.5.1" + +"@metaplex-foundation/umi-web3js-adapters@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-web3js-adapters/-/umi-web3js-adapters-1.5.1.tgz" + integrity sha512-6W3JElD0B0EbgHofVKqk4PbP/JDrUHIKWciM7tEuXTDXbuXbSECDe7qlTU0JZXmVZNfYufI6FHnkCfPys2ZnIQ== + dependencies: + buffer "^6.0.3" + +"@metaplex-foundation/umi@^1.5.1", "@metaplex-foundation/umi@>= 0.8.2 <= 1": + version "1.5.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi/-/umi-1.5.1.tgz" + integrity sha512-ONRv5a0kv+23AMlR8oyFBHnjVg3o3N8pUfFcV4gzbg6OgZf87zHsPWBfED3OTJqx267v1bEn6d6DABXNFq9Z3A== + dependencies: + "@metaplex-foundation/umi-options" "^1.5.1" + "@metaplex-foundation/umi-public-keys" "^1.5.1" + "@metaplex-foundation/umi-serializers" "^1.5.1" + +"@noble/curves@^1.0.0", "@noble/curves@^1.4.2": version "1.9.1" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.1.tgz#9654a0bc6c13420ae252ddcf975eaf0f58f0a35c" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz" integrity sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA== dependencies: "@noble/hashes" "1.8.0" -"@noble/hashes@1.8.0", "@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0": +"@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0", "@noble/hashes@1.8.0": version "1.8.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== -"@solana/buffer-layout@^4.0.1": +"@solana/buffer-layout-utils@^0.2.0": + version "0.2.0" + resolved "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz" + integrity sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g== + dependencies: + "@solana/buffer-layout" "^4.0.0" + "@solana/web3.js" "^1.32.0" + bigint-buffer "^1.1.5" + bignumber.js "^9.0.1" + +"@solana/buffer-layout@^4.0.0", "@solana/buffer-layout@^4.0.1": version "4.0.1" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" + resolved "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz" integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== dependencies: buffer "~6.0.3" +"@solana/codecs-core@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz" + integrity sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ== + dependencies: + "@solana/errors" "2.0.0-rc.1" + "@solana/codecs-core@2.1.1": version "2.1.1" - resolved "https://registry.yarnpkg.com/@solana/codecs-core/-/codecs-core-2.1.1.tgz#5d09d7f35b0266789d7c1f9306c08051128a6a64" + resolved "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.1.1.tgz" integrity sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg== dependencies: "@solana/errors" "2.1.1" +"@solana/codecs-data-structures@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz" + integrity sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/codecs-numbers" "2.0.0-rc.1" + "@solana/errors" "2.0.0-rc.1" + "@solana/codecs-numbers@^2.1.0": version "2.1.1" - resolved "https://registry.yarnpkg.com/@solana/codecs-numbers/-/codecs-numbers-2.1.1.tgz#b7a69024e2397e236bbfb11b75ff4a077236b9d2" + resolved "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.1.1.tgz" integrity sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ== dependencies: "@solana/codecs-core" "2.1.1" "@solana/errors" "2.1.1" +"@solana/codecs-numbers@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz" + integrity sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/errors" "2.0.0-rc.1" + +"@solana/codecs-strings@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz" + integrity sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/codecs-numbers" "2.0.0-rc.1" + "@solana/errors" "2.0.0-rc.1" + +"@solana/codecs@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-rc.1.tgz" + integrity sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/codecs-data-structures" "2.0.0-rc.1" + "@solana/codecs-numbers" "2.0.0-rc.1" + "@solana/codecs-strings" "2.0.0-rc.1" + "@solana/options" "2.0.0-rc.1" + +"@solana/errors@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz" + integrity sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ== + dependencies: + chalk "^5.3.0" + commander "^12.1.0" + "@solana/errors@2.1.1": version "2.1.1" - resolved "https://registry.yarnpkg.com/@solana/errors/-/errors-2.1.1.tgz#009ebf387b0c014a8fc60a59d65757fef942e4fd" + resolved "https://registry.npmjs.org/@solana/errors/-/errors-2.1.1.tgz" integrity sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw== dependencies: chalk "^5.4.1" commander "^13.1.0" -"@solana/web3.js@^1.69.0": +"@solana/options@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.npmjs.org/@solana/options/-/options-2.0.0-rc.1.tgz" + integrity sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/codecs-data-structures" "2.0.0-rc.1" + "@solana/codecs-numbers" "2.0.0-rc.1" + "@solana/codecs-strings" "2.0.0-rc.1" + "@solana/errors" "2.0.0-rc.1" + +"@solana/spl-governance@^0.3.28": + version "0.3.28" + resolved "https://registry.npmjs.org/@solana/spl-governance/-/spl-governance-0.3.28.tgz" + integrity sha512-CUi1hMvzId2rAtMFTlxMwOy0EmFeT0VcmiC+iQnDhRBuM8LLLvRrbTYBWZo3xIvtPQW9HfhVBoL7P/XNFIqYVQ== + 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-group@^0.0.7": + version "0.0.7" + resolved "https://registry.npmjs.org/@solana/spl-token-group/-/spl-token-group-0.0.7.tgz" + integrity sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug== + dependencies: + "@solana/codecs" "2.0.0-rc.1" + +"@solana/spl-token-metadata@^0.1.6": + version "0.1.6" + resolved "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz" + integrity sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA== + dependencies: + "@solana/codecs" "2.0.0-rc.1" + +"@solana/spl-token@^0.4.14": + version "0.4.14" + resolved "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.4.14.tgz" + integrity sha512-u09zr96UBpX4U685MnvQsNzlvw9TiY005hk1vJmJr7gMJldoPG1eYU5/wNEyOA5lkMLiR/gOi9SFD4MefOYEsA== + dependencies: + "@solana/buffer-layout" "^4.0.0" + "@solana/buffer-layout-utils" "^0.2.0" + "@solana/spl-token-group" "^0.0.7" + "@solana/spl-token-metadata" "^0.1.6" + buffer "^6.0.3" + +"@solana/web3.js@^1.22.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.69.0", "@solana/web3.js@^1.72.0", "@solana/web3.js@^1.95.3", "@solana/web3.js@^1.95.5": version "1.98.2" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.98.2.tgz#45167a5cfb64436944bf4dc1e8be8482bd6d4c14" + resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.2.tgz" integrity sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A== dependencies: "@babel/runtime" "^7.25.0" @@ -104,103 +349,110 @@ "@swc/helpers@^0.5.11": version "0.5.17" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.17.tgz#5a7be95ac0f0bf186e7e6e890e7a6f6cda6ce971" + resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz" integrity sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A== dependencies: tslib "^2.8.0" +"@types/bn.js@^4.11.5": + version "4.11.6" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + "@types/bn.js@^5.1.0": version "5.1.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz" integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== dependencies: "@types/node" "*" "@types/chai@^4.3.0": version "4.3.20" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.20.tgz#cb291577ed342ca92600430841a00329ba05cecc" + resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz" integrity sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ== "@types/connect@^3.4.33": version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/mocha@^9.0.0": version "9.1.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== "@types/node@*": version "22.15.19" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.19.tgz#ba9f321675243af0456d607fa82a4865931e0cef" + resolved "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz" integrity sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw== dependencies: undici-types "~6.21.0" "@types/node@^12.12.54": version "12.20.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== "@types/uuid@^8.3.4": version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz" integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== "@types/ws@^7.4.4": version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== dependencies: "@types/node" "*" "@types/ws@^8.2.2": version "8.18.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz" integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== dependencies: "@types/node" "*" "@ungap/promise-all-settled@1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== agentkeepalive@^4.5.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz" integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== dependencies: humanize-ms "^1.2.1" ansi-colors@4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" anymatch@~3.1.2: version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -208,49 +460,92 @@ anymatch@~3.1.2: argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== arrify@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== assertion-error@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +axios@^1.1.3: + version "1.16.0" + resolved "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz" + integrity sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w== + dependencies: + follow-redirects "^1.16.0" + form-data "^4.0.5" + proxy-from-env "^2.1.0" + balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.2: version "3.0.11" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.11.tgz#40d80e2a1aeacba29792ccc6c5354806421287ff" + resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz" integrity sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA== dependencies: safe-buffer "^5.0.1" base64-js@^1.3.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bigint-buffer@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz" + integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== + dependencies: + bindings "^1.3.0" + +bignumber.js@^9.0.1: + version "9.3.1" + resolved "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz" + integrity sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ== + binary-extensions@^2.0.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: +bindings@^1.3.0: + version "1.5.0" + resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bn.js@^5.0.0, bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.2" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.2.tgz#82c09f9ebbb17107cd72cb7fd39bd1f9d0aaa566" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz" integrity sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw== +borsh@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/borsh/-/borsh-0.3.1.tgz" + integrity sha512-gJoSTnhwLxN/i2+15Y7uprU8h3CKI+Co4YKZKvrGYUy0FwHWM20x5Sx7eU8Xv4HQqV+7rb4r3P7K1cBIQe3q8A== + dependencies: + "@types/bn.js" "^4.11.5" + bn.js "^5.0.0" + bs58 "^4.0.0" + text-encoding-utf-8 "^1.0.2" + borsh@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" + resolved "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz" integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== dependencies: bn.js "^5.2.0" @@ -259,7 +554,7 @@ borsh@^0.7.0: brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -267,36 +562,36 @@ brace-expansion@^1.1.7: braces@~3.0.2: version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" browser-stdout@1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + resolved "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== dependencies: base-x "^3.0.2" buffer-from@^1.0.0, buffer-from@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-layout@^1.2.0, buffer-layout@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" + resolved "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz" integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== -buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: +buffer@^6.0.3, buffer@~6.0.3, buffer@6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== dependencies: base64-js "^1.3.1" @@ -304,19 +599,27 @@ buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: bufferutil@^4.0.1: version "4.0.9" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.9.tgz#6e81739ad48a95cad45a279588e13e95e24a800a" + resolved "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz" integrity sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw== dependencies: node-gyp-build "^4.3.0" +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + camelcase@^6.0.0, camelcase@^6.3.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== chai@^4.3.4: version "4.5.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8" + resolved "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz" integrity sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw== dependencies: assertion-error "^1.1.0" @@ -329,27 +632,32 @@ chai@^4.3.4: chalk@^4.1.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^5.3.0: + version "5.6.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz" + integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== + chalk@^5.4.1: version "5.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" + resolved "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz" integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== check-error@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz" integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== dependencies: get-func-name "^2.0.2" chokidar@3.5.3: version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: anymatch "~3.1.2" @@ -364,7 +672,7 @@ chokidar@3.5.3: cliui@^7.0.2: version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" @@ -373,129 +681,192 @@ cliui@^7.0.2: color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^12.1.0: + version "12.1.0" + resolved "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz" + integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== + commander@^13.1.0: version "13.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-13.1.0.tgz#776167db68c78f38dcce1f9b8d7b8b9a488abf46" + resolved "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz" integrity sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw== commander@^2.20.3: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== cross-fetch@^3.1.5: version "3.2.0" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.2.0.tgz#34e9192f53bc757d6614304d9e5e6fb4edb782e3" + resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz" integrity sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q== dependencies: node-fetch "^2.7.0" debug@4.3.3: version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" decamelize@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== deep-eql@^4.1.3: version "4.1.4" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.4.tgz#d0d3912865911bb8fac5afb4e3acfa6a28dc72b7" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz" integrity sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg== dependencies: type-detect "^4.0.0" delay@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + resolved "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz" integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== diff@^3.1.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + es6-promise@^4.0.3: version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== es6-promisify@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== dependencies: es6-promise "^4.0.3" escalade@^3.1.1: version "3.2.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-string-regexp@4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eventemitter3@^4.0.7: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== eventemitter3@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== eyes@^0.1.8: version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + resolved "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== fast-stable-stringify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" + resolved "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz" integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== +fastestsmallesttextencoderdecoder@^1.0.22: + version "1.0.22" + resolved "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz" + integrity sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + fill-range@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" find-up@5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -503,39 +874,79 @@ find-up@5.0.0: flat@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +follow-redirects@^1.16.0: + version "1.16.0" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz" + integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw== + +form-data@^4.0.5: + version "4.0.5" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz" + integrity sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" + hasown "^2.0.2" + mime-types "^2.1.12" + fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-func-name@^2.0.1, get-func-name@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== +get-intrinsic@^1.2.6: + version "1.3.0" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob@7.2.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" @@ -545,36 +956,60 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + growl@1.10.5: version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbols@^1.0.3, has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + +hasown@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz" + integrity sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg== + dependencies: + function-bind "^1.1.2" + he@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== humanize-ms@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== dependencies: ms "^2.0.0" ieee754@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -582,61 +1017,61 @@ inflight@^1.0.4: inherits@2: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-plain-obj@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isomorphic-ws@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== jayson@^4.1.1: version "4.2.0" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.2.0.tgz#b71762393fa40bc9637eaf734ca6f40d3b8c0c93" + resolved "https://registry.npmjs.org/jayson/-/jayson-4.2.0.tgz" integrity sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg== dependencies: "@types/connect" "^3.4.33" @@ -654,33 +1089,33 @@ jayson@^4.1.1: js-yaml@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" json-stringify-safe@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== json5@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" log-symbols@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" @@ -688,45 +1123,62 @@ log-symbols@4.1.0: loupe@^2.3.6: version "2.3.7" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz" integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== dependencies: get-func-name "^2.0.1" make-error@^1.1.1: version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - brace-expansion "^1.1.7" + mime-db "1.52.0" minimatch@^3.0.4: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== + dependencies: + brace-expansion "^1.1.7" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== mkdirp@^0.5.1: version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" -mocha@^9.0.3: +"mocha@^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X", mocha@^9.0.3: version "9.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== dependencies: "@ungap/promise-all-settled" "1.1.2" @@ -754,111 +1206,116 @@ mocha@^9.0.3: yargs-parser "20.2.4" yargs-unparser "2.0.0" +ms@^2.0.0, ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.0.0: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - nanoid@3.3.1: version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== -node-fetch@^2.7.0: +node-fetch@^2.6.7, node-fetch@^2.7.0: version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" node-gyp-build@^4.3.0: version "4.8.4" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz" integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== once@^1.3.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" pako@^2.0.3: version "2.1.0" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + resolved "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz" integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== pathval@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== picomatch@^2.0.4, picomatch@^2.2.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== prettier@^2.6.2: version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +proxy-from-env@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz" + integrity sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA== + randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== rpc-websockets@^9.0.2: version "9.1.1" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-9.1.1.tgz#5764336f3623ee1c5cc8653b7335183e3c0c78bd" + resolved "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.1.tgz" integrity sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA== dependencies: "@swc/helpers" "^0.5.11" @@ -874,19 +1331,19 @@ rpc-websockets@^9.0.2: safe-buffer@^5.0.1, safe-buffer@^5.1.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== serialize-javascript@6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== dependencies: randombytes "^2.1.0" source-map-support@^0.5.6: version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" @@ -894,24 +1351,24 @@ source-map-support@^0.5.6: source-map@^0.6.0: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== stream-chain@^2.2.5: version "2.2.5" - resolved "https://registry.yarnpkg.com/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09" + resolved "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz" integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA== stream-json@^1.9.1: version "1.9.1" - resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.9.1.tgz#e3fec03e984a503718946c170db7d74556c2a187" + resolved "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz" integrity sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw== dependencies: stream-chain "^2.2.5" string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -920,70 +1377,70 @@ string-width@^4.1.0, string-width@^4.2.0: strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== 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" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -superstruct@^0.15.4: +superstruct@^0.15.2, superstruct@^0.15.4: version "0.15.5" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab" + resolved "https://registry.npmjs.org/superstruct/-/superstruct-0.15.5.tgz" integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== superstruct@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-2.0.2.tgz#3f6d32fbdc11c357deff127d591a39b996300c54" + resolved "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz" integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + text-encoding-utf-8@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + resolved "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz" integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" toml@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + resolved "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz" integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== tr46@~0.0.3: version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-mocha@^10.0.0: version "10.1.0" - resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.1.0.tgz#17a1c055f5f7733fd82447c4420740db87221bc8" + resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.1.0.tgz" integrity sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA== dependencies: ts-node "7.0.1" @@ -992,7 +1449,7 @@ ts-mocha@^10.0.0: ts-node@7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== dependencies: arrify "^1.0.0" @@ -1006,7 +1463,7 @@ ts-node@7.0.1: tsconfig-paths@^3.5.0: version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" @@ -1016,44 +1473,44 @@ tsconfig-paths@^3.5.0: tslib@^2.8.0: version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== type-detect@^4.0.0, type-detect@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz" integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw== -typescript@^5.7.3: +typescript@^5.7.3, typescript@>=5, typescript@>=5.3.3: version "5.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz" integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== undici-types@~6.21.0: version "6.21.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz" integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== -utf-8-validate@^5.0.2: +utf-8-validate@^5.0.2, utf-8-validate@>=5.0.2: version "5.0.10" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + resolved "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz" integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== dependencies: node-gyp-build "^4.3.0" uuid@^8.3.2: version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" @@ -1061,19 +1518,19 @@ whatwg-url@^5.0.0: which@2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" workerpool@6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -1082,37 +1539,42 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@^7.5.10: +ws@*, ws@^7.5.10: version "7.5.10" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== ws@^8.5.0: version "8.18.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.2.tgz#42738b2be57ced85f46154320aabb51ab003705a" + resolved "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz" integrity sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== +yaml@^2.7.0: + version "2.8.4" + resolved "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz" + integrity sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog== yargs-parser@^20.2.2: version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + yargs-unparser@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== dependencies: camelcase "^6.0.0" @@ -1122,7 +1584,7 @@ yargs-unparser@2.0.0: yargs@16.2.0: version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" @@ -1135,10 +1597,10 @@ yargs@16.2.0: yn@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + resolved "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/КОШЕЛЬКИ_DEVNET_ТЕСТ.md b/КОШЕЛЬКИ_DEVNET_ТЕСТ.md index 3d33840..b7f3ce1 100644 --- a/КОШЕЛЬКИ_DEVNET_ТЕСТ.md +++ b/КОШЕЛЬКИ_DEVNET_ТЕСТ.md @@ -1,35 +1,58 @@ -# Кошельки Devnet (тестовые) +# Кошельки Devnet (тестовые, приватные ключи в Base58) -> Только для тестового этапа. Не использовать в production. +> Только для тестов. Не использовать в production. +> +> Балансы ниже актуальны на 2026-05-08 (Devnet), могут меняться после транзакций. -## DAO (текущий) +## DAO (текущий для Shine Payments) - public: `6bFc5Gz5qF172GQhK5HpDbWs8F6qcSxdHn5XqAstf1fY` - private (base58): `3VYfYZZ3ugmgwisiQQAfcimX9T65AE9BmwmYVixAUj4jyneccSE9rzbC3g5twvH7ECZ8xgp7emJo3pR4yQqCwjGn` +- роль: основной DAO-кошелёк в `shine_payments` (получает DAO-часть выплат, выдаёт лимиты менеджерам) -## Manager для coef/limit (текущий) +## Manager / deploy wallet (текущий системный) - public: `4yzHKs2zFXpyqqCETe8KpAs4xhEo4QhJ2ybyTgRZphZv` -- private (json array): - -```json -[90,184,152,226,36,29,0,20,192,35,239,186,138,46,197,219,65,216,46,150,150,113,95,216,66,95,68,79,178,239,166,133,59,44,90,189,77,253,249,234,240,215,66,104,14,194,200,186,203,176,232,154,245,165,226,23,127,115,246,181,134,24,148,45] -``` +- private (base58): `2pCe8GWpXL7hYf3tFQZg4azfPw3hm1UwvybRbJ6j5rKBvTjBme2DuWESKM5e5jd2JLw7b4D5sWno4YbxRdot4Gap` +- роль: + - upgrade authority и кошелёк деплоя программ; + - `MANAGER_WALLET` в настройках (имеет право менять `coef/limit`). ## Тестовый кошелёк key1 - public: `HMww7YSVfwVm4i8sugqj7wyH26dqzHykzv3wzWwzEvPA` - private (base58): `5pbFo9Zq1VsNheHwbEp6AZKa6R62CZHoGkJFZnugpMEtCmkQFjuUP7TgA5hSPqv4NABGmPP62qVnDPHmRqEAwvJc` +- роль: дополнительный тестовый пользователь (покупка билетов, получение выплат) ## Тестовый кошелёк key2 - public: `E3ZDHbWv1qiFvDTmaRc9wjFCgbQw6UmKJLJYbaTNvjAh` - private (base58): `5qm1GJGXB1fFJ3YsU5Y3XXgTiQfaimqBWk79oEveFASH9D2of3jqUoT7dumBvS449fW5j5Sw8MgAMH2QBMmFPdry` +- роль: дополнительный тестовый пользователь (второй участник сценариев) -## Тестовый кошелёк phantomWallet +## Тестовый кошелёк phantomWallet (твой основной рабочий) -- private (json array): +- public: `FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P` +- private (base58): `5RpEoxRKSr2norQP3vEnq9XokQGh9EbGN8q8xUUVAdm1M5mTD1vMuyJPYJfViMWFf6c8qT5mj2bt64gLE2zm6VG3` +- роль: + - основной кошелёк для ручного тестирования через UI; + - можно использовать как менеджер очередей (после выдачи лимитов DAO через `grant_manager_limits`). -```json -[221,119,143,125,90,136,155,115,191,198,210,85,228,111,251,118,168,138,27,60,249,62,247,24,121,228,139,112,218,69,55,143,215,21,229,69,219,1,74,36,10,239,63,163,48,240,58,208,237,251,209,37,17,202,215,77,13,165,178,18,141,21,193,64] -``` +## testDaoCreator (Phantom-совместимый) + +- public: `A9AP6TMUuxbXwR8H2xN8hA7SXddnnxRH1vhP2qwEuG2r` +- private (base58): `5JR37dCQUB4jtjSzoLp3pkGMkCoTpNLxZLXJDrGZnYCDcBgX9cmqmHVbQz2VbYgGZnG2StNSQ5cMgJf1PSa8gvpv` +- роль: резервный тестовый кошелёк (можно использовать как отдельный DAO/менеджер в экспериментах) + +## Program keypair (для деплоя) + +- `shine_payments` + - program id: `4QDCcaURt7phJGcvDS4VQQtrqDmUSMXvkWnMnMKCiUyE` + - private key (base58): `3Fk2zYKTfoLMoU1tqMypGBsxj9zFF7PdXNEtodamv9aqtm8KWJNqsmT5DE9Z8pyDLCSqwdLM59LxbfdYp99b4xGg` + - роль: ключ адреса программы (не пользовательский кошелёк) + - баланс Devnet (program account): `0.00114144 SOL` +- `shine_users` + - program id: `8Z3HQizFRhyVu5cNBwWNBXZHTpu89VMkn7Wuk1oCtkeJ` + - private key (base58): `2Zi4zNSFv69s3PPWr2vCtySiKSxiLA37TSSvHHVTygEQrehHScPoDkjKXYjVXDAHXi1Kg6LiZvYAq1ftV6aPSdrN` + - роль: ключ адреса программы (не пользовательский кошелёк) + - баланс Devnet (program account): `0.00114144 SOL`