From c32134cd98c495e37d8a8a96f63b2e689f522436 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 02:08:14 +0000 Subject: [PATCH 1/6] Establish White Lotus (WLOTUS) ALP PoW remint scaffold Migrate the covenant/miner scaffold from eminer branch cursor/wlotus-scaffold-d6bb into the canonical wlotus repo, and include feasibility research from eminer#1. Includes consensus params (Moore 99918/100000, N=8 batons), CashScript remint draft, genesis plan, Moore math + tests. Co-authored-by: nghiacc --- .env.example | 5 + .gitignore | 9 + LICENSE | 21 + README.md | 56 +- contracts/WlotusRemint.cash | 75 + docs/ARCHITECTURE.md | 48 + docs/PROPOSAL.md | 194 + docs/SPEC.md | 56 + docs/STATUS.md | 22 + docs/research/README.md | 11 + docs/research/alp-token-burn-on-ecash.md | 272 + .../research/ergon-style-issuance-on-ecash.md | 184 + jest.config.cjs | 19 + package-lock.json | 4820 +++++++++++++++++ package.json | 33 + scripts/compute-moore.ts | 34 + src/genesis/createGenesis.ts | 52 + src/index.ts | 17 + src/lib/moore.ts | 69 + src/miner/remint.ts | 44 + src/params/consensus.ts | 59 + tests/moore.test.ts | 71 + tsconfig.json | 16 + 23 files changed, 6185 insertions(+), 2 deletions(-) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 contracts/WlotusRemint.cash create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/PROPOSAL.md create mode 100644 docs/SPEC.md create mode 100644 docs/STATUS.md create mode 100644 docs/research/README.md create mode 100644 docs/research/alp-token-burn-on-ecash.md create mode 100644 docs/research/ergon-style-issuance-on-ecash.md create mode 100644 jest.config.cjs create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/compute-moore.ts create mode 100644 src/genesis/createGenesis.ts create mode 100644 src/index.ts create mode 100644 src/lib/moore.ts create mode 100644 src/miner/remint.ts create mode 100644 src/params/consensus.ts create mode 100644 tests/moore.test.ts create mode 100644 tsconfig.json diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e28f861 --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +# Chipnet / mainnet secrets — never commit +CHRONIK_URL=https://chronik.fabien.cash +# WIF for fee + mining payouts (chipnet) +# MINER_WIF= +# GENESIS_WIF= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bcd4026 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +node_modules/ +dist/ +.cache/ +.env +.env.* +!.env.example +*.log +.DS_Store +coverage/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8a8415a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 WLotus contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 2017ed5..2e76a1a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,54 @@ -# wlotus -White Lotus Token +# WLotus + +**White Lotus (WLOTUS)** — Ergon-like ritual ALP token on eCash with permissionless PoW remint. + +This repository holds the **covenant, parameters, genesis tooling, and remint miner**. +Website / temple UI live in a separate repo. + +## Design (short) + +| Piece | Choice | +|-------|--------| +| Host | eCash (XEC) | +| Token | ALP (`SLP2` / eMPP) | +| Issuance | Fixed PoW difficulty; atoms/remint with Moore decay; **many remints/block** | +| Parallelism | **`N ≥ 2` mint batons** (true concurrent remints) | +| Moore factor | Ergon post-fix **`99918/100000`** per wall-day (~2.3y half-life) | +| Supply cap | None — PoW batons never die | +| Burn | Intentional ALP burn (temple / vàng mã offerings) — app layer | + +Issuance elasticity comes from **remint frequency ∝ hashrate**, not from `mint ∝ D`. +Do **not** use Mist-style 1-mint-per-host-block CLTV. + +See [docs/SPEC.md](./docs/SPEC.md) and [docs/PROPOSAL.md](./docs/PROPOSAL.md). + +## Status + +Scaffold for covenant + miner (migrated from the temporary +`eminer` branch `cursor/wlotus-scaffold-d6bb`). Chipnet genesis and +audited Script are TODO. See [docs/STATUS.md](./docs/STATUS.md). + +## Layout + +``` +contracts/ # CashScript remint covenant +docs/ # Consensus / product spec + research +src/params/ # Consensus constants (Moore, batons, …) +src/lib/ # Moore math, ALP helpers +src/genesis/ # GENESIS + baton handoff tooling +src/miner/ # PoW remint miner (Chronik + ecash-lib) +scripts/ # Utilities +tests/ # Unit tests +``` + +## Quick start + +```bash +npm install +npm test +npm run moore -- --days 365 # print M after 365 wall-days +``` + +## License + +MIT diff --git a/contracts/WlotusRemint.cash b/contracts/WlotusRemint.cash new file mode 100644 index 0000000..670b5f9 --- /dev/null +++ b/contracts/WlotusRemint.cash @@ -0,0 +1,75 @@ +/** + * WLOTUS PoW remint covenant (CashScript draft). + * + * Intent (enforce on every remint): + * 1. PoW: hash256(txPreimage || nonce) has `difficultyLeadingZeroBytes` leading zero bytes + * 2. Mint atoms == Moore-adjusted M(k) from host time (δ = 99918/100000 per day-step) + * 3. Outputs include ALP MINT for `tokenId` paying `mintAtoms` to miner + * 4. Exactly one mint baton returned to this covenant (cardinality conserved per tip) + * + * Parallelism: genesis creates N independent UTXOs locked to this same redeem template + * (possibly with a batonIndex constructor arg). Miners race each tip separately. + * + * NOT production-ready: needs chipnet testing, CashScript version pin, and audit. + * ALP OP_RETURN bytes must match Chronik / ecash-lib `alpMint` encoding exactly. + * + * Moore clock MUST use host median time / block height — never token-mint height. + */ + +pragma cashscript ^0.10.0; + +contract WlotusRemint( + bytes32 tokenId, + int difficultyLeadingZeroBytes, + int baseMintAtoms, + int genesisHostHeight, + int mooreDayBlocks, // 144 + int mooreNum, // 99918 — Ergon post-fix only + int mooreDen, // 100000 + int batonIndex // 0 .. N-1, binds this tip in a multi-baton set +) { + /** + * Permissionless remint: solve PoW, mint M(k), pass baton forward. + * + * Unlocking args are illustrative — final sighash / introspection wiring + * will follow ecash-lib / Agora patterns on chipnet. + */ + function remint( + bytes nonce, + pubkey minerPk, + sig minerSig, + int hostHeight + ) { + // Host height must not precede genesis. + require(hostHeight >= genesisHostHeight); + + // k = floor((hostHeight - genesisHostHeight) / mooreDayBlocks) + int k = (hostHeight - genesisHostHeight) / mooreDayBlocks; + + // M(k) via repeated (x * 99918) / 100000 — forbid obsolete 99826. + require(mooreNum == 99918); + require(mooreDen == 100000); + int mintAtoms = baseMintAtoms; + // Bounded loop: cashscript needs a fixed max iterations in practice. + // Implementation plan: precompute mintAtoms off-chain and verify with + // a covenant-friendly proof, OR unroll with a max-k cap for early years. + // Placeholder verification hook: + require(mintAtoms == baseMintAtoms || k >= 0); + + // PoW over preimage||nonce — exact preimage source TBD (native introspection). + // require(tx.preimage matches BIP143 / covenant pattern); + // bytes32 h = hash256(preimage + nonce); + // require(leadingZeroBytes(h) >= difficultyLeadingZeroBytes); + + require(checkSig(minerSig, minerPk)); + + // Outputs (conceptual): + // out0: OP_RETURN eMPP + ALP MINT(tokenId, [mintAtoms], numBatons=1) + // out1: P2PKH(minerPk) colored with mintAtoms + // out2: P2SH(this contract) mint baton (same constructors, batonIndex unchanged) + + // Enforce baton conservation and ALP byte template in a follow-up diff + // once introspection output locks are pinned to ecash-lib encodings. + require(batonIndex >= 0); + } +} diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..1df2225 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,48 @@ +# Architecture + +## Flow + +``` +GENESIS (ALP) + └─ creates N PoW mint batons → each locked to remint covenant P2SH + │ + ├─ miner solves PoW on baton i + │ outputs: ALP MINT M(k) → miner + │ baton → next covenant state (same rules) + │ + └─ devotee acquires WLOTUS → alpBurn (+ memorial metadata in app repo) +``` + +## Why multi-baton + +A single ALP mint baton tip is **serial**: only one spend wins at a time. +`N` independent PoW batons allow **true parallel** remints in one eCash block, so: + +`coins/time ≈ N × (hashrate/N) / work_per_solution × M(k) ≈ hashrate × M(k) / work` + +## Covenant responsibilities + +For each remint spend, Script must enforce: + +1. PoW: `hash256(preimage || nonce)` has `POW_LEADING_ZERO_BYTES` leading zero bytes +2. Mint atoms equal Moore-adjusted `M(k)` from host time +3. Outputs include valid ALP MINT section for this `tokenId` +4. Exactly one mint baton returned to the covenant (P2SH with updated state if any) +5. No destruction of PoW baton set cardinality + +ALP validity is still indexer-enforced (Chronik); the covenant must emit **byte-exact** MINT pushdata. + +## Components + +| Path | Role | +|------|------| +| `contracts/WlotusRemint.cash` | CashScript draft of remint covenant | +| `src/params/consensus.ts` | Shared constants | +| `src/lib/moore.ts` | `M(k)` integer math | +| `src/genesis/` | Build GENESIS + hand off `N` batons | +| `src/miner/` | Watch Chronik baton UTXOs, mine, broadcast | + +## Networks + +Target order: **chipnet → test → mainnet**. +Do not mainnet-genesis until Script is reviewed and `D` / `M₀` / `N` are tuned. diff --git a/docs/PROPOSAL.md b/docs/PROPOSAL.md new file mode 100644 index 0000000..098e1fb --- /dev/null +++ b/docs/PROPOSAL.md @@ -0,0 +1,194 @@ +# Proposal: White Lotus — Ergon-like ritual coin + +**Recommendation: build White Lotus as an Ergon-like ALP token on eCash first. Do not launch an L1 unless the token proves ritual demand and outgrows eCash rails.** + +--- + +## 1. Decision + +| Option | Role | +|--------|------| +| **A. White Lotus on eCash (ALP + PoW remint)** | **Primary — ship this** | +| **B. White Lotus L1 (eCash/Ergon-style fork)** | Contingency only — after product-market fit | + +Ritual need (vàng mã sacrifice + rebirth + commons) is satisfied by **issuance rules**, not by owning a blockchain. eCash already gives maintenance, Chronik, wallets, and Agora. An L1 buys fork-fairness and sovereign monetary policy at the cost of becoming a chain operator. + +--- + +## 2. Why A over B (now) + +| Criterion | ALP on eCash | New L1 | +|-----------|--------------|--------| +| Work-elastic issuance | Yes — remint *frequency* ∝ hashrate (+ Moore) | Yes — `GetBlockSubsidy ∝ difficulty` (+ Moore) | +| Vàng mã burn + rebirth | Yes — burn + perpetual baton(s) | Yes — native burn + subsidy | +| Holder-capture vs Lotus `log(D)` | Avoided (issuance answers work) | Avoided if subsidy ∝ `D` | +| Ops burden | App + covenant + miner | Full node, miners, explorers, upgrades forever | +| User acquisition of offering | XEC → Agora/desk → burn | Need exchange/liquidity for new coin | +| Maintenance of base chain | Bitcoin ABC / eCash | You | +| Fork-energy fairness | Soft (token PoW) | Strong (L1 work) | +| Time to a working temple | Much shorter | Much longer | + +Lotus Temple already showed: **elastic but inelastic issuance (`log D`) + burns** enriched holders. Fix issuance, don’t fork a nation-state chain on day one. + +--- + +## 3. Product architecture (Option A) + +### 3.1 Narrative + +- **White Lotus (hoa sen trắng)** — Vietnamese mourning / purity symbol +- Cycle: *effort remints the flower → devotee burns it → merit is public → flower can bloom again* +- Cumulative burned = spiritual ledger; circulating supply is secondary + +### 3.2 Token + +| Item | Choice | +|------|--------| +| Host | eCash (XEC) | +| Protocol | **ALP** (`SLP2` / eMPP) | +| Ticker (example) | `WLOTUS` / `WLTS` | +| Mint authority | **Permissionless PoW covenants** on **multiple** mint batons | +| Burn | Intentional `alpBurn` + memorial metadata (person / temple / offering tier) | +| Indexer | Chronik | +| Liquidity | Agora + optional temple desk (XEC ↔ token) | + +### 3.3 Issuance — remint frequency + Moore decay + +**Insight:** On Ergon, block *rate* is held ~constant by the DAA, so elasticity lives in **coins per block** (`∝ D`). On an ALP PoW remint, invert that: + +- Fixed PoW difficulty; base atoms per remint before Moore +- **Many remints per eCash block** (no Mist “1 mint / host block” CLTV) +- **Multiple ALP mint batons** for **true parallel** remints (§3.5) +- ⇒ **remints/time ∝ hashrate** ⇒ **coins/time ∝ hashrate** + +``` +coins/time ≈ N_batons × (hashrate_per_baton / hashes_per_solution) × M(t) +``` + +No token DAA and no `mintAmount ∝ work(D)` required for Ergon-like *flow*. + +#### Moore / Koomey — Ergon **post-launch** constant only + +Ergon’s daily correction in [`validation.cpp` (GetBlockSubsidy)](https://github.com/Ergon-moe/Bitcoin-Static/blob/2e8d5f7635c899cc99e71f06dedbe72b3ff7f07b/src/validation.cpp#L978): + +```cpp +// Pre-EMA (obsolete ~1.1y half-life) — DO NOT USE FOR WLOTUS +aWork *= 99826; aWork /= 100000; + +// Post-EMA / corrected (~2.3y half-life) — USE THIS +aWork *= 99918; aWork /= 100000; +``` + +Bitcoin Static release notes fixed Moore from **1.1y → 2.3y**. **WLOTUS ships `δ = 99918/100000` from genesis** — never the old `99826` factor. + +| Symbol | WLOTUS | Notes | +|--------|--------|-------| +| `δ` | **`99918 / 100000`** | Ergon corrected daily factor | +| Day step | ~1 wall day | Ergon: once per `nSubsidyHalvingInterval` (144 × 10‑min blocks). Mirror with ~144 eCash blocks or median-time day | +| `M(t)` | `M₀ · δ^{k}` | `k = floor(elapsed_days)` since genesis | +| Clock | **eCash height / median time** | **Not** token-mint height (that races with hashrate) | + +Covenant integer form: + +``` +M_expected = M₀ +repeat k times: + M_expected = (M_expected * 99918) / 100000 +verify mintAtoms == M_expected +``` + +#### Canonical knobs + +| Knob | Setting | Role | +|------|---------|------| +| PoW difficulty `D` | Fixed, tunable | Effort per remint solution | +| Base atoms `M₀` | Genesis constant | Initial unlock per solution | +| Moore `δ` | **`99918/100000`** | ~2.3y half-life efficiency decay | +| Host CLTV 1-mint/block | **Off** | Keep hashrate → issuance elasticity | +| Supply cap | **None** | Batons never die | +| PoW baton count `N` | **`N ≥ 2` at genesis** | True parallel remints (§3.5) | + +**Skip unless needed later:** token-local DAA; `mintAmount ∝ work(D)`. + +Tune `D` / `M₀` / `N` from burn demand and miner contention. Each remint pays XEC fees (anti-spam). + +### 3.4 App flow + +``` +Devotee opens memorial page + → acquires WLOTUS (Agora / desk / gifted) + → chooses offering (flower / incense / candle = burn tiers) + → alpBurn + eMPP memorial payload + → Chronik + API update cumulative merit + +Parallel: + Miners race across N PoW batons → remint → sell / provide liquidity +``` + +Reuse `app-lotus-temple` UX; retarget settlement from XPI burns to ALP burns on eCash. + +### 3.5 Multiple mint batons (first-class parallelization) + +ALP allows **many mint batons** (SLP allowed only one). White Lotus treats multi-baton as **core design**. + +**A. PoW baton set (canonical issuance)** + +- Genesis creates **`N ≥ 2` identical PoW covenant batons** (independent tips, same rules). +- Miners remint **in parallel** in the same eCash block — not merely a serial chain on one tip. +- Each successful spend: PoW OK → mint exactly `M(t)` → **return one baton** to the next covenant state (**conserve `N`**). +- Choose `N` at genesis (e.g. 4–16); change only via a deliberate migration if ever required. + +This is how “multiple mints per block” becomes **true parallelization** and matches frequency-elasticity in §3.3. A single baton alone still serializes and wastes work under load. + +**B. Optional temple baton (bootstrap only)** + +- Separate rate-limited / multi-sig baton for cold-start or emergency. +- Prefer destroying it once PoW batons + Agora liquidity exist. + +**Invariant:** PoW batons are never burned; temple baton may be retired. + +--- + +## 4. Option B — L1 (when, and only when) + +Consider a White Lotus / Ergon-like L1 **only if**: + +1. Temple has sustained burn volume and cultural adoption +2. eCash fee / policy / tooling constraints block the ritual +3. You accept permanent chain ops (or a funded commons to run them) +4. You want hard fork-fairness (“energy can’t be counted twice”) as a first-class property + +Then: fork a maintained UTXO codebase, set work-elastic subsidy + **`δ = 99918/100000` Moore**, **0% founder fund**, fee burn optional. Port the temple app to native burns. + +Until then, L1 is premature optimization of sovereignty. + +--- + +## 5. Phased delivery (Option A) + +| Phase | Deliverable | +|-------|-------------| +| **0** | Spec: covenant rules, `M(t)` with `δ=99918/100000`, burn LOKAD, **`N` baton policy** | +| **1** | GENESIS (`N` PoW batons) + Chronik + temple burn UI (custodial remint OK to dogfood) | +| **2** | PoW remint covenant + miner (fixed `D`, Moore on wall-time, **multi-baton parallel**, no 1-mint/block CLTV) | +| **3** | Agora market + public cumulative-burn explorer | +| **4** | Retune `D` / `M₀` / `N` from burn & hashrate data | +| **5** | Revisit L1 only with evidence from 1–4 | + +--- + +## 6. Explicit non-goals (v1) + +- USD stablecoin +- Fixed max supply +- Lotus-style `log(D)` inelastic subsidy +- Ergon’s obsolete Moore factor `99826/100000` +- Mist-style 1-mint-per-host-block CLTV +- Launching a new L1 to “build community faster” +- Relying on TBP (not needed on eCash) + +--- + +## 7. One-line decision + +**White Lotus = ALP on eCash with parallel PoW remint batons, fixed `D`, Moore `δ=99918/100000`, and burn-as-vàng-mã. L1 only after the ritual works.** diff --git a/docs/SPEC.md b/docs/SPEC.md new file mode 100644 index 0000000..b53b6b3 --- /dev/null +++ b/docs/SPEC.md @@ -0,0 +1,56 @@ +# WLOTUS Consensus Parameters (v0.1 draft) + +These constants define the **intended** genesis / covenant policy. +They are not live on mainnet until GENESIS + baton handoff are executed. + +## Identity + +| Param | Value | Notes | +|-------|-------|-------| +| Ticker | `WLOTUS` | White Lotus | +| Name | `White Lotus` | | +| Protocol | ALP standard (`SLP2`) | eCash | +| Decimals | `6` | Precision for Moore integer decay | + +## PoW remint + +| Param | Value | Notes | +|-------|-------|-------| +| `POW_LEADING_ZERO_BYTES` | `2` | Draft — retune on chipnet | +| `BASE_MINT_ATOMS` (`M₀`) | `100_000_000` | = 100 WLOTUS @ 6 decimals per remint at genesis (keep large for Moore floor-div) | +| Host 1-mint/block CLTV | **disabled** | Required for frequency elasticity | +| Supply cap | **none** | PoW batons never die | + +## Parallel batons + +| Param | Value | Notes | +|-------|-------|-------| +| `POW_BATON_COUNT` (`N`) | `8` | True parallel remint tips at genesis | +| Temple bootstrap baton | optional | Separate; retire after liquidity | + +Each remint spends exactly one PoW baton and recreates exactly one PoW baton (conserve `N`). + +## Moore / Koomey decay (Ergon post-fix) + +Source: [Ergon-moe/Bitcoin-Static `validation.cpp` L978](https://github.com/Ergon-moe/Bitcoin-Static/blob/2e8d5f7635c899cc99e71f06dedbe72b3ff7f07b/src/validation.cpp#L978) + +| Param | Value | Notes | +|-------|-------|-------| +| `MOORE_NUM` | **`99918`** | Use this — ~2.3y half-life | +| `MOORE_DEN` | **`100000`** | | +| Obsolete factor | `99826/100000` | Pre-fix ~1.1y — **forbidden** | +| Day step | `144` eCash blocks | Same idea as Ergon `nSubsidyHalvingInterval` @ 10 min | +| Clock | Host chain height / median time | **Not** token-mint height | + +``` +M(k) = floor_div_iter(M₀, k) +where each step: x ← (x * 99918) / 100000 +k = floor( (hostHeight - genesisHeight) / 144 ) +``` + +## Explicit non-goals (v0.1) + +- `mintAmount ∝ work(D)` / token DAA +- Fixed max supply +- Mist 1-mint-per-block CLTV +- Website / temple app (separate repo) diff --git a/docs/STATUS.md b/docs/STATUS.md new file mode 100644 index 0000000..4dab84b --- /dev/null +++ b/docs/STATUS.md @@ -0,0 +1,22 @@ +# Repository status + +Canonical home: **https://github.com/bcProFoundation/wlotus** + +Scaffold was first drafted on a temporary orphan branch of `eminer` +(`cursor/wlotus-scaffold-d6bb`) while the Cursor GitHub App lacked push +access to this repo. That work is now landed here. + +## Design sources + +| Doc | Role | +|-----|------| +| [PROPOSAL.md](./PROPOSAL.md) | Product decision (ALP on eCash first; L1 deferred) | +| [SPEC.md](./SPEC.md) | Consensus draft parameters | +| [ARCHITECTURE.md](./ARCHITECTURE.md) | Covenant / multi-baton flow | +| [research/](./research/) | Feasibility notes from [eminer#1](https://github.com/bcProFoundation/eminer/pull/1) | + +## Next ops + +1. Chipnet GENESIS with `N` PoW batons +2. Harden `contracts/WlotusRemint.cash` + Chronik miner wiring +3. Temple / burn UI in a separate app repo diff --git a/docs/research/README.md b/docs/research/README.md new file mode 100644 index 0000000..681a651 --- /dev/null +++ b/docs/research/README.md @@ -0,0 +1,11 @@ +# Research notes + +Feasibility write-ups that informed the White Lotus design. +Canonical product decision: [../PROPOSAL.md](../PROPOSAL.md). + +Upstream discussion: [bcProFoundation/eminer#1](https://github.com/bcProFoundation/eminer/pull/1). + +| File | Topic | +|------|--------| +| [alp-token-burn-on-ecash.md](./alp-token-burn-on-ecash.md) | Intentional ALP burns (vàng mã) on eCash | +| [ergon-style-issuance-on-ecash.md](./ergon-style-issuance-on-ecash.md) | Ergon-like elastic issuance via ALP PoW remint | diff --git a/docs/research/alp-token-burn-on-ecash.md b/docs/research/alp-token-burn-on-ecash.md new file mode 100644 index 0000000..785fb03 --- /dev/null +++ b/docs/research/alp-token-burn-on-ecash.md @@ -0,0 +1,272 @@ +# Evaluation: ALP for intentional token burn on eCash (temple / White Lotus) + +**Verdict: Yes — ALP is suitable and currently the right token layer for a burn-as-respect product on eCash.** Prefer ALP over legacy SLP. Do not plan on CashTokens (those are BCH-native; eCash would need a hard fork). TBP (Token Burn *Protection*) is a different problem and is largely unnecessary on eCash. + +**Supply policy correction:** A **fixed supply is a poor fit** for Eastern memorial / rebirth symbolism. When every token is burned, offerings cannot continue. Prefer a **perpetual mint baton** so tokens can be **reborn** as new offerings are made. Track **cumulative burned** (merit) separately from **circulating** supply. + +--- + +## 1. Correction: CashTokens vs ALP on eCash + +| Protocol | Chain | Role | +|----------|-------|------| +| **CashTokens** | Bitcoin Cash (BCH) | Consensus-native tokens; **not** available on eCash without a hard fork | +| **SLP / eToken** | eCash (legacy) | OP_RETURN meta-protocol; Chronik-indexed | +| **ALP (Augmented Ledger Protocol)** | eCash | SLP successor (`SLP2` LokadID over **eMPP**); Chronik-indexed; intentional **BURN** supported in `ecash-lib` | + +Earlier guidance that recommended CashTokens for eCash was wrong. For eCash apps, **ALP is the modern token path**. + +Official ALP spec: [bitcoin-abc `doc/standards/alp.md`](https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/standards/alp.md) (also published on ecashbuilders Notion). + +--- + +## 2. What the linked TBP page is (and is not) + +[Token burn protection (TBP)](https://ecashbuilders.notion.site/Token-burn-protection-TBP-protocol-14e9edc6e92f80abbb36ec1ca70adfe9) is about **accidental** burns: non-token wallets spending SLP/ALP UTXOs as plain sats and destroying tokens. + +The same page states: + +> This spec is only intended to be deployed on blockchains where non-token wallets are common. **eCash (XEC) wallets are already very aware of tokens, so this spec is not needed there.** + +So for a temple on eCash: + +- **TBP ≠ intentional offering burn** +- You do **not** need TBP to ship incense/flower burns +- You **do** need intentional burn encoding + indexing (ALP + Chronik + wallet UX) + +--- + +## 3. Does ALP support intentional burns? + +**Yes.** + +1. **Protocol design:** ALP SEND verifies `∑ inputs ≥ ∑ outputs`. Destroying the difference is a burn (same family as SLP). ALP also defines an explicit **BURN** section type (envisioned in the spec; implemented in tooling). +2. **`ecash-lib`:** `alpBurn(tokenId, tokenType, burnAtoms)` builds intentional burn pushdata. +3. **`ecash-wallet` / Cashtab path:** ALP standard tokens support GENESIS / MINT / SEND / **BURN**. ALP can burn an exact amount and keep change in one flow; SLP often needs chained txs for exact intentional burns. +4. **Chronik:** Default token index covers **SLP and ALP**, with safety checks so XEC-only apps do not accidentally spend token UTXOs. + +For a memorial offering, a burn tx can also carry **extra eMPP pushdata** (temple id, person id, offering type) beside the ALP BURN/SEND section — something SLP’s single-OP_RETURN monopoly made awkward. + +--- + +## 4. Fit for “online temple / White Lotus” burns + +| Requirement | ALP fit | +|-------------|---------| +| Intentional, attributable destruction of value | Strong — explicit burn + Chronik history | +| Branded offering token (e.g. White Lotus) | Strong — GENESIS with ticker/name/url/data | +| Regenerative / rebirth supply (never “runs out”) | Strong — keep mint baton(s) alive; ALP allows multiple batons | +| Metadata: who / which temple / flower vs incense | Strong — eMPP multi-section + app OP_RETURN | +| Wallet / indexer support on eCash | Strong — Chronik + Cashtab/`ecash-lib` stack | +| Consensus enforcement like CashTokens | **No** — still indexer rules; trust Chronik + wallet discipline | +| Accidental burn by random XEC wallet | Low risk on eCash (token-aware ecosystem); still educate users | + +**Recommended token policy for offerings (rebirth / regenerative)** + +Do **not** close the mint baton. ALP was explicitly improved over SLP to allow **multiple mint batons** and ongoing `MINT` while a baton input is present ([ALP spec](https://ecashbuilders.notion.site/ALP-a862a4130877448387373b9e6a93dd97)). + +Preferred cycle: + +``` +devotee pays XEC (or holds tokens) + ↓ + ALP MINT (rebirth) — baton stays alive + ↓ + ALP BURN as offering + memorial metadata + ↓ + cumulative burned ↑ circulating can stay small +``` + +Practical variants (pick one trust model): + +| Model | How rebirth works | Trust | Spiritual fit | +|-------|-------------------|-------|----------------| +| **A. Mint-at-offering (recommended v1)** | App/temple holds baton; each offering mints then burns (or mints to user who burns) | Temple/app key | Simple “reborn when remembered” | +| **B. Multi-temple batons** | ALP multi-baton: one baton per temple/region | Each temple | Federated White Lotus network | +| **C. Permissionless PoW remint** | Mist/eminer-style covenant on the baton; anyone remints by work | Rules in script | Strongest “no earthly owner”; harder to build — see §8 | +| **D. Burn-coupled remint** | Policy remints in proportion to recent burns / demand | Policy + baton custody or covenant | Closest to Lotus founder economics | + +Product metrics to show in the temple UI: + +- **Cumulative offerings burned** (never shrinks) — the spiritual ledger +- **Circulating tokens** (can be near zero) — not the point of the ritual +- **Alive mint baton(s)** — proof the flower can bloom again + +**Alternative (even simpler):** burn **native XEC** with OP_RETURN memorial tags (closest to current Lotus Temple XPI burns). Use ALP when you want a **named sacred token** with an explicit rebirth (mint) story. + +--- + +## 5. ALP vs other burn options on eCash + +| Approach | Pros | Cons | +|----------|------|------| +| **ALP intentional burn** | Branded token; exact burn; eMPP metadata; maintained stack | Meta-protocol; need Chronik; mint policy discipline | +| **Legacy SLP burn** | Older ecosystem familiarity | Worse endian/overflow/ghost-output footguns; weaker multi-protocol; exact burns harder | +| **Burn XEC only** | Simplest UX; max liquidity; no token mint politics | No separate “White Lotus” unit; offering is just cash | +| **CashTokens** | Consensus-native | **Not on eCash** without hard fork | +| **New L1 (White Lotus chain)** | Full monetary control | Ops burden; liquidity cold start | + +--- + +## 6. Risks / implementation notes + +1. **Indexer dependency:** Invalid ALP sections are discarded by indexers; consensus still moves the sats. Always build with Chronik validation before broadcast. +2. **Mint baton custody:** An open baton is *required* for rebirth, but whoever holds it can inflate supply. Mitigations: mint-only-at-offering (no free airdrops), rate limits, multi-sig/temple federation, or later a PoW/covenant baton (model C). +3. **OP_RETURN size:** Practical ALP output count is capped (~29 under current policy); fine for burns (usually 0–1 token change outputs). +4. **UX:** Cashtab users can hold/burn ALP; in-app temple wallet should use `ecash-lib` / `ecash-wallet` rather than hand-rolled SLP. +5. **Do not confuse TBP with product burns:** TBP is accidental-burn *prevention* for non-token chains; your product needs intentional burn *expression*. + +--- + +## 7. Bottom line + +**ALP is suitable — and is the best current eCash token protocol — for building intentional token burns for a White Lotus / online temple.** + +Ship path: + +1. Genesis an ALP token **with mint baton(s) kept alive** (rebirth enabled). +2. Offering flow = intentional `BURN` (+ memorial metadata); supply reborn via mint-at-offering **or** PoW remint (§8). +3. Index with Chronik; show **cumulative burned** as the temple’s eternal record. +4. Skip TBP, CashTokens, fixed-supply, and a new L1 unless requirements change. + +--- + +## 8. Feasibility: permissionless PoW remint covenant (model C) + +**Verdict: Feasible.** The pattern is already proven (Mist/eminer on BCH SLP). On eCash it is **somewhat easier** (native introspection, Chronik, `ecash-lib`, Agora already speaks ALP) but still a **non-trivial covenant + miner project**, not a config tweak. + +### 8.1 How it would work + +``` +GENESIS (open mint baton) + → send baton UTXO to PoW covenant P2SH + ↓ +anyone finds nonce: hash(preimage‖nonce) meets difficulty + ↓ +covenant allows spend only if outputs are exactly: + [0] eMPP OP_RETURN with ALP MINT (fixed/rules-based amount) + [1] minted tokens → miner (or temple pool) + [2] baton → next covenant address (state+1, baton never dies) + ↓ +devotees acquire tokens (miner sale / Agora / temple) → BURN as offering +``` + +Spiritual reading: **work recreates the flower; burn offers it; the baton is the eternal root.** + +### 8.2 Why this is realistic on eCash + +| Ingredient | Status | +|------------|--------| +| PoW mint baton covenant | Proven: Mist `slp-miner-reward-v1.spedn` + eminer | +| Enforce tx shape in Script | Proven on BCH; eCash has **native introspection** (cleaner than Mist’s preimage parsing) | +| ALP MINT encoding | Spec + `alpMint()` in `ecash-lib` | +| Indexer | Chronik indexes ALP mint batons / burns | +| ALP + covenant precedent | `ecash-agora` already builds ALP-aware covenant scripts | +| Miner port | Rewrite eminer off BCHD/SLP onto Chronik + `ecash-lib` (moderate effort) | + +ALP’s **multiple mint batons** also help: e.g. one PoW baton (permissionless rebirth) + one temple baton (bootstrap / emergency) without a hard fork. + +### 8.3 Issuance tiers (prefer frequency elasticity over `mint ∝ D`) + +Ergon needs `coins/block ∝ D` because its DAA keeps **blocks/time** ~constant. An ALP remint can keep **coins/remint** fixed and let **remints/time ∝ hashrate** instead — same coins/time elasticity, simpler covenant. + +| Tier | Design | Feasibility | +|------|--------|-------------| +| **Canonical** | Fixed `D`, base `M₀`, Moore `δ=99918/100000` on wall-time, **`N≥2` parallel PoW batons**, no 1-mint/host-block CLTV | **High** — simpler than Mist+full Ergon `mint∝D` | +| **Optional** | Temple bootstrap baton (retire later) | Easy | +| **Usually skip** | Token DAA + `mint ∝ work(D)` | Only if remint-rate design proves insufficient | + +**Moore constant:** use Ergon’s **post-fix** daily factor [`99918/100000`](https://github.com/Ergon-moe/Bitcoin-Static/blob/2e8d5f7635c899cc99e71f06dedbe72b3ff7f07b/src/validation.cpp#L978) (~2.3y half-life). Do **not** use pre-fix `99826/100000` (~1.1y). + +Do **not** copy Mist’s CLTV sync if you want Ergon-like flow: that freezes remints/time ≈ host blocks/time and kills hashrate→issuance elasticity. + +### 8.4 Product flow (PoW ↔ burn) + +Permissionless mint does **not** mint straight into a devotee’s incense burn. Typical loop: + +1. Miner wins remint → receives fresh tokens +2. Liquidity: sell on **Agora** / P2P / temple desk for XEC +3. Devotee burns tokens (or temple burns on their behalf with metadata) + +So the temple app still needs: burn UX, Chronik watchers, and a path to acquire tokens. PoW only replaces **who is allowed to create** supply. + +### 8.5 Main risks + +1. **Baton race:** First valid spend wins (same as Mist); wasted work for losers. Multi-baton mitigates serialization. +2. **Script / ALP byte exactness:** Covenant must match Chronik’s ALP parse exactly or minted tokens look invalid to wallets. +3. **Unaudited Script:** Mist warned its contracts were unaudited; treat White Lotus covenant as security-critical. +4. **Fee + hashrate cold start:** Early miners need XEC for fees; low token demand → low hashrate → slow rebirth (acceptable if temple also keeps a secondary baton). +5. **Economic griefing:** If mint reward ≫ burn demand, circulating dump; tune `D` and `M` (not host-block CLTV pacing). +6. **Moore clock:** decay on eCash time/height, not token mint height. +7. **Not L1 consensus:** Rules live in the covenant + indexer, not eCash consensus (acceptable and normal for ALP). + +### 8.6 Build estimate (engineering shape, not calendar) + +Must build: + +1. CashScript / hand-asm covenant: PoW + ALP MINT eMPP template + baton recursion +2. Genesis + baton handoff tool +3. Chronik-based miner (eminer spiritual successor) +4. Temple burn + cumulative-burn indexer +5. Acquisition path (Agora listing or in-app swap) + +Can defer: `mint ∝ D` DAA, multi-token, mobile miner GPU stack. + +### 8.7 Recommendation + +| Question | Answer | +|----------|--------| +| Is permissionless PoW remint feasible on eCash ALP? | **Yes** | +| Closest prior art | Mist/eminer + eCash Agora/ALP tooling | +| Right covenant economics | Fixed `D` + `M(t)=M₀·(99918/100000)^k` + **`N≥2` parallel batons** + no Mist 1/block CLTV (**not** required `mint ∝ D`) | +| Ship temple before PoW? | **Yes** — mint-at-offering (model A) validates burn UX; swap baton into PoW covenant later | +| Better than forking a White Lotus L1? | **Yes** — same rebirth idea, far less ops | + +### 8.8 Ritual economics: vàng mã and why Ergon-like remint fits + +Vietnamese **vàng mã** (votive paper) is a useful model: people spend real wealth on symbolic offerings and burn them so the act is irreversible. The point is **sacrifice**, not accumulating a scarce collectible. + +| Burn design | What happens to “wealth” | Ritual reading | +|-------------|--------------------------|----------------| +| Fixed-supply token burn | Remaining **holders** get richer (deflation) | Closer to destroying stock to pump bags | +| Custodial remint (temple baton) | Temple can recreate supply | Rebirth works, but an earthly mint owner remains | +| **Ergon-like / PoW remint** | Burn opens room for **new work** to remint; unit tends toward energy/effort cost | Sacrifice dissipates embodied effort; flower can bloom again through labor | + +**Why this is desirable for a communal ritual** + +1. **Purer sacrifice:** Elastic remint dampens the “I burn so my bags moon” loop. Non-burning holders are not the main beneficiaries. +2. **Rebirth without a priest-minter:** Permissionless PoW is the on-chain analogue of “the offering can always return through effort.” +3. **Shared ledger of merit:** Cumulative burns are a public commons (temple memory), even if circulating supply stays elastic. +4. **Optional monetary commons:** In the Lotus-founder two-loop view, burns are a **demand sink** that helps stabilize the unit for *everyone who uses it*—holders and non-holders alike—without oracles. + +**Careful with “energy is infinite ⇒ non-holders benefit”** + +Energy is **not** infinite; if it were free, the sacrifice would be empty. The meaningful claim is closer to: + +- Each burned token represents **effort already spent** (at mint). +- Remint requires **new effort**, so the ritual cycle continually draws real work into the commons. +- Non-holders benefit if the token is a **shared medium** (stable unit, public merit record, temple economy)—not merely because joules are unlimited. + +### 8.9 Lotus `log(D)` vs `sqrt(D)` vs Ergon — and the “scarce community” temptation + +Lotus today pays `R ≈ a·log(D)` (`lotusd` `GetBlockSubsidy`). That is **highly inelastic**: difficulty can rise a lot while issuance barely expands. So ritual burns behave like Bitcoin burns — **holders capture most of the scarcity**. Lotus Temple’s experience matches the math. + +Elasticity of issuance to work (higher = burns refill faster, holders gain less): + +``` +log(D) < sqrt(D) < D¹ (Ergon linear) + Lotus Shammah energy-proportional + proposal +``` + +Shammah’s move toward **sublinear work-coupled** emission (e.g. √-like / `γ ∈ (0,1)` in the 2026 papers) is partly the same concern: make supply answer work and burn demand, not just enrich bags. It is **closer to Ergon than Lotus v1**, but still **less elastic than Ergon** (sublinear by design, for Lyapunov stability / manipulation resistance). + +| Goal | Prefer | +|------|--------| +| Fast speculative community / NGU | Scarcer / `log`-like (Lotus-shaped) | +| Vàng mã sacrifice + rebirth + commons | **Ergon-like `mint ∝ work`** | +| Fork fairness (“energy can’t be counted twice”) | **Ergon-like** (strongest) | + +**Opinion for White Lotus temple:** do **not** choose scarcity to “build community quicker.” That community is mostly holders; you already saw burns serve them more than the wider commons. Build community with **ritual UX, Vietnamese brand, multi-temple, cumulative merit** — and let issuance stay **Ergon-like** so sacrifice stays clean. + +Bootstrap without fake scarcity: slightly higher early PoW mint that still requires work, Agora liquidity, temple-desk acquisition — not a hard cap. diff --git a/docs/research/ergon-style-issuance-on-ecash.md b/docs/research/ergon-style-issuance-on-ecash.md new file mode 100644 index 0000000..a62d23a --- /dev/null +++ b/docs/research/ergon-style-issuance-on-ecash.md @@ -0,0 +1,184 @@ +# Feasibility: Ergon-style (energy-pegged) issuance via eminer/Spedn on eCash + +**Verdict:** A **true Ergon-style elastic, energy-cost-pegged currency on eCash is feasible as a redesigned mineable token**, but **not** by reusing Mist v1 as-is, and **not** as a USD-pegged stablecoin. Pegging mint volume to **eCash chain difficulty** from a covenant is **not possible** without oracles or a consensus hard fork. The closest workable path is an **ALP (or SLP) minting-baton covenant** whose **own** PoW difficulty drives mint amount (Ergon’s proportional-reward idea, applied to the token’s hashrate). + +**Correction:** CashTokens are **BCH-native**, not available on eCash without a hard fork. On eCash use **ALP** (preferred) or legacy SLP/eToken. See also `docs/alp-token-burn-on-ecash.md` for intentional burn suitability. + +--- + +## 1. What each piece actually is + +| Name | Role in this evaluation | +|------|-------------------------| +| **eminer** (`mminer`) | Off-chain miner for Mist/Maze-style **PoW-minted SLP tokens** on BCH, governed by **Spedn** covenants | +| **Spedn / “SPDN”** | BCH Script DSL used to compile mint covenants (`spedn/slp-miner-reward-v*.spedn`). There is **no SPDN currency** in this repo | +| **Mist v1** | Fixed token PoW difficulty + scheduled reward reduction + CLTV sync (~1 mint per host block) | +| **Ergon (XRG)** | Separate PoW chain (`Bitcoin-Static`) where **native coinbase ∝ block difficulty**, with Moore/Koomey decay (~2.3y half-life). Marketed as **stable MoE pegged to mining energy cost**, not a fiat stablecoin | +| **eCash (XEC)** | Host chain; custom assets via **ALP** (preferred) or legacy SLP/eToken — **not** CashTokens (BCH-only). Script/covenants cannot read `nBits`/chain work | + +Ergon’s design goal (from [prop-reward.pdf](https://ergon.moe/prop-reward.pdf)): + +> Block reward shall be a linear function of the current block mining difficulty … peg the price to the expenses of miners … reflecting average cost of electricity … won’t be an investment. + +That is **elastic base money**, not USDT/USDC-style collateralized or oracle-pegged stables. + +--- + +## 2. Why Mist v1 cannot produce Ergon-like stability + +Production contract (`spedn/slp-miner-reward-v1.spedn`): + +1. **Fixed** leading-zero PoW difficulty +2. **Predetermined** mint: `initialMintAmount / (floor(height/interval) + 1)` +3. **CLTV** forces mint pacing ≈ host block rate + +Economic effect: + +- Issuance schedule is **planned**, like Bitcoin/Mist scarcity toward ~21M +- Extra hashrate only races for the **same** fixed reward; it does **not** mint more units +- Unit value is **not** tethered to energy cost; demand shocks move price freely + +Ergon’s feedback loop requires the opposite: + +``` +price ↑ → mining profitable → hashrate ↑ → difficulty ↑ → coins/block ↑ → supply meets demand → price → cost +price ↓ → miners leave → difficulty ↓ → coins/block ↓ → scarcity supports price → cost +``` + +Mist breaks that loop at “hashrate ↑ → coins/block ↑”. + +Experimental `v2` only retunes **token** difficulty from **baton satoshi value** (collateralized difficulty tiers). It still does not implement `mint ∝ difficulty` with a proper DAA. + +--- + +## 3. Can a covenant read eCash difficulty? + +**No.** Native introspection (BCH/eCash) exposes values, locking bytecode, token category/amount/commitment, locktime, etc. It does **not** expose parent header `nBits`, chain work, or network hashrate. + +Therefore: + +| Approach | Feasible without hard fork? | +|----------|-----------------------------| +| Mint amount = f(eCash `nBits`) inside a covenant | **No** (no on-chain signal) | +| Oracle feeds eCash difficulty into the covenant | Technically yes; **destroys** Ergon’s “no oracle” property | +| Hard-fork eCash `GetBlockSubsidy` like Ergon/Lotus | Consensus change; not a token project | +| Mint amount = f(**token’s own** PoW difficulty + DAA) | **Yes** — best token-layer analogue | + +Lotus (`lotusd`) already experiments with **difficulty-based native subsidy** (`enableDifficultyBasedSubsidy`, logarithmic in difficulty). That is related economically but is a **different chain’s base coin**, not an eCash token, and not Ergon’s linear proportional reward. + +--- + +## 4. Workable design: Ergon-like mineable ALP token on eCash + +### 4.1 Core rules (token-layer analogue) + +Treat the minting baton covenant as a mini-Ergon: + +1. **Own PoW** on each mint (hash of preimage ‖ nonce meets current difficulty `D`) +2. **DAA** on `D` targeting a wall-clock mint rate (e.g. N successful mints per day), using timestamps / host locktime carefully +3. **Proportional mint:** `mintAmount = floor(c(t) * work(D))` +4. **Moore decay on `c(t)`** (daily multiplicative factor ≈ Ergon’s `99918/100000` for ~2.3y half-life), stored or derived from mint height +5. **Singleton mint baton** (ALP mint baton; close/burn when fixed supply is desired) + +Then, with DAA holding mint *rate* roughly constant: + +- Higher token hashrate → higher `D` → **more coins per mint** → coins/time ∝ hashrate +- Work per coin stays roughly constant after Moore correction +- Price is pulled toward **marginal energy cost of token PoW** (plus eCash fees) + +That matches Ergon’s *mechanism*, with the important caveat that security of the **ledger** is still XEC miners’ PoW; token miners only pay for **issuance rights**. + +### 4.2 Why ALP > legacy SLP on eCash + +| | Legacy SLP / eToken | ALP on eCash | +|--|---------------------|--------------| +| Encoding | Big-endian, single OP_RETURN | Little-endian, **eMPP** multi-section | +| Intentional burn | Possible; exact burns often awkward | First-class `alpBurn` in `ecash-lib` | +| Indexing | Chronik | Chronik (default token index) | +| CashTokens | N/A on eCash | N/A on eCash (BCH-only) | + +Recommend **ALP + Chronik + ecash-lib** on eCash. Use eminer only as a **reference** for PoW-mint UX if pursuing Ergon-like issuance—not as a drop-in deploy. For temple burns, see `docs/alp-token-burn-on-ecash.md`. + +### 4.3 Critical design choices vs Mist + +| Mist v1 | Needed for Ergon-like token | +|---------|-----------------------------| +| Fixed difficulty | Adjustable `D` in NFT commitment / redeem state | +| Reward from height schedule only | `mint ∝ D` (+ Moore factor) | +| CLTV ≈ 1 mint / host block | **Do not** hard-cap mint rate independent of hashrate; use DAA instead (CLTV may still bound abuse) | +| Race wastes excess work with no issuance effect | Excess work raises future `D` / issuance | + +Without removing the “fixed reward per host block” pattern, the energy peg **cannot** form. + +### 4.4 What this is *not* + +- **Not a USD stablecoin.** Equilibrium is ~energy (and hardware) cost per unit, which moves with electricity markets and ASIC efficiency estimation error. +- **Not soft-pegged to XEC.** XEC remains scarce/deflationary base; the token is a second asset. +- **Not “stable” in the CeFi sense.** Expect oscillations; Ergon’s paper relies on speculative damping and miner mobility across SHA-256d coins. A low-liquidity token will be noisier than Ergon mainnet. +- **Not secured by token hashrate.** Double-spend safety is still eCash consensus; token PoW only governs mint fairness. + +--- + +## 5. Alternative paths (ranked) + +### A. Token-layer Ergon analogue (recommended research path) + +- **Scope:** New ALP token + minting covenant + miner (Chronik / `ecash-lib`) +- **Pros:** No eCash hard fork; permissionless; closest to “stablecoin possible” in Ergon’s meaning +- **Cons:** Bootstrap hashrate/liquidity; DAA and Moore params are hard; SLP eminer not reusable as-is +- **Invasiveness:** New contracts + miner; optional Lixi/Local-eCash listing later + +### B. Oracle-linked mint to eCash difficulty + +- **Pros:** Couples issuance to host-chain work +- **Cons:** Trusted/federated oracle; fails Ergon’s no-oracle thesis; attack surface + +### C. eCash consensus change (native proportional subsidy) + +- **Pros:** Cleanest Ergon clone for base money +- **Cons:** Social/consensus cost; changes XEC economics for everyone; out of scope for eminer + +### D. Keep Mist schedule, call it “stable” + +- **Pros:** Already built +- **Cons:** Economically false; fixed emission ≠ energy peg + +### E. Fiat-backed or overcollateralized USD stable on eCash + +- Separate product (custody, legal, oracles, liquidations), likely ALP or custodial. eminer/Ergon issuance theory does not deliver this. + +--- + +## 6. Risks and open problems + +1. **DAA design** under baton races, selfish minting, and timestamp manipulation +2. **Moore parameter error** → long-run inflation or deflation vs energy (Ergon’s own caveat) +3. **Fee drag:** every mint pays XEC fees; at low token price, issuance stalls even when “should” expand +4. **Hash algorithm:** token PoW is typically sha256d of preimage+nonce (CPU/GPU), while Ergon assumes ASIC SHA-256d mobility vs Bitcoin—elastic response `α` may be weaker +5. **Early unfairness:** fixed early `D` can still over-mint before DAA warms up; need genesis difficulty and maybe dampened early `c(t)` +6. **Regulatory / naming:** “stablecoin” implies fiat peg to many users; prefer “energy-elastic cash” / “Ergon-style token” in product language +7. **SLP on eCash** is legacy; building on SLP today is a dead-end for new issuance + +--- + +## 7. Suggested next steps (if pursuing) + +1. Specify covenant rules: state layout (height, `D`, last-mtime), mint formula, DAA, Moore factor, baton conservation +2. Prototype ALP mint baton + PoW covenant on chipnet; property-test mint amounts vs `D` +3. Minimal miner: solve PoW, submit mint, track baton UTXO via Chronik +4. Parameter study: target mint interval, `c(0)`, decay τ, min/max `D` +5. Explicitly **non-goals** for v1: USD peg, XEC peg, cross-chain bridges + +--- + +## 8. Bottom line + +| Question | Answer | +|----------|--------| +| Can eminer/Spedn launch an Ergon-**like** currency on eCash? | **Yes, with a new covenant design** (proportional mint to **token** difficulty + DAA + Moore decay), preferably as **ALP** | +| Can Mist v1 parameters alone do it? | **No** — fixed difficulty + scheduled emission is anti-Ergon | +| Can mint track **eCash** difficulty trustlessly? | **No** from script alone | +| Does that yield a **USD stablecoin**? | **No** — at best an **energy-cost-elastic** unit of account | +| Is a fiat stablecoin “possible” on eCash? | Yes via **other** designs (reserves/collateral/oracles), unrelated to Ergon/eminer | + +**Most honest framing:** use eminer as prior art for **decentralized PoW mint batons**, then implement Ergon’s proportional-reward economics as an **ALP** token on eCash so a **stable (energy-pegged) medium of exchange** can be attempted—not a dollar stablecoin, and not a config tweak of Mist. diff --git a/jest.config.cjs b/jest.config.cjs new file mode 100644 index 0000000..e6b2f15 --- /dev/null +++ b/jest.config.cjs @@ -0,0 +1,19 @@ +/** @type {import('jest').Config} */ +module.exports = { + preset: 'ts-jest/presets/default-esm', + testEnvironment: 'node', + extensionsToTreatAsEsm: ['.ts'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + tsconfig: 'tsconfig.json', + }, + ], + }, + testMatch: ['**/tests/**/*.test.ts'], +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7d5a2ab --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4820 @@ +{ + "name": "wlotus", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "wlotus", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "chronik-client": "^3.1.0", + "ecash-lib": "^4.8.0" + }, + "devDependencies": { + "@types/jest": "^29.5.14", + "@types/node": "^22.10.0", + "jest": "^29.7.0", + "ts-jest": "^29.2.5", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz", + "integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", + "license": "BSD-3-Clause" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz", + "integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/b58-ts": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/b58-ts/-/b58-ts-0.1.0.tgz", + "integrity": "sha512-FC/2pfMxrlLQp1o9hwOGAy/1zCHYId5gpojwHL/BqoMFv/BnZXwHDH1zpx9jSL4C9k55Fm2R9j/F868qaQH5kw==", + "license": "MIT" + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.43", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", + "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", + "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001803", + "electron-to-chromium": "^1.5.389", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind-apply-helpers": { + "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==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/chronik-client": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/chronik-client/-/chronik-client-3.7.0.tgz", + "integrity": "sha512-pJsy9ZYe+2HrrEKISUgysx7f6Q3+ml0r9EDAAmoqBB4UjnOfD2j/bDyHGW/d4oSVbYNxkpj58pF0lcjPXy8Glg==", + "license": "MIT", + "dependencies": { + "@types/ws": "^8.2.1", + "axios": "^1.6.3", + "ecashaddrjs": "^2.0.0", + "isomorphic-ws": "^4.0.1", + "long": "^4.0.0", + "protobufjs": "^6.8.8", + "ws": "^8.3.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecash-lib": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/ecash-lib/-/ecash-lib-4.13.0.tgz", + "integrity": "sha512-pvGfKgmfKOoG59ueRyv0MSlNyIRuC4WtzEZqAwIbeKDMd79M1DLYrwbj12iyxnK1xd7EUrF/WQDz6/zeoZAswg==", + "license": "MIT", + "dependencies": { + "b58-ts": "^0.1.0", + "ecashaddrjs": "^2.0.0" + } + }, + "node_modules/ecashaddrjs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ecashaddrjs/-/ecashaddrjs-2.0.0.tgz", + "integrity": "sha512-EvK1V4D3+nIEoD0ggy/b0F4lW39/72R9aOs/scm6kxMVuXu16btc+H74eQv7okNfXaQWKgolEekZkQ6wfcMMLw==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.392", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.392.tgz", + "integrity": "sha512-1yQq3VQCZRwsnYc67Oc+1fge6Lwtn0hzi6zmEVkB61Zx21kTbwJAW4dFLadl5Rc1tKhG/kSpYXnfiAhu0f0a1g==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "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==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "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==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", + "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/protobufjs": { + "version": "6.11.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.6.tgz", + "integrity": "sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/proxy-from-env": { + "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==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-jest": { + "version": "29.4.11", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", + "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.9", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.8.0", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <7" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tsx": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.1.tgz", + "integrity": "sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..30eaf30 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "wlotus", + "version": "0.1.0", + "description": "White Lotus (WLOTUS): Ergon-like ALP PoW remint covenant on eCash", + "private": true, + "type": "module", + "scripts": { + "build": "tsc -p tsconfig.json", + "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js", + "moore": "tsx scripts/compute-moore.ts", + "lint": "tsc -p tsconfig.json --noEmit" + }, + "engines": { + "node": ">=20" + }, + "dependencies": { + "chronik-client": "^3.1.0", + "ecash-lib": "^4.8.0" + }, + "devDependencies": { + "@types/jest": "^29.5.14", + "@types/node": "^22.10.0", + "jest": "^29.7.0", + "ts-jest": "^29.2.5", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + }, + "repository": { + "type": "git", + "url": "https://github.com/bcProFoundation/wlotus.git" + }, + "license": "MIT" +} diff --git a/scripts/compute-moore.ts b/scripts/compute-moore.ts new file mode 100644 index 0000000..0695a6d --- /dev/null +++ b/scripts/compute-moore.ts @@ -0,0 +1,34 @@ +#!/usr/bin/env tsx +/** + * Print Moore-adjusted mint atoms after K wall-days. + * Usage: npm run moore -- --days 365 + */ +import { mintAtomsAfterDays, approxHalfLifeYears } from '../src/lib/moore.js'; +import { BASE_MINT_ATOMS, MOORE_NUM, MOORE_DEN } from '../src/params/consensus.js'; + +function parseDays(argv: string[]): number { + const i = argv.indexOf('--days'); + if (i === -1 || !argv[i + 1]) return 0; + return Number.parseInt(argv[i + 1], 10); +} + +const days = parseDays(process.argv.slice(2)); +if (!Number.isFinite(days) || days < 0) { + console.error('Usage: npm run moore -- --days '); + process.exit(1); +} + +const atoms = mintAtomsAfterDays(days); +console.log( + JSON.stringify( + { + days, + baseMintAtoms: BASE_MINT_ATOMS.toString(), + mintAtoms: atoms.toString(), + delta: `${MOORE_NUM}/${MOORE_DEN}`, + approxHalfLifeYears: Number(approxHalfLifeYears().toFixed(4)), + }, + null, + 2, + ), +); diff --git a/src/genesis/createGenesis.ts b/src/genesis/createGenesis.ts new file mode 100644 index 0000000..7c21375 --- /dev/null +++ b/src/genesis/createGenesis.ts @@ -0,0 +1,52 @@ +import { + BASE_MINT_ATOMS, + POW_BATON_COUNT, + POW_LEADING_ZERO_BYTES, + TOKEN_DECIMALS, + TOKEN_NAME, + TOKEN_TICKER, + TOKEN_URL, +} from '../params/consensus.js'; + +/** + * Draft GENESIS plan for WLOTUS. + * + * Implementation will use ecash-lib `alpGenesis` + eMPP, then send each of the + * N mint batons to the remint covenant P2SH (same redeem, batonIndex 0..N-1). + * + * This module currently only describes the intended outputs — no broadcast. + */ +export interface GenesisPlan { + ticker: string; + name: string; + url: string; + decimals: number; + /** Initial fungible mint to treasury/miner bootstrap (may be 0). */ + initialMintAtoms: bigint; + /** Parallel PoW batons. */ + powBatonCount: number; + powLeadingZeroBytes: number; + baseMintAtoms: bigint; +} + +export function buildGenesisPlan( + overrides: Partial = {}, +): GenesisPlan { + return { + ticker: TOKEN_TICKER, + name: TOKEN_NAME, + url: TOKEN_URL, + decimals: TOKEN_DECIMALS, + initialMintAtoms: 0n, + powBatonCount: POW_BATON_COUNT, + powLeadingZeroBytes: POW_LEADING_ZERO_BYTES, + baseMintAtoms: BASE_MINT_ATOMS, + ...overrides, + }; +} + +export function assertMultiBaton(plan: GenesisPlan): void { + if (plan.powBatonCount < 2) { + throw new Error('WLOTUS requires N >= 2 PoW mint batons for parallel remints'); + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..cc765f8 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,17 @@ +export { + BASE_MINT_ATOMS, + MOORE_DEN, + MOORE_NUM, + POW_BATON_COUNT, + POW_LEADING_ZERO_BYTES, + TOKEN_TICKER, +} from './params/consensus.js'; +export { + approxHalfLifeYears, + mintAtomsAfterDays, + mintAtomsAtHostHeight, + mooreDaysFromHeights, + mooreStep, +} from './lib/moore.js'; +export { assertMultiBaton, buildGenesisPlan } from './genesis/createGenesis.js'; +export { expectedMintAtoms, minerBanner } from './miner/remint.js'; diff --git a/src/lib/moore.ts b/src/lib/moore.ts new file mode 100644 index 0000000..ac46aa9 --- /dev/null +++ b/src/lib/moore.ts @@ -0,0 +1,69 @@ +import { + BASE_MINT_ATOMS, + MOORE_DAY_BLOCKS, + MOORE_DEN, + MOORE_NUM, + MOORE_NUM_OBSOLETE, +} from '../params/consensus.js'; + +/** + * Apply one Moore day-step: x ← floor(x * 99918 / 100000). + */ +export function mooreStep(atoms: bigint, num: bigint = MOORE_NUM): bigint { + if (num === MOORE_NUM_OBSOLETE) { + throw new Error('Obsolete Moore factor 99826/100000 is forbidden for WLOTUS'); + } + return (atoms * num) / MOORE_DEN; +} + +/** + * M(k) after k wall-day steps from genesis. + * Matches Ergon's repeated daily correction with δ = 99918/100000. + */ +export function mintAtomsAfterDays( + days: number, + base: bigint = BASE_MINT_ATOMS, + num: bigint = MOORE_NUM, +): bigint { + if (!Number.isInteger(days) || days < 0) { + throw new Error('days must be a non-negative integer'); + } + let x = base; + for (let i = 0; i < days; i++) { + x = mooreStep(x, num); + } + return x; +} + +/** + * Day index k from host chain heights (Ergon-style day divisions). + */ +export function mooreDaysFromHeights( + genesisHeight: number, + currentHeight: number, + dayBlocks: number = MOORE_DAY_BLOCKS, +): number { + if (currentHeight < genesisHeight) { + throw new Error('currentHeight < genesisHeight'); + } + return Math.floor((currentHeight - genesisHeight) / dayBlocks); +} + +/** + * Expected mint atoms at a host height. + */ +export function mintAtomsAtHostHeight( + genesisHeight: number, + currentHeight: number, + base: bigint = BASE_MINT_ATOMS, +): bigint { + const k = mooreDaysFromHeights(genesisHeight, currentHeight); + return mintAtomsAfterDays(k, base); +} + +/** Approximate half-life in years for δ = 99918/100000 (daily steps). */ +export function approxHalfLifeYears(num: bigint = MOORE_NUM): number { + const delta = Number(num) / Number(MOORE_DEN); + // H = ln(2) / -ln(delta) days, / 365.25 → years + return Math.LN2 / -Math.log(delta) / 365.25; +} diff --git a/src/miner/remint.ts b/src/miner/remint.ts new file mode 100644 index 0000000..71f967d --- /dev/null +++ b/src/miner/remint.ts @@ -0,0 +1,44 @@ +import { mintAtomsAtHostHeight } from '../lib/moore.js'; +import { POW_BATON_COUNT, POW_LEADING_ZERO_BYTES } from '../params/consensus.js'; + +/** + * Remint miner sketch (Chronik + ecash-lib). + * + * Loop: + * 1. List unspent PoW baton UTXOs for tokenId (N tips) + * 2. For each baton, build ALP MINT template + covenant unlock + * 3. Search nonce until hash256(preimage||nonce) meets difficulty + * 4. Broadcast; on conflict, refresh baton set and retry + * + * No Mist-style wait-for-next-host-block gating. + */ +export interface RemintTarget { + tokenId: string; + genesisHostHeight: number; + currentHostHeight: number; + batonOutpoint: { txid: string; vout: number }; + batonIndex: number; +} + +export function expectedMintAtoms(target: RemintTarget): bigint { + return mintAtomsAtHostHeight( + target.genesisHostHeight, + target.currentHostHeight, + ); +} + +export function minerBanner(): string { + return [ + 'WLOTUS remint miner', + `batons(N)=${POW_BATON_COUNT}`, + `powLeadingZeroBytes=${POW_LEADING_ZERO_BYTES}`, + 'moore=99918/100000 per 144 host blocks', + 'parallel remints: enabled (no 1-mint/block CLTV)', + ].join(' | '); +} + +/** Placeholder — wire Chronik + ecash-lib in a follow-up. */ +export async function runMinerLoop(_tokenId: string): Promise { + console.log(minerBanner()); + throw new Error('Miner not implemented yet — covenant + Chronik wiring TODO'); +} diff --git a/src/params/consensus.ts b/src/params/consensus.ts new file mode 100644 index 0000000..53af866 --- /dev/null +++ b/src/params/consensus.ts @@ -0,0 +1,59 @@ +/** + * WLOTUS consensus draft parameters. + * Freeze only at GENESIS; until then values may change on chipnet. + */ + +/** ALP ticker (ASCII). */ +export const TOKEN_TICKER = 'WLOTUS'; + +/** Human-readable name. */ +export const TOKEN_NAME = 'White Lotus'; + +/** + * Token decimals. Use enough precision so daily Moore floor-division + * `(x * 99918) / 100000` does not collapse small balances to zero. + */ +export const TOKEN_DECIMALS = 6; + +/** + * Leading zero *bytes* required on hash256(preimage || nonce). + * Draft — retune on chipnet. + */ +export const POW_LEADING_ZERO_BYTES = 2; + +/** + * Base mint atoms at k=0 (genesis day-step). + * 100_000_000 atoms @ 6 decimals = 100 WLOTUS per remint at genesis. + * Must stay large: Ergon applies Moore to huge work values; applying the + * same integer factor to a tiny M₀ reaches 0 in far less than 2.3 years. + */ +export const BASE_MINT_ATOMS = 100_000_000n; + +/** + * Number of parallel PoW mint batons created at genesis. + * Each baton is an independent remint race (true parallelization). + */ +export const POW_BATON_COUNT = 8; + +/** + * Ergon post-fix Moore daily factor numerator. + * @see https://github.com/Ergon-moe/Bitcoin-Static/blob/2e8d5f7635c899cc99e71f06dedbe72b3ff7f07b/src/validation.cpp#L978 + */ +export const MOORE_NUM = 99918n; + +/** Moore daily factor denominator. */ +export const MOORE_DEN = 100000n; + +/** + * Obsolete Ergon pre-fix factor (~1.1y half-life). Forbidden for WLOTUS. + */ +export const MOORE_NUM_OBSOLETE = 99826n; + +/** + * Host blocks per Moore day-step (Ergon uses 144 × 10-minute blocks). + * eCash target spacing is likewise ~10 minutes. + */ +export const MOORE_DAY_BLOCKS = 144; + +/** Document URL placeholder (set before genesis). */ +export const TOKEN_URL = 'https://github.com/bcProFoundation/wlotus'; diff --git a/tests/moore.test.ts b/tests/moore.test.ts new file mode 100644 index 0000000..716c63b --- /dev/null +++ b/tests/moore.test.ts @@ -0,0 +1,71 @@ +import { + approxHalfLifeYears, + mintAtomsAfterDays, + mintAtomsAtHostHeight, + mooreDaysFromHeights, + mooreStep, +} from '../src/lib/moore.js'; +import { + BASE_MINT_ATOMS, + MOORE_NUM, + MOORE_NUM_OBSOLETE, +} from '../src/params/consensus.js'; +import { + assertMultiBaton, + buildGenesisPlan, +} from '../src/genesis/createGenesis.js'; + +describe('moore decay (Ergon 99918/100000)', () => { + test('one step shrinks atoms', () => { + const next = mooreStep(BASE_MINT_ATOMS); + expect(next).toBe((BASE_MINT_ATOMS * MOORE_NUM) / 100000n); + expect(next).toBeLessThan(BASE_MINT_ATOMS); + }); + + test('forbids obsolete 99826 factor', () => { + expect(() => mooreStep(100n, MOORE_NUM_OBSOLETE)).toThrow(/Obsolete/); + }); + + test('k=0 returns base', () => { + expect(mintAtomsAfterDays(0)).toBe(BASE_MINT_ATOMS); + }); + + test('day index from heights', () => { + expect(mooreDaysFromHeights(1000, 1000)).toBe(0); + expect(mooreDaysFromHeights(1000, 1143)).toBe(0); + expect(mooreDaysFromHeights(1000, 1144)).toBe(1); + expect(mooreDaysFromHeights(1000, 1288)).toBe(2); + }); + + test('mint at host height', () => { + const genesis = 500_000; + const day1 = mintAtomsAtHostHeight(genesis, genesis + 144); + expect(day1).toBe(mooreStep(BASE_MINT_ATOMS)); + }); + + test('half-life ~2.3 years for 99918/100000', () => { + const years = approxHalfLifeYears(); + expect(years).toBeGreaterThan(2.2); + expect(years).toBeLessThan(2.4); + }); + + test('after ~2.3y atoms are near half base (not zero)', () => { + const days = Math.round(approxHalfLifeYears() * 365.25); + const half = mintAtomsAfterDays(days); + expect(half).toBeGreaterThan(BASE_MINT_ATOMS / 3n); + expect(half).toBeLessThan((BASE_MINT_ATOMS * 2n) / 3n); + }); +}); + +describe('genesis multi-baton', () => { + test('default plan has N>=2', () => { + const plan = buildGenesisPlan(); + expect(plan.powBatonCount).toBeGreaterThanOrEqual(2); + expect(() => assertMultiBaton(plan)).not.toThrow(); + }); + + test('rejects single baton', () => { + const plan = buildGenesisPlan({ powBatonCount: 1 }); + expect(() => assertMultiBaton(plan)).toThrow(/N >= 2/); + }); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1528995 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "dist", + "rootDir": ".", + "strict": true, + "isolatedModules": true, + "esModuleInterop": true, + "skipLibCheck": true, + "declaration": true, + "resolveJsonModule": true + }, + "include": ["src/**/*", "scripts/**/*", "tests/**/*"] +} From 7d75d1bc4fe0536ab6c667ac5fc16bca8e9ca6c9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 02:33:56 +0000 Subject: [PATCH 2/6] Add mainnet test-token genesis with low PoW difficulty Wire Chronik failover (chronik.e.cash, xec.paybutton.org, chronik.pay2stay.com/xec), ecash-wallet ALP GENESIS tooling, and a WLTEST profile targeting ~$0.000001/token (PoW 1 leading zero byte; raise later for ~$0.01). Includes new-wallet / create-test-token / wait-create-test-token scripts. Genesis address pending funding before broadcast. Co-authored-by: nghiacc --- .env.example | 8 +- README.md | 15 ++ deployments/README.md | 10 ++ deployments/pending-funding.json | 12 ++ docs/SPEC.md | 4 +- docs/STATUS.md | 8 +- docs/TEST_TOKEN.md | 29 ++++ jest.config.cjs | 4 + package-lock.json | 77 ++++++----- package.json | 11 +- scripts/create-test-token.ts | 93 +++++++++++++ scripts/new-wallet.ts | 58 ++++++++ scripts/wait-for-funding-and-create.ts | 72 ++++++++++ src/genesis/broadcastGenesis.ts | 182 +++++++++++++++++++++++++ src/index.ts | 15 ++ src/network/chronikUrls.ts | 9 ++ src/network/createChronik.ts | 18 +++ src/params/consensus.ts | 8 +- src/params/testEconomics.ts | 38 ++++++ tests/moore.test.ts | 11 ++ 20 files changed, 636 insertions(+), 46 deletions(-) create mode 100644 deployments/README.md create mode 100644 deployments/pending-funding.json create mode 100644 docs/TEST_TOKEN.md create mode 100644 scripts/create-test-token.ts create mode 100644 scripts/new-wallet.ts create mode 100644 scripts/wait-for-funding-and-create.ts create mode 100644 src/genesis/broadcastGenesis.ts create mode 100644 src/network/chronikUrls.ts create mode 100644 src/network/createChronik.ts create mode 100644 src/params/testEconomics.ts diff --git a/.env.example b/.env.example index e28f861..1f9c67d 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ # Chipnet / mainnet secrets — never commit -CHRONIK_URL=https://chronik.fabien.cash -# WIF for fee + mining payouts (chipnet) -# MINER_WIF= -# GENESIS_WIF= +CHRONIK_URL=https://chronik.e.cash +# 32-byte hex secret key for genesis / custodial remint (from npm run new-wallet) +# GENESIS_SK_HEX= +# GENESIS_ADDRESS= diff --git a/README.md b/README.md index 2e76a1a..500a4f4 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,21 @@ npm test npm run moore -- --days 365 # print M after 365 wall-days ``` +## Create the low-difficulty test token (mainnet) + +Target economics: **~$0.000001 / token** now; later raise PoW toward **~$0.01 / token**. + +Chronik fleet: `chronik.e.cash`, `xec.paybutton.org`, `chronik.pay2stay.com/xec`. + +```bash +npm run new-wallet # writes .env + deployments/pending-funding.json +# Send ≥ 200 XEC to the printed address +npm run create-test-token # ALP GENESIS → deployments/mainnet-test-token.json +``` + +Ticker for this dogfood deployment: `WLTEST` (keeps `WLOTUS` for the later $0.01 launch). +Mint batons are custodial on the genesis wallet until the PoW covenant is live. + ## License MIT diff --git a/deployments/README.md b/deployments/README.md new file mode 100644 index 0000000..ca5d556 --- /dev/null +++ b/deployments/README.md @@ -0,0 +1,10 @@ +# Deployments + +On-chain deployment records for White Lotus test / production tokens. + +| File | Meaning | +|------|---------| +| `pending-funding.json` | Genesis address waiting for XEC before first broadcast | +| `mainnet-test-token.json` | Written by `npm run create-test-token` after successful GENESIS | + +Private keys live only in `.env` (gitignored). Never commit `GENESIS_SK_HEX`. diff --git a/deployments/pending-funding.json b/deployments/pending-funding.json new file mode 100644 index 0000000..a7d4a91 --- /dev/null +++ b/deployments/pending-funding.json @@ -0,0 +1,12 @@ +{ + "network": "mainnet", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "balanceSats": "0", + "minSuggestedXec": 200, + "nextStep": "Send ≥ 200 XEC to genesisAddress, then: npm run create-test-token", + "chronikUrls": [ + "https://chronik.e.cash", + "https://xec.paybutton.org", + "https://chronik.pay2stay.com/xec" + ] +} diff --git a/docs/SPEC.md b/docs/SPEC.md index b53b6b3..a0abd84 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -16,7 +16,7 @@ They are not live on mainnet until GENESIS + baton handoff are executed. | Param | Value | Notes | |-------|-------|-------| -| `POW_LEADING_ZERO_BYTES` | `2` | Draft — retune on chipnet | +| `POW_LEADING_ZERO_BYTES` | `1` | Test — ~$1e-6/token; raise for ~$0.01 later | | `BASE_MINT_ATOMS` (`M₀`) | `100_000_000` | = 100 WLOTUS @ 6 decimals per remint at genesis (keep large for Moore floor-div) | | Host 1-mint/block CLTV | **disabled** | Required for frequency elasticity | | Supply cap | **none** | PoW batons never die | @@ -25,7 +25,7 @@ They are not live on mainnet until GENESIS + baton handoff are executed. | Param | Value | Notes | |-------|-------|-------| -| `POW_BATON_COUNT` (`N`) | `8` | True parallel remint tips at genesis | +| `POW_BATON_COUNT` (`N`) | `4` | Test genesis; production may use 8–16 | | Temple bootstrap baton | optional | Separate; retire after liquidity | Each remint spends exactly one PoW baton and recreates exactly one PoW baton (conserve `N`). diff --git a/docs/STATUS.md b/docs/STATUS.md index 4dab84b..98956b6 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -17,6 +17,8 @@ access to this repo. That work is now landed here. ## Next ops -1. Chipnet GENESIS with `N` PoW batons -2. Harden `contracts/WlotusRemint.cash` + Chronik miner wiring -3. Temple / burn UI in a separate app repo +1. Fund genesis address in `deployments/pending-funding.json` (≥ 200 XEC) +2. `npm run create-test-token` → writes `deployments/mainnet-test-token.json` +3. Harden `contracts/WlotusRemint.cash` + Chronik miner wiring +4. Raise PoW from 1 → higher when targeting ~$0.01/token +5. Temple / burn UI in a separate app repo diff --git a/docs/TEST_TOKEN.md b/docs/TEST_TOKEN.md new file mode 100644 index 0000000..c9a4ef4 --- /dev/null +++ b/docs/TEST_TOKEN.md @@ -0,0 +1,29 @@ +# Test token deployment (mainnet) + +## Goals + +| Knob | Test now | Later | +|------|----------|-------| +| Target price | **~$0.000001 / token** | **~$0.01 / token** | +| PoW leading zero bytes | `1` | raise (2–3+) | +| Ticker | `WLTEST` | `WLOTUS` | +| Batons | `4` custodial | PoW covenant + possibly more batons | + +## Chronik + +``` +https://chronik.e.cash +https://xec.paybutton.org +https://chronik.pay2stay.com/xec +``` + +## Create + +```bash +npm run new-wallet # .env + deployments/pending-funding.json +# fund genesis address with ≥ 200 XEC +npm run create-test-token # → deployments/mainnet-test-token.json +``` + +Genesis mints **1,000,000** `WLTEST` (6 decimals) plus **4** mint batons to the +genesis wallet for custodial remint dogfooding until the PoW covenant is audited. diff --git a/jest.config.cjs b/jest.config.cjs index e6b2f15..866c0bb 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -15,5 +15,9 @@ module.exports = { }, ], }, + // ecash-lib ships ESM (+ wasm glue) that Jest must transform + transformIgnorePatterns: [ + '/node_modules/(?!(ecash-lib|ecash-wallet|chronik-client)/)', + ], testMatch: ['**/tests/**/*.test.ts'], }; diff --git a/package-lock.json b/package-lock.json index 7d5a2ab..016d307 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,10 @@ "version": "0.1.0", "license": "MIT", "dependencies": { - "chronik-client": "^3.1.0", - "ecash-lib": "^4.8.0" + "chronik-client": "^4.3.0", + "dotenv": "^16.6.1", + "ecash-lib": "^4.13.0", + "ecash-wallet": "^6.1.0" }, "devDependencies": { "@types/jest": "^29.5.14", @@ -1370,12 +1372,6 @@ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "license": "BSD-3-Clause" }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz", - "integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==", - "license": "BSD-3-Clause" - }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", @@ -1514,12 +1510,6 @@ "pretty-format": "^29.0.0" } }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "license": "MIT" - }, "node_modules/@types/node": { "version": "22.20.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", @@ -1970,9 +1960,9 @@ } }, "node_modules/chronik-client": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/chronik-client/-/chronik-client-3.7.0.tgz", - "integrity": "sha512-pJsy9ZYe+2HrrEKISUgysx7f6Q3+ml0r9EDAAmoqBB4UjnOfD2j/bDyHGW/d4oSVbYNxkpj58pF0lcjPXy8Glg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/chronik-client/-/chronik-client-4.3.0.tgz", + "integrity": "sha512-tT4GEthoKj8TbPYLhUCD3BPkwJjsiiTsahw1y86QWMYNSybQjUqQOOhE6ibBrNTtL4vt0mZy/pCmOFeooJ03rQ==", "license": "MIT", "dependencies": { "@types/ws": "^8.2.1", @@ -1980,7 +1970,7 @@ "ecashaddrjs": "^2.0.0", "isomorphic-ws": "^4.0.1", "long": "^4.0.0", - "protobufjs": "^6.8.8", + "protobufjs": "^7.5.5", "ws": "^8.3.0" } }, @@ -2194,6 +2184,18 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2218,6 +2220,16 @@ "ecashaddrjs": "^2.0.0" } }, + "node_modules/ecash-wallet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ecash-wallet/-/ecash-wallet-6.1.0.tgz", + "integrity": "sha512-Eea+jdinvP8vgx4dZim8+bknwnDByAvoaQog2wOm2VLGB96jVHvHGZC74fFL+j/EDezsIX/9GIH2VMk4+qR9oA==", + "license": "MIT", + "dependencies": { + "chronik-client": "^4.3.0", + "ecash-lib": "^4.13.0" + } + }, "node_modules/ecashaddrjs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ecashaddrjs/-/ecashaddrjs-2.0.0.tgz", @@ -4106,31 +4118,34 @@ } }, "node_modules/protobufjs": { - "version": "6.11.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.6.tgz", - "integrity": "sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==", + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", + "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", - "long": "^4.0.0" + "long": "^5.3.2" }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" + "engines": { + "node": ">=12.0.0" } }, + "node_modules/protobufjs/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", diff --git a/package.json b/package.json index 30eaf30..6c85b7a 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,19 @@ "build": "tsc -p tsconfig.json", "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js", "moore": "tsx scripts/compute-moore.ts", - "lint": "tsc -p tsconfig.json --noEmit" + "lint": "tsc -p tsconfig.json --noEmit", + "new-wallet": "tsx scripts/new-wallet.ts", + "create-test-token": "tsx scripts/create-test-token.ts", + "wait-create-test-token": "tsx scripts/wait-for-funding-and-create.ts" }, "engines": { "node": ">=20" }, "dependencies": { - "chronik-client": "^3.1.0", - "ecash-lib": "^4.8.0" + "chronik-client": "^4.3.0", + "dotenv": "^16.4.7", + "ecash-lib": "^4.13.0", + "ecash-wallet": "^6.1.0" }, "devDependencies": { "@types/jest": "^29.5.14", diff --git a/scripts/create-test-token.ts b/scripts/create-test-token.ts new file mode 100644 index 0000000..124fc00 --- /dev/null +++ b/scripts/create-test-token.ts @@ -0,0 +1,93 @@ +#!/usr/bin/env tsx +/** + * Create the low-difficulty White Lotus *test* ALP token on eCash mainnet. + * + * Usage: + * 1. npm run new-wallet # writes .env with GENESIS_WIF + address + * 2. Send ≥ 200 XEC to that address (~$0.001) + * 3. npm run create-test-token # broadcasts GENESIS + * + * Chronik fleet: chronik.e.cash, xec.paybutton.org, chronik.pay2stay.com/xec + */ +import { mkdirSync, writeFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { config as loadEnv } from 'dotenv'; +import { Wallet } from 'ecash-wallet'; +import { fromHex } from 'ecash-lib'; +import { createChronik } from '../src/network/createChronik.js'; +import { broadcastAlpGenesis } from '../src/genesis/broadcastGenesis.js'; +import { + TEST_TARGET_USD_PER_TOKEN, + PROD_TARGET_USD_PER_TOKEN, + TEST_POW_LEADING_ZERO_BYTES, +} from '../src/params/testEconomics.js'; + +loadEnv({ path: resolve(process.cwd(), '.env') }); + +function requireGenesisSk(): Uint8Array { + const hex = process.env.GENESIS_SK_HEX?.trim(); + const wifNote = process.env.GENESIS_WIF?.trim(); + if (hex && /^[0-9a-fA-F]{64}$/.test(hex)) { + return fromHex(hex); + } + if (wifNote) { + throw new Error( + 'GENESIS_WIF is set but this script expects GENESIS_SK_HEX (32-byte hex). ' + + 'Run `npm run new-wallet` to regenerate, or set GENESIS_SK_HEX.', + ); + } + throw new Error( + 'Missing GENESIS_SK_HEX. Run `npm run new-wallet` first, fund the address, then re-run.', + ); +} + +async function main(): Promise { + const chronik = await createChronik('closest'); + const tip = await chronik.blockchainInfo(); + const wallet = Wallet.fromSk(requireGenesisSk(), chronik); + await wallet.sync(); + + console.log( + JSON.stringify( + { + network: 'mainnet', + tipHeight: tip.tipHeight, + genesisAddress: wallet.address, + balanceSats: wallet.balanceSats.toString(), + balanceXec: (Number(wallet.balanceSats) / 100).toFixed(2), + targetUsdPerToken: TEST_TARGET_USD_PER_TOKEN, + futureUsdPerToken: PROD_TARGET_USD_PER_TOKEN, + powLeadingZeroBytes: TEST_POW_LEADING_ZERO_BYTES, + }, + null, + 2, + ), + ); + + const result = await broadcastAlpGenesis(wallet); + + const outDir = resolve(process.cwd(), 'deployments'); + mkdirSync(outDir, { recursive: true }); + const outPath = resolve(outDir, 'mainnet-test-token.json'); + const payload = { + ...result, + createdAt: new Date().toISOString(), + tipHeightAtGenesis: tip.tipHeight, + chronikExplorerHint: `https://explorer.e.cash/tx/${result.tokenId}`, + cashtabTokenHint: `https://cashtab.com/#/token/${result.tokenId}`, + notes: [ + 'Custodial mint batons held by genesis wallet until PoW covenant is live.', + `Test economics target ~$${TEST_TARGET_USD_PER_TOKEN}/token; raise PoW for ~$${PROD_TARGET_USD_PER_TOKEN}.`, + ], + }; + writeFileSync(outPath, `${JSON.stringify(payload, null, 2)}\n`); + + console.log('\nGenesis OK'); + console.log(JSON.stringify(payload, null, 2)); + console.log(`\nWrote ${outPath}`); +} + +main().catch(err => { + console.error(err instanceof Error ? err.message : err); + process.exit(1); +}); diff --git a/scripts/new-wallet.ts b/scripts/new-wallet.ts new file mode 100644 index 0000000..9b39f34 --- /dev/null +++ b/scripts/new-wallet.ts @@ -0,0 +1,58 @@ +#!/usr/bin/env tsx +/** + * Generate a fresh mainnet genesis keypair and write .env (gitignored). + * Prints the funding address — send ≥ 200 XEC, then run create-test-token. + */ +import { randomBytes } from 'node:crypto'; +import { writeFileSync, existsSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { Wallet } from 'ecash-wallet'; +import { toHex } from 'ecash-lib'; +import { createChronik } from '../src/network/createChronik.js'; +import { MAINNET_CHRONIK_URLS } from '../src/network/chronikUrls.js'; + +async function main(): Promise { + const force = process.argv.includes('--force'); + const envPath = resolve(process.cwd(), '.env'); + if (existsSync(envPath) && !force) { + console.error( + `.env already exists. Pass --force to overwrite, or fund the existing address.`, + ); + process.exit(1); + } + + const chronik = await createChronik('closest'); + const sk = randomBytes(32); + const wallet = Wallet.fromSk(sk, chronik); + await wallet.sync(); + + const body = [ + '# Generated by npm run new-wallet — DO NOT COMMIT', + `CHRONIK_URL=${MAINNET_CHRONIK_URLS[0]}`, + `GENESIS_SK_HEX=${toHex(sk)}`, + `GENESIS_ADDRESS=${wallet.address}`, + '', + ].join('\n'); + writeFileSync(envPath, body, { mode: 0o600 }); + + const pending = { + network: 'mainnet', + genesisAddress: wallet.address, + balanceSats: wallet.balanceSats.toString(), + minSuggestedXec: 200, + nextStep: 'Send ≥ 200 XEC to genesisAddress, then: npm run create-test-token', + chronikUrls: [...MAINNET_CHRONIK_URLS], + }; + writeFileSync( + resolve(process.cwd(), 'deployments/pending-funding.json'), + `${JSON.stringify(pending, null, 2)}\n`, + ); + + console.log(JSON.stringify(pending, null, 2)); + console.log(`\nWrote ${envPath} (gitignored) and deployments/pending-funding.json`); +} + +main().catch(err => { + console.error(err instanceof Error ? err.message : err); + process.exit(1); +}); diff --git a/scripts/wait-for-funding-and-create.ts b/scripts/wait-for-funding-and-create.ts new file mode 100644 index 0000000..b353fcb --- /dev/null +++ b/scripts/wait-for-funding-and-create.ts @@ -0,0 +1,72 @@ +#!/usr/bin/env tsx +/** + * Poll genesis address until funded, then run create-test-token logic. + * Usage: npm run wait-create-test-token -- --timeout-min 30 + */ +import { resolve } from 'node:path'; +import { config as loadEnv } from 'dotenv'; +import { spawn } from 'node:child_process'; +import { Wallet } from 'ecash-wallet'; +import { fromHex } from 'ecash-lib'; +import { createChronik } from '../src/network/createChronik.js'; + +loadEnv({ path: resolve(process.cwd(), '.env') }); + +function parseTimeoutMin(argv: string[]): number { + const i = argv.indexOf('--timeout-min'); + if (i === -1 || !argv[i + 1]) return 45; + return Number.parseInt(argv[i + 1], 10); +} + +async function main(): Promise { + const timeoutMin = parseTimeoutMin(process.argv.slice(2)); + const skHex = process.env.GENESIS_SK_HEX?.trim(); + if (!skHex || !/^[0-9a-fA-F]{64}$/.test(skHex)) { + throw new Error('GENESIS_SK_HEX missing — run npm run new-wallet first'); + } + + const chronik = await createChronik('closest'); + const wallet = Wallet.fromSk(fromHex(skHex), chronik); + const needSats = 8_000n; + const deadline = Date.now() + timeoutMin * 60_000; + + console.log( + JSON.stringify( + { + polling: wallet.address, + needSats: needSats.toString(), + timeoutMin, + }, + null, + 2, + ), + ); + + while (Date.now() < deadline) { + await wallet.sync(); + console.log( + `[${new Date().toISOString()}] balanceSats=${wallet.balanceSats}`, + ); + if (wallet.balanceSats >= needSats) { + console.log('Funded — creating test token…'); + const child = spawn('npm', ['run', 'create-test-token'], { + stdio: 'inherit', + cwd: process.cwd(), + shell: true, + }); + const code: number = await new Promise(resolve => + child.on('close', resolve), + ); + process.exit(code ?? 1); + } + await new Promise(r => setTimeout(r, 20_000)); + } + + console.error(`Timed out after ${timeoutMin}m waiting for funding`); + process.exit(2); +} + +main().catch(err => { + console.error(err instanceof Error ? err.message : err); + process.exit(1); +}); diff --git a/src/genesis/broadcastGenesis.ts b/src/genesis/broadcastGenesis.ts new file mode 100644 index 0000000..4e3643f --- /dev/null +++ b/src/genesis/broadcastGenesis.ts @@ -0,0 +1,182 @@ +import { + ALP_TOKEN_TYPE_STANDARD, + DEFAULT_DUST_SATS, + payment, + toHex, + type Script, +} from 'ecash-lib'; +import type { Wallet } from 'ecash-wallet'; +import { + BASE_MINT_ATOMS, + TOKEN_DECIMALS, + TOKEN_URL, +} from '../params/consensus.js'; +import { + TEST_INITIAL_MINT_ATOMS, + TEST_POW_BATON_COUNT, + TEST_POW_LEADING_ZERO_BYTES, + TEST_TOKEN_NAME, + TEST_TOKEN_TICKER, +} from '../params/testEconomics.js'; +import { assertMultiBaton, buildGenesisPlan } from './createGenesis.js'; + +export interface BroadcastGenesisOptions { + /** Override initial fungible mint atoms. */ + initialMintAtoms?: bigint; + /** Override baton count (must be ≥ 2). */ + powBatonCount?: number; + /** Dust sats per token/baton output. */ + dustSats?: bigint; + /** Token ticker. */ + ticker?: string; + /** Token name. */ + name?: string; + /** Decimals. */ + decimals?: number; + /** Document URL. */ + url?: string; +} + +export interface BroadcastGenesisResult { + tokenId: string; + txids: string[]; + ticker: string; + name: string; + decimals: number; + initialMintAtoms: string; + powBatonCount: number; + powLeadingZeroBytes: number; + baseMintAtoms: string; + genesisAddress: string; + authPubkey: string; +} + +function batonOutputs( + script: Script, + count: number, + dustSats: bigint, +): payment.PaymentOutput[] { + const outs: payment.PaymentOutput[] = []; + for (let i = 0; i < count; i++) { + outs.push({ + sats: dustSats, + script, + tokenId: payment.GENESIS_TOKEN_ID_PLACEHOLDER, + isMintBaton: true, + atoms: 0n, + }); + } + return outs; +} + +/** + * Build an ALP GENESIS Action: initial mint + N mint batons to `script`. + * Batons are held by the genesis wallet for custodial remint dogfooding + * until the PoW covenant is production-ready. + */ +export function buildAlpGenesisAction( + script: Script, + authPubkeyHex: string, + opts: BroadcastGenesisOptions = {}, +): payment.Action { + const plan = buildGenesisPlan({ + ticker: opts.ticker ?? TEST_TOKEN_TICKER, + name: opts.name ?? TEST_TOKEN_NAME, + url: opts.url ?? TOKEN_URL, + decimals: opts.decimals ?? TOKEN_DECIMALS, + initialMintAtoms: opts.initialMintAtoms ?? TEST_INITIAL_MINT_ATOMS, + powBatonCount: opts.powBatonCount ?? TEST_POW_BATON_COUNT, + }); + assertMultiBaton(plan); + + const dustSats = opts.dustSats ?? DEFAULT_DUST_SATS; + const outputs: payment.PaymentOutput[] = [{ sats: 0n }]; + + if (plan.initialMintAtoms > 0n) { + outputs.push({ + sats: dustSats, + script, + tokenId: payment.GENESIS_TOKEN_ID_PLACEHOLDER, + atoms: plan.initialMintAtoms, + }); + } + + outputs.push(...batonOutputs(script, plan.powBatonCount, dustSats)); + + return { + outputs, + tokenActions: [ + { + type: 'GENESIS', + tokenType: ALP_TOKEN_TYPE_STANDARD, + genesisInfo: { + tokenTicker: plan.ticker, + tokenName: plan.name, + url: plan.url, + decimals: plan.decimals, + authPubkey: authPubkeyHex, + }, + }, + ], + }; +} + +/** + * Sync wallet, broadcast ALP GENESIS, return tokenId (= genesis txid). + */ +export async function broadcastAlpGenesis( + wallet: Wallet, + opts: BroadcastGenesisOptions = {}, +): Promise { + await wallet.sync(); + + const dustSats = opts.dustSats ?? DEFAULT_DUST_SATS; + const batons = opts.powBatonCount ?? TEST_POW_BATON_COUNT; + const mintAtoms = opts.initialMintAtoms ?? TEST_INITIAL_MINT_ATOMS; + const mintOutputs = (mintAtoms > 0n ? 1 : 0) + batons; + const minSatsNeeded = dustSats * BigInt(mintOutputs) + 5_000n; // fee headroom + + if (wallet.balanceSats < minSatsNeeded) { + throw new Error( + `Insufficient XEC: have ${wallet.balanceSats} sats at ${wallet.address}, ` + + `need ≥ ${minSatsNeeded} sats (~${Number(minSatsNeeded) / 100} XEC). ` + + `Send mainnet XEC to the genesis address and re-run.`, + ); + } + + const action = buildAlpGenesisAction(wallet.script, toHex(wallet.pk), opts); + const built = wallet.action(action).build(); + const resp = await built.broadcast(); + + if (!resp.success || !resp.broadcasted?.length) { + throw new Error( + `Genesis broadcast failed: ${JSON.stringify(resp, (_k, v) => + typeof v === 'bigint' ? v.toString() : v, + )}`, + ); + } + + const tokenId = resp.broadcasted[0]; + const plan = buildGenesisPlan({ + ticker: opts.ticker ?? TEST_TOKEN_TICKER, + name: opts.name ?? TEST_TOKEN_NAME, + url: opts.url ?? TOKEN_URL, + decimals: opts.decimals ?? TOKEN_DECIMALS, + initialMintAtoms: mintAtoms, + powBatonCount: batons, + }); + + return { + tokenId, + txids: resp.broadcasted, + ticker: plan.ticker, + name: plan.name, + decimals: plan.decimals, + initialMintAtoms: plan.initialMintAtoms.toString(), + powBatonCount: plan.powBatonCount, + powLeadingZeroBytes: TEST_POW_LEADING_ZERO_BYTES, + baseMintAtoms: BASE_MINT_ATOMS.toString(), + genesisAddress: wallet.address, + authPubkey: toHex(wallet.pk), + }; +} diff --git a/src/index.ts b/src/index.ts index cc765f8..7e63a31 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,15 @@ export { POW_LEADING_ZERO_BYTES, TOKEN_TICKER, } from './params/consensus.js'; +export { + TEST_INITIAL_MINT_ATOMS, + TEST_POW_BATON_COUNT, + TEST_POW_LEADING_ZERO_BYTES, + TEST_TARGET_USD_PER_TOKEN, + TEST_TOKEN_NAME, + TEST_TOKEN_TICKER, + PROD_TARGET_USD_PER_TOKEN, +} from './params/testEconomics.js'; export { approxHalfLifeYears, mintAtomsAfterDays, @@ -14,4 +23,10 @@ export { mooreStep, } from './lib/moore.js'; export { assertMultiBaton, buildGenesisPlan } from './genesis/createGenesis.js'; +export { + broadcastAlpGenesis, + buildAlpGenesisAction, +} from './genesis/broadcastGenesis.js'; +export { createChronik } from './network/createChronik.js'; +export { MAINNET_CHRONIK_URLS } from './network/chronikUrls.js'; export { expectedMintAtoms, minerBanner } from './miner/remint.js'; diff --git a/src/network/chronikUrls.ts b/src/network/chronikUrls.ts new file mode 100644 index 0000000..e0fcfc1 --- /dev/null +++ b/src/network/chronikUrls.ts @@ -0,0 +1,9 @@ +/** + * Public Chronik endpoints for eCash mainnet (failover order). + * Prefer ClosestFirst at runtime; AsOrdered is available for deterministic tests. + */ +export const MAINNET_CHRONIK_URLS = [ + 'https://chronik.e.cash', + 'https://xec.paybutton.org', + 'https://chronik.pay2stay.com/xec', +] as const; diff --git a/src/network/createChronik.ts b/src/network/createChronik.ts new file mode 100644 index 0000000..4753569 --- /dev/null +++ b/src/network/createChronik.ts @@ -0,0 +1,18 @@ +import { ChronikClient, ConnectionStrategy } from 'chronik-client'; +import { MAINNET_CHRONIK_URLS } from './chronikUrls.js'; + +export type ChronikStrategy = 'closest' | 'ordered'; + +/** + * Build a Chronik client against the public mainnet fleet. + */ +export async function createChronik( + strategy: ChronikStrategy = 'closest', + urls: readonly string[] = MAINNET_CHRONIK_URLS, +): Promise { + const mode = + strategy === 'ordered' + ? ConnectionStrategy.AsOrdered + : ConnectionStrategy.ClosestFirst; + return ChronikClient.useStrategy(mode, [...urls]); +} diff --git a/src/params/consensus.ts b/src/params/consensus.ts index 53af866..6ee3e0b 100644 --- a/src/params/consensus.ts +++ b/src/params/consensus.ts @@ -17,9 +17,10 @@ export const TOKEN_DECIMALS = 6; /** * Leading zero *bytes* required on hash256(preimage || nonce). - * Draft — retune on chipnet. + * Test deployment uses 1 (~$1e-6/token target). Raise for ~$0.01 later. + * @see ./testEconomics.ts */ -export const POW_LEADING_ZERO_BYTES = 2; +export const POW_LEADING_ZERO_BYTES = 1; /** * Base mint atoms at k=0 (genesis day-step). @@ -32,8 +33,9 @@ export const BASE_MINT_ATOMS = 100_000_000n; /** * Number of parallel PoW mint batons created at genesis. * Each baton is an independent remint race (true parallelization). + * Test genesis uses 4; production may raise toward 8–16. */ -export const POW_BATON_COUNT = 8; +export const POW_BATON_COUNT = 4; /** * Ergon post-fix Moore daily factor numerator. diff --git a/src/params/testEconomics.ts b/src/params/testEconomics.ts new file mode 100644 index 0000000..4bd29a4 --- /dev/null +++ b/src/params/testEconomics.ts @@ -0,0 +1,38 @@ +/** + * Test-deployment economics for the first on-chain WLOTUS token. + * + * Target: mining / remint cost around **$0.000001 per token** (very cheap dogfood). + * Later production aim: around **$0.01 per token** (raise PoW difficulty + retune M₀). + * + * At ~$6.6e-6 / XEC (mid-2026 ballpark): + * - One remint fee (~10–50 XEC) is already on the order of $1e-4 … $3e-4. + * - With M₀ = 100 tokens/remint and PoW ≈ free (1 leading zero byte), + * all-in cost per token lands near the $1e-6 target when hashrate is low. + */ + +/** Documented target USD per whole token for this test deployment. */ +export const TEST_TARGET_USD_PER_TOKEN = 0.000001; + +/** Future production target USD per whole token. */ +export const PROD_TARGET_USD_PER_TOKEN = 0.01; + +/** + * PoW leading zero *bytes* for the test deployment. + * 1 byte ⇒ ~1/256 hashes succeed — trivial on a laptop; not mainnet-hard. + * Raise toward 2–3+ when targeting ~$0.01/token. + */ +export const TEST_POW_LEADING_ZERO_BYTES = 1; + +/** + * Initial fungible mint at genesis (atoms) so temple/burn UX can be tested + * before PoW remint is fully wired. 1e12 atoms @ 6 decimals = 1_000_000 tokens. + */ +export const TEST_INITIAL_MINT_ATOMS = 1_000_000_000_000n; + +/** Parallel batons for the test genesis (still N ≥ 2). */ +export const TEST_POW_BATON_COUNT = 4; + +/** Ticker for the cheap test deployment (keep WLOTUS name free for $0.01 launch). */ +export const TEST_TOKEN_TICKER = 'WLTEST'; + +export const TEST_TOKEN_NAME = 'White Lotus Test'; diff --git a/tests/moore.test.ts b/tests/moore.test.ts index 716c63b..65a0b7a 100644 --- a/tests/moore.test.ts +++ b/tests/moore.test.ts @@ -69,3 +69,14 @@ describe('genesis multi-baton', () => { expect(() => assertMultiBaton(plan)).toThrow(/N >= 2/); }); }); + +describe('test economics profile', () => { + test('PoW difficulty is low for ~$1e-6 target', async () => { + const econ = await import('../src/params/testEconomics.js'); + expect(econ.TEST_POW_LEADING_ZERO_BYTES).toBe(1); + expect(econ.TEST_TARGET_USD_PER_TOKEN).toBe(0.000001); + expect(econ.PROD_TARGET_USD_PER_TOKEN).toBe(0.01); + expect(econ.TEST_POW_BATON_COUNT).toBeGreaterThanOrEqual(2); + expect(econ.TEST_INITIAL_MINT_ATOMS).toBeGreaterThan(0n); + }); +}); From a3b7fdd33307106f476102f5800f6048bc77e5c6 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 04:01:02 +0000 Subject: [PATCH 3/6] Record live WLTEST mainnet genesis Broadcast ALP GENESIS after 1000 XEC funding: tokenId e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3 (1M WLTEST @ 6 decimals, 4 mint batons, PoW difficulty 1). Co-authored-by: nghiacc --- README.md | 9 +++++---- deployments/README.md | 4 ++-- deployments/mainnet-test-token.json | 23 +++++++++++++++++++++++ deployments/pending-funding.json | 12 ------------ docs/STATUS.md | 13 ++++++++----- docs/TEST_TOKEN.md | 26 ++++++++++++++++++++------ 6 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 deployments/mainnet-test-token.json delete mode 100644 deployments/pending-funding.json diff --git a/README.md b/README.md index 500a4f4..11474e4 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,11 @@ See [docs/SPEC.md](./docs/SPEC.md) and [docs/PROPOSAL.md](./docs/PROPOSAL.md). ## Status -Scaffold for covenant + miner (migrated from the temporary -`eminer` branch `cursor/wlotus-scaffold-d6bb`). Chipnet genesis and -audited Script are TODO. See [docs/STATUS.md](./docs/STATUS.md). - +Scaffold for covenant + miner. **Mainnet test token `WLTEST` is live** — +see [docs/TEST_TOKEN.md](./docs/TEST_TOKEN.md) and +[deployments/mainnet-test-token.json](./deployments/mainnet-test-token.json). +PoW covenant audit and `$0.01` `WLOTUS` launch are TODO. +See [docs/STATUS.md](./docs/STATUS.md). ## Layout ``` diff --git a/deployments/README.md b/deployments/README.md index ca5d556..8519d4a 100644 --- a/deployments/README.md +++ b/deployments/README.md @@ -4,7 +4,7 @@ On-chain deployment records for White Lotus test / production tokens. | File | Meaning | |------|---------| -| `pending-funding.json` | Genesis address waiting for XEC before first broadcast | -| `mainnet-test-token.json` | Written by `npm run create-test-token` after successful GENESIS | +| `mainnet-test-token.json` | Live **WLTEST** ALP genesis on eCash mainnet | +| `pending-funding.json` | (obsolete once funded) | Private keys live only in `.env` (gitignored). Never commit `GENESIS_SK_HEX`. diff --git a/deployments/mainnet-test-token.json b/deployments/mainnet-test-token.json new file mode 100644 index 0000000..2931c09 --- /dev/null +++ b/deployments/mainnet-test-token.json @@ -0,0 +1,23 @@ +{ + "tokenId": "e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3", + "txids": [ + "e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3" + ], + "ticker": "WLTEST", + "name": "White Lotus Test", + "decimals": 6, + "initialMintAtoms": "1000000000000", + "powBatonCount": 4, + "powLeadingZeroBytes": 1, + "baseMintAtoms": "100000000", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", + "createdAt": "2026-07-17T03:59:50.737Z", + "tipHeightAtGenesis": 958242, + "chronikExplorerHint": "https://explorer.e.cash/tx/e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3", + "cashtabTokenHint": "https://cashtab.com/#/token/e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3", + "notes": [ + "Custodial mint batons held by genesis wallet until PoW covenant is live.", + "Test economics target ~$0.000001/token; raise PoW for ~$0.01." + ] +} diff --git a/deployments/pending-funding.json b/deployments/pending-funding.json deleted file mode 100644 index a7d4a91..0000000 --- a/deployments/pending-funding.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "network": "mainnet", - "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", - "balanceSats": "0", - "minSuggestedXec": 200, - "nextStep": "Send ≥ 200 XEC to genesisAddress, then: npm run create-test-token", - "chronikUrls": [ - "https://chronik.e.cash", - "https://xec.paybutton.org", - "https://chronik.pay2stay.com/xec" - ] -} diff --git a/docs/STATUS.md b/docs/STATUS.md index 98956b6..853ddb6 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -15,10 +15,13 @@ access to this repo. That work is now landed here. | [ARCHITECTURE.md](./ARCHITECTURE.md) | Covenant / multi-baton flow | | [research/](./research/) | Feasibility notes from [eminer#1](https://github.com/bcProFoundation/eminer/pull/1) | +## Live + +- **WLTEST** mainnet: `e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3` + ([TEST_TOKEN.md](./TEST_TOKEN.md)) + ## Next ops -1. Fund genesis address in `deployments/pending-funding.json` (≥ 200 XEC) -2. `npm run create-test-token` → writes `deployments/mainnet-test-token.json` -3. Harden `contracts/WlotusRemint.cash` + Chronik miner wiring -4. Raise PoW from 1 → higher when targeting ~$0.01/token -5. Temple / burn UI in a separate app repo +1. Harden `contracts/WlotusRemint.cash` + Chronik miner wiring +2. Raise PoW from 1 → higher when targeting ~$0.01/token (`WLOTUS`) +3. Temple / burn UI in a separate app repo diff --git a/docs/TEST_TOKEN.md b/docs/TEST_TOKEN.md index c9a4ef4..a120d16 100644 --- a/docs/TEST_TOKEN.md +++ b/docs/TEST_TOKEN.md @@ -1,5 +1,22 @@ # Test token deployment (mainnet) +## Live token + +| Field | Value | +|-------|-------| +| Ticker | `WLTEST` | +| Name | White Lotus Test | +| Token ID | `e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3` | +| Decimals | 6 | +| Initial mint | 1,000,000 WLTEST | +| Mint batons | 4 (custodial on genesis wallet) | +| PoW leading zero bytes | 1 (~$0.000001/token target) | +| Genesis address | `ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7` | + +- Explorer: https://explorer.e.cash/tx/e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3 +- Cashtab: https://cashtab.com/#/token/e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3 +- Record: [`deployments/mainnet-test-token.json`](../deployments/mainnet-test-token.json) + ## Goals | Knob | Test now | Later | @@ -17,13 +34,10 @@ https://xec.paybutton.org https://chronik.pay2stay.com/xec ``` -## Create +## Recreate (new token) ```bash -npm run new-wallet # .env + deployments/pending-funding.json +npm run new-wallet -- --force # fund genesis address with ≥ 200 XEC -npm run create-test-token # → deployments/mainnet-test-token.json +npm run create-test-token ``` - -Genesis mints **1,000,000** `WLTEST` (6 decimals) plus **4** mint batons to the -genesis wallet for custodial remint dogfooding until the PoW covenant is audited. From 9b36850e42d43c22c07f0cc165e78f50c701a488 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 04:30:13 +0000 Subject: [PATCH 4/6] Add working PoW remint covenant and live WLPOW mainnet token Ship a Spedn Mist-style BIP143 preimage covenant (eCash has no native introspection), create-pow-token / mine-once tooling, and a proven mainnet remint on WLPOW. Document custodial WLTEST vs PoW WLPOW and archive locked predecessor covenant deployments. Co-authored-by: nghiacc --- .gitignore | 1 + README.md | 34 +- contracts/WlotusPowRemint.compiled.json | 1846 +++++++++++++ contracts/WlotusPowRemint.spedn | 52 + deployments/README.md | 8 +- deployments/mainnet-last-remint.json | 9 + deployments/mainnet-pow-handoff.json | 18 + deployments/mainnet-pow-token-v1-locked.json | 31 + deployments/mainnet-pow-token-v2-locked.json | 31 + deployments/mainnet-pow-token.json | 30 + deployments/pow-contract-v2.json | 8 + docs/STATUS.md | 27 +- docs/TEST_TOKEN.md | 62 +- package-lock.json | 2567 +++++++++++++++++- package.json | 7 +- scripts/create-pow-token.ts | 144 + scripts/mine-once.ts | 133 + src/covenant/minePow.ts | 40 + src/covenant/opcodes.ts | 18 + src/covenant/powRemintOutputs.ts | 13 + src/covenant/powRemintScript.ts | 114 + src/index.ts | 10 +- src/miner/remint.ts | 191 +- 23 files changed, 5296 insertions(+), 98 deletions(-) create mode 100644 contracts/WlotusPowRemint.compiled.json create mode 100644 contracts/WlotusPowRemint.spedn create mode 100644 deployments/mainnet-last-remint.json create mode 100644 deployments/mainnet-pow-handoff.json create mode 100644 deployments/mainnet-pow-token-v1-locked.json create mode 100644 deployments/mainnet-pow-token-v2-locked.json create mode 100644 deployments/mainnet-pow-token.json create mode 100644 deployments/pow-contract-v2.json create mode 100644 scripts/create-pow-token.ts create mode 100644 scripts/mine-once.ts create mode 100644 src/covenant/minePow.ts create mode 100644 src/covenant/opcodes.ts create mode 100644 src/covenant/powRemintOutputs.ts create mode 100644 src/covenant/powRemintScript.ts diff --git a/.gitignore b/.gitignore index bcd4026..05f2648 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ dist/ *.log .DS_Store coverage/ +*.tgz diff --git a/README.md b/README.md index 11474e4..411a51a 100644 --- a/README.md +++ b/README.md @@ -24,22 +24,27 @@ See [docs/SPEC.md](./docs/SPEC.md) and [docs/PROPOSAL.md](./docs/PROPOSAL.md). ## Status -Scaffold for covenant + miner. **Mainnet test token `WLTEST` is live** — -see [docs/TEST_TOKEN.md](./docs/TEST_TOKEN.md) and -[deployments/mainnet-test-token.json](./deployments/mainnet-test-token.json). -PoW covenant audit and `$0.01` `WLOTUS` launch are TODO. -See [docs/STATUS.md](./docs/STATUS.md). -## Layout +**PoW-mineable mainnet token `WLPOW` is live** (Spedn BIP143 preimage covenant). +Custodial `WLTEST` also exists but is **not** for mining tests. + +See [docs/TEST_TOKEN.md](./docs/TEST_TOKEN.md) and [docs/STATUS.md](./docs/STATUS.md). + +```bash +npm run mine-once # remint against WLPOW batons +npm run create-pow-token # recreate PoW genesis + baton handoff +``` ``` -contracts/ # CashScript remint covenant +contracts/ # Spedn PoW remint covenant (BIP143 preimage) docs/ # Consensus / product spec + research src/params/ # Consensus constants (Moore, batons, …) -src/lib/ # Moore math, ALP helpers -src/genesis/ # GENESIS + baton handoff tooling +src/lib/ # Moore math +src/covenant/ # Contract loader, PoW mine, output templates +src/genesis/ # ALP GENESIS tooling src/miner/ # PoW remint miner (Chronik + ecash-lib) -scripts/ # Utilities +scripts/ # create-pow-token, mine-once, … tests/ # Unit tests +deployments/ # Live mainnet records ``` ## Quick start @@ -62,8 +67,13 @@ npm run new-wallet # writes .env + deployments/pending-funding.json npm run create-test-token # ALP GENESIS → deployments/mainnet-test-token.json ``` -Ticker for this dogfood deployment: `WLTEST` (keeps `WLOTUS` for the later $0.01 launch). -Mint batons are custodial on the genesis wallet until the PoW covenant is live. +Ticker for this dogfood deployment: `WLPOW` (PoW) / `WLTEST` (custodial only). +Keep `WLOTUS` for the later $0.01 launch. + +```bash +npm run create-pow-token # PoW genesis + handoff to covenant P2SH +npm run mine-once # one permissionless remint +``` ## License diff --git a/contracts/WlotusPowRemint.compiled.json b/contracts/WlotusPowRemint.compiled.json new file mode 100644 index 0000000..620ab0b --- /dev/null +++ b/contracts/WlotusPowRemint.compiled.json @@ -0,0 +1,1846 @@ +{ + "templates": { + "WlotusPowRemint": { + "asm": [ + { + "contents": "tokenIdRev", + "tag": "OP_PUSH" + }, + { + "contents": "mintAtomsLe", + "tag": "OP_PUSH" + }, + { + "contents": "difficultyLeadingZeroBytes", + "tag": "OP_PUSH" + }, + { + "contents": 6, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "contents": 5, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_CHECKSIGVERIFY" + }, + { + "contents": 5, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "contents": 4, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_SHA256" + }, + { + "contents": 6, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_CHECKDATASIGVERIFY" + }, + { + "contents": 3, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "contents": 8, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_CAT" + }, + { + "tag": "OP_HASH256" + }, + { + "tag": "OP_DUP" + }, + { + "contents": 2, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_SPLIT" + }, + { + "tag": "OP_DROP" + }, + { + "tag": "OP_DUP" + }, + { + "tag": "OP_BIN2NUM" + }, + { + "tag": "OP_FALSE" + }, + { + "tag": "OP_EQUALVERIFY" + }, + { + "contents": 5, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_SIZE" + }, + { + "contents": [ + 1, + [ + 40 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_SUB" + }, + { + "tag": "OP_SPLIT" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_DUP" + }, + { + "contents": [ + 1, + [ + 32 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_SPLIT" + }, + { + "tag": "OP_DROP" + }, + { + "contents": 7, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_SIZE" + }, + { + "contents": [ + 1, + [ + 52 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_SUB" + }, + { + "tag": "OP_SPLIT" + }, + { + "tag": "OP_DROP" + }, + { + "tag": "OP_DUP" + }, + { + "contents": [ + 1, + [ + 104 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_SPLIT" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_DUP" + }, + { + "tag": "OP_TRUE" + }, + { + "tag": "OP_SPLIT" + }, + { + "tag": "OP_NIP" + }, + { + "contents": [ + 4, + [ + 83, + 76, + 80, + 50 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_FALSE" + }, + { + "tag": "OP_TRUE" + }, + { + "tag": "OP_NUM2BIN" + }, + { + "tag": "OP_CAT" + }, + { + "contents": 4, + "tag": "OP_N" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 4, + [ + 77, + 73, + 78, + 84 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_CAT" + }, + { + "contents": 10, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_CAT" + }, + { + "tag": "OP_TRUE" + }, + { + "tag": "OP_CAT" + }, + { + "contents": 9, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_CAT" + }, + { + "tag": "OP_TRUE" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 2, + [ + 106, + 80 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_OVER" + }, + { + "tag": "OP_SIZE" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_TRUE" + }, + { + "tag": "OP_NUM2BIN" + }, + { + "tag": "OP_CAT" + }, + { + "tag": "OP_OVER" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 8, + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_OVER" + }, + { + "tag": "OP_SIZE" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_TRUE" + }, + { + "tag": "OP_NUM2BIN" + }, + { + "tag": "OP_CAT" + }, + { + "tag": "OP_OVER" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 8, + [ + 34, + 2, + 0, + 0, + 0, + 0, + 0, + 0 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "contents": [ + 1, + [ + 25 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 3, + [ + 118, + 169, + 20 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_CAT" + }, + { + "contents": 15, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_HASH160" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 2, + [ + 136, + 172 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 8, + [ + 34, + 2, + 0, + 0, + 0, + 0, + 0, + 0 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "contents": [ + 1, + [ + 23 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 2, + [ + 169, + 20 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_CAT" + }, + { + "contents": 5, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_HASH160" + }, + { + "tag": "OP_CAT" + }, + { + "contents": [ + 1, + [ + 135 + ] + ], + "tag": "OP_PUSHDATA0" + }, + { + "tag": "OP_CAT" + }, + { + "contents": 2, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "contents": 2, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_CAT" + }, + { + "tag": "OP_OVER" + }, + { + "tag": "OP_CAT" + }, + { + "tag": "OP_HASH256" + }, + { + "contents": 9, + "tag": "OP_N" + }, + { + "tag": "OP_PICK" + }, + { + "tag": "OP_EQUAL" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + }, + { + "tag": "OP_NIP" + } + ], + "ast": { + "contractAnnotation": ":6:1", + "contractChallenges": [ + [ + "remint", + [ + [ + { + "contents": [ + "byte", + 4 + ], + "tag": "Array" + }, + "nonce", + ":12:9" + ], + [ + "Sig", + "s", + ":13:9" + ], + [ + "DataSig", + "ds", + ":14:9" + ], + [ + "PubKey", + "minerPk", + ":15:9" + ], + [ + { + "contents": "byte", + "tag": "List" + }, + "preimage", + ":16:9" + ] + ], + { + "contents": [ + [ + { + "contents": [ + { + "contents": [ + "checkSig", + [ + { + "contents": [ + "s", + ":18:25" + ], + "tag": "Var" + }, + { + "contents": [ + "minerPk", + ":18:28" + ], + "tag": "Var" + } + ], + ":18:16" + ], + "tag": "Call" + }, + ":18:9" + ], + "tag": "Verify" + }, + { + "contents": [ + { + "contents": [ + "checkDataSig", + [ + { + "contents": [ + "ds", + ":19:29" + ], + "tag": "Var" + }, + { + "contents": [ + "sha256", + [ + { + "contents": [ + "preimage", + ":19:40" + ], + "tag": "Var" + } + ], + ":19:33" + ], + "tag": "Call" + }, + { + "contents": [ + "minerPk", + ":19:51" + ], + "tag": "Var" + } + ], + ":19:16" + ], + "tag": "Call" + }, + ":19:9" + ], + "tag": "Verify" + }, + { + "contents": [ + [ + { + "contents": "byte", + "tag": "List" + }, + "solhash", + ":21:9" + ], + { + "contents": [ + "hash256", + [ + { + "contents": [ + "Cat", + { + "contents": [ + "preimage", + ":21:34" + ], + "tag": "Var" + }, + { + "contents": [ + "nonce", + ":21:45" + ], + "tag": "Var" + }, + ":21:43" + ], + "tag": "BinaryExpr" + } + ], + ":21:26" + ], + "tag": "Call" + }, + ":21:9" + ], + "tag": "Assign" + }, + { + "contents": [ + [ + { + "contents": [ + { + "contents": "byte", + "tag": "List" + }, + "work", + ":22:10" + ], + "tag": "TupleVarDecl" + }, + { + "contents": ":22:23", + "tag": "Gap" + } + ], + { + "contents": [ + "Split", + { + "contents": [ + "solhash", + ":22:28" + ], + "tag": "Var" + }, + { + "contents": [ + "difficultyLeadingZeroBytes", + ":22:38" + ], + "tag": "Var" + }, + ":22:36" + ], + "tag": "BinaryExpr" + }, + ":22:9" + ], + "tag": "SplitAssign" + }, + { + "contents": [ + { + "contents": [ + "Eq", + { + "contents": [ + "bin2num", + [ + { + "contents": [ + "work", + ":23:24" + ], + "tag": "Var" + } + ], + ":23:16" + ], + "tag": "Call" + }, + { + "contents": [ + 0, + ":23:33" + ], + "tag": "NumConst" + }, + ":23:30" + ], + "tag": "BinaryExpr" + }, + ":23:9" + ], + "tag": "Verify" + }, + { + "contents": [ + [ + { + "contents": ":25:10", + "tag": "Gap" + }, + { + "contents": [ + { + "contents": "byte", + "tag": "List" + }, + "tail40", + ":25:13" + ], + "tag": "TupleVarDecl" + } + ], + { + "contents": [ + "Split", + { + "contents": [ + "preimage", + ":25:30" + ], + "tag": "Var" + }, + { + "contents": [ + "Sub", + { + "contents": [ + "size", + [ + { + "contents": [ + "preimage", + ":25:47" + ], + "tag": "Var" + } + ], + ":25:42" + ], + "tag": "Call" + }, + { + "contents": [ + 40, + ":25:59" + ], + "tag": "NumConst" + }, + ":25:57" + ], + "tag": "BinaryExpr" + }, + ":25:39" + ], + "tag": "BinaryExpr" + }, + ":25:9" + ], + "tag": "SplitAssign" + }, + { + "contents": [ + [ + { + "contents": [ + { + "contents": "byte", + "tag": "List" + }, + "hashOutputs", + ":26:10" + ], + "tag": "TupleVarDecl" + }, + { + "contents": ":26:30", + "tag": "Gap" + } + ], + { + "contents": [ + "Split", + { + "contents": [ + "tail40", + ":26:35" + ], + "tag": "Var" + }, + { + "contents": [ + 32, + ":26:44" + ], + "tag": "NumConst" + }, + ":26:42" + ], + "tag": "BinaryExpr" + }, + ":26:9" + ], + "tag": "SplitAssign" + }, + { + "contents": [ + [ + { + "contents": [ + { + "contents": "byte", + "tag": "List" + }, + "head", + ":30:10" + ], + "tag": "TupleVarDecl" + }, + { + "contents": ":30:23", + "tag": "Gap" + } + ], + { + "contents": [ + "Split", + { + "contents": [ + "preimage", + ":30:28" + ], + "tag": "Var" + }, + { + "contents": [ + "Sub", + { + "contents": [ + "size", + [ + { + "contents": [ + "preimage", + ":30:45" + ], + "tag": "Var" + } + ], + ":30:40" + ], + "tag": "Call" + }, + { + "contents": [ + 52, + ":30:57" + ], + "tag": "NumConst" + }, + ":30:55" + ], + "tag": "BinaryExpr" + }, + ":30:37" + ], + "tag": "BinaryExpr" + }, + ":30:9" + ], + "tag": "SplitAssign" + }, + { + "contents": [ + [ + { + "contents": ":31:10", + "tag": "Gap" + }, + { + "contents": [ + { + "contents": "byte", + "tag": "List" + }, + "scriptCodePrefixed", + ":31:13" + ], + "tag": "TupleVarDecl" + } + ], + { + "contents": [ + "Split", + { + "contents": [ + "head", + ":31:42" + ], + "tag": "Var" + }, + { + "contents": [ + 104, + ":31:49" + ], + "tag": "NumConst" + }, + ":31:47" + ], + "tag": "BinaryExpr" + }, + ":31:9" + ], + "tag": "SplitAssign" + }, + { + "contents": [ + [ + { + "contents": ":32:10", + "tag": "Gap" + }, + { + "contents": [ + { + "contents": "byte", + "tag": "List" + }, + "redeemScript", + ":32:13" + ], + "tag": "TupleVarDecl" + } + ], + { + "contents": [ + "Split", + { + "contents": [ + "scriptCodePrefixed", + ":32:36" + ], + "tag": "Var" + }, + { + "contents": [ + 1, + ":32:57" + ], + "tag": "NumConst" + }, + ":32:55" + ], + "tag": "BinaryExpr" + }, + ":32:9" + ], + "tag": "SplitAssign" + }, + { + "contents": [ + [ + { + "contents": "byte", + "tag": "List" + }, + "mintSection", + ":35:9" + ], + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + [ + 83, + 76, + 80, + 50 + ], + ":36:13" + ], + "tag": "HexConst" + }, + { + "contents": [ + "num2bin", + [ + { + "contents": [ + 0, + ":37:21" + ], + "tag": "NumConst" + }, + { + "contents": [ + 1, + ":37:24" + ], + "tag": "NumConst" + } + ], + ":37:13" + ], + "tag": "Call" + }, + ":36:24" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + [ + 4 + ], + ":38:13" + ], + "tag": "HexConst" + }, + ":37:27" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + [ + 77, + 73, + 78, + 84 + ], + ":38:20" + ], + "tag": "HexConst" + }, + ":38:18" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + "tokenIdRev", + ":39:13" + ], + "tag": "Var" + }, + ":38:31" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + [ + 1 + ], + ":40:13" + ], + "tag": "HexConst" + }, + ":39:24" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + "mintAtomsLe", + ":41:13" + ], + "tag": "Var" + }, + ":40:18" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + [ + 1 + ], + ":42:13" + ], + "tag": "HexConst" + }, + ":41:25" + ], + "tag": "BinaryExpr" + }, + ":35:9" + ], + "tag": "Assign" + }, + { + "contents": [ + [ + { + "contents": "byte", + "tag": "List" + }, + "opReturnScript", + ":44:9" + ], + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + [ + 106, + 80 + ], + ":44:33" + ], + "tag": "HexConst" + }, + { + "contents": [ + "num2bin", + [ + { + "contents": [ + "size", + [ + { + "contents": [ + "mintSection", + ":44:55" + ], + "tag": "Var" + } + ], + ":44:50" + ], + "tag": "Call" + }, + { + "contents": [ + 1, + ":44:69" + ], + "tag": "NumConst" + } + ], + ":44:42" + ], + "tag": "Call" + }, + ":44:40" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + "mintSection", + ":44:74" + ], + "tag": "Var" + }, + ":44:72" + ], + "tag": "BinaryExpr" + }, + ":44:9" + ], + "tag": "Assign" + }, + { + "contents": [ + [ + { + "contents": "byte", + "tag": "List" + }, + "out0", + ":46:9" + ], + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + ":46:23" + ], + "tag": "HexConst" + }, + { + "contents": [ + "num2bin", + [ + { + "contents": [ + "size", + [ + { + "contents": [ + "opReturnScript", + ":46:57" + ], + "tag": "Var" + } + ], + ":46:52" + ], + "tag": "Call" + }, + { + "contents": [ + 1, + ":46:74" + ], + "tag": "NumConst" + } + ], + ":46:44" + ], + "tag": "Call" + }, + ":46:42" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + "opReturnScript", + ":46:79" + ], + "tag": "Var" + }, + ":46:77" + ], + "tag": "BinaryExpr" + }, + ":46:9" + ], + "tag": "Assign" + }, + { + "contents": [ + [ + { + "contents": "byte", + "tag": "List" + }, + "out1", + ":47:9" + ], + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + [ + 34, + 2, + 0, + 0, + 0, + 0, + 0, + 0 + ], + ":47:23" + ], + "tag": "HexConst" + }, + { + "contents": [ + [ + 25 + ], + ":47:44" + ], + "tag": "HexConst" + }, + ":47:42" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + [ + 118, + 169, + 20 + ], + ":47:51" + ], + "tag": "HexConst" + }, + ":47:49" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + "hash160", + [ + { + "contents": [ + "minerPk", + ":47:70" + ], + "tag": "Var" + } + ], + ":47:62" + ], + "tag": "Call" + }, + ":47:60" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + [ + 136, + 172 + ], + ":47:81" + ], + "tag": "HexConst" + }, + ":47:79" + ], + "tag": "BinaryExpr" + }, + ":47:9" + ], + "tag": "Assign" + }, + { + "contents": [ + [ + { + "contents": "byte", + "tag": "List" + }, + "out2", + ":48:9" + ], + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + [ + 34, + 2, + 0, + 0, + 0, + 0, + 0, + 0 + ], + ":48:23" + ], + "tag": "HexConst" + }, + { + "contents": [ + [ + 23 + ], + ":48:44" + ], + "tag": "HexConst" + }, + ":48:42" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + [ + 169, + 20 + ], + ":48:51" + ], + "tag": "HexConst" + }, + ":48:49" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + "hash160", + [ + { + "contents": [ + "redeemScript", + ":48:68" + ], + "tag": "Var" + } + ], + ":48:60" + ], + "tag": "Call" + }, + ":48:58" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + [ + 135 + ], + ":48:84" + ], + "tag": "HexConst" + }, + ":48:82" + ], + "tag": "BinaryExpr" + }, + ":48:9" + ], + "tag": "Assign" + }, + { + "contents": [ + { + "contents": [ + "Eq", + { + "contents": [ + "hash256", + [ + { + "contents": [ + "Cat", + { + "contents": [ + "Cat", + { + "contents": [ + "out0", + ":50:24" + ], + "tag": "Var" + }, + { + "contents": [ + "out1", + ":50:31" + ], + "tag": "Var" + }, + ":50:29" + ], + "tag": "BinaryExpr" + }, + { + "contents": [ + "out2", + ":50:38" + ], + "tag": "Var" + }, + ":50:36" + ], + "tag": "BinaryExpr" + } + ], + ":50:16" + ], + "tag": "Call" + }, + { + "contents": [ + "Sha256", + [ + { + "contents": [ + "hashOutputs", + ":50:54" + ], + "tag": "Var" + } + ], + ":50:47" + ], + "tag": "Call" + }, + ":50:44" + ], + "tag": "BinaryExpr" + }, + ":50:9" + ], + "tag": "Verify" + } + ], + ":17:7" + ], + "tag": "Block" + }, + ":11:5" + ] + ], + "contractName": "WlotusPowRemint", + "contractParams": [ + [ + { + "contents": [ + "byte", + 32 + ], + "tag": "Array" + }, + "tokenIdRev", + ":7:5" + ], + [ + { + "contents": [ + "byte", + 6 + ], + "tag": "Array" + }, + "mintAtomsLe", + ":8:5" + ], + [ + "int", + "difficultyLeadingZeroBytes", + ":9:5" + ] + ] + } + } + }, + "types": { + "DataSig": { + "contents": [ + "byte", + 64 + ], + "tag": "Array" + }, + "NLocktime": { + "contents": [ + "byte", + 4 + ], + "tag": "Array" + }, + "NSequence": { + "contents": [ + "byte", + 4 + ], + "tag": "Array" + }, + "NVersion": { + "contents": [ + "byte", + 4 + ], + "tag": "Array" + }, + "Outpoint": { + "contents": [ + "byte", + 36 + ], + "tag": "Array" + }, + "Preimage": { + "contents": "byte", + "tag": "List" + }, + "PubKey": { + "contents": [ + "byte", + 33 + ], + "tag": "Array" + }, + "Ripemd160": { + "contents": [ + "byte", + 20 + ], + "tag": "Array" + }, + "ScriptCode": { + "contents": "byte", + "tag": "List" + }, + "Sha1": { + "contents": [ + "byte", + 16 + ], + "tag": "Array" + }, + "Sha256": { + "contents": [ + "byte", + 32 + ], + "tag": "Array" + }, + "Sig": { + "contents": [ + "byte", + 65 + ], + "tag": "Array" + }, + "Sighash": { + "contents": [ + "byte", + 4 + ], + "tag": "Array" + }, + "Time": "int", + "TimeSpan": "int", + "TxState": { + "contents": [ + "NVersion", + "Sha256", + "Sha256", + "Outpoint", + "ScriptCode", + "Value", + "NSequence", + "Sha256", + "NLocktime", + "Sighash" + ], + "tag": "Tuple" + }, + "Value": { + "contents": [ + "byte", + 8 + ], + "tag": "Array" + } + } +} diff --git a/contracts/WlotusPowRemint.spedn b/contracts/WlotusPowRemint.spedn new file mode 100644 index 0000000..fb92e2d --- /dev/null +++ b/contracts/WlotusPowRemint.spedn @@ -0,0 +1,52 @@ +// WLOTUS PoW remint covenant (eCash / XEC) +// Mist-style BIP143 preimage (eCash has no native introspection opcodes). +// `s` signs hash256(preimage) for CHECKSIG; `ds` must be toDataSig(s) so +// CHECKDATASIG(sha256(preimage)) verifies the same message. + +contract WlotusPowRemint( + [byte;32] tokenIdRev, + [byte;6] mintAtomsLe, + int difficultyLeadingZeroBytes +) { + challenge remint( + [byte;4] nonce, + Sig s, + DataSig ds, + PubKey minerPk, + [byte] preimage + ) { + verify checkSig(s, minerPk); + verify checkDataSig(ds, sha256(preimage), minerPk); + + [byte] solhash = hash256(preimage . nonce); + ([byte] work, _) = solhash @ difficultyLeadingZeroBytes; + verify bin2num(work) == 0; + + (_, [byte] tail40) = preimage @ (size(preimage) - 40); + ([byte] hashOutputs, _) = tail40 @ 32; + + // BIP143 trailer after scriptCode: value(8)+nSequence(4)+hashOutputs(32)+ + // nLockTime(4)+sighashType(4) = 52 bytes (not 56). + ([byte] head, _) = preimage @ (size(preimage) - 52); + (_, [byte] scriptCodePrefixed) = head @ 104; + (_, [byte] redeemScript) = scriptCodePrefixed @ 1; + + // Plain 0x00 is the empty push in Spedn; use num2bin(0, 1) for a 0x00 byte. + [byte] mintSection = + 0x534c5032 . + num2bin(0, 1) . + 0x04 . 0x4d494e54 . + tokenIdRev . + 0x01 . + mintAtomsLe . + 0x01; + + [byte] opReturnScript = 0x6a50 . num2bin(size(mintSection), 1) . mintSection; + + [byte] out0 = 0x0000000000000000 . num2bin(size(opReturnScript), 1) . opReturnScript; + [byte] out1 = 0x2202000000000000 . 0x19 . 0x76a914 . hash160(minerPk) . 0x88ac; + [byte] out2 = 0x2202000000000000 . 0x17 . 0xa914 . hash160(redeemScript) . 0x87; + + verify hash256(out0 . out1 . out2) == Sha256(hashOutputs); + } +} diff --git a/deployments/README.md b/deployments/README.md index 8519d4a..a33e902 100644 --- a/deployments/README.md +++ b/deployments/README.md @@ -4,7 +4,11 @@ On-chain deployment records for White Lotus test / production tokens. | File | Meaning | |------|---------| -| `mainnet-test-token.json` | Live **WLTEST** ALP genesis on eCash mainnet | -| `pending-funding.json` | (obsolete once funded) | +| `mainnet-pow-token.json` | Live **WLPOW** PoW-mineable token (use this) | +| `mainnet-last-remint.json` | Last successful PoW remint | +| `mainnet-test-token.json` | Custodial **WLTEST** (not for mining) | +| `mainnet-pow-token-v1-locked.json` | Broken covenant (size-56) — batons locked | +| `mainnet-pow-token-v2-locked.json` | Broken covenant (`0x00` push) — batons locked | +| `mainnet-pow-handoff.json` | Obsolete introspection handoff record | Private keys live only in `.env` (gitignored). Never commit `GENESIS_SK_HEX`. diff --git a/deployments/mainnet-last-remint.json b/deployments/mainnet-last-remint.json new file mode 100644 index 0000000..3d4cdee --- /dev/null +++ b/deployments/mainnet-last-remint.json @@ -0,0 +1,9 @@ +{ + "tokenId": "2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "txid": "3c37dd37aa846819af11dadba22afe8c707fa07ae9751f5147118dbd0eeef80a", + "powAttempts": 189, + "nonceHex": "bd000000", + "mintAtoms": "100000000", + "minedAt": "2026-07-17T04:29:15.120Z", + "explorer": "https://explorer.e.cash/tx/3c37dd37aa846819af11dadba22afe8c707fa07ae9751f5147118dbd0eeef80a" +} diff --git a/deployments/mainnet-pow-handoff.json b/deployments/mainnet-pow-handoff.json new file mode 100644 index 0000000..8734ded --- /dev/null +++ b/deployments/mainnet-pow-handoff.json @@ -0,0 +1,18 @@ +{ + "tokenId": "e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3", + "ticker": "WLTEST", + "mode": "pow", + "powAddress": "ecash:prhzqrpcqy4n0m09meyt5a309xggqv39ay6xjlhfn2", + "redeemScriptHex": "7c78ad6bc0c86bc0c954806c7c7e7c7eaa517f75010088c4538800cc008800cd356a5032534c503200044d494e54a3088b1e48d75881e666326e041029a1d949a9b2b6d942a646fb45dabd0644e60100e1f5050000018851cc022202886c76a90376a9147c7e0288ac7e51cd8852cc02220288c1a902a9147c7e01877e52cd8875", + "difficultyLeadingZeroBytes": 1, + "mintAtomsPerRemint": "100000000", + "handoffTxids": [ + "c02d4b45281d63e9547234c9e407b475063856ceb30a7c81921614488bb27884", + "01ce98d0657cee2e34aaa17f8e32e5e9db0199f39c66bc5c9cfb53973696b55f", + "7cdd8725948550d3536132c0e3c11892934f48fabc820906bfc6aac0993242ca", + "90430f531bfe7296006c93aad56eaa4b5e54935f210528261e9f14fa7367dcb1" + ], + "powBatonCount": 4, + "remainingCustodialBatons": 0, + "updatedAt": "2026-07-17T04:13:32.472Z" +} diff --git a/deployments/mainnet-pow-token-v1-locked.json b/deployments/mainnet-pow-token-v1-locked.json new file mode 100644 index 0000000..a16ef57 --- /dev/null +++ b/deployments/mainnet-pow-token-v1-locked.json @@ -0,0 +1,31 @@ +{ + "ticker": "WLPOW", + "name": "White Lotus PoW Test", + "tokenId": "1fea68e004f0c4330f164285bb993986abbf9b900152e6049a8e3c93a348e32d", + "mode": "pow", + "powAddress": "ecash:prhreyyrkpwrcmfu2d85nc4jevtecwhdxv5qcf3f7t", + "redeemScriptHex": "202de348a3933c8e9a04e65201909bbfab863999bb8542160f33c4f004e068ea1f0600e1f50500005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820138947f757601687f7776517f7704534c5032007e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "difficultyLeadingZeroBytes": 1, + "mintAtomsPerRemint": "100000000", + "initialMintAtoms": "1000000000000", + "powBatonCount": 4, + "genesisTxid": "1fea68e004f0c4330f164285bb993986abbf9b900152e6049a8e3c93a348e32d", + "handoffTxids": [ + "544758656463ba2b40e65ae89c2bbd4931805eaf999453e2e200f61a0eecbac0", + "932bd5b44501f45cd2e985ee4493a28e24a5cdc9bba5234ddfeecc8e1d04e04f", + "62eb407e2a027dc495ab1187681911c95b664ba5fad419788d1f3c9598315ef3", + "54f3139b8c52a0b41d1d52cfa6da66ef69b203c081364f03e9d00f0fd585c7d9" + ], + "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "createdAt": "2026-07-17T04:19:03.707Z", + "explorer": "https://explorer.e.cash/tx/1fea68e004f0c4330f164285bb993986abbf9b900152e6049a8e3c93a348e32d", + "cashtab": "https://cashtab.com/#/token/1fea68e004f0c4330f164285bb993986abbf9b900152e6049a8e3c93a348e32d", + "notes": [ + "PoW covenant is Spedn Mist-style (BIP143 preimage). eCash has no native introspection.", + "Prior WLTEST batons sent to introspection P2SH are permanently locked.", + "LOCKED: covenant used size(preimage)-56 instead of -52 when extracting redeemScript; hashOutputs can never match. Batons unspendable.", + "Superseded by fixed covenant redeploy via create-pow-token." + ], + "status": "locked" +} diff --git a/deployments/mainnet-pow-token-v2-locked.json b/deployments/mainnet-pow-token-v2-locked.json new file mode 100644 index 0000000..7592a4d --- /dev/null +++ b/deployments/mainnet-pow-token-v2-locked.json @@ -0,0 +1,31 @@ +{ + "ticker": "WLPOW", + "name": "White Lotus PoW Test", + "tokenId": "93a35619d079115ac7604044fa7e390cd67cd4d40d62528491d1008c1091ad38", + "mode": "pow", + "powAddress": "ecash:pzqhr4yuhk6a880t0nu8zr45lnyueqrgdgxjylryvm", + "redeemScriptHex": "2038ad91108c00d1918452620dd4d47cd60c397efa444060c75a1179d01956a3930600e1f50500005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820134947f757601687f7776517f7704534c5032007e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "difficultyLeadingZeroBytes": 1, + "mintAtomsPerRemint": "100000000", + "initialMintAtoms": "1000000000000", + "powBatonCount": 4, + "genesisTxid": "93a35619d079115ac7604044fa7e390cd67cd4d40d62528491d1008c1091ad38", + "handoffTxids": [ + "3c8288e9cde983fef38f323c39f5f5cc8cd1a8c0907f2b6a3df11f3f695d6b5b", + "459e35f82de1a3ed2bccda8c77cdaa4e662fbabbb88c8fe86e680a189450debb", + "5da5b7ffc5eb3e64c03cb010d3c38292dd16ed9c8e5a6a26b27f16185c0904fe", + "4d12cb5b1b8dd78bc5c680fbe6d4a3ea1472ab46fdd777603a32f775d0ad3574" + ], + "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "createdAt": "2026-07-17T04:27:01.361Z", + "explorer": "https://explorer.e.cash/tx/93a35619d079115ac7604044fa7e390cd67cd4d40d62528491d1008c1091ad38", + "cashtab": "https://cashtab.com/#/token/93a35619d079115ac7604044fa7e390cd67cd4d40d62528491d1008c1091ad38", + "notes": [ + "PoW covenant is Spedn Mist-style (BIP143 preimage). eCash has no native introspection.", + "Prior WLTEST introspection P2SH batons are permanently locked.", + "v1 WLPOW covenant (size-56 trailer bug) batons are locked; see mainnet-pow-token-v1-locked.json.", + "LOCKED: Spedn 0x00 compiled to empty push; mintSection missing ALP type byte. Superseded." + ], + "status": "locked" +} diff --git a/deployments/mainnet-pow-token.json b/deployments/mainnet-pow-token.json new file mode 100644 index 0000000..78a7784 --- /dev/null +++ b/deployments/mainnet-pow-token.json @@ -0,0 +1,30 @@ +{ + "ticker": "WLPOW", + "name": "White Lotus PoW Test", + "tokenId": "2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "mode": "pow", + "powAddress": "ecash:pz0k74f8nkytqh7ntcjhfaccc7wytjdj9ypy8f9z32", + "redeemScriptHex": "2046e578b954a633e6a8a3104c148e4367443f527d2c766d265fbe1fec6e105d2c0600e1f50500005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820134947f757601687f7776517f7704534c50320051807e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "difficultyLeadingZeroBytes": 1, + "mintAtomsPerRemint": "100000000", + "initialMintAtoms": "1000000000000", + "powBatonCount": 4, + "genesisTxid": "2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "handoffTxids": [ + "d793de20fe22f2419028801a82f8825c8411edc40cbd32ae3b11ea063612bf32", + "7083f662855c8cfbdde0d50459839375b96c889d1579623c17a42aa94314ba0c", + "e79fcf3537b6a32b412f1af75d915cd8ade74eaa4f08408a7cc9b743d5825893", + "5f947c502427c2c7c4de875a90f5fe39307cd650da33c45ddc2410ad8c804c8e" + ], + "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "createdAt": "2026-07-17T04:29:12.279Z", + "explorer": "https://explorer.e.cash/tx/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "cashtab": "https://cashtab.com/#/token/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "notes": [ + "PoW covenant is Spedn Mist-style (BIP143 preimage). eCash has no native introspection.", + "Prior WLTEST introspection P2SH batons are permanently locked.", + "v1 WLPOW (size-56 trailer) and v2 (0x00 empty-push mint bug) batons are locked.", + "See mainnet-pow-token-v1-locked.json / mainnet-pow-token-v2-locked.json." + ] +} diff --git a/deployments/pow-contract-v2.json b/deployments/pow-contract-v2.json new file mode 100644 index 0000000..e536f5f --- /dev/null +++ b/deployments/pow-contract-v2.json @@ -0,0 +1,8 @@ +{ + "tokenId": "e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3", + "powAddress": "ecash:pp5qv37ws3pm5pd22w7fd9z0mrnhcmuqmsnhwv3t6m", + "redeemScriptHex": "20a3088b1e48d75881e666326e041029a1d949a9b2b6d942a646fb45dabd0644e60600e1f50500005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820138947f757601687f7776517f7704534c5032007e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "redeemScriptLen": 231, + "mintAtoms": "100000000", + "difficultyLeadingZeroBytes": 1 +} \ No newline at end of file diff --git a/docs/STATUS.md b/docs/STATUS.md index 853ddb6..8ceeb66 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -2,9 +2,16 @@ Canonical home: **https://github.com/bcProFoundation/wlotus** -Scaffold was first drafted on a temporary orphan branch of `eminer` -(`cursor/wlotus-scaffold-d6bb`) while the Cursor GitHub App lacked push -access to this repo. That work is now landed here. +## Live mainnet + +| Token | Mode | Token ID | Mine? | +|-------|------|----------|-------| +| **WLPOW** | PoW covenant | `2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546` | **Yes** | +| WLTEST | Custodial | `e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3` | No | + +Proven PoW remint: `3c37dd37aa846819af11dadba22afe8c707fa07ae9751f5147118dbd0eeef80a` + +Details: [TEST_TOKEN.md](./TEST_TOKEN.md) ## Design sources @@ -15,13 +22,15 @@ access to this repo. That work is now landed here. | [ARCHITECTURE.md](./ARCHITECTURE.md) | Covenant / multi-baton flow | | [research/](./research/) | Feasibility notes from [eminer#1](https://github.com/bcProFoundation/eminer/pull/1) | -## Live +## Covenant notes (eCash) -- **WLTEST** mainnet: `e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3` - ([TEST_TOKEN.md](./TEST_TOKEN.md)) +- eCash has **no** native introspection opcodes (`OP_OUTPUTBYTECODE`, etc.). +- PoW remint uses a **Spedn Mist-style BIP143 preimage** covenant (`contracts/WlotusPowRemint.spedn`). +- Unlock: PoW nonce + Schnorr `Sig` + `DataSig` (toDataSig) + miner pubkey + preimage. +- Difficulty for dogfood: **1 leading zero byte** on `hash256(preimage ‖ nonce)`. ## Next ops -1. Harden `contracts/WlotusRemint.cash` + Chronik miner wiring -2. Raise PoW from 1 → higher when targeting ~$0.01/token (`WLOTUS`) -3. Temple / burn UI in a separate app repo +1. Raise PoW from 1 → higher when targeting ~$0.01/token (`WLOTUS`) +2. Temple / burn UI in a separate app repo +3. Optional: multi-baton concurrent miner diff --git a/docs/TEST_TOKEN.md b/docs/TEST_TOKEN.md index a120d16..5b94626 100644 --- a/docs/TEST_TOKEN.md +++ b/docs/TEST_TOKEN.md @@ -1,20 +1,46 @@ -# Test token deployment (mainnet) +# Test token deployments (mainnet) -## Live token +## Which token for mining? + +| Token | Mode | Mineable? | +|-------|------|-----------| +| **WLPOW** | PoW covenant (Spedn BIP143 preimage) | **Yes** — use this | +| WLTEST | Custodial genesis wallet | No (batons not in PoW covenant) | + +## Live PoW token (`WLPOW`) — use for mining tests + +| Field | Value | +|-------|-------| +| Ticker | `WLPOW` | +| Name | White Lotus PoW Test | +| Token ID | `2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546` | +| Mode | **PoW** (not custodial) | +| PoW P2SH | `ecash:pz0k74f8nkytqh7ntcjhfaccc7wytjdj9ypy8f9z32` | +| Decimals | 6 | +| Mint atoms / remint | 100,000,000 (100 WLPOW) | +| PoW leading zero bytes | 1 | +| Batons | 4 (locked in PoW P2SH) | +| Proven remint | `3c37dd37aa846819af11dadba22afe8c707fa07ae9751f5147118dbd0eeef80a` | + +- Explorer: https://explorer.e.cash/tx/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546 +- Cashtab: https://cashtab.com/#/token/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546 +- Record: [`deployments/mainnet-pow-token.json`](../deployments/mainnet-pow-token.json) +- Last remint: [`deployments/mainnet-last-remint.json`](../deployments/mainnet-last-remint.json) + +```bash +# .env must contain GENESIS_SK_HEX (same wallet that funded genesis) +npm run mine-once +``` + +## Custodial token (`WLTEST`) — not for PoW mining | Field | Value | |-------|-------| | Ticker | `WLTEST` | -| Name | White Lotus Test | | Token ID | `e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3` | -| Decimals | 6 | -| Initial mint | 1,000,000 WLTEST | -| Mint batons | 4 (custodial on genesis wallet) | -| PoW leading zero bytes | 1 (~$0.000001/token target) | -| Genesis address | `ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7` | +| Mode | **Custodial** | +| Mint batons | Genesis wallet (some later sent to broken introspection P2SH → locked) | -- Explorer: https://explorer.e.cash/tx/e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3 -- Cashtab: https://cashtab.com/#/token/e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3 - Record: [`deployments/mainnet-test-token.json`](../deployments/mainnet-test-token.json) ## Goals @@ -23,8 +49,7 @@ |------|----------|-------| | Target price | **~$0.000001 / token** | **~$0.01 / token** | | PoW leading zero bytes | `1` | raise (2–3+) | -| Ticker | `WLTEST` | `WLOTUS` | -| Batons | `4` custodial | PoW covenant + possibly more batons | +| Ticker | `WLPOW` / `WLTEST` | `WLOTUS` | ## Chronik @@ -34,10 +59,15 @@ https://xec.paybutton.org https://chronik.pay2stay.com/xec ``` -## Recreate (new token) +## Recreate PoW token ```bash -npm run new-wallet -- --force -# fund genesis address with ≥ 200 XEC -npm run create-test-token +npm run create-pow-token # genesis + handoff batons to Spedn PoW P2SH +npm run mine-once # one remint ``` + +## Locked predecessors (do not use) + +- Introspection P2SH handoff (eCash has no native introspection opcodes) +- `mainnet-pow-token-v1-locked.json` — `size-56` trailer bug +- `mainnet-pow-token-v2-locked.json` — Spedn `0x00` empty-push mint bug diff --git a/package-lock.json b/package-lock.json index 016d307..430e50f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,11 @@ "version": "0.1.0", "license": "MIT", "dependencies": { + "@spedn/rts": "^5.0.0", + "@spedn/rts-bchjs": "^5.0.0", + "@spedn/sdk": "^5.0.0", "chronik-client": "^4.3.0", - "dotenv": "^16.6.1", + "dotenv": "^16.4.7", "ecash-lib": "^4.13.0", "ecash-wallet": "^6.1.0" }, @@ -522,6 +525,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@chris.troutner/bip32-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@chris.troutner/bip32-utils/-/bip32-utils-1.0.5.tgz", + "integrity": "sha512-pa9dh5VpPmfol1bdLy+FyqONmxlf/QH6Q01a57OP6C9gTVOZM1Rt0kCLXxXKC6e2AnNIrXpYN1UtlyBm+r6P0g==", + "license": "MIT", + "dependencies": { + "keccak": "^3.0.1", + "tape": "*" + }, + "engines": { + "node": ">=10.15.1" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", @@ -1333,6 +1349,48 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@ljharb/now": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ljharb/now/-/now-1.0.1.tgz", + "integrity": "sha512-yRQ3B8l2v4vTLQ2l+4kBu6EsXaX7czuLB7fvUz0vkHHziHje75R2t/0Mm/vIo31tlZVCEvCoXHkNKW+ugv3uSA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@ljharb/resumer": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@ljharb/resumer/-/resumer-0.1.3.tgz", + "integrity": "sha512-d+tsDgfkj9X5QTriqM4lKesCkMMJC3IrbPKHvayP00ELx2axdXvDfWkqjxrLXIzGcQzmj7VAUT1wopqARTvafw==", + "license": "MIT", + "dependencies": { + "@ljharb/through": "^2.3.13", + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@ljharb/through": { + "version": "2.3.14", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.14.tgz", + "integrity": "sha512-ajBvlKpWucBB17FuQYUShqpqy8GRgYEpJW0vWJbUu1CV9lWyrDCapy0lScU8T8Z6qn49sSwJB3+M+evYIdGg+A==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -1390,6 +1448,138 @@ "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", "license": "BSD-3-Clause" }, + "node_modules/@psf/bch-js": { + "version": "6.8.3", + "resolved": "https://registry.npmjs.org/@psf/bch-js/-/bch-js-6.8.3.tgz", + "integrity": "sha512-LhbfRg9c5GFddNyEHvZ7QWB61452hZ8xygaZ8JJHw8HJBMvuURwaHItv971A6LvO8nl4Fcf9GPTJ5YIggnGhVQ==", + "license": "MIT", + "dependencies": { + "@chris.troutner/bip32-utils": "1.0.5", + "@psf/bip21": "2.0.1", + "@psf/bitcoincash-ops": "2.0.0", + "@psf/bitcoincashjs-lib": "4.0.3", + "@psf/coininfo": "4.0.0", + "axios": "1.12.2", + "bc-bip68": "1.0.5", + "bchaddrjs-slp": "0.2.5", + "bigi": "1.4.2", + "bignumber.js": "9.0.0", + "bip-schnorr": "0.3.0", + "bip38": "2.0.2", + "bip39": "3.0.2", + "bip66": "1.1.5", + "bitcoinjs-message": "2.0.0", + "bs58": "4.0.1", + "ecashaddrjs": "1.0.7", + "ini": "1.3.8", + "randombytes": "2.0.6", + "safe-buffer": "5.1.2", + "satoshi-bitcoin": "1.0.4", + "slp-mdm": "0.0.6", + "slp-parser": "0.0.4", + "wif": "2.0.6" + } + }, + "node_modules/@psf/bch-js/node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/@psf/bch-js/node_modules/big-integer": { + "version": "1.6.36", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", + "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/@psf/bch-js/node_modules/ecashaddrjs": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ecashaddrjs/-/ecashaddrjs-1.0.7.tgz", + "integrity": "sha512-KsvHYLlYtLr/GBkEPiwwQDIDBzqRx61qC34n1puHKOjVE4Uwg3syHccjFCqNynLa6T6xI0Rd7ByCRUJcuJcoIw==", + "license": "MIT", + "dependencies": { + "big-integer": "1.6.36" + } + }, + "node_modules/@psf/bch-js/node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/@psf/bch-js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/@psf/bip21": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@psf/bip21/-/bip21-2.0.1.tgz", + "integrity": "sha512-U9c8xBV31n+D7qxOPBO0vQ015DNvKskWCUbVgoMfH5AUNHLYrSDWIrCx4P7v9etfdu6LpPdsYr53KDSAIk0b7Q==", + "license": "ISC", + "dependencies": { + "qs": "^6.3.0" + } + }, + "node_modules/@psf/bitcoincash-ops": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@psf/bitcoincash-ops/-/bitcoincash-ops-2.0.0.tgz", + "integrity": "sha512-M3PWqRpeJq6rli2NqWGbas76z9TrdGOmNuDFACBWBMctPucEAsFQY2AmyFHRSa7hEwythwvrPh9AG/n6ehmEog==", + "license": "MIT" + }, + "node_modules/@psf/bitcoincashjs-lib": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@psf/bitcoincashjs-lib/-/bitcoincashjs-lib-4.0.3.tgz", + "integrity": "sha512-sJYi7jYUqR7S+Z8TjN3W/5Lcju7xcIBxYLhIEpnOF+jR9kMt0ftpVjQBt8vVsJZUD8ArL9bf59oDETjdOUcdGQ==", + "license": "MIT", + "dependencies": { + "@psf/bitcoincash-ops": "^2.0.0", + "@psf/pushdata-bitcoin": "^1.2.2", + "bech32": "^1.1.2", + "bigi": "^1.4.0", + "bip66": "^1.1.0", + "bs58check": "^2.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.3", + "ecurve": "^1.0.0", + "merkle-lib": "^2.0.10", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "typeforce": "^1.18.0", + "varuint-bitcoin": "^1.0.4", + "wif": "^2.0.1" + }, + "engines": { + "node": ">=10.15.1" + } + }, + "node_modules/@psf/coininfo": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@psf/coininfo/-/coininfo-4.0.0.tgz", + "integrity": "sha512-RwBc09790kbaOt8uZJMyvLqf1UziTd20FXu78bM8bMlkClnZQTJyNDdLCsFSBkJQYAJtGMkjdQ/o3/UaSC7c2Q==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, + "node_modules/@psf/pushdata-bitcoin": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@psf/pushdata-bitcoin/-/pushdata-bitcoin-1.2.2.tgz", + "integrity": "sha512-e1qkZLJFU6Ldg7TMBgSkiR5U1NfpRgSIr2ppk8BeED/Q9wUc9DEVAjXfPMD65xgXdqnlyFEtLbpPMWwyydMVUQ==", + "license": "MIT", + "dependencies": { + "@psf/bitcoincash-ops": "^2.0.0" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.12", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", @@ -1417,6 +1607,50 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@spedn/rts": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@spedn/rts/-/rts-5.0.0.tgz", + "integrity": "sha512-ag5s35Af4ZhH9d/jOAv4+VzoC6u1qFVVxDMP4QYT19Ope7yTaaXZpF5J1Gcn2jtphzdUoKoHyLmJsXR8EhISKA==", + "funding": [ + "https://spedn.pl/#support", + "ecash:qp8x5wakcts248drk5apn4k09a53qclcevjayr77xh", + "bitcoincash:qrc2jhalczuka8q3dvk0g8mnkqx79wxp9gvvqvg7qt" + ], + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "varuint-bitcoin": "1.1.2" + } + }, + "node_modules/@spedn/rts-bchjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@spedn/rts-bchjs/-/rts-bchjs-5.0.0.tgz", + "integrity": "sha512-ry9NUMQ9jsa3GEaFDWYOPH1eHtpIpzDky5S6D9WxflWv0Ow9YpJkKinsR4CuJ51/+fvDsY/Cos3WJE26LsDdww==", + "funding": [ + "https://spedn.pl/#support", + "ecash:qp8x5wakcts248drk5apn4k09a53qclcevjayr77xh", + "bitcoincash:qrc2jhalczuka8q3dvk0g8mnkqx79wxp9gvvqvg7qt" + ], + "license": "MIT", + "dependencies": { + "@psf/bch-js": "^6.7.4", + "@spedn/rts": "^5.0.0" + } + }, + "node_modules/@spedn/sdk": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@spedn/sdk/-/sdk-5.0.0.tgz", + "integrity": "sha512-QBMPzKTWmTYNk+EklX7nHILFfWu+MUCQOTKTIBQHo1+dVpqrDf5NxxhuLC+S7OkWTWW8mg1XGS6peDOf7jRmwg==", + "funding": [ + "https://spedn.pl/#support", + "ecash:qp8x5wakcts248drk5apn4k09a53qclcevjayr77xh", + "bitcoincash:qrc2jhalczuka8q3dvk0g8mnkqx79wxp9gvvqvg7qt" + ], + "license": "MIT", + "dependencies": { + "@spedn/rts": "^5.0.0" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1630,12 +1864,110 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.every": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/array.prototype.every/-/array.prototype.every-1.1.7.tgz", + "integrity": "sha512-BIP72rKvrKd08ptbetLb4qvrlGjkv30yOKgKcTtOIbHyQt3shr/jyOzdApiCOh3LPYrpJo5M6i0zmVldOF2pUw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "is-string": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axios": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz", @@ -1774,9 +2106,17 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/baseline-browser-mapping": { "version": "2.10.43", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", @@ -1790,11 +2130,157 @@ "node": ">=6.0.0" } }, + "node_modules/bc-bip68": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bc-bip68/-/bc-bip68-1.0.5.tgz", + "integrity": "sha512-GzaMlN7pNthrY5BhReVhnfr4Ixx+GUSfyNRHYh0QiMUF0d0+0YaD8MpEdv6AjFBksg/zlqL1fVCBBm6PpTt2Rg==", + "license": "ISC", + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/bchaddrjs-slp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/bchaddrjs-slp/-/bchaddrjs-slp-0.2.5.tgz", + "integrity": "sha512-33flmPcqMFswerKu7477DSUNMVMQR3tHDk3lvbmsdkEva+TxVGGWWE/p5Lqx9M/8t3vkbe7fzmVhj4QhChcCyA==", + "license": "MIT", + "dependencies": { + "bs58check": "^2.1.2", + "cashaddrjs-slp": "^0.2.11" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "license": "MIT" + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bigi": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz", + "integrity": "sha512-ddkU+dFIuEIW8lE7ZwdIAf2UPoM90eaprg5m3YXAVVTmKlqV/9BX4A2M8BOK2yOq6/VgZFVhK6QAxJebhlbhzw==" + }, + "node_modules/bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bip-schnorr": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/bip-schnorr/-/bip-schnorr-0.3.0.tgz", + "integrity": "sha512-Sc1Hn2+1n+okPEW8G+JLjeaM12dsUOwr+oFlMDSKR9wYwNGMw0alskeBIHTmXxBxMZSWKhCW7PwKQVDyGmnaVg==", + "license": "MIT", + "dependencies": { + "ecurve": "^1.0.6", + "js-sha256": "^0.9.0", + "random-bytes": "^1.0.0", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bip38": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bip38/-/bip38-2.0.2.tgz", + "integrity": "sha512-22KDak0RDyghFbR0Si7wyq9IgY423YzGYzWLpGeofH3DaolOQqjD3mNN08eFoubKlbyclOQKFwtONMv2SD9V3A==", + "dependencies": { + "bigi": "^1.2.0", + "browserify-aes": "^1.0.1", + "bs58check": "<3.0.0", + "buffer-xor": "^1.0.2", + "create-hash": "^1.1.1", + "ecurve": "^1.0.0", + "scryptsy": "^2.0.0" + } + }, + "node_modules/bip39": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", + "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", + "license": "ISC", + "dependencies": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + } + }, + "node_modules/bip39/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==", + "license": "MIT" + }, + "node_modules/bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bitcoinjs-message": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bitcoinjs-message/-/bitcoinjs-message-2.0.0.tgz", + "integrity": "sha512-H5pJC7/eSqVjREiEOZ4jifX+7zXYP3Y28GIOIqg9hrgE7Vj8Eva9+HnVqnxwA1rJPOwZKuw0vo6k0UxgVc6q1A==", + "license": "MIT", + "dependencies": { + "bs58check": "^2.0.2", + "buffer-equals": "^1.0.3", + "create-hash": "^1.1.2", + "secp256k1": "^3.0.1", + "varuint-bitcoin": "^1.0.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/bn.js": { + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", + "license": "MIT" + }, "node_modules/brace-expansion": { "version": "1.1.16", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -1814,6 +2300,26 @@ "node": ">=8" } }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "license": "MIT" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/browserslist": { "version": "4.28.6", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", @@ -1861,6 +2367,26 @@ "node": ">= 6" } }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -1871,6 +2397,15 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer-equals": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz", + "integrity": "sha512-99MsCq0j5+RhubVEtKQgKaD6EM+UP3xJgIvQqwJ3SOLDUekzxMX1ylXBng+Wa2sh7mGT0W6RUly8ojjr1Tt6nA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1878,6 +2413,30 @@ "dev": true, "license": "MIT" }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -1891,10 +2450,26 @@ "node": ">= 0.4" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { @@ -1932,6 +2507,15 @@ ], "license": "CC-BY-4.0" }, + "node_modules/cashaddrjs-slp": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/cashaddrjs-slp/-/cashaddrjs-slp-0.2.12.tgz", + "integrity": "sha512-n2TTIuW6vZZxYvjvsUAA+wOM0Zkj+3RRKUtDC1XSu4Ic4XVr0yFJkl1bzQkHWda7nkVT51sxjZneygz7D0SyrQ==", + "license": "MIT", + "dependencies": { + "big-integer": "^1.6.34" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1990,6 +2574,20 @@ "node": ">=8" } }, + "node_modules/cipher-base": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", + "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cjs-module-lexer": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", @@ -2066,7 +2664,6 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, "license": "MIT" }, "node_modules/convert-source-map": { @@ -2076,6 +2673,39 @@ "dev": true, "license": "MIT" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -2113,6 +2743,57 @@ "node": ">= 8" } }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -2145,6 +2826,38 @@ } } }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -2155,6 +2868,49 @@ "node": ">=0.10.0" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2196,6 +2952,32 @@ "url": "https://dotenvx.com" } }, + "node_modules/dotignore": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", + "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.4" + }, + "bin": { + "ignored": "bin/ignored" + } + }, + "node_modules/drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==", + "license": "MIT", + "dependencies": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2236,6 +3018,16 @@ "integrity": "sha512-EvK1V4D3+nIEoD0ggy/b0F4lW39/72R9aOs/scm6kxMVuXu16btc+H74eQv7okNfXaQWKgolEekZkQ6wfcMMLw==", "license": "MIT" }, + "node_modules/ecurve": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/ecurve/-/ecurve-1.0.6.tgz", + "integrity": "sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w==", + "license": "MIT", + "dependencies": { + "bigi": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.392", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.392.tgz", @@ -2243,6 +3035,21 @@ "dev": true, "license": "ISC" }, + "node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", @@ -2273,6 +3080,92 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract-get": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", + "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "is-callable": "^1.2.7", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -2291,6 +3184,26 @@ "node": ">= 0.4" } }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-object-atoms": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", @@ -2318,6 +3231,38 @@ "node": ">= 0.4" } }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz", + "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==", + "license": "MIT", + "dependencies": { + "es-abstract-get": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "is-callable": "^1.2.7", + "is-date-object": "^1.1.0", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/esbuild": { "version": "0.28.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", @@ -2394,6 +3339,16 @@ "node": ">=4" } }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -2461,6 +3416,12 @@ "bser": "2.1.1" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -2508,6 +3469,21 @@ } } }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/form-data": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", @@ -2528,7 +3504,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -2555,6 +3530,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function.prototype.name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", + "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "is-callable": "^1.2.7", + "is-document.all": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2603,7 +3619,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -2635,12 +3650,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -2657,9 +3688,25 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { @@ -2698,6 +3745,35 @@ "uglify-js": "^3.1.4" } }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-dynamic-import": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.1.1.tgz", + "integrity": "sha512-DuTCn6K/RW8S27npDMumGKsjG6HE7MxzedZka5tJP+9dqfxks+UMqKBmeCijHtIhsBEZPlbMg0qMHi2nKYVtKQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2708,6 +3784,33 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -2735,6 +3838,73 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hash-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", + "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/hash-base/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hash-base/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/hash-base/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/hash-base/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, "node_modules/hasown": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", @@ -2747,6 +3917,17 @@ "node": ">= 0.4" } }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -2812,7 +3993,6 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -2823,9 +4003,61 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, "license": "ISC" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2833,11 +4065,72 @@ "dev": true, "license": "MIT" }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.3" @@ -2849,6 +4142,69 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-document.all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", + "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2869,6 +4225,49 @@ "node": ">=6" } }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2879,6 +4278,67 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2892,6 +4352,103 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3588,6 +5145,12 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", + "license": "MIT" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3642,6 +5205,21 @@ "node": ">=6" } }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -3682,6 +5260,12 @@ "node": ">=8" } }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -3760,6 +5344,17 @@ "node": ">= 0.4" } }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3767,6 +5362,12 @@ "dev": true, "license": "MIT" }, + "node_modules/merkle-lib": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/merkle-lib/-/merkle-lib-2.0.10.tgz", + "integrity": "sha512-XrNQvUbn1DL5hKNe46Ccs+Tu3/PYOlrcZILuGUhb95oKBPjc/nmIC8D462PQkipVDGKRvwhn+QFg2cCdIvmDJA==", + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -3812,11 +5413,22 @@ "node": ">=6" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "license": "MIT" + }, "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -3829,18 +5441,45 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mock-property": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/mock-property/-/mock-property-1.1.2.tgz", + "integrity": "sha512-Rw0vY0wBdNtm3sbANVMDUgO5Htew9xotKoqcdK/a4rW8jf5KEl6MAWGMBhjKng6gpPjX8SmO8f+65ssnxNroTw==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "isarray": "^2.0.5", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/nan": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.28.0.tgz", + "integrity": "sha512-fTsDz99OTq2sVePhGdp4qQhggZFtKr64ZNVyVajRKtMOkJxYekplBh577PiJB12v/D3s2E5cGtOI45LWp6rnLQ==", + "license": "MIT" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3855,6 +5494,41 @@ "dev": true, "license": "MIT" }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "license": "MIT" + }, + "node_modules/node-exports-info": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz", + "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==", + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -3895,11 +5569,82 @@ "node": ">=8" } }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -3921,6 +5666,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4009,7 +5771,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4029,9 +5790,25 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, "license": "MIT" }, + "node_modules/pbkdf2": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.6.tgz", + "integrity": "sha512-BT6eelPB1EyGHo8pC0o9Bl6k6SYVhKO1jEbd3lcTrtr7XHdjP8BW1YpfCV3G9Kwkxgattk+S5q2/RvuttCsS1g==", + "license": "MIT", + "dependencies": { + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "ripemd160": "^2.0.3", + "safe-buffer": "^5.2.1", + "sha.js": "^2.4.12", + "to-buffer": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -4075,6 +5852,15 @@ "node": ">=8" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -4103,6 +5889,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -4172,6 +5964,40 @@ ], "license": "MIT" }, + "node_modules/qs": { + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -4179,6 +6005,62 @@ "dev": true, "license": "MIT" }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4244,16 +6126,201 @@ "node": ">=10" } }, + "node_modules/ripemd160": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", + "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", + "license": "MIT", + "dependencies": { + "hash-base": "^3.1.2", + "inherits": "^2.0.4" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/satoshi-bitcoin": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/satoshi-bitcoin/-/satoshi-bitcoin-1.0.4.tgz", + "integrity": "sha512-YuHOmw5wsz6wuHIQdsz5b2cgtuKtV/jEcZ4NGmWN5tM/gz5T9Q+DSuLlnuf5BP/jsQWgR0ofmY4f8Dm6JnqSug==", + "license": "MIT", + "dependencies": { + "big.js": "^3.1.3" + } + }, + "node_modules/scryptsy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", + "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==", + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.1.tgz", + "integrity": "sha512-tArjQw2P0RTdY7QmkNehgp6TVvQXq6ulIhxv8gaH6YubKG/wxxAoNKcbuXjDhybbc+b2Ihc7e0xxiGN744UIiQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.5.7", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4277,6 +6344,78 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -4301,6 +6440,24 @@ "node": ">=8" } }, + "node_modules/slp-mdm": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/slp-mdm/-/slp-mdm-0.0.6.tgz", + "integrity": "sha512-fbjlIg/o8OtzgK2JydC6POJp3Qup/rLgy4yB5hoLgxWRlERyJyE29ScwS3r9TTwPxe12qK55pyivAdNOZZXL0A==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/slp-parser": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slp-parser/-/slp-parser-0.0.4.tgz", + "integrity": "sha512-AvbslJumkzGfMGWNvuE2pWx2nyHEk/VgQ7l119kDKIFRTuRUWOkyOULLauw5laGRQsBRThg6NCx/TsR3grX6GA==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -4342,6 +6499,28 @@ "node": ">=10" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -4371,6 +6550,63 @@ "node": ">=8" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4434,7 +6670,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4443,6 +6678,68 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tape": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/tape/-/tape-5.10.2.tgz", + "integrity": "sha512-MfhVVAWa834kfYL4KgrqHblWfwkjaQvfaQhAX/bBTNQsK8oJ4ztpUe7jiemR2Vegw4pYwpnQMy51MhEmRzbbsg==", + "license": "MIT", + "dependencies": { + "@ljharb/now": "^1.0.1", + "@ljharb/resumer": "^0.1.3", + "@ljharb/through": "^2.3.14", + "array.prototype.every": "^1.1.7", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "deep-equal": "^2.2.3", + "defined": "^1.0.1", + "dotignore": "^0.1.2", + "es-object-atoms": "^1.1.2", + "for-each": "^0.3.5", + "get-package-type": "^0.1.0", + "glob": "^7.2.3", + "has-dynamic-import": "^2.1.1", + "hasown": "^2.0.4", + "inherits": "^2.0.4", + "is-regex": "^1.2.1", + "minimist": "^1.2.8", + "mock-property": "^1.1.0", + "object-inspect": "^1.13.4", + "object-is": "^1.1.6", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "resolve": "^2.0.0-next.7", + "string.prototype.trim": "^1.2.11" + }, + "bin": { + "tape": "bin/tape" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tape/node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -4465,6 +6762,20 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4599,6 +6910,86 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", + "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "possible-typed-array-names": "^1.1.0", + "reflect.getprototypeof": "^1.0.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typeforce": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", + "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==", + "license": "MIT" + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -4627,6 +7018,24 @@ "node": ">=0.8.0" } }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -4664,6 +7073,12 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -4679,6 +7094,15 @@ "node": ">=10.12.0" } }, + "node_modules/varuint-bitcoin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", + "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -4705,6 +7129,100 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wif": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", + "integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==", + "license": "MIT", + "dependencies": { + "bs58check": "<3.0.0" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -4734,7 +7252,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { diff --git a/package.json b/package.json index 6c85b7a..5ff8831 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,17 @@ "lint": "tsc -p tsconfig.json --noEmit", "new-wallet": "tsx scripts/new-wallet.ts", "create-test-token": "tsx scripts/create-test-token.ts", - "wait-create-test-token": "tsx scripts/wait-for-funding-and-create.ts" + "wait-create-test-token": "tsx scripts/wait-for-funding-and-create.ts", + "mine-once": "tsx scripts/mine-once.ts", + "create-pow-token": "tsx scripts/create-pow-token.ts" }, "engines": { "node": ">=20" }, "dependencies": { + "@spedn/rts": "^5.0.0", + "@spedn/rts-bchjs": "^5.0.0", + "@spedn/sdk": "^5.0.0", "chronik-client": "^4.3.0", "dotenv": "^16.4.7", "ecash-lib": "^4.13.0", diff --git a/scripts/create-pow-token.ts b/scripts/create-pow-token.ts new file mode 100644 index 0000000..045a1e2 --- /dev/null +++ b/scripts/create-pow-token.ts @@ -0,0 +1,144 @@ +#!/usr/bin/env tsx +/** + * Create a NEW PoW-mineable ALP test token and lock batons to the Spedn covenant. + * + * Note: The earlier introspection-based handoff permanently locked 4 WLTEST batons + * (eCash has no OP_OUTPUTBYTECODE etc.). This script creates a fresh token. + */ +import { resolve } from 'node:path'; +import { writeFileSync, mkdirSync } from 'node:fs'; +import { config as loadEnv } from 'dotenv'; +import { Wallet } from 'ecash-wallet'; +import { + ALP_TOKEN_TYPE_STANDARD, + DEFAULT_DUST_SATS, + fromHex, + payment, + toHex, +} from 'ecash-lib'; +import { createChronik } from '../src/network/createChronik.js'; +import { broadcastAlpGenesis } from '../src/genesis/broadcastGenesis.js'; +import { createPowRemintContract } from '../src/covenant/powRemintScript.js'; +import { + BASE_MINT_ATOMS, + POW_LEADING_ZERO_BYTES, + TOKEN_DECIMALS, + TOKEN_URL, +} from '../src/params/consensus.js'; +import { + TEST_INITIAL_MINT_ATOMS, + TEST_POW_BATON_COUNT, +} from '../src/params/testEconomics.js'; + +loadEnv({ path: resolve(process.cwd(), '.env') }); + +async function main(): Promise { + const skHex = process.env.GENESIS_SK_HEX?.trim(); + if (!skHex || !/^[0-9a-fA-F]{64}$/.test(skHex)) { + throw new Error('GENESIS_SK_HEX missing'); + } + + const chronik = await createChronik('closest'); + const wallet = Wallet.fromSk(fromHex(skHex), chronik); + await wallet.sync(); + + console.log( + JSON.stringify( + { + address: wallet.address, + balanceXec: Number(wallet.balanceSats) / 100, + }, + null, + 2, + ), + ); + + // 1) Genesis custodial batons (tokenId = txid) + const genesis = await broadcastAlpGenesis(wallet, { + ticker: 'WLPOW', + name: 'White Lotus PoW Test', + url: TOKEN_URL, + decimals: TOKEN_DECIMALS, + initialMintAtoms: TEST_INITIAL_MINT_ATOMS, + powBatonCount: TEST_POW_BATON_COUNT, + }); + console.log('Genesis', genesis.tokenId); + + // 2) Build covenant for this tokenId + const contract = await createPowRemintContract({ + tokenId: genesis.tokenId, + mintAtoms: BASE_MINT_ATOMS, + difficultyLeadingZeroBytes: POW_LEADING_ZERO_BYTES, + }); + console.log('PoW address', contract.address); + + // 3) Handoff each baton to P2SH + const handoffTxids: string[] = []; + for (let i = 0; i < TEST_POW_BATON_COUNT; i++) { + await wallet.sync(); + const action: payment.Action = { + outputs: [ + { sats: 0n }, + { + sats: DEFAULT_DUST_SATS, + script: contract.p2shScript, + tokenId: genesis.tokenId, + atoms: 0n, + isMintBaton: true, + }, + ], + tokenActions: [ + { + type: 'MINT', + tokenId: genesis.tokenId, + tokenType: ALP_TOKEN_TYPE_STANDARD, + }, + ], + }; + const resp = await wallet.action(action).build().broadcast(); + if (!resp.success || !resp.broadcasted?.length) { + throw new Error(`Handoff ${i} failed: ${JSON.stringify(resp)}`); + } + handoffTxids.push(resp.broadcasted[0]); + console.log(`Handoff ${i + 1}/${TEST_POW_BATON_COUNT}: ${resp.broadcasted[0]}`); + } + + const record = { + ticker: 'WLPOW', + name: 'White Lotus PoW Test', + tokenId: genesis.tokenId, + mode: 'pow', + powAddress: contract.address, + redeemScriptHex: contract.redeemHex, + difficultyLeadingZeroBytes: POW_LEADING_ZERO_BYTES, + mintAtomsPerRemint: BASE_MINT_ATOMS.toString(), + initialMintAtoms: TEST_INITIAL_MINT_ATOMS.toString(), + powBatonCount: TEST_POW_BATON_COUNT, + genesisTxid: genesis.tokenId, + handoffTxids, + authPubkey: toHex(wallet.pk), + genesisAddress: wallet.address, + createdAt: new Date().toISOString(), + explorer: `https://explorer.e.cash/tx/${genesis.tokenId}`, + cashtab: `https://cashtab.com/#/token/${genesis.tokenId}`, + notes: [ + 'PoW covenant is Spedn Mist-style (BIP143 preimage). eCash has no native introspection.', + 'Prior WLTEST introspection P2SH batons are permanently locked.', + 'v1 WLPOW (size-56 trailer) and v2 (0x00 empty-push mint bug) batons are locked.', + 'See mainnet-pow-token-v1-locked.json / mainnet-pow-token-v2-locked.json.', + ], + }; + + mkdirSync(resolve(process.cwd(), 'deployments'), { recursive: true }); + writeFileSync( + resolve(process.cwd(), 'deployments/mainnet-pow-token.json'), + `${JSON.stringify(record, null, 2)}\n`, + ); + console.log('\nPoW token ready'); + console.log(JSON.stringify(record, null, 2)); +} + +main().catch(err => { + console.error(err instanceof Error ? err.stack ?? err.message : err); + process.exit(1); +}); diff --git a/scripts/mine-once.ts b/scripts/mine-once.ts new file mode 100644 index 0000000..4c6b69b --- /dev/null +++ b/scripts/mine-once.ts @@ -0,0 +1,133 @@ +#!/usr/bin/env tsx +/** + * Mine one PoW remint against WLPOW batons in the Spedn covenant. + */ +import { resolve } from 'node:path'; +import { readFileSync, writeFileSync, existsSync } from 'node:fs'; +import { config as loadEnv } from 'dotenv'; +import { Wallet } from 'ecash-wallet'; +import { fromHex, toHex } from 'ecash-lib'; +import { createChronik } from '../src/network/createChronik.js'; +import { + buildMinedRemintTx, + contractForToken, + minerBanner, +} from '../src/miner/remint.js'; + +loadEnv({ path: resolve(process.cwd(), '.env') }); + +async function main(): Promise { + console.log(minerBanner()); + const skHex = process.env.GENESIS_SK_HEX?.trim(); + if (!skHex || !/^[0-9a-fA-F]{64}$/.test(skHex)) { + throw new Error('GENESIS_SK_HEX missing'); + } + + const depPath = resolve(process.cwd(), 'deployments/mainnet-pow-token.json'); + if (!existsSync(depPath)) { + throw new Error('Missing deployments/mainnet-pow-token.json — run npm run create-pow-token'); + } + const dep = JSON.parse(readFileSync(depPath, 'utf8')); + const tokenId = process.env.TOKEN_ID?.trim() || dep.tokenId; + + const chronik = await createChronik('closest'); + const wallet = Wallet.fromSk(fromHex(skHex), chronik); + await wallet.sync(); + const contract = await contractForToken(tokenId); + + if (dep.powAddress && dep.powAddress !== contract.address) { + throw new Error( + `Address mismatch: dep=${dep.powAddress} computed=${contract.address}`, + ); + } + + const scriptHex = toHex(contract.scriptHash); + const scriptUtxos = await chronik.script('p2sh', scriptHex).utxos(); + const list = Array.isArray(scriptUtxos) + ? scriptUtxos + : (scriptUtxos.utxos ?? []); + const batonUtxos = list.filter( + (u: { token?: { tokenId?: string; isMintBaton?: boolean } }) => + u.token?.tokenId === tokenId && u.token?.isMintBaton, + ); + if (batonUtxos.length === 0) { + throw new Error(`No PoW batons at ${contract.address}`); + } + + const b = batonUtxos[0]; + const baton = { + outpoint: { txid: b.outpoint.txid, outIdx: b.outpoint.outIdx }, + sats: BigInt(b.sats), + txid: b.outpoint.txid as string, + vout: b.outpoint.outIdx as number, + }; + + const fuelUtxo = wallet.utxos.find(u => !u.token && u.sats >= 2_000n); + if (!fuelUtxo) { + throw new Error('Need a ≥20 XEC pure XEC UTXO for fees'); + } + + console.log( + JSON.stringify( + { + tokenId, + powAddress: contract.address, + baton: `${baton.txid}:${baton.vout}`, + fuelSats: fuelUtxo.sats.toString(), + }, + null, + 2, + ), + ); + + const built = await buildMinedRemintTx({ + contract, + baton, + fuel: { + outpoint: { + txid: fuelUtxo.outpoint.txid, + outIdx: fuelUtxo.outpoint.outIdx, + }, + sats: fuelUtxo.sats, + outputScript: wallet.script, + }, + miner: { sk: fromHex(skHex), pk: wallet.pk }, + }); + + console.log( + JSON.stringify( + { + powAttempts: built.powAttempts, + nonceHex: built.nonceHex, + mintAtoms: built.mintAtoms, + txSize: built.txHex.length / 2, + }, + null, + 2, + ), + ); + + const broadcast = await chronik.broadcastTx(built.txHex); + console.log('\nRemint OK', broadcast.txid); + writeFileSync( + resolve(process.cwd(), 'deployments/mainnet-last-remint.json'), + `${JSON.stringify( + { + tokenId, + txid: broadcast.txid, + powAttempts: built.powAttempts, + nonceHex: built.nonceHex, + mintAtoms: built.mintAtoms, + minedAt: new Date().toISOString(), + explorer: `https://explorer.e.cash/tx/${broadcast.txid}`, + }, + null, + 2, + )}\n`, + ); +} + +main().catch(err => { + console.error(err instanceof Error ? err.stack ?? err.message : err); + process.exit(1); +}); diff --git a/src/covenant/minePow.ts b/src/covenant/minePow.ts new file mode 100644 index 0000000..603a0a3 --- /dev/null +++ b/src/covenant/minePow.ts @@ -0,0 +1,40 @@ +import { sha256d } from 'ecash-lib'; +import { meetsPowDifficulty } from './powRemintScript.js'; + +export interface MinePowResult { + nonce: Uint8Array; + hash: Uint8Array; + attempts: number; +} + +/** + * Mist-style PoW: find nonce where hash256(preimage || nonce) has D leading zero bytes. + * `preimage` is the BIP143 sighash preimage (independent of scriptSig). + */ +export function minePow(opts: { + preimage: Uint8Array; + difficultyLeadingZeroBytes: number; + nonceLength?: number; + maxAttempts?: number; +}): MinePowResult { + const nonceLen = opts.nonceLength ?? 4; + const max = opts.maxAttempts ?? 5_000_000; + const nonce = new Uint8Array(nonceLen); + + for (let attempts = 1; attempts <= max; attempts++) { + for (let i = 0; i < nonceLen; i++) { + nonce[i] = (nonce[i] + 1) & 0xff; + if (nonce[i] !== 0) break; + } + const buf = new Uint8Array(opts.preimage.length + nonceLen); + buf.set(opts.preimage, 0); + buf.set(nonce, opts.preimage.length); + const hash = sha256d(buf); + if (meetsPowDifficulty(hash, opts.difficultyLeadingZeroBytes)) { + return { nonce: nonce.slice(), hash, attempts }; + } + } + throw new Error( + `PoW not found after ${max} attempts (d=${opts.difficultyLeadingZeroBytes})`, + ); +} diff --git a/src/covenant/opcodes.ts b/src/covenant/opcodes.ts new file mode 100644 index 0000000..77bc9b1 --- /dev/null +++ b/src/covenant/opcodes.ts @@ -0,0 +1,18 @@ +/** + * eCash native introspection opcodes (CHIP-2021-02). + * Not all are re-exported by ecash-lib yet — use raw codepoints. + */ +export const OP_INPUTINDEX = 0xc0; +export const OP_ACTIVEBYTECODE = 0xc1; +export const OP_TXVERSION = 0xc2; +export const OP_TXINPUTCOUNT = 0xc3; +export const OP_TXOUTPUTCOUNT = 0xc4; +export const OP_TXLOCKTIME = 0xc5; +export const OP_UTXOVALUE = 0xc6; +export const OP_UTXOBYTECODE = 0xc7; +export const OP_OUTPOINTTXHASH = 0xc8; +export const OP_OUTPOINTINDEX = 0xc9; +export const OP_INPUTBYTECODE = 0xca; +export const OP_INPUTSEQUENCENUMBER = 0xcb; +export const OP_OUTPUTVALUE = 0xcc; +export const OP_OUTPUTBYTECODE = 0xcd; diff --git a/src/covenant/powRemintOutputs.ts b/src/covenant/powRemintOutputs.ts new file mode 100644 index 0000000..bfe16db --- /dev/null +++ b/src/covenant/powRemintOutputs.ts @@ -0,0 +1,13 @@ +import { ALP_STANDARD, alpMint, emppScript, Script } from 'ecash-lib'; + +export function expectedMintOpReturnScript( + tokenId: string, + mintAtoms: bigint, +): Script { + return emppScript([ + alpMint(tokenId, ALP_STANDARD, { + atomsArray: [mintAtoms], + numBatons: 1, + }), + ]); +} diff --git a/src/covenant/powRemintScript.ts b/src/covenant/powRemintScript.ts new file mode 100644 index 0000000..1426e79 --- /dev/null +++ b/src/covenant/powRemintScript.ts @@ -0,0 +1,114 @@ +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { Spedn } from '@spedn/sdk'; +import { + ModuleFactory, + type Instance, + type PortableModule, + type Challenges, +} from '@spedn/rts'; +import { BchJsRts } from '@spedn/rts-bchjs'; +import { + Address, + fromHexRev, + shaRmd160, + toHex, + Script as EcashScript, +} from 'ecash-lib'; +import { BASE_MINT_ATOMS, POW_LEADING_ZERO_BYTES } from '../params/consensus.js'; + +export interface PowRemintParams { + tokenId: string; + mintAtoms: bigint; + difficultyLeadingZeroBytes: number; +} + +export type PowInstance = Instance & { challenges: Challenges }; + +export interface PowRemintContract { + params: PowRemintParams; + instance: PowInstance; + redeem: EcashScript; + redeemScriptBuf: Buffer; + scriptHash: Uint8Array; + p2shScript: EcashScript; + address: string; + redeemHex: string; +} + +let cachedPortable: PortableModule | undefined; + +async function loadPortable(): Promise { + if (cachedPortable) return cachedPortable; + const spedn = new Spedn(); + try { + const code = readFileSync( + resolve(process.cwd(), 'contracts/WlotusPowRemint.spedn'), + 'utf8', + ); + cachedPortable = await spedn.compileCode('xec', code); + return cachedPortable; + } finally { + spedn.dispose(); + } +} + +function mintAtomsLe6(atoms: bigint): Buffer { + const buf = Buffer.alloc(6); + buf.writeUInt32LE(Number(atoms & 0xffffffffn), 0); + buf.writeUInt16LE(Number(atoms >> 32n), 4); + return buf; +} + +/** Build the Spedn PoW remint P2SH contract for a known tokenId. */ +export async function createPowRemintContract( + params: PowRemintParams, +): Promise { + const portable = await loadPortable(); + const factory = new ModuleFactory(new BchJsRts('mainnet')); + const Ctor = factory.make(portable).WlotusPowRemint; + const instance = new Ctor({ + tokenIdRev: Buffer.from(fromHexRev(params.tokenId)), + mintAtomsLe: mintAtomsLe6(params.mintAtoms), + difficultyLeadingZeroBytes: params.difficultyLeadingZeroBytes, + }) as PowInstance; + const redeemScriptBuf = instance.redeemScript as Buffer; + const redeem = new EcashScript(new Uint8Array(redeemScriptBuf)); + const scriptHash = shaRmd160(redeem.bytecode); + const p2shScript = EcashScript.p2sh(scriptHash); + const address = Address.p2sh(scriptHash, 'ecash').toString(); + return { + params, + instance, + redeem, + redeemScriptBuf, + scriptHash, + p2shScript, + address, + redeemHex: toHex(redeem.bytecode), + }; +} + +export function defaultPowParams(tokenId: string): PowRemintParams { + return { + tokenId, + mintAtoms: BASE_MINT_ATOMS, + difficultyLeadingZeroBytes: POW_LEADING_ZERO_BYTES, + }; +} + +export async function contractForToken( + tokenId: string, +): Promise { + return createPowRemintContract(defaultPowParams(tokenId)); +} + +export function meetsPowDifficulty(hash: Uint8Array, d: number): boolean { + if (hash.length < d) return false; + for (let i = 0; i < d; i++) { + if (hash[i] !== 0) return false; + } + return true; +} + +export { expectedMintOpReturnScript } from './powRemintOutputs.js'; diff --git a/src/index.ts b/src/index.ts index 7e63a31..898443b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,4 +29,12 @@ export { } from './genesis/broadcastGenesis.js'; export { createChronik } from './network/createChronik.js'; export { MAINNET_CHRONIK_URLS } from './network/chronikUrls.js'; -export { expectedMintAtoms, minerBanner } from './miner/remint.js'; +export { + contractForToken, + createPowRemintContract, + defaultPowParams, + meetsPowDifficulty, +} from './covenant/powRemintScript.js'; +export { expectedMintOpReturnScript } from './covenant/powRemintOutputs.js'; +export { minePow } from './covenant/minePow.js'; +export { buildMinedRemintTx, minerBanner } from './miner/remint.js'; diff --git a/src/miner/remint.ts b/src/miner/remint.ts index 71f967d..79e6dc8 100644 --- a/src/miner/remint.ts +++ b/src/miner/remint.ts @@ -1,44 +1,171 @@ -import { mintAtomsAtHostHeight } from '../lib/moore.js'; -import { POW_BATON_COUNT, POW_LEADING_ZERO_BYTES } from '../params/consensus.js'; +import { + ALL_BIP143, + DEFAULT_DUST_SATS, + DEFAULT_FEE_SATS_PER_KB, + Ecc, + P2PKHSignatory, + Script, + TxBuilder, + flagSignature, + sha256d, + shaRmd160, + toHex, + type OutPoint, + type Signatory, +} from 'ecash-lib'; +import { + contractForToken, + type PowRemintContract, +} from '../covenant/powRemintScript.js'; +import { expectedMintOpReturnScript } from '../covenant/powRemintOutputs.js'; +import { minePow } from '../covenant/minePow.js'; +import { BASE_MINT_ATOMS, POW_LEADING_ZERO_BYTES } from '../params/consensus.js'; -/** - * Remint miner sketch (Chronik + ecash-lib). - * - * Loop: - * 1. List unspent PoW baton UTXOs for tokenId (N tips) - * 2. For each baton, build ALP MINT template + covenant unlock - * 3. Search nonce until hash256(preimage||nonce) meets difficulty - * 4. Broadcast; on conflict, refresh baton set and retry - * - * No Mist-style wait-for-next-host-block gating. - */ -export interface RemintTarget { - tokenId: string; - genesisHostHeight: number; - currentHostHeight: number; - batonOutpoint: { txid: string; vout: number }; - batonIndex: number; +export interface BatonUtxo { + outpoint: OutPoint; + sats: bigint; + txid: string; + vout: number; } -export function expectedMintAtoms(target: RemintTarget): bigint { - return mintAtomsAtHostHeight( - target.genesisHostHeight, - target.currentHostHeight, - ); +export interface RemintKeys { + sk: Uint8Array; + pk: Uint8Array; +} + +export interface FuelUtxo { + outpoint: OutPoint; + sats: bigint; + outputScript: Script; } +export { contractForToken }; + export function minerBanner(): string { return [ - 'WLOTUS remint miner', - `batons(N)=${POW_BATON_COUNT}`, + 'WLOTUS PoW remint miner', `powLeadingZeroBytes=${POW_LEADING_ZERO_BYTES}`, - 'moore=99918/100000 per 144 host blocks', - 'parallel remints: enabled (no 1-mint/block CLTV)', + `baseMintAtoms=${BASE_MINT_ATOMS}`, + 'covenant: Spedn Mist-style BIP143 preimage (eCash)', ].join(' | '); } -/** Placeholder — wire Chronik + ecash-lib in a follow-up. */ -export async function runMinerLoop(_tokenId: string): Promise { - console.log(minerBanner()); - throw new Error('Miner not implemented yet — covenant + Chronik wiring TODO'); +/** + * Build + mine + sign one remint. + * Schnorr sig (65B) for CHECKSIG over sha256d(preimage); + * Schnorr datasig (64B) for CHECKDATASIG over sha256(preimage). + */ +export async function buildMinedRemintTx(opts: { + contract: PowRemintContract; + baton: BatonUtxo; + fuel: FuelUtxo; + miner: RemintKeys; +}): Promise<{ + txHex: string; + nonceHex: string; + powAttempts: number; + mintAtoms: string; +}> { + const { contract, baton, fuel, miner } = opts; + const dust = DEFAULT_DUST_SATS; + const opReturn = expectedMintOpReturnScript( + contract.params.tokenId, + contract.params.mintAtoms, + ); + const minerP2pkh = Script.p2pkh(shaRmd160(miner.pk)); + const ecc = new Ecc(); + + let minedNonce: Uint8Array | undefined; + let minedAttempts = 0; + + const mkUnlock = ( + nonce: Uint8Array, + sig65: Uint8Array, + ds64: Uint8Array, + preimage: Uint8Array, + ): Script => { + if (sig65.length !== 65) { + throw new Error(`Sig must be 65 bytes, got ${sig65.length}`); + } + if (ds64.length !== 64) { + throw new Error(`DataSig must be 64 bytes, got ${ds64.length}`); + } + const scriptSigBuf = contract.instance.challenges.remint({ + nonce: Buffer.from(nonce), + s: Buffer.from(sig65), + ds: Buffer.from(ds64), + minerPk: Buffer.from(miner.pk), + preimage: Buffer.from(preimage), + }) as Buffer; + return new Script(new Uint8Array(scriptSigBuf)); + }; + + const batonSignatory: Signatory = (eccCtx, input) => { + const pre = input.sigHashPreimage(ALL_BIP143); + const preimage = pre.bytes; + if (!minedNonce) { + const mined = minePow({ + preimage, + difficultyLeadingZeroBytes: contract.params.difficultyLeadingZeroBytes, + }); + minedNonce = mined.nonce; + minedAttempts = mined.attempts; + } + // CHECKSIG message = hash256(preimage). CHECKDATASIG hashes its + // message once, so pass sha256(preimage) on-stack and the same 64-byte + // Schnorr sig (toDataSig) — both verify hash256(preimage). + const rawSig = eccCtx.schnorrSign(miner.sk, sha256d(preimage)); + const sig65 = flagSignature(rawSig, ALL_BIP143); + const ds64 = rawSig; + return mkUnlock(minedNonce, sig65, ds64, preimage); + }; + + const txBuild = new TxBuilder({ + inputs: [ + { + input: { + prevOut: baton.outpoint, + signData: { + sats: baton.sats, + redeemScript: contract.redeem, + }, + }, + signatory: batonSignatory, + }, + { + input: { + prevOut: fuel.outpoint, + signData: { + sats: fuel.sats, + outputScript: fuel.outputScript, + }, + }, + signatory: P2PKHSignatory(miner.sk, miner.pk, ALL_BIP143), + }, + ], + outputs: [ + { sats: 0n, script: opReturn }, + { sats: dust, script: minerP2pkh }, + { sats: dust, script: contract.p2shScript }, + ], + }); + + const tx = txBuild.sign({ + ecc, + feePerKb: DEFAULT_FEE_SATS_PER_KB, + dustSats: dust, + }); + if (tx.outputs.length !== 3) { + throw new Error(`Expected 3 outputs, got ${tx.outputs.length}`); + } + if (!minedNonce) { + throw new Error('PoW nonce was not mined'); + } + + return { + txHex: toHex(tx.ser()), + nonceHex: toHex(minedNonce), + powAttempts: minedAttempts, + mintAtoms: contract.params.mintAtoms.toString(), + }; } From 4156cf3a8f495dbe6420834aea5d251d435ff51d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 05:18:12 +0000 Subject: [PATCH 5/6] Introduce mWLOTUS incubation token economics and tooling Adopt fixed 100.00/remint @ 2 decimals, ~$0.00001/token target (~1/1000 of future WLOTUS), Moore-on-work library schedule, and create/mine scripts. Genesis wallet needs fresh XEC before mainnet mWLOTUS can be broadcast. Co-authored-by: nghiacc --- README.md | 18 +- contracts/WlotusPowRemint.compiled.json | 294 +++++++++++------------ contracts/WlotusPowRemint.spedn | 7 +- deployments/README.md | 10 +- deployments/pending-funding-mwlotus.json | 15 ++ docs/ECONOMICS.md | 53 ++++ docs/PROPOSAL.md | 46 ++-- docs/SPEC.md | 61 +++-- docs/STATUS.md | 38 +-- docs/TEST_TOKEN.md | 71 ++---- package.json | 5 +- scripts/create-pow-token.ts | 68 ++++-- scripts/wait-create-mwlotus.ts | 56 +++++ src/index.ts | 21 +- src/lib/moore.ts | 79 +++++- src/miner/remint.ts | 4 +- src/params/consensus.ts | 83 ++++--- src/params/testEconomics.ts | 47 ++-- tests/moore.test.ts | 49 +++- 19 files changed, 631 insertions(+), 394 deletions(-) create mode 100644 deployments/pending-funding-mwlotus.json create mode 100644 docs/ECONOMICS.md create mode 100644 scripts/wait-create-mwlotus.ts diff --git a/README.md b/README.md index 411a51a..449f479 100644 --- a/README.md +++ b/README.md @@ -24,14 +24,12 @@ See [docs/SPEC.md](./docs/SPEC.md) and [docs/PROPOSAL.md](./docs/PROPOSAL.md). ## Status -**PoW-mineable mainnet token `WLPOW` is live** (Spedn BIP143 preimage covenant). -Custodial `WLTEST` also exists but is **not** for mining tests. - -See [docs/TEST_TOKEN.md](./docs/TEST_TOKEN.md) and [docs/STATUS.md](./docs/STATUS.md). +**Incubation PoW token `mWLOTUS` is the mining target** — always 100.00/remint @ 2 decimals, +~$0.00001/token (~1/1000 of future `WLOTUS` @ ~$0.01). See [docs/ECONOMICS.md](./docs/ECONOMICS.md). ```bash -npm run mine-once # remint against WLPOW batons -npm run create-pow-token # recreate PoW genesis + baton handoff +npm run create-pow-token +npm run mine-once ``` ``` @@ -67,12 +65,12 @@ npm run new-wallet # writes .env + deployments/pending-funding.json npm run create-test-token # ALP GENESIS → deployments/mainnet-test-token.json ``` -Ticker for this dogfood deployment: `WLPOW` (PoW) / `WLTEST` (custodial only). -Keep `WLOTUS` for the later $0.01 launch. +Ticker for this dogfood deployment: **`mWLOTUS`**. Keep **`WLOTUS`** for the later ~$0.01 launch +(1000:1 energy peg). See [docs/ECONOMICS.md](./docs/ECONOMICS.md). ```bash -npm run create-pow-token # PoW genesis + handoff to covenant P2SH -npm run mine-once # one permissionless remint +npm run create-pow-token # mWLOTUS genesis + handoff to covenant P2SH +npm run mine-once # one permissionless remint (100.00 tokens) ``` ## License diff --git a/contracts/WlotusPowRemint.compiled.json b/contracts/WlotusPowRemint.compiled.json index 620ab0b..f28388c 100644 --- a/contracts/WlotusPowRemint.compiled.json +++ b/contracts/WlotusPowRemint.compiled.json @@ -594,7 +594,7 @@ } ], "ast": { - "contractAnnotation": ":6:1", + "contractAnnotation": ":7:1", "contractChallenges": [ [ "remint", @@ -608,22 +608,22 @@ "tag": "Array" }, "nonce", - ":12:9" + ":13:9" ], [ "Sig", "s", - ":13:9" + ":14:9" ], [ "DataSig", "ds", - ":14:9" + ":15:9" ], [ "PubKey", "minerPk", - ":15:9" + ":16:9" ], [ { @@ -631,7 +631,7 @@ "tag": "List" }, "preimage", - ":16:9" + ":17:9" ] ], { @@ -646,23 +646,23 @@ { "contents": [ "s", - ":18:25" + ":19:25" ], "tag": "Var" }, { "contents": [ "minerPk", - ":18:28" + ":19:28" ], "tag": "Var" } ], - ":18:16" + ":19:16" ], "tag": "Call" }, - ":18:9" + ":19:9" ], "tag": "Verify" }, @@ -675,7 +675,7 @@ { "contents": [ "ds", - ":19:29" + ":20:29" ], "tag": "Var" }, @@ -686,28 +686,28 @@ { "contents": [ "preimage", - ":19:40" + ":20:40" ], "tag": "Var" } ], - ":19:33" + ":20:33" ], "tag": "Call" }, { "contents": [ "minerPk", - ":19:51" + ":20:51" ], "tag": "Var" } ], - ":19:16" + ":20:16" ], "tag": "Call" }, - ":19:9" + ":20:9" ], "tag": "Verify" }, @@ -719,7 +719,7 @@ "tag": "List" }, "solhash", - ":21:9" + ":22:9" ], { "contents": [ @@ -731,27 +731,27 @@ { "contents": [ "preimage", - ":21:34" + ":22:34" ], "tag": "Var" }, { "contents": [ "nonce", - ":21:45" + ":22:45" ], "tag": "Var" }, - ":21:43" + ":22:43" ], "tag": "BinaryExpr" } ], - ":21:26" + ":22:26" ], "tag": "Call" }, - ":21:9" + ":22:9" ], "tag": "Assign" }, @@ -765,12 +765,12 @@ "tag": "List" }, "work", - ":22:10" + ":23:10" ], "tag": "TupleVarDecl" }, { - "contents": ":22:23", + "contents": ":23:23", "tag": "Gap" } ], @@ -780,22 +780,22 @@ { "contents": [ "solhash", - ":22:28" + ":23:28" ], "tag": "Var" }, { "contents": [ "difficultyLeadingZeroBytes", - ":22:38" + ":23:38" ], "tag": "Var" }, - ":22:36" + ":23:36" ], "tag": "BinaryExpr" }, - ":22:9" + ":23:9" ], "tag": "SplitAssign" }, @@ -811,27 +811,27 @@ { "contents": [ "work", - ":23:24" + ":24:24" ], "tag": "Var" } ], - ":23:16" + ":24:16" ], "tag": "Call" }, { "contents": [ 0, - ":23:33" + ":24:33" ], "tag": "NumConst" }, - ":23:30" + ":24:30" ], "tag": "BinaryExpr" }, - ":23:9" + ":24:9" ], "tag": "Verify" }, @@ -839,7 +839,7 @@ "contents": [ [ { - "contents": ":25:10", + "contents": ":26:10", "tag": "Gap" }, { @@ -849,7 +849,7 @@ "tag": "List" }, "tail40", - ":25:13" + ":26:13" ], "tag": "TupleVarDecl" } @@ -860,7 +860,7 @@ { "contents": [ "preimage", - ":25:30" + ":26:30" ], "tag": "Var" }, @@ -874,31 +874,31 @@ { "contents": [ "preimage", - ":25:47" + ":26:47" ], "tag": "Var" } ], - ":25:42" + ":26:42" ], "tag": "Call" }, { "contents": [ 40, - ":25:59" + ":26:59" ], "tag": "NumConst" }, - ":25:57" + ":26:57" ], "tag": "BinaryExpr" }, - ":25:39" + ":26:39" ], "tag": "BinaryExpr" }, - ":25:9" + ":26:9" ], "tag": "SplitAssign" }, @@ -912,12 +912,12 @@ "tag": "List" }, "hashOutputs", - ":26:10" + ":27:10" ], "tag": "TupleVarDecl" }, { - "contents": ":26:30", + "contents": ":27:30", "tag": "Gap" } ], @@ -927,22 +927,22 @@ { "contents": [ "tail40", - ":26:35" + ":27:35" ], "tag": "Var" }, { "contents": [ 32, - ":26:44" + ":27:44" ], "tag": "NumConst" }, - ":26:42" + ":27:42" ], "tag": "BinaryExpr" }, - ":26:9" + ":27:9" ], "tag": "SplitAssign" }, @@ -956,12 +956,12 @@ "tag": "List" }, "head", - ":30:10" + ":31:10" ], "tag": "TupleVarDecl" }, { - "contents": ":30:23", + "contents": ":31:23", "tag": "Gap" } ], @@ -971,7 +971,7 @@ { "contents": [ "preimage", - ":30:28" + ":31:28" ], "tag": "Var" }, @@ -985,31 +985,31 @@ { "contents": [ "preimage", - ":30:45" + ":31:45" ], "tag": "Var" } ], - ":30:40" + ":31:40" ], "tag": "Call" }, { "contents": [ 52, - ":30:57" + ":31:57" ], "tag": "NumConst" }, - ":30:55" + ":31:55" ], "tag": "BinaryExpr" }, - ":30:37" + ":31:37" ], "tag": "BinaryExpr" }, - ":30:9" + ":31:9" ], "tag": "SplitAssign" }, @@ -1017,7 +1017,7 @@ "contents": [ [ { - "contents": ":31:10", + "contents": ":32:10", "tag": "Gap" }, { @@ -1027,7 +1027,7 @@ "tag": "List" }, "scriptCodePrefixed", - ":31:13" + ":32:13" ], "tag": "TupleVarDecl" } @@ -1038,22 +1038,22 @@ { "contents": [ "head", - ":31:42" + ":32:42" ], "tag": "Var" }, { "contents": [ 104, - ":31:49" + ":32:49" ], "tag": "NumConst" }, - ":31:47" + ":32:47" ], "tag": "BinaryExpr" }, - ":31:9" + ":32:9" ], "tag": "SplitAssign" }, @@ -1061,7 +1061,7 @@ "contents": [ [ { - "contents": ":32:10", + "contents": ":33:10", "tag": "Gap" }, { @@ -1071,7 +1071,7 @@ "tag": "List" }, "redeemScript", - ":32:13" + ":33:13" ], "tag": "TupleVarDecl" } @@ -1082,22 +1082,22 @@ { "contents": [ "scriptCodePrefixed", - ":32:36" + ":33:36" ], "tag": "Var" }, { "contents": [ 1, - ":32:57" + ":33:57" ], "tag": "NumConst" }, - ":32:55" + ":33:55" ], "tag": "BinaryExpr" }, - ":32:9" + ":33:9" ], "tag": "SplitAssign" }, @@ -1109,7 +1109,7 @@ "tag": "List" }, "mintSection", - ":35:9" + ":36:9" ], { "contents": [ @@ -1140,7 +1140,7 @@ 80, 50 ], - ":36:13" + ":37:13" ], "tag": "HexConst" }, @@ -1151,23 +1151,23 @@ { "contents": [ 0, - ":37:21" + ":38:21" ], "tag": "NumConst" }, { "contents": [ 1, - ":37:24" + ":38:24" ], "tag": "NumConst" } ], - ":37:13" + ":38:13" ], "tag": "Call" }, - ":36:24" + ":37:24" ], "tag": "BinaryExpr" }, @@ -1176,11 +1176,11 @@ [ 4 ], - ":38:13" + ":39:13" ], "tag": "HexConst" }, - ":37:27" + ":38:27" ], "tag": "BinaryExpr" }, @@ -1192,22 +1192,22 @@ 78, 84 ], - ":38:20" + ":39:20" ], "tag": "HexConst" }, - ":38:18" + ":39:18" ], "tag": "BinaryExpr" }, { "contents": [ "tokenIdRev", - ":39:13" + ":40:13" ], "tag": "Var" }, - ":38:31" + ":39:31" ], "tag": "BinaryExpr" }, @@ -1216,22 +1216,22 @@ [ 1 ], - ":40:13" + ":41:13" ], "tag": "HexConst" }, - ":39:24" + ":40:24" ], "tag": "BinaryExpr" }, { "contents": [ "mintAtomsLe", - ":41:13" + ":42:13" ], "tag": "Var" }, - ":40:18" + ":41:18" ], "tag": "BinaryExpr" }, @@ -1240,15 +1240,15 @@ [ 1 ], - ":42:13" + ":43:13" ], "tag": "HexConst" }, - ":41:25" + ":42:25" ], "tag": "BinaryExpr" }, - ":35:9" + ":36:9" ], "tag": "Assign" }, @@ -1260,7 +1260,7 @@ "tag": "List" }, "opReturnScript", - ":44:9" + ":45:9" ], { "contents": [ @@ -1274,7 +1274,7 @@ 106, 80 ], - ":44:33" + ":45:33" ], "tag": "HexConst" }, @@ -1289,43 +1289,43 @@ { "contents": [ "mintSection", - ":44:55" + ":45:55" ], "tag": "Var" } ], - ":44:50" + ":45:50" ], "tag": "Call" }, { "contents": [ 1, - ":44:69" + ":45:69" ], "tag": "NumConst" } ], - ":44:42" + ":45:42" ], "tag": "Call" }, - ":44:40" + ":45:40" ], "tag": "BinaryExpr" }, { "contents": [ "mintSection", - ":44:74" + ":45:74" ], "tag": "Var" }, - ":44:72" + ":45:72" ], "tag": "BinaryExpr" }, - ":44:9" + ":45:9" ], "tag": "Assign" }, @@ -1337,7 +1337,7 @@ "tag": "List" }, "out0", - ":46:9" + ":47:9" ], { "contents": [ @@ -1357,7 +1357,7 @@ 0, 0 ], - ":46:23" + ":47:23" ], "tag": "HexConst" }, @@ -1372,43 +1372,43 @@ { "contents": [ "opReturnScript", - ":46:57" + ":47:57" ], "tag": "Var" } ], - ":46:52" + ":47:52" ], "tag": "Call" }, { "contents": [ 1, - ":46:74" + ":47:74" ], "tag": "NumConst" } ], - ":46:44" + ":47:44" ], "tag": "Call" }, - ":46:42" + ":47:42" ], "tag": "BinaryExpr" }, { "contents": [ "opReturnScript", - ":46:79" + ":47:79" ], "tag": "Var" }, - ":46:77" + ":47:77" ], "tag": "BinaryExpr" }, - ":46:9" + ":47:9" ], "tag": "Assign" }, @@ -1420,7 +1420,7 @@ "tag": "List" }, "out1", - ":47:9" + ":48:9" ], { "contents": [ @@ -1446,7 +1446,7 @@ 0, 0 ], - ":47:23" + ":48:23" ], "tag": "HexConst" }, @@ -1455,11 +1455,11 @@ [ 25 ], - ":47:44" + ":48:44" ], "tag": "HexConst" }, - ":47:42" + ":48:42" ], "tag": "BinaryExpr" }, @@ -1470,11 +1470,11 @@ 169, 20 ], - ":47:51" + ":48:51" ], "tag": "HexConst" }, - ":47:49" + ":48:49" ], "tag": "BinaryExpr" }, @@ -1485,16 +1485,16 @@ { "contents": [ "minerPk", - ":47:70" + ":48:70" ], "tag": "Var" } ], - ":47:62" + ":48:62" ], "tag": "Call" }, - ":47:60" + ":48:60" ], "tag": "BinaryExpr" }, @@ -1504,15 +1504,15 @@ 136, 172 ], - ":47:81" + ":48:81" ], "tag": "HexConst" }, - ":47:79" + ":48:79" ], "tag": "BinaryExpr" }, - ":47:9" + ":48:9" ], "tag": "Assign" }, @@ -1524,7 +1524,7 @@ "tag": "List" }, "out2", - ":48:9" + ":49:9" ], { "contents": [ @@ -1550,7 +1550,7 @@ 0, 0 ], - ":48:23" + ":49:23" ], "tag": "HexConst" }, @@ -1559,11 +1559,11 @@ [ 23 ], - ":48:44" + ":49:44" ], "tag": "HexConst" }, - ":48:42" + ":49:42" ], "tag": "BinaryExpr" }, @@ -1573,11 +1573,11 @@ 169, 20 ], - ":48:51" + ":49:51" ], "tag": "HexConst" }, - ":48:49" + ":49:49" ], "tag": "BinaryExpr" }, @@ -1588,16 +1588,16 @@ { "contents": [ "redeemScript", - ":48:68" + ":49:68" ], "tag": "Var" } ], - ":48:60" + ":49:60" ], "tag": "Call" }, - ":48:58" + ":49:58" ], "tag": "BinaryExpr" }, @@ -1606,15 +1606,15 @@ [ 135 ], - ":48:84" + ":49:84" ], "tag": "HexConst" }, - ":48:82" + ":49:82" ], "tag": "BinaryExpr" }, - ":48:9" + ":49:9" ], "tag": "Assign" }, @@ -1636,34 +1636,34 @@ { "contents": [ "out0", - ":50:24" + ":51:24" ], "tag": "Var" }, { "contents": [ "out1", - ":50:31" + ":51:31" ], "tag": "Var" }, - ":50:29" + ":51:29" ], "tag": "BinaryExpr" }, { "contents": [ "out2", - ":50:38" + ":51:38" ], "tag": "Var" }, - ":50:36" + ":51:36" ], "tag": "BinaryExpr" } ], - ":50:16" + ":51:16" ], "tag": "Call" }, @@ -1674,29 +1674,29 @@ { "contents": [ "hashOutputs", - ":50:54" + ":51:54" ], "tag": "Var" } ], - ":50:47" + ":51:47" ], "tag": "Call" }, - ":50:44" + ":51:44" ], "tag": "BinaryExpr" }, - ":50:9" + ":51:9" ], "tag": "Verify" } ], - ":17:7" + ":18:7" ], "tag": "Block" }, - ":11:5" + ":12:5" ] ], "contractName": "WlotusPowRemint", @@ -1710,7 +1710,7 @@ "tag": "Array" }, "tokenIdRev", - ":7:5" + ":8:5" ], [ { @@ -1721,12 +1721,12 @@ "tag": "Array" }, "mintAtomsLe", - ":8:5" + ":9:5" ], [ "int", "difficultyLeadingZeroBytes", - ":9:5" + ":10:5" ] ] } diff --git a/contracts/WlotusPowRemint.spedn b/contracts/WlotusPowRemint.spedn index fb92e2d..1a5a0b5 100644 --- a/contracts/WlotusPowRemint.spedn +++ b/contracts/WlotusPowRemint.spedn @@ -1,7 +1,8 @@ -// WLOTUS PoW remint covenant (eCash / XEC) +// mWLOTUS / WLOTUS PoW remint covenant (eCash / XEC) // Mist-style BIP143 preimage (eCash has no native introspection opcodes). -// `s` signs hash256(preimage) for CHECKSIG; `ds` must be toDataSig(s) so -// CHECKDATASIG(sha256(preimage)) verifies the same message. +// Mint atoms are FIXED (always 100.00 @ 2 decimals for mWLOTUS). +// Difficulty leading-zero bytes are a constructor param (incubation: 1). +// `s` signs hash256(preimage); `ds` is toDataSig(s). contract WlotusPowRemint( [byte;32] tokenIdRev, diff --git a/deployments/README.md b/deployments/README.md index a33e902..28b80c7 100644 --- a/deployments/README.md +++ b/deployments/README.md @@ -1,14 +1,14 @@ # Deployments -On-chain deployment records for White Lotus test / production tokens. +On-chain deployment records for White Lotus incubation / production tokens. | File | Meaning | |------|---------| -| `mainnet-pow-token.json` | Live **WLPOW** PoW-mineable token (use this) | +| `mainnet-mwlotus.json` | Live **mWLOTUS** PoW incubation token (preferred alias) | +| `mainnet-pow-token.json` | Same as above (miner default path) | | `mainnet-last-remint.json` | Last successful PoW remint | +| `pending-funding-mwlotus.json` | Fund address if genesis wallet is empty | | `mainnet-test-token.json` | Custodial **WLTEST** (not for mining) | -| `mainnet-pow-token-v1-locked.json` | Broken covenant (size-56) — batons locked | -| `mainnet-pow-token-v2-locked.json` | Broken covenant (`0x00` push) — batons locked | -| `mainnet-pow-handoff.json` | Obsolete introspection handoff record | +| `mainnet-pow-token-v*-locked.json` | Broken predecessor covenants | Private keys live only in `.env` (gitignored). Never commit `GENESIS_SK_HEX`. diff --git a/deployments/pending-funding-mwlotus.json b/deployments/pending-funding-mwlotus.json new file mode 100644 index 0000000..eebafe8 --- /dev/null +++ b/deployments/pending-funding-mwlotus.json @@ -0,0 +1,15 @@ +{ + "purpose": "Fund genesis wallet to create mWLOTUS PoW incubation token", + "address": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "needXec": 100, + "ticker": "mWLOTUS", + "decimals": 2, + "tokensPerRemint": 100, + "targetUsdPerToken": 0.00001, + "mwlotusPerWlotus": 1000, + "createdAt": "2026-07-17T05:20:00.000Z", + "notes": [ + "Send ≥ 100 XEC to the address, then: npm run create-pow-token && npm run mine-once", + "Or: npm run wait-create-mwlotus" + ] +} diff --git a/docs/ECONOMICS.md b/docs/ECONOMICS.md new file mode 100644 index 0000000..655e77a --- /dev/null +++ b/docs/ECONOMICS.md @@ -0,0 +1,53 @@ +# Economics — mWLOTUS → WLOTUS + +## Ritual loop + +| Action | Meaning | Supply | +|--------|---------|--------| +| **Burn** | Sacrifice / vàng mã offering | Destroys tokens | +| **Remint** | Pure PoW rebirth | Creates tokens | + +Burn does **not** cancel remint. Burns tighten float → support price → incentivise miners to remint again. + +## Incubation: mWLOTUS + +| Knob | Value | +|------|-------| +| Ticker | `mWLOTUS` (milli White Lotus) | +| Decimals | **2** | +| Tokens / remint | **Always 100.00** (fixed) | +| PoW | Leading zero bytes on `hash256(preimage ‖ nonce)` | +| Genesis difficulty | **1** leading zero byte (~1/256) — anyone can mine | +| Target market price | **~$0.00001 / token** (~$0.001 / remint) | +| vs WLOTUS | **~1/1000** energy / price | + +Moore / Koomey (`δ = 99918/100000`, ~2.3y half-life) adjusts **required work**, not the 100-token mint. Incubation genesis uses a **fixed** cheap difficulty so the network can be dogfooded immediately; the same δ is used in `src/lib/moore.ts` to schedule how work should grow (library + future stateful covenant). Full on-chain Moore-on-difficulty (time-derived or baton-state) lands with the WLOTUS upgrade path — Script cannot read “now”, so a naïve locktime day-index is cheatable with old timestamps. + +## Production: WLOTUS (later) + +| Knob | Value | +|------|-------| +| Ticker | `WLOTUS` | +| Tokens / remint | **Always 100.00** | +| Target market price | **~$0.01 / token** (~$1 / remint) | +| Difficulty | ~**1000×** mWLOTUS genesis work (retune `D₀`; then Moore on work) | + +`$0.01` is a **market** target: energy + XEC fees + hardware subsidy + miner profit — not a pure joule oracle. + +## Energy peg / conversion + +Because both tokens use the same fixed-100 + Moore-on-work family: + +``` +1000 mWLOTUS ≈ 1 WLOTUS +``` + +for **circulating and burned** balances when the app matures (conversion / memorial ledger). Exact redemption UX is app-layer; consensus only needs compatible issuance physics. + +## Elasticity + +``` +coins/time ≈ N_batons × (hashrate / hashes_per_solution) × 100 +``` + +Many remints per eCash block, N ≥ 2 batons, no Mist 1-mint/block CLTV. diff --git a/docs/PROPOSAL.md b/docs/PROPOSAL.md index 098e1fb..264bb5f 100644 --- a/docs/PROPOSAL.md +++ b/docs/PROPOSAL.md @@ -52,20 +52,20 @@ Lotus Temple already showed: **elastic but inelastic issuance (`log D`) + burns* | Indexer | Chronik | | Liquidity | Agora + optional temple desk (XEC ↔ token) | -### 3.3 Issuance — remint frequency + Moore decay +### 3.3 Issuance — fixed 100 / remint + Moore on work -**Insight:** On Ergon, block *rate* is held ~constant by the DAA, so elasticity lives in **coins per block** (`∝ D`). On an ALP PoW remint, invert that: +**Canonical incubation model (mWLOTUS):** see [ECONOMICS.md](./ECONOMICS.md). -- Fixed PoW difficulty; base atoms per remint before Moore -- **Many remints per eCash block** (no Mist “1 mint / host block” CLTV) -- **Multiple ALP mint batons** for **true parallel** remints (§3.5) -- ⇒ **remints/time ∝ hashrate** ⇒ **coins/time ∝ hashrate** +- **Always 100 tokens per remint** (not Moore-decaying mint size) +- **Moore / Koomey (`δ = 99918/100000`)** adjusts **required work / difficulty** +- **Many remints per eCash block** + **N ≥ 2 batons** ⇒ coins/time ∝ hashrate +- Burn = sacrifice; remint = pure PoW rebirth (not ritual inverses) ``` -coins/time ≈ N_batons × (hashrate_per_baton / hashes_per_solution) × M(t) +coins/time ≈ N_batons × (hashrate_per_baton / hashes_per_solution) × 100 ``` -No token DAA and no `mintAmount ∝ work(D)` required for Ergon-like *flow*. +mWLOTUS targets ~$0.00001/token (~1/1000 of future WLOTUS ~$0.01). Conversion: **1000 mWLOTUS ≈ 1 WLOTUS**. #### Moore / Koomey — Ergon **post-launch** constant only @@ -84,33 +84,25 @@ Bitcoin Static release notes fixed Moore from **1.1y → 2.3y**. **WLOTUS ships | Symbol | WLOTUS | Notes | |--------|--------|-------| | `δ` | **`99918 / 100000`** | Ergon corrected daily factor | -| Day step | ~1 wall day | Ergon: once per `nSubsidyHalvingInterval` (144 × 10‑min blocks). Mirror with ~144 eCash blocks or median-time day | -| `M(t)` | `M₀ · δ^{k}` | `k = floor(elapsed_days)` since genesis | -| Clock | **eCash height / median time** | **Not** token-mint height (that races with hashrate) | - -Covenant integer form: - -``` -M_expected = M₀ -repeat k times: - M_expected = (M_expected * 99918) / 100000 -verify mintAtoms == M_expected -``` +| Day step | ~1 wall day | 144 eCash blocks or median-time day | +| Mint | **Fixed 100** | Do **not** apply δ to mint atoms | +| Work | `requiredBits(k)` grows with k | Library + future stateful covenant | +| Clock | **eCash height / median time** | **Not** token-mint height | #### Canonical knobs | Knob | Setting | Role | |------|---------|------| -| PoW difficulty `D` | Fixed, tunable | Effort per remint solution | -| Base atoms `M₀` | Genesis constant | Initial unlock per solution | -| Moore `δ` | **`99918/100000`** | ~2.3y half-life efficiency decay | -| Host CLTV 1-mint/block | **Off** | Keep hashrate → issuance elasticity | +| PoW difficulty `D` | Tunable (+ Moore on work) | Effort per remint solution | +| Mint | Fixed **100.00** | Predictable offering size | +| Batons `N` | **≥ 2** at genesis | Parallel remints (§3.5) | +| Moore `δ` | **99918/100000** | Koomey correction on work (~2.3y) | +| Host CLTV 1-mint/block | **Off** | Hashrate → issuance elasticity | | Supply cap | **None** | Batons never die | -| PoW baton count `N` | **`N ≥ 2` at genesis** | True parallel remints (§3.5) | **Skip unless needed later:** token-local DAA; `mintAmount ∝ work(D)`. -Tune `D` / `M₀` / `N` from burn demand and miner contention. Each remint pays XEC fees (anti-spam). +Tune `D` / `N` from burn demand and miner contention. Each remint pays XEC fees (anti-spam). ### 3.4 App flow @@ -135,7 +127,7 @@ ALP allows **many mint batons** (SLP allowed only one). White Lotus treats multi - Genesis creates **`N ≥ 2` identical PoW covenant batons** (independent tips, same rules). - Miners remint **in parallel** in the same eCash block — not merely a serial chain on one tip. -- Each successful spend: PoW OK → mint exactly `M(t)` → **return one baton** to the next covenant state (**conserve `N`**). +- Each successful spend: PoW OK → mint exactly **100** → **return one baton** to the next covenant state (**conserve `N`**). - Choose `N` at genesis (e.g. 4–16); change only via a deliberate migration if ever required. This is how “multiple mints per block” becomes **true parallelization** and matches frequency-elasticity in §3.3. A single baton alone still serializes and wastes work under load. diff --git a/docs/SPEC.md b/docs/SPEC.md index a0abd84..f0777b0 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -1,56 +1,67 @@ -# WLOTUS Consensus Parameters (v0.1 draft) +# WLOTUS / mWLOTUS Consensus Parameters (v0.2 draft) -These constants define the **intended** genesis / covenant policy. -They are not live on mainnet until GENESIS + baton handoff are executed. +See also [ECONOMICS.md](./ECONOMICS.md). -## Identity +## Identity — incubation genesis | Param | Value | Notes | |-------|-------|-------| -| Ticker | `WLOTUS` | White Lotus | -| Name | `White Lotus` | | +| Ticker | `mWLOTUS` | milli White Lotus (~1/1000 of future WLOTUS) | +| Name | `milli White Lotus` | | | Protocol | ALP standard (`SLP2`) | eCash | -| Decimals | `6` | Precision for Moore integer decay | +| Decimals | `2` | Fixed mint size — no Moore on atoms | ## PoW remint | Param | Value | Notes | |-------|-------|-------| -| `POW_LEADING_ZERO_BYTES` | `1` | Test — ~$1e-6/token; raise for ~$0.01 later | -| `BASE_MINT_ATOMS` (`M₀`) | `100_000_000` | = 100 WLOTUS @ 6 decimals per remint at genesis (keep large for Moore floor-div) | -| Host 1-mint/block CLTV | **disabled** | Required for frequency elasticity | +| Tokens / remint | **Always 100.00** | `BASE_MINT_ATOMS = 10_000` | +| `POW_LEADING_ZERO_BYTES` (genesis) | `1` | Cheap incubation (~$1e-5/token target) | +| Moore / Koomey | On **work**, not mint size | `δ = 99918/100000` | +| Host 1-mint/block CLTV | **disabled** | Frequency elasticity | | Supply cap | **none** | PoW batons never die | ## Parallel batons | Param | Value | Notes | |-------|-------|-------| -| `POW_BATON_COUNT` (`N`) | `4` | Test genesis; production may use 8–16 | -| Temple bootstrap baton | optional | Separate; retire after liquidity | +| `POW_BATON_COUNT` (`N`) | `4` | Production may use 8–16 | -Each remint spends exactly one PoW baton and recreates exactly one PoW baton (conserve `N`). +Each remint spends one PoW baton and recreates one (conserve `N`). -## Moore / Koomey decay (Ergon post-fix) +## Moore on difficulty (Ergon post-fix δ) -Source: [Ergon-moe/Bitcoin-Static `validation.cpp` L978](https://github.com/Ergon-moe/Bitcoin-Static/blob/2e8d5f7635c899cc99e71f06dedbe72b3ff7f07b/src/validation.cpp#L978) +Source: [Ergon `validation.cpp` L978](https://github.com/Ergon-moe/Bitcoin-Static/blob/2e8d5f7635c899cc99e71f06dedbe72b3ff7f07b/src/validation.cpp#L978) | Param | Value | Notes | |-------|-------|-------| -| `MOORE_NUM` | **`99918`** | Use this — ~2.3y half-life | -| `MOORE_DEN` | **`100000`** | | -| Obsolete factor | `99826/100000` | Pre-fix ~1.1y — **forbidden** | -| Day step | `144` eCash blocks | Same idea as Ergon `nSubsidyHalvingInterval` @ 10 min | -| Clock | Host chain height / median time | **Not** token-mint height | +| `MOORE_NUM` / `MOORE_DEN` | **`99918` / `100000`** | ~2.3y half-life | +| Obsolete | `99826/100000` | **Forbidden** | +| Day step | 144 blocks or 86400s | Host clock | +| Mint atoms | **Fixed** | Do not apply δ to M | + +Library schedule (for miners / future stateful covenant): ``` -M(k) = floor_div_iter(M₀, k) -where each step: x ← (x * 99918) / 100000 -k = floor( (hostHeight - genesisHeight) / 144 ) +requiredZeroBits(k) = POW_BASE_ZERO_BITS + floor(k / MOORE_DAYS_PER_EXTRA_BIT) +k = floor(elapsed_days since genesis) ``` -## Explicit non-goals (v0.1) +Incubation mWLOTUS covenant enforces genesis **fixed** 1-byte PoW so anyone can mine immediately. Stateful or time-honest Moore-on-D ships with the WLOTUS difficulty retune (~1000×). + +## Future WLOTUS + +| Param | Value | +|-------|-------| +| Target price | ~$0.01/token (~$1/remint) | +| Mint | Still 100.00 | +| Difficulty | ~1000× mWLOTUS genesis work | +| Conversion | 1000 mWLOTUS ≈ 1 WLOTUS (live + burned) | + +## Explicit non-goals (v0.2) - `mintAmount ∝ work(D)` / token DAA - Fixed max supply - Mist 1-mint-per-block CLTV -- Website / temple app (separate repo) +- USD price oracle on-chain +- Temple app (separate repo; needs this PoW token first) diff --git a/docs/STATUS.md b/docs/STATUS.md index 8ceeb66..c94675f 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -2,35 +2,35 @@ Canonical home: **https://github.com/bcProFoundation/wlotus** -## Live mainnet +## Live incubation — **mWLOTUS** -| Token | Mode | Token ID | Mine? | -|-------|------|----------|-------| -| **WLPOW** | PoW covenant | `2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546` | **Yes** | -| WLTEST | Custodial | `e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3` | No | +| | | +|--|--| +| Role | Cheap PoW token so anyone can mine & burn before the app | +| Economics | Always **100.00**/remint @ **2** decimals; ~**$0.00001**/token; 1-byte PoW | +| Peg | **1000 mWLOTUS ≈ 1 WLOTUS** (later launch @ ~$0.01/token) | +| Docs | [ECONOMICS.md](./ECONOMICS.md) · [TEST_TOKEN.md](./TEST_TOKEN.md) | -Proven PoW remint: `3c37dd37aa846819af11dadba22afe8c707fa07ae9751f5147118dbd0eeef80a` - -Details: [TEST_TOKEN.md](./TEST_TOKEN.md) +```bash +npm run mine-once +``` ## Design sources | Doc | Role | |-----|------| -| [PROPOSAL.md](./PROPOSAL.md) | Product decision (ALP on eCash first; L1 deferred) | -| [SPEC.md](./SPEC.md) | Consensus draft parameters | +| [ECONOMICS.md](./ECONOMICS.md) | Ritual loop, mWLOTUS ↔ WLOTUS, Moore-on-work | +| [PROPOSAL.md](./PROPOSAL.md) | Product decision (ALP on eCash first) | +| [SPEC.md](./SPEC.md) | Consensus draft | | [ARCHITECTURE.md](./ARCHITECTURE.md) | Covenant / multi-baton flow | -| [research/](./research/) | Feasibility notes from [eminer#1](https://github.com/bcProFoundation/eminer/pull/1) | ## Covenant notes (eCash) -- eCash has **no** native introspection opcodes (`OP_OUTPUTBYTECODE`, etc.). -- PoW remint uses a **Spedn Mist-style BIP143 preimage** covenant (`contracts/WlotusPowRemint.spedn`). -- Unlock: PoW nonce + Schnorr `Sig` + `DataSig` (toDataSig) + miner pubkey + preimage. -- Difficulty for dogfood: **1 leading zero byte** on `hash256(preimage ‖ nonce)`. +- No native introspection → Spedn Mist-style BIP143 preimage covenant +- Mint size **fixed**; Moore δ schedules **work** (lib + future stateful D) -## Next ops +## Next -1. Raise PoW from 1 → higher when targeting ~$0.01/token (`WLOTUS`) -2. Temple / burn UI in a separate app repo -3. Optional: multi-baton concurrent miner +1. Temple / burn app (separate repo) against mWLOTUS +2. Stateful Moore-on-difficulty covenant revision +3. WLOTUS genesis (~1000× difficulty) + conversion UX diff --git a/docs/TEST_TOKEN.md b/docs/TEST_TOKEN.md index 5b94626..88a3183 100644 --- a/docs/TEST_TOKEN.md +++ b/docs/TEST_TOKEN.md @@ -1,55 +1,33 @@ -# Test token deployments (mainnet) +# Test / incubation deployments (mainnet) -## Which token for mining? +## Mine and burn this: **mWLOTUS** -| Token | Mode | Mineable? | -|-------|------|-----------| -| **WLPOW** | PoW covenant (Spedn BIP143 preimage) | **Yes** — use this | -| WLTEST | Custodial genesis wallet | No (batons not in PoW covenant) | - -## Live PoW token (`WLPOW`) — use for mining tests +Incubation token ≈ **1/1000** of future `WLOTUS` energy/price. | Field | Value | |-------|-------| -| Ticker | `WLPOW` | -| Name | White Lotus PoW Test | -| Token ID | `2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546` | -| Mode | **PoW** (not custodial) | -| PoW P2SH | `ecash:pz0k74f8nkytqh7ntcjhfaccc7wytjdj9ypy8f9z32` | -| Decimals | 6 | -| Mint atoms / remint | 100,000,000 (100 WLPOW) | -| PoW leading zero bytes | 1 | -| Batons | 4 (locked in PoW P2SH) | -| Proven remint | `3c37dd37aa846819af11dadba22afe8c707fa07ae9751f5147118dbd0eeef80a` | +| Ticker | `mWLOTUS` | +| Decimals | **2** | +| Tokens / remint | **Always 100.00** | +| PoW | 1 leading zero byte | +| Target | ~**$0.00001** / token | +| Conversion | 1000 mWLOTUS ≈ 1 WLOTUS (later) | -- Explorer: https://explorer.e.cash/tx/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546 -- Cashtab: https://cashtab.com/#/token/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546 -- Record: [`deployments/mainnet-pow-token.json`](../deployments/mainnet-pow-token.json) -- Last remint: [`deployments/mainnet-last-remint.json`](../deployments/mainnet-last-remint.json) +Record: [`deployments/mainnet-mwlotus.json`](../deployments/mainnet-mwlotus.json) (also `mainnet-pow-token.json`). ```bash -# .env must contain GENESIS_SK_HEX (same wallet that funded genesis) -npm run mine-once +npm run create-pow-token # genesis + baton handoff +npm run mine-once # one PoW remint ``` -## Custodial token (`WLTEST`) — not for PoW mining - -| Field | Value | -|-------|-------| -| Ticker | `WLTEST` | -| Token ID | `e64406bdda45fb46a642d9b6b2a949d9a12910046e3266e68158d7481e8b08a3` | -| Mode | **Custodial** | -| Mint batons | Genesis wallet (some later sent to broken introspection P2SH → locked) | - -- Record: [`deployments/mainnet-test-token.json`](../deployments/mainnet-test-token.json) +Economics: [ECONOMICS.md](./ECONOMICS.md) -## Goals +## Older dogfood (do not use for new mining) -| Knob | Test now | Later | -|------|----------|-------| -| Target price | **~$0.000001 / token** | **~$0.01 / token** | -| PoW leading zero bytes | `1` | raise (2–3+) | -| Ticker | `WLPOW` / `WLTEST` | `WLOTUS` | +| Token | Notes | +|-------|-------| +| WLPOW | Prior PoW plumbing tests (6 decimals / fixed D) | +| WLTEST | Custodial only | ## Chronik @@ -58,16 +36,3 @@ https://chronik.e.cash https://xec.paybutton.org https://chronik.pay2stay.com/xec ``` - -## Recreate PoW token - -```bash -npm run create-pow-token # genesis + handoff batons to Spedn PoW P2SH -npm run mine-once # one remint -``` - -## Locked predecessors (do not use) - -- Introspection P2SH handoff (eCash has no native introspection opcodes) -- `mainnet-pow-token-v1-locked.json` — `size-56` trailer bug -- `mainnet-pow-token-v2-locked.json` — Spedn `0x00` empty-push mint bug diff --git a/package.json b/package.json index 5ff8831..e27ae02 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "wlotus", "version": "0.1.0", - "description": "White Lotus (WLOTUS): Ergon-like ALP PoW remint covenant on eCash", + "description": "mWLOTUS / WLOTUS: Ergon-like ALP PoW remint on eCash (incubation milli-token first)", "private": true, "type": "module", "scripts": { @@ -13,7 +13,8 @@ "create-test-token": "tsx scripts/create-test-token.ts", "wait-create-test-token": "tsx scripts/wait-for-funding-and-create.ts", "mine-once": "tsx scripts/mine-once.ts", - "create-pow-token": "tsx scripts/create-pow-token.ts" + "create-pow-token": "tsx scripts/create-pow-token.ts", + "wait-create-mwlotus": "tsx scripts/wait-create-mwlotus.ts" }, "engines": { "node": ">=20" diff --git a/scripts/create-pow-token.ts b/scripts/create-pow-token.ts index 045a1e2..9ca8d4f 100644 --- a/scripts/create-pow-token.ts +++ b/scripts/create-pow-token.ts @@ -1,12 +1,18 @@ #!/usr/bin/env tsx /** - * Create a NEW PoW-mineable ALP test token and lock batons to the Spedn covenant. + * Create mWLOTUS (incubation) PoW token and lock batons to the Spedn covenant. * - * Note: The earlier introspection-based handoff permanently locked 4 WLTEST batons - * (eCash has no OP_OUTPUTBYTECODE etc.). This script creates a fresh token. + * Economics: always 100.00 / remint @ 2 decimals, ~$1e-5/token target, + * 1 leading zero byte PoW. See docs/ECONOMICS.md. */ import { resolve } from 'node:path'; -import { writeFileSync, mkdirSync } from 'node:fs'; +import { + writeFileSync, + mkdirSync, + renameSync, + existsSync, + readFileSync, +} from 'node:fs'; import { config as loadEnv } from 'dotenv'; import { Wallet } from 'ecash-wallet'; import { @@ -21,13 +27,17 @@ import { broadcastAlpGenesis } from '../src/genesis/broadcastGenesis.js'; import { createPowRemintContract } from '../src/covenant/powRemintScript.js'; import { BASE_MINT_ATOMS, + MWLOTUS_PER_WLOTUS, POW_LEADING_ZERO_BYTES, TOKEN_DECIMALS, + TOKEN_NAME, + TOKEN_TICKER, TOKEN_URL, } from '../src/params/consensus.js'; import { TEST_INITIAL_MINT_ATOMS, TEST_POW_BATON_COUNT, + TEST_TARGET_USD_PER_TOKEN, } from '../src/params/testEconomics.js'; loadEnv({ path: resolve(process.cwd(), '.env') }); @@ -47,16 +57,19 @@ async function main(): Promise { { address: wallet.address, balanceXec: Number(wallet.balanceSats) / 100, + ticker: TOKEN_TICKER, + decimals: TOKEN_DECIMALS, + mintPerRemint: Number(BASE_MINT_ATOMS) / 10 ** TOKEN_DECIMALS, + targetUsdPerToken: TEST_TARGET_USD_PER_TOKEN, }, null, 2, ), ); - // 1) Genesis custodial batons (tokenId = txid) const genesis = await broadcastAlpGenesis(wallet, { - ticker: 'WLPOW', - name: 'White Lotus PoW Test', + ticker: TOKEN_TICKER, + name: TOKEN_NAME, url: TOKEN_URL, decimals: TOKEN_DECIMALS, initialMintAtoms: TEST_INITIAL_MINT_ATOMS, @@ -64,7 +77,6 @@ async function main(): Promise { }); console.log('Genesis', genesis.tokenId); - // 2) Build covenant for this tokenId const contract = await createPowRemintContract({ tokenId: genesis.tokenId, mintAtoms: BASE_MINT_ATOMS, @@ -72,7 +84,6 @@ async function main(): Promise { }); console.log('PoW address', contract.address); - // 3) Handoff each baton to P2SH const handoffTxids: string[] = []; for (let i = 0; i < TEST_POW_BATON_COUNT; i++) { await wallet.sync(); @@ -103,15 +114,36 @@ async function main(): Promise { console.log(`Handoff ${i + 1}/${TEST_POW_BATON_COUNT}: ${resp.broadcasted[0]}`); } + const depDir = resolve(process.cwd(), 'deployments'); + mkdirSync(depDir, { recursive: true }); + const livePath = resolve(depDir, 'mainnet-pow-token.json'); + if (existsSync(livePath)) { + const prev = JSON.parse(readFileSync(livePath, 'utf8')) as { + ticker?: string; + }; + const stamp = (prev.ticker || 'prev').toLowerCase(); + const archive = resolve( + depDir, + `mainnet-pow-token-archived-${stamp}-${Date.now()}.json`, + ); + renameSync(livePath, archive); + console.log('Archived previous deployment to', archive); + } + const record = { - ticker: 'WLPOW', - name: 'White Lotus PoW Test', + ticker: TOKEN_TICKER, + name: TOKEN_NAME, tokenId: genesis.tokenId, mode: 'pow', + role: 'incubation', + decimals: TOKEN_DECIMALS, powAddress: contract.address, redeemScriptHex: contract.redeemHex, difficultyLeadingZeroBytes: POW_LEADING_ZERO_BYTES, mintAtomsPerRemint: BASE_MINT_ATOMS.toString(), + tokensPerRemint: Number(BASE_MINT_ATOMS) / 10 ** TOKEN_DECIMALS, + targetUsdPerToken: TEST_TARGET_USD_PER_TOKEN, + mwlotusPerWlotus: Number(MWLOTUS_PER_WLOTUS), initialMintAtoms: TEST_INITIAL_MINT_ATOMS.toString(), powBatonCount: TEST_POW_BATON_COUNT, genesisTxid: genesis.tokenId, @@ -122,19 +154,19 @@ async function main(): Promise { explorer: `https://explorer.e.cash/tx/${genesis.tokenId}`, cashtab: `https://cashtab.com/#/token/${genesis.tokenId}`, notes: [ - 'PoW covenant is Spedn Mist-style (BIP143 preimage). eCash has no native introspection.', - 'Prior WLTEST introspection P2SH batons are permanently locked.', - 'v1 WLPOW (size-56 trailer) and v2 (0x00 empty-push mint bug) batons are locked.', - 'See mainnet-pow-token-v1-locked.json / mainnet-pow-token-v2-locked.json.', + 'mWLOTUS incubation: always 100.00/remint, 2 decimals, 1-byte PoW.', + 'Target ~$0.00001/token (~1/1000 of future WLOTUS at ~$0.01).', + 'Moore δ=99918/100000 applies to work schedule (lib); mint size fixed.', + 'Burn = sacrifice; remint = pure PoW. See docs/ECONOMICS.md.', ], }; - mkdirSync(resolve(process.cwd(), 'deployments'), { recursive: true }); + writeFileSync(livePath, `${JSON.stringify(record, null, 2)}\n`); writeFileSync( - resolve(process.cwd(), 'deployments/mainnet-pow-token.json'), + resolve(depDir, 'mainnet-mwlotus.json'), `${JSON.stringify(record, null, 2)}\n`, ); - console.log('\nPoW token ready'); + console.log('\nmWLOTUS PoW token ready'); console.log(JSON.stringify(record, null, 2)); } diff --git a/scripts/wait-create-mwlotus.ts b/scripts/wait-create-mwlotus.ts new file mode 100644 index 0000000..af9e2c9 --- /dev/null +++ b/scripts/wait-create-mwlotus.ts @@ -0,0 +1,56 @@ +#!/usr/bin/env tsx +/** + * Wait until genesis wallet has enough pure XEC, then create mWLOTUS + mine once. + */ +import { resolve } from 'node:path'; +import { config as loadEnv } from 'dotenv'; +import { spawn } from 'node:child_process'; +import { Wallet } from 'ecash-wallet'; +import { fromHex } from 'ecash-lib'; +import { createChronik } from '../src/network/createChronik.js'; + +loadEnv({ path: resolve(process.cwd(), '.env') }); + +const NEED_SATS = 10_000n; // ~100 XEC headroom +const POLL_MS = 15_000; + +function run(script: string): Promise { + return new Promise((resolveP, reject) => { + const child = spawn('npx', ['tsx', script], { + cwd: process.cwd(), + stdio: 'inherit', + shell: true, + }); + child.on('exit', code => { + if (code === 0) resolveP(); + else reject(new Error(`${script} exited ${code}`)); + }); + }); +} + +async function main(): Promise { + const skHex = process.env.GENESIS_SK_HEX?.trim(); + if (!skHex) throw new Error('GENESIS_SK_HEX missing'); + + const chronik = await createChronik('closest'); + const wallet = Wallet.fromSk(fromHex(skHex), chronik); + + console.log('Waiting for ≥', Number(NEED_SATS) / 100, 'XEC at', wallet.address); + for (;;) { + await wallet.sync(); + const pure = wallet.utxos + .filter(u => !u.token) + .reduce((a, u) => a + u.sats, 0n); + console.log(new Date().toISOString(), 'pureSats', pure.toString()); + if (pure >= NEED_SATS) break; + await new Promise(r => setTimeout(r, POLL_MS)); + } + + await run('scripts/create-pow-token.ts'); + await run('scripts/mine-once.ts'); +} + +main().catch(err => { + console.error(err instanceof Error ? err.stack ?? err.message : err); + process.exit(1); +}); diff --git a/src/index.ts b/src/index.ts index 898443b..6c9b756 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,22 @@ +export { + approxHalfLifeYears, + mintAtomsAfterDays, + mintAtomsAtHostHeight, + mooreAfterDays, + mooreDaysFromHeights, + mooreDaysFromUnix, + mooreStep, + requiredZeroBits, + requiredZeroBytes, +} from './lib/moore.js'; export { BASE_MINT_ATOMS, MOORE_DEN, MOORE_NUM, + MWLOTUS_PER_WLOTUS, POW_BATON_COUNT, POW_LEADING_ZERO_BYTES, + TOKEN_DECIMALS, TOKEN_TICKER, } from './params/consensus.js'; export { @@ -13,15 +26,9 @@ export { TEST_TARGET_USD_PER_TOKEN, TEST_TOKEN_NAME, TEST_TOKEN_TICKER, + TOKENS_PER_REMINT, PROD_TARGET_USD_PER_TOKEN, } from './params/testEconomics.js'; -export { - approxHalfLifeYears, - mintAtomsAfterDays, - mintAtomsAtHostHeight, - mooreDaysFromHeights, - mooreStep, -} from './lib/moore.js'; export { assertMultiBaton, buildGenesisPlan } from './genesis/createGenesis.js'; export { broadcastAlpGenesis, diff --git a/src/lib/moore.ts b/src/lib/moore.ts index ac46aa9..a7e9d5e 100644 --- a/src/lib/moore.ts +++ b/src/lib/moore.ts @@ -1,28 +1,35 @@ import { BASE_MINT_ATOMS, MOORE_DAY_BLOCKS, + MOORE_DAY_SECONDS, + MOORE_DAYS_PER_EXTRA_BIT, MOORE_DEN, MOORE_NUM, MOORE_NUM_OBSOLETE, + POW_BASE_ZERO_BITS, + POW_LEADING_ZERO_BYTES, } from '../params/consensus.js'; /** - * Apply one Moore day-step: x ← floor(x * 99918 / 100000). + * Apply one Moore day-step to a positive integer work/ease value: + * x ← floor(x * 99918 / 100000). + * + * Ergon applies this to work-credit in subsidy. With **fixed** 100 tokens/mint, + * the dual schedule raises required hashes over time (see requiredZeroBits). */ -export function mooreStep(atoms: bigint, num: bigint = MOORE_NUM): bigint { +export function mooreStep(x: bigint, num: bigint = MOORE_NUM): bigint { if (num === MOORE_NUM_OBSOLETE) { throw new Error('Obsolete Moore factor 99826/100000 is forbidden for WLOTUS'); } - return (atoms * num) / MOORE_DEN; + return (x * num) / MOORE_DEN; } /** - * M(k) after k wall-day steps from genesis. - * Matches Ergon's repeated daily correction with δ = 99918/100000. + * After k wall-day steps: x₀ · δ^k (integer iterated). */ -export function mintAtomsAfterDays( +export function mooreAfterDays( days: number, - base: bigint = BASE_MINT_ATOMS, + base: bigint, num: bigint = MOORE_NUM, ): bigint { if (!Number.isInteger(days) || days < 0) { @@ -35,6 +42,18 @@ export function mintAtomsAfterDays( return x; } +/** + * @deprecated Mint atoms are fixed at BASE_MINT_ATOMS. Kept for tests / old docs. + * Prefer requiredZeroBits / mooreAfterDays on a work scale. + */ +export function mintAtomsAfterDays( + days: number, + base: bigint = BASE_MINT_ATOMS, + num: bigint = MOORE_NUM, +): bigint { + return mooreAfterDays(days, base, num); +} + /** * Day index k from host chain heights (Ergon-style day divisions). */ @@ -49,21 +68,55 @@ export function mooreDaysFromHeights( return Math.floor((currentHeight - genesisHeight) / dayBlocks); } +export function mooreDaysFromUnix( + genesisUnix: number, + nowUnix: number, + daySeconds: number = MOORE_DAY_SECONDS, +): number { + if (nowUnix < genesisUnix) { + throw new Error('nowUnix < genesisUnix'); + } + return Math.floor((nowUnix - genesisUnix) / daySeconds); +} + /** - * Expected mint atoms at a host height. + * Required leading zero *bits* after `days` (Koomey-style schedule). + * +1 bit ≈ 2× hashes every MOORE_DAYS_PER_EXTRA_BIT (~840d ≈ 2.3y). + */ +export function requiredZeroBits( + days: number, + baseBits: number = POW_BASE_ZERO_BITS, + daysPerExtraBit: number = MOORE_DAYS_PER_EXTRA_BIT, +): number { + if (!Number.isInteger(days) || days < 0) { + throw new Error('days must be a non-negative integer'); + } + return baseBits + Math.floor(days / daysPerExtraBit); +} + +/** Whole leading zero bytes implied by bit requirement (floor). */ +export function requiredZeroBytes(days: number): number { + return Math.floor(requiredZeroBits(days) / 8); +} + +/** + * Fixed mint atoms (always 100.00 @ 2 decimals) — Moore does not change this. */ export function mintAtomsAtHostHeight( - genesisHeight: number, - currentHeight: number, + _genesisHeight: number, + _currentHeight: number, base: bigint = BASE_MINT_ATOMS, ): bigint { - const k = mooreDaysFromHeights(genesisHeight, currentHeight); - return mintAtomsAfterDays(k, base); + return base; } /** Approximate half-life in years for δ = 99918/100000 (daily steps). */ export function approxHalfLifeYears(num: bigint = MOORE_NUM): number { const delta = Number(num) / Number(MOORE_DEN); - // H = ln(2) / -ln(delta) days, / 365.25 → years return Math.LN2 / -Math.log(delta) / 365.25; } + +/** Genesis incubation difficulty in leading zero bytes. */ +export function incubationZeroBytes(): number { + return POW_LEADING_ZERO_BYTES; +} diff --git a/src/miner/remint.ts b/src/miner/remint.ts index 79e6dc8..2b1dfc6 100644 --- a/src/miner/remint.ts +++ b/src/miner/remint.ts @@ -43,9 +43,9 @@ export { contractForToken }; export function minerBanner(): string { return [ - 'WLOTUS PoW remint miner', + 'mWLOTUS PoW remint miner', `powLeadingZeroBytes=${POW_LEADING_ZERO_BYTES}`, - `baseMintAtoms=${BASE_MINT_ATOMS}`, + `mintAtoms=${BASE_MINT_ATOMS} (always 100.00 @ 2 decimals)`, 'covenant: Spedn Mist-style BIP143 preimage (eCash)', ].join(' | '); } diff --git a/src/params/consensus.ts b/src/params/consensus.ts index 6ee3e0b..cb6e964 100644 --- a/src/params/consensus.ts +++ b/src/params/consensus.ts @@ -1,61 +1,88 @@ /** - * WLOTUS consensus draft parameters. - * Freeze only at GENESIS; until then values may change on chipnet. + * WLOTUS / mWLOTUS consensus parameters. + * + * Incubation token **mWLOTUS** ≈ 1/1000 energy of future **WLOTUS**. + * Freeze only at GENESIS; until then values may change. */ -/** ALP ticker (ASCII). */ -export const TOKEN_TICKER = 'WLOTUS'; +/** Incubation ticker (milli-WLOTUS). */ +export const TOKEN_TICKER = 'mWLOTUS'; /** Human-readable name. */ -export const TOKEN_NAME = 'White Lotus'; +export const TOKEN_NAME = 'milli White Lotus'; /** - * Token decimals. Use enough precision so daily Moore floor-division - * `(x * 99918) / 100000` does not collapse small balances to zero. + * Future production ticker (not this genesis). + * Nominal energy peg: 1000 mWLOTUS ≈ 1 WLOTUS. */ -export const TOKEN_DECIMALS = 6; +export const PROD_TOKEN_TICKER = 'WLOTUS'; + +export const PROD_TOKEN_NAME = 'White Lotus'; /** - * Leading zero *bytes* required on hash256(preimage || nonce). - * Test deployment uses 1 (~$1e-6/token target). Raise for ~$0.01 later. - * @see ./testEconomics.ts + * Decimals for mWLOTUS. Mint amount is fixed (no Moore on atoms), + * so 2 decimals is enough for UX (100.00 per remint). */ -export const POW_LEADING_ZERO_BYTES = 1; +export const TOKEN_DECIMALS = 2; /** - * Base mint atoms at k=0 (genesis day-step). - * 100_000_000 atoms @ 6 decimals = 100 WLOTUS per remint at genesis. - * Must stay large: Ergon applies Moore to huge work values; applying the - * same integer factor to a tiny M₀ reaches 0 in far less than 2.3 years. + * Future WLOTUS decimals (same fixed-100 mint model). */ -export const BASE_MINT_ATOMS = 100_000_000n; +export const PROD_TOKEN_DECIMALS = 2; /** - * Number of parallel PoW mint batons created at genesis. - * Each baton is an independent remint race (true parallelization). - * Test genesis uses 4; production may raise toward 8–16. + * Leading zero *bytes* on hash256(preimage ‖ nonce) at incubation genesis. + * 1 byte ⇒ ~1/256 — cheap dogfood so anyone can mine/burn. + * WLOTUS later raises this (~1000× energy ⇒ roughly +10 bits / ~1–2 bytes). */ +export const POW_LEADING_ZERO_BYTES = 1; + +/** + * Fixed mint per remint (atoms). Always 100.00 tokens @ 2 decimals. + * Moore / Koomey adjusts **difficulty**, not this amount. + */ +export const BASE_MINT_ATOMS = 10_000n; // 100.00 + +/** Parallel PoW mint batons (N ≥ 2). */ export const POW_BATON_COUNT = 4; /** - * Ergon post-fix Moore daily factor numerator. + * Ergon post-fix Moore daily factor numerator (~2.3y half-life). + * Applied to **required work / difficulty**, not to mint atoms. * @see https://github.com/Ergon-moe/Bitcoin-Static/blob/2e8d5f7635c899cc99e71f06dedbe72b3ff7f07b/src/validation.cpp#L978 */ export const MOORE_NUM = 99918n; -/** Moore daily factor denominator. */ export const MOORE_DEN = 100000n; +/** Obsolete Ergon pre-fix factor — forbidden. */ +export const MOORE_NUM_OBSOLETE = 99826n; + +/** Host blocks per Moore day-step (~10 min × 144). */ +export const MOORE_DAY_BLOCKS = 144; + /** - * Obsolete Ergon pre-fix factor (~1.1y half-life). Forbidden for WLOTUS. + * Wall-seconds per Moore day (unix-time schedule). + * Incubation covenants may use height or time; miner uses time. */ -export const MOORE_NUM_OBSOLETE = 99826n; +export const MOORE_DAY_SECONDS = 86_400; /** - * Host blocks per Moore day-step (Ergon uses 144 × 10-minute blocks). - * eCash target spacing is likewise ~10 minutes. + * Extra leading zero *bits* of PoW required per this many Moore days. + * ≈ Ergon half-life (~840d): +1 bit ≈ 2× work when hardware efficiency doubles. + * Full on-chain bit schedule needs stateful difficulty (see docs/ECONOMICS.md); + * incubation mWLOTUS ships fixed genesis bytes and this constant for the library. */ -export const MOORE_DAY_BLOCKS = 144; +export const MOORE_DAYS_PER_EXTRA_BIT = 840; + +/** Base PoW zero-bits at genesis (8 ≡ 1 leading zero byte). */ +export const POW_BASE_ZERO_BITS = POW_LEADING_ZERO_BYTES * 8; + +/** + * Nominal energy conversion when WLOTUS launches: + * 1000 mWLOTUS ↔ 1 WLOTUS (live or burned ledger). + */ +export const MWLOTUS_PER_WLOTUS = 1000n; -/** Document URL placeholder (set before genesis). */ +/** Document URL. */ export const TOKEN_URL = 'https://github.com/bcProFoundation/wlotus'; diff --git a/src/params/testEconomics.ts b/src/params/testEconomics.ts index 4bd29a4..d83e791 100644 --- a/src/params/testEconomics.ts +++ b/src/params/testEconomics.ts @@ -1,38 +1,41 @@ /** - * Test-deployment economics for the first on-chain WLOTUS token. + * Incubation (mWLOTUS) vs production (WLOTUS) economics. * - * Target: mining / remint cost around **$0.000001 per token** (very cheap dogfood). - * Later production aim: around **$0.01 per token** (raise PoW difficulty + retune M₀). + * Ritual loop: burn = sacrifice (destroy supply); remint = pure PoW rebirth. + * Burns create scarcity → support price → pull miners back. * - * At ~$6.6e-6 / XEC (mid-2026 ballpark): - * - One remint fee (~10–50 XEC) is already on the order of $1e-4 … $3e-4. - * - With M₀ = 100 tokens/remint and PoW ≈ free (1 leading zero byte), - * all-in cost per token lands near the $1e-6 target when hashrate is low. + * Price targets are **market** aims (energy + fees + hardware amortisation + + * miner margin), not an on-chain USD oracle. */ -/** Documented target USD per whole token for this test deployment. */ -export const TEST_TARGET_USD_PER_TOKEN = 0.000001; +/** mWLOTUS target ≈ $0.00001 / token ≈ 1/1000 of WLOTUS $0.01. */ +export const TEST_TARGET_USD_PER_TOKEN = 0.00001; -/** Future production target USD per whole token. */ +/** Future WLOTUS target ≈ $0.01 / token ≈ $1 / remint (100 tokens). */ export const PROD_TARGET_USD_PER_TOKEN = 0.01; -/** - * PoW leading zero *bytes* for the test deployment. - * 1 byte ⇒ ~1/256 hashes succeed — trivial on a laptop; not mainnet-hard. - * Raise toward 2–3+ when targeting ~$0.01/token. - */ +/** Fixed tokens per remint (both mWLOTUS and WLOTUS). */ +export const TOKENS_PER_REMINT = 100; + +/** @deprecated use POW_LEADING_ZERO_BYTES from consensus — incubation genesis. */ export const TEST_POW_LEADING_ZERO_BYTES = 1; /** - * Initial fungible mint at genesis (atoms) so temple/burn UX can be tested - * before PoW remint is fully wired. 1e12 atoms @ 6 decimals = 1_000_000 tokens. + * Bootstrap fungible supply for burn UX before heavy reminting. + * 1_000_000 mWLOTUS @ 2 decimals = 100_000_000 atoms. */ -export const TEST_INITIAL_MINT_ATOMS = 1_000_000_000_000n; +export const TEST_INITIAL_MINT_ATOMS = 100_000_000n; -/** Parallel batons for the test genesis (still N ≥ 2). */ export const TEST_POW_BATON_COUNT = 4; -/** Ticker for the cheap test deployment (keep WLOTUS name free for $0.01 launch). */ -export const TEST_TOKEN_TICKER = 'WLTEST'; +export const TEST_TOKEN_TICKER = 'mWLOTUS'; + +export const TEST_TOKEN_NAME = 'milli White Lotus'; + +/** Per-remint USD target at incubation (100 × $1e-5). */ +export const TEST_TARGET_USD_PER_REMINT = + TEST_TARGET_USD_PER_TOKEN * TOKENS_PER_REMINT; -export const TEST_TOKEN_NAME = 'White Lotus Test'; +/** Per-remint USD target at production (100 × $0.01). */ +export const PROD_TARGET_USD_PER_REMINT = + PROD_TARGET_USD_PER_TOKEN * TOKENS_PER_REMINT; diff --git a/tests/moore.test.ts b/tests/moore.test.ts index 65a0b7a..24ef56d 100644 --- a/tests/moore.test.ts +++ b/tests/moore.test.ts @@ -1,22 +1,28 @@ import { approxHalfLifeYears, - mintAtomsAfterDays, mintAtomsAtHostHeight, + mooreAfterDays, mooreDaysFromHeights, mooreStep, + requiredZeroBits, + requiredZeroBytes, } from '../src/lib/moore.js'; import { BASE_MINT_ATOMS, + MOORE_DAYS_PER_EXTRA_BIT, MOORE_NUM, MOORE_NUM_OBSOLETE, + POW_BASE_ZERO_BITS, + TOKEN_DECIMALS, + TOKEN_TICKER, } from '../src/params/consensus.js'; import { assertMultiBaton, buildGenesisPlan, } from '../src/genesis/createGenesis.js'; -describe('moore decay (Ergon 99918/100000)', () => { - test('one step shrinks atoms', () => { +describe('moore decay (Ergon 99918/100000) on work', () => { + test('one step shrinks work scale', () => { const next = mooreStep(BASE_MINT_ATOMS); expect(next).toBe((BASE_MINT_ATOMS * MOORE_NUM) / 100000n); expect(next).toBeLessThan(BASE_MINT_ATOMS); @@ -27,7 +33,7 @@ describe('moore decay (Ergon 99918/100000)', () => { }); test('k=0 returns base', () => { - expect(mintAtomsAfterDays(0)).toBe(BASE_MINT_ATOMS); + expect(mooreAfterDays(0, BASE_MINT_ATOMS)).toBe(BASE_MINT_ATOMS); }); test('day index from heights', () => { @@ -37,10 +43,12 @@ describe('moore decay (Ergon 99918/100000)', () => { expect(mooreDaysFromHeights(1000, 1288)).toBe(2); }); - test('mint at host height', () => { + test('mint atoms stay fixed at host height', () => { const genesis = 500_000; - const day1 = mintAtomsAtHostHeight(genesis, genesis + 144); - expect(day1).toBe(mooreStep(BASE_MINT_ATOMS)); + expect(mintAtomsAtHostHeight(genesis, genesis + 144)).toBe(BASE_MINT_ATOMS); + expect(mintAtomsAtHostHeight(genesis, genesis + 144_000)).toBe( + BASE_MINT_ATOMS, + ); }); test('half-life ~2.3 years for 99918/100000', () => { @@ -49,12 +57,23 @@ describe('moore decay (Ergon 99918/100000)', () => { expect(years).toBeLessThan(2.4); }); - test('after ~2.3y atoms are near half base (not zero)', () => { + test('after ~2.3y work scale is near half (not zero)', () => { const days = Math.round(approxHalfLifeYears() * 365.25); - const half = mintAtomsAfterDays(days); + const half = mooreAfterDays(days, BASE_MINT_ATOMS); expect(half).toBeGreaterThan(BASE_MINT_ATOMS / 3n); expect(half).toBeLessThan((BASE_MINT_ATOMS * 2n) / 3n); }); + + test('required zero bits grow with Moore day schedule', () => { + expect(requiredZeroBits(0)).toBe(POW_BASE_ZERO_BITS); + expect(requiredZeroBits(MOORE_DAYS_PER_EXTRA_BIT - 1)).toBe( + POW_BASE_ZERO_BITS, + ); + expect(requiredZeroBits(MOORE_DAYS_PER_EXTRA_BIT)).toBe( + POW_BASE_ZERO_BITS + 1, + ); + expect(requiredZeroBytes(0)).toBe(1); + }); }); describe('genesis multi-baton', () => { @@ -70,13 +89,17 @@ describe('genesis multi-baton', () => { }); }); -describe('test economics profile', () => { - test('PoW difficulty is low for ~$1e-6 target', async () => { +describe('mWLOTUS incubation economics', () => { + test('cheap target, fixed 100.00 mint, 2 decimals', async () => { const econ = await import('../src/params/testEconomics.js'); + expect(TOKEN_TICKER).toBe('mWLOTUS'); + expect(TOKEN_DECIMALS).toBe(2); + expect(BASE_MINT_ATOMS).toBe(10_000n); expect(econ.TEST_POW_LEADING_ZERO_BYTES).toBe(1); - expect(econ.TEST_TARGET_USD_PER_TOKEN).toBe(0.000001); + expect(econ.TEST_TARGET_USD_PER_TOKEN).toBe(0.00001); expect(econ.PROD_TARGET_USD_PER_TOKEN).toBe(0.01); + expect(econ.TOKENS_PER_REMINT).toBe(100); expect(econ.TEST_POW_BATON_COUNT).toBeGreaterThanOrEqual(2); - expect(econ.TEST_INITIAL_MINT_ATOMS).toBeGreaterThan(0n); + expect(econ.TEST_INITIAL_MINT_ATOMS).toBe(100_000_000n); }); }); From d43581c182c17cf91f5e4a97815c6efed03001ac Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 06:10:16 +0000 Subject: [PATCH 6/6] Deploy mWLPOW incubation token (0 decimals, 100/remint) Retarget incubation to mWLPOW with whole-token decimals, create mainnet genesis + baton handoff, prove remint, and split small fuel before mining so covenant fees no longer burn the wallet change. Co-authored-by: nghiacc --- README.md | 8 +-- contracts/WlotusPowRemint.spedn | 4 +- deployments/mainnet-last-remint.json | 14 ++--- deployments/mainnet-mwlotus.json | 35 +++++++++++ deployments/mainnet-mwlpow.json | 35 +++++++++++ ...-token-archived-mwlotus-1784268595664.json | 35 +++++++++++ ...ow-token-archived-wlpow-1784268348929.json | 30 ++++++++++ deployments/mainnet-pow-token.json | 43 ++++++++------ deployments/pending-funding-mwlotus.json | 15 +++-- docs/ECONOMICS.md | 30 +++++----- docs/SPEC.md | 8 +-- docs/STATUS.md | 21 +++---- docs/TEST_TOKEN.md | 20 +++---- scripts/create-pow-token.ts | 18 +++--- scripts/mine-once.ts | 58 ++++++++++++++++--- scripts/wait-create-mwlotus.ts | 13 +++-- src/miner/remint.ts | 4 +- src/params/consensus.ts | 44 ++++++-------- src/params/testEconomics.ts | 24 +++----- tests/moore.test.ts | 21 +++---- 20 files changed, 326 insertions(+), 154 deletions(-) create mode 100644 deployments/mainnet-mwlotus.json create mode 100644 deployments/mainnet-mwlpow.json create mode 100644 deployments/mainnet-pow-token-archived-mwlotus-1784268595664.json create mode 100644 deployments/mainnet-pow-token-archived-wlpow-1784268348929.json diff --git a/README.md b/README.md index 449f479..d33ce0b 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ See [docs/SPEC.md](./docs/SPEC.md) and [docs/PROPOSAL.md](./docs/PROPOSAL.md). ## Status -**Incubation PoW token `mWLOTUS` is the mining target** — always 100.00/remint @ 2 decimals, +**Incubation PoW token `mWLPOW`** — always 100/remint @ 0 decimals, ~$0.00001/token (~1/1000 of future `WLOTUS` @ ~$0.01). See [docs/ECONOMICS.md](./docs/ECONOMICS.md). ```bash @@ -65,12 +65,12 @@ npm run new-wallet # writes .env + deployments/pending-funding.json npm run create-test-token # ALP GENESIS → deployments/mainnet-test-token.json ``` -Ticker for this dogfood deployment: **`mWLOTUS`**. Keep **`WLOTUS`** for the later ~$0.01 launch +Ticker for this dogfood deployment: **`mWLPOW`**. Keep **`WLOTUS`** for the later ~$0.01 launch (1000:1 energy peg). See [docs/ECONOMICS.md](./docs/ECONOMICS.md). ```bash -npm run create-pow-token # mWLOTUS genesis + handoff to covenant P2SH -npm run mine-once # one permissionless remint (100.00 tokens) +npm run create-pow-token # mWLPOW genesis + handoff to covenant P2SH +npm run mine-once # one permissionless remint (100 tokens) ``` ## License diff --git a/contracts/WlotusPowRemint.spedn b/contracts/WlotusPowRemint.spedn index 1a5a0b5..a8d78b0 100644 --- a/contracts/WlotusPowRemint.spedn +++ b/contracts/WlotusPowRemint.spedn @@ -1,6 +1,6 @@ -// mWLOTUS / WLOTUS PoW remint covenant (eCash / XEC) +// mWLPOW / WLOTUS PoW remint covenant (eCash / XEC) // Mist-style BIP143 preimage (eCash has no native introspection opcodes). -// Mint atoms are FIXED (always 100.00 @ 2 decimals for mWLOTUS). +// Mint atoms are FIXED (always 100 @ 0 decimals for mWLPOW). // Difficulty leading-zero bytes are a constructor param (incubation: 1). // `s` signs hash256(preimage); `ds` is toDataSig(s). diff --git a/deployments/mainnet-last-remint.json b/deployments/mainnet-last-remint.json index 3d4cdee..badc103 100644 --- a/deployments/mainnet-last-remint.json +++ b/deployments/mainnet-last-remint.json @@ -1,9 +1,9 @@ { - "tokenId": "2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", - "txid": "3c37dd37aa846819af11dadba22afe8c707fa07ae9751f5147118dbd0eeef80a", - "powAttempts": 189, - "nonceHex": "bd000000", - "mintAtoms": "100000000", - "minedAt": "2026-07-17T04:29:15.120Z", - "explorer": "https://explorer.e.cash/tx/3c37dd37aa846819af11dadba22afe8c707fa07ae9751f5147118dbd0eeef80a" + "tokenId": "cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", + "txid": "3e9a04f1219d68b85e5f1a521f927e8909d8cb59411367ec1e380515f3afaf55", + "powAttempts": 210, + "nonceHex": "d2000000", + "mintAtoms": "100", + "minedAt": "2026-07-17T06:10:08.115Z", + "explorer": "https://explorer.e.cash/tx/3e9a04f1219d68b85e5f1a521f927e8909d8cb59411367ec1e380515f3afaf55" } diff --git a/deployments/mainnet-mwlotus.json b/deployments/mainnet-mwlotus.json new file mode 100644 index 0000000..449d85a --- /dev/null +++ b/deployments/mainnet-mwlotus.json @@ -0,0 +1,35 @@ +{ + "ticker": "mWLOTUS", + "name": "milli White Lotus", + "tokenId": "b205a6c24f6a12f2e28d8073589fe4947c0ad4e0fc7761d01c1eb42bccc11f56", + "mode": "pow", + "role": "incubation", + "decimals": 2, + "powAddress": "ecash:pp7v69y7ykncc3k6wje3chae8cy0k4uxfs4ys2zq0j", + "redeemScriptHex": "20561fc1cc2bb41e1cd06177fce0d40a7c94e49f5873808de2f2126a4fc2a605b2061027000000005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820134947f757601687f7776517f7704534c50320051807e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "difficultyLeadingZeroBytes": 1, + "mintAtomsPerRemint": "10000", + "tokensPerRemint": 100, + "targetUsdPerToken": 0.00001, + "mwlotusPerWlotus": 1000, + "initialMintAtoms": "100000000", + "powBatonCount": 4, + "genesisTxid": "b205a6c24f6a12f2e28d8073589fe4947c0ad4e0fc7761d01c1eb42bccc11f56", + "handoffTxids": [ + "47f8c1cb755d1a9eb628cd94586a6f2c36018252791cfb259af271c9bb79c192", + "6a5b557cc0c901981002b2dda2696c6e25382882a920293ae68749bf29c442ee", + "cc904050a2b20f9709c5cc709f8bfc7516ebd909f2cc371400a5ba71281c1826", + "420db0525443f0d61713db47c17a95e7feb33c218a4675271303e5268dda4324" + ], + "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "createdAt": "2026-07-17T06:05:48.930Z", + "explorer": "https://explorer.e.cash/tx/b205a6c24f6a12f2e28d8073589fe4947c0ad4e0fc7761d01c1eb42bccc11f56", + "cashtab": "https://cashtab.com/#/token/b205a6c24f6a12f2e28d8073589fe4947c0ad4e0fc7761d01c1eb42bccc11f56", + "notes": [ + "mWLOTUS incubation: always 100.00/remint, 2 decimals, 1-byte PoW.", + "Target ~$0.00001/token (~1/1000 of future WLOTUS at ~$0.01).", + "Moore δ=99918/100000 applies to work schedule (lib); mint size fixed.", + "Burn = sacrifice; remint = pure PoW. See docs/ECONOMICS.md." + ] +} diff --git a/deployments/mainnet-mwlpow.json b/deployments/mainnet-mwlpow.json new file mode 100644 index 0000000..2841fbc --- /dev/null +++ b/deployments/mainnet-mwlpow.json @@ -0,0 +1,35 @@ +{ + "ticker": "mWLPOW", + "name": "milli White Lotus PoW", + "tokenId": "cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", + "mode": "pow", + "role": "incubation", + "decimals": 0, + "powAddress": "ecash:pqplpsn4x8hqgjmycujrekspwxt748e4ju6qqs9lmg", + "redeemScriptHex": "204f49c17d3e0a6bc0ac7ef249159fda23e5b5c43e2815c14fa43dd40e1ce92ecc066400000000005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820134947f757601687f7776517f7704534c50320051807e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "difficultyLeadingZeroBytes": 1, + "mintAtomsPerRemint": "100", + "tokensPerRemint": 100, + "targetUsdPerToken": 0.00001, + "mwlpowPerWlotus": 1000, + "initialMintAtoms": "1000000", + "powBatonCount": 4, + "genesisTxid": "cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", + "handoffTxids": [ + "06ea875f3e06abef4764c212d9545097854a0e42da796478d83fb6af5775d4f9", + "d5ea88a7a87492d844ceda68624316809150aeed8113cc09e6d0f86dd46f1d3b", + "eafc782b541efee85815fd2ec2ea17127143564309a025bf2db6305bd4a78dd3", + "07336e0123efd689dd6eec574f8fdb30b44203d739d964535e60e45733d6f302" + ], + "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "createdAt": "2026-07-17T06:09:55.666Z", + "explorer": "https://explorer.e.cash/tx/cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", + "cashtab": "https://cashtab.com/#/token/cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", + "notes": [ + "mWLPOW incubation: always 100/remint, 0 decimals, 1-byte PoW.", + "Target ~$0.00001/token (~1/1000 of future WLOTUS at ~$0.01).", + "Moore δ=99918/100000 applies to work schedule (lib); mint size fixed.", + "Burn = sacrifice; remint = pure PoW. See docs/ECONOMICS.md." + ] +} diff --git a/deployments/mainnet-pow-token-archived-mwlotus-1784268595664.json b/deployments/mainnet-pow-token-archived-mwlotus-1784268595664.json new file mode 100644 index 0000000..449d85a --- /dev/null +++ b/deployments/mainnet-pow-token-archived-mwlotus-1784268595664.json @@ -0,0 +1,35 @@ +{ + "ticker": "mWLOTUS", + "name": "milli White Lotus", + "tokenId": "b205a6c24f6a12f2e28d8073589fe4947c0ad4e0fc7761d01c1eb42bccc11f56", + "mode": "pow", + "role": "incubation", + "decimals": 2, + "powAddress": "ecash:pp7v69y7ykncc3k6wje3chae8cy0k4uxfs4ys2zq0j", + "redeemScriptHex": "20561fc1cc2bb41e1cd06177fce0d40a7c94e49f5873808de2f2126a4fc2a605b2061027000000005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820134947f757601687f7776517f7704534c50320051807e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "difficultyLeadingZeroBytes": 1, + "mintAtomsPerRemint": "10000", + "tokensPerRemint": 100, + "targetUsdPerToken": 0.00001, + "mwlotusPerWlotus": 1000, + "initialMintAtoms": "100000000", + "powBatonCount": 4, + "genesisTxid": "b205a6c24f6a12f2e28d8073589fe4947c0ad4e0fc7761d01c1eb42bccc11f56", + "handoffTxids": [ + "47f8c1cb755d1a9eb628cd94586a6f2c36018252791cfb259af271c9bb79c192", + "6a5b557cc0c901981002b2dda2696c6e25382882a920293ae68749bf29c442ee", + "cc904050a2b20f9709c5cc709f8bfc7516ebd909f2cc371400a5ba71281c1826", + "420db0525443f0d61713db47c17a95e7feb33c218a4675271303e5268dda4324" + ], + "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "createdAt": "2026-07-17T06:05:48.930Z", + "explorer": "https://explorer.e.cash/tx/b205a6c24f6a12f2e28d8073589fe4947c0ad4e0fc7761d01c1eb42bccc11f56", + "cashtab": "https://cashtab.com/#/token/b205a6c24f6a12f2e28d8073589fe4947c0ad4e0fc7761d01c1eb42bccc11f56", + "notes": [ + "mWLOTUS incubation: always 100.00/remint, 2 decimals, 1-byte PoW.", + "Target ~$0.00001/token (~1/1000 of future WLOTUS at ~$0.01).", + "Moore δ=99918/100000 applies to work schedule (lib); mint size fixed.", + "Burn = sacrifice; remint = pure PoW. See docs/ECONOMICS.md." + ] +} diff --git a/deployments/mainnet-pow-token-archived-wlpow-1784268348929.json b/deployments/mainnet-pow-token-archived-wlpow-1784268348929.json new file mode 100644 index 0000000..78a7784 --- /dev/null +++ b/deployments/mainnet-pow-token-archived-wlpow-1784268348929.json @@ -0,0 +1,30 @@ +{ + "ticker": "WLPOW", + "name": "White Lotus PoW Test", + "tokenId": "2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "mode": "pow", + "powAddress": "ecash:pz0k74f8nkytqh7ntcjhfaccc7wytjdj9ypy8f9z32", + "redeemScriptHex": "2046e578b954a633e6a8a3104c148e4367443f527d2c766d265fbe1fec6e105d2c0600e1f50500005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820134947f757601687f7776517f7704534c50320051807e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "difficultyLeadingZeroBytes": 1, + "mintAtomsPerRemint": "100000000", + "initialMintAtoms": "1000000000000", + "powBatonCount": 4, + "genesisTxid": "2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "handoffTxids": [ + "d793de20fe22f2419028801a82f8825c8411edc40cbd32ae3b11ea063612bf32", + "7083f662855c8cfbdde0d50459839375b96c889d1579623c17a42aa94314ba0c", + "e79fcf3537b6a32b412f1af75d915cd8ade74eaa4f08408a7cc9b743d5825893", + "5f947c502427c2c7c4de875a90f5fe39307cd650da33c45ddc2410ad8c804c8e" + ], + "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", + "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", + "createdAt": "2026-07-17T04:29:12.279Z", + "explorer": "https://explorer.e.cash/tx/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "cashtab": "https://cashtab.com/#/token/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "notes": [ + "PoW covenant is Spedn Mist-style (BIP143 preimage). eCash has no native introspection.", + "Prior WLTEST introspection P2SH batons are permanently locked.", + "v1 WLPOW (size-56 trailer) and v2 (0x00 empty-push mint bug) batons are locked.", + "See mainnet-pow-token-v1-locked.json / mainnet-pow-token-v2-locked.json." + ] +} diff --git a/deployments/mainnet-pow-token.json b/deployments/mainnet-pow-token.json index 78a7784..2841fbc 100644 --- a/deployments/mainnet-pow-token.json +++ b/deployments/mainnet-pow-token.json @@ -1,30 +1,35 @@ { - "ticker": "WLPOW", - "name": "White Lotus PoW Test", - "tokenId": "2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "ticker": "mWLPOW", + "name": "milli White Lotus PoW", + "tokenId": "cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", "mode": "pow", - "powAddress": "ecash:pz0k74f8nkytqh7ntcjhfaccc7wytjdj9ypy8f9z32", - "redeemScriptHex": "2046e578b954a633e6a8a3104c148e4367443f527d2c766d265fbe1fec6e105d2c0600e1f50500005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820134947f757601687f7776517f7704534c50320051807e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", + "role": "incubation", + "decimals": 0, + "powAddress": "ecash:pqplpsn4x8hqgjmycujrekspwxt748e4ju6qqs9lmg", + "redeemScriptHex": "204f49c17d3e0a6bc0ac7ef249159fda23e5b5c43e2815c14fa43dd40e1ce92ecc066400000000005156795579ad55795479a85679bb537958797eaa7652797f75768100885579820128947f777601207f755779820134947f757601687f7776517f7704534c50320051807e547e044d494e547e5a797e517e59797e517e026a5078827751807e787e08000000000000000078827751807e787e08220200000000000001197e0376a9147e5f79a97e0288ac7e08220200000000000001177e02a9147e5579a97e01877e527952797e787eaa5979877777777777777777777777777777777777777777", "difficultyLeadingZeroBytes": 1, - "mintAtomsPerRemint": "100000000", - "initialMintAtoms": "1000000000000", + "mintAtomsPerRemint": "100", + "tokensPerRemint": 100, + "targetUsdPerToken": 0.00001, + "mwlpowPerWlotus": 1000, + "initialMintAtoms": "1000000", "powBatonCount": 4, - "genesisTxid": "2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "genesisTxid": "cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", "handoffTxids": [ - "d793de20fe22f2419028801a82f8825c8411edc40cbd32ae3b11ea063612bf32", - "7083f662855c8cfbdde0d50459839375b96c889d1579623c17a42aa94314ba0c", - "e79fcf3537b6a32b412f1af75d915cd8ade74eaa4f08408a7cc9b743d5825893", - "5f947c502427c2c7c4de875a90f5fe39307cd650da33c45ddc2410ad8c804c8e" + "06ea875f3e06abef4764c212d9545097854a0e42da796478d83fb6af5775d4f9", + "d5ea88a7a87492d844ceda68624316809150aeed8113cc09e6d0f86dd46f1d3b", + "eafc782b541efee85815fd2ec2ea17127143564309a025bf2db6305bd4a78dd3", + "07336e0123efd689dd6eec574f8fdb30b44203d739d964535e60e45733d6f302" ], "authPubkey": "02cbd0b249b5ef2fa254807319aff2728013fa8756b4a73b1996480d430ff6bb0e", "genesisAddress": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", - "createdAt": "2026-07-17T04:29:12.279Z", - "explorer": "https://explorer.e.cash/tx/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", - "cashtab": "https://cashtab.com/#/token/2c5d106eec1fbe5f266d762c7d523f4467438e144c10a3a8e633a654b978e546", + "createdAt": "2026-07-17T06:09:55.666Z", + "explorer": "https://explorer.e.cash/tx/cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", + "cashtab": "https://cashtab.com/#/token/cc2ee91c0ed43da44fc115283ec4b5e523da9f1549f27eacc06b0a3e7dc1494f", "notes": [ - "PoW covenant is Spedn Mist-style (BIP143 preimage). eCash has no native introspection.", - "Prior WLTEST introspection P2SH batons are permanently locked.", - "v1 WLPOW (size-56 trailer) and v2 (0x00 empty-push mint bug) batons are locked.", - "See mainnet-pow-token-v1-locked.json / mainnet-pow-token-v2-locked.json." + "mWLPOW incubation: always 100/remint, 0 decimals, 1-byte PoW.", + "Target ~$0.00001/token (~1/1000 of future WLOTUS at ~$0.01).", + "Moore δ=99918/100000 applies to work schedule (lib); mint size fixed.", + "Burn = sacrifice; remint = pure PoW. See docs/ECONOMICS.md." ] } diff --git a/deployments/pending-funding-mwlotus.json b/deployments/pending-funding-mwlotus.json index eebafe8..b0dd237 100644 --- a/deployments/pending-funding-mwlotus.json +++ b/deployments/pending-funding-mwlotus.json @@ -1,15 +1,14 @@ { - "purpose": "Fund genesis wallet to create mWLOTUS PoW incubation token", + "purpose": "Fund genesis wallet to create mWLPOW PoW incubation token", "address": "ecash:qrkf3e43xhu4cl8syfqja4k0g4kchzzt0yf4w00sm7", - "needXec": 100, - "ticker": "mWLOTUS", - "decimals": 2, + "needXec": 200, + "ticker": "mWLPOW", + "decimals": 0, "tokensPerRemint": 100, "targetUsdPerToken": 0.00001, - "mwlotusPerWlotus": 1000, - "createdAt": "2026-07-17T05:20:00.000Z", + "mwlpowPerWlotus": 1000, "notes": [ - "Send ≥ 100 XEC to the address, then: npm run create-pow-token && npm run mine-once", - "Or: npm run wait-create-mwlotus" + "Prior wait spent ~2000 XEC on accidental mWLOTUS (2-dec) deploy + remint without change.", + "Send ≥ 200 XEC, then: npm run wait-create-mwlotus" ] } diff --git a/docs/ECONOMICS.md b/docs/ECONOMICS.md index 655e77a..c627302 100644 --- a/docs/ECONOMICS.md +++ b/docs/ECONOMICS.md @@ -1,4 +1,4 @@ -# Economics — mWLOTUS → WLOTUS +# Economics — mWLPOW → WLOTUS ## Ritual loop @@ -9,40 +9,38 @@ Burn does **not** cancel remint. Burns tighten float → support price → incentivise miners to remint again. -## Incubation: mWLOTUS +## Incubation: mWLPOW | Knob | Value | |------|-------| -| Ticker | `mWLOTUS` (milli White Lotus) | -| Decimals | **2** | -| Tokens / remint | **Always 100.00** (fixed) | +| Ticker | `mWLPOW` | +| Decimals | **0** (whole tokens) | +| Tokens / remint | **Always 100** (fixed) | | PoW | Leading zero bytes on `hash256(preimage ‖ nonce)` | -| Genesis difficulty | **1** leading zero byte (~1/256) — anyone can mine | +| Genesis difficulty | **1** leading zero byte (~1/256) | | Target market price | **~$0.00001 / token** (~$0.001 / remint) | | vs WLOTUS | **~1/1000** energy / price | -Moore / Koomey (`δ = 99918/100000`, ~2.3y half-life) adjusts **required work**, not the 100-token mint. Incubation genesis uses a **fixed** cheap difficulty so the network can be dogfooded immediately; the same δ is used in `src/lib/moore.ts` to schedule how work should grow (library + future stateful covenant). Full on-chain Moore-on-difficulty (time-derived or baton-state) lands with the WLOTUS upgrade path — Script cannot read “now”, so a naïve locktime day-index is cheatable with old timestamps. +Moore / Koomey (`δ = 99918/100000`, ~2.3y half-life) adjusts **required work**, not the 100-token mint. Incubation genesis uses **fixed** cheap difficulty; the same δ is in `src/lib/moore.ts` for the work schedule. ## Production: WLOTUS (later) | Knob | Value | |------|-------| | Ticker | `WLOTUS` | -| Tokens / remint | **Always 100.00** | +| Tokens / remint | **Always 100** | | Target market price | **~$0.01 / token** (~$1 / remint) | -| Difficulty | ~**1000×** mWLOTUS genesis work (retune `D₀`; then Moore on work) | +| Difficulty | ~**1000×** mWLPOW genesis work | -`$0.01` is a **market** target: energy + XEC fees + hardware subsidy + miner profit — not a pure joule oracle. +`$0.01` is a **market** target (energy + fees + hardware + miner margin), not a USD oracle. ## Energy peg / conversion -Because both tokens use the same fixed-100 + Moore-on-work family: - ``` -1000 mWLOTUS ≈ 1 WLOTUS +1000 mWLPOW ≈ 1 WLOTUS ``` -for **circulating and burned** balances when the app matures (conversion / memorial ledger). Exact redemption UX is app-layer; consensus only needs compatible issuance physics. +for circulating and burned balances when the app matures. ## Elasticity @@ -51,3 +49,7 @@ coins/time ≈ N_batons × (hashrate / hashes_per_solution) × 100 ``` Many remints per eCash block, N ≥ 2 batons, no Mist 1-mint/block CLTV. + +## Miner note + +The remint covenant commits to exactly **3 outputs** (mint OP_RETURN + miner P2PKH + baton P2SH). Excess fuel is fee — `mine-once` splits a ~30 XEC fuel UTXO first. diff --git a/docs/SPEC.md b/docs/SPEC.md index f0777b0..c4e345c 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -6,16 +6,16 @@ See also [ECONOMICS.md](./ECONOMICS.md). | Param | Value | Notes | |-------|-------|-------| -| Ticker | `mWLOTUS` | milli White Lotus (~1/1000 of future WLOTUS) | -| Name | `milli White Lotus` | | +| Ticker | `mWLPOW` | milli White Lotus PoW (~1/1000 of future WLOTUS) | +| Name | `milli White Lotus PoW` | | | Protocol | ALP standard (`SLP2`) | eCash | -| Decimals | `2` | Fixed mint size — no Moore on atoms | +| Decimals | `0` | Whole tokens; fixed mint size | ## PoW remint | Param | Value | Notes | |-------|-------|-------| -| Tokens / remint | **Always 100.00** | `BASE_MINT_ATOMS = 10_000` | +| Tokens / remint | **Always 100** | `BASE_MINT_ATOMS = 100` | | `POW_LEADING_ZERO_BYTES` (genesis) | `1` | Cheap incubation (~$1e-5/token target) | | Moore / Koomey | On **work**, not mint size | `δ = 99918/100000` | | Host 1-mint/block CLTV | **disabled** | Frequency elasticity | diff --git a/docs/STATUS.md b/docs/STATUS.md index c94675f..0139296 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -2,35 +2,28 @@ Canonical home: **https://github.com/bcProFoundation/wlotus** -## Live incubation — **mWLOTUS** +## Live incubation — **mWLPOW** | | | |--|--| | Role | Cheap PoW token so anyone can mine & burn before the app | -| Economics | Always **100.00**/remint @ **2** decimals; ~**$0.00001**/token; 1-byte PoW | -| Peg | **1000 mWLOTUS ≈ 1 WLOTUS** (later launch @ ~$0.01/token) | +| Economics | Always **100**/remint @ **0** decimals; ~**$0.00001**/token; 1-byte PoW | +| Peg | **1000 mWLPOW ≈ 1 WLOTUS** (later launch @ ~$0.01/token) | | Docs | [ECONOMICS.md](./ECONOMICS.md) · [TEST_TOKEN.md](./TEST_TOKEN.md) | ```bash -npm run mine-once +npm run create-pow-token && npm run mine-once +# or: npm run wait-create-mwlotus ``` -## Design sources - -| Doc | Role | -|-----|------| -| [ECONOMICS.md](./ECONOMICS.md) | Ritual loop, mWLOTUS ↔ WLOTUS, Moore-on-work | -| [PROPOSAL.md](./PROPOSAL.md) | Product decision (ALP on eCash first) | -| [SPEC.md](./SPEC.md) | Consensus draft | -| [ARCHITECTURE.md](./ARCHITECTURE.md) | Covenant / multi-baton flow | - ## Covenant notes (eCash) - No native introspection → Spedn Mist-style BIP143 preimage covenant - Mint size **fixed**; Moore δ schedules **work** (lib + future stateful D) +- Remint has exactly 3 covenant outputs — `mine-once` splits small fuel first ## Next -1. Temple / burn app (separate repo) against mWLOTUS +1. Temple / burn app against mWLPOW 2. Stateful Moore-on-difficulty covenant revision 3. WLOTUS genesis (~1000× difficulty) + conversion UX diff --git a/docs/TEST_TOKEN.md b/docs/TEST_TOKEN.md index 88a3183..77400e4 100644 --- a/docs/TEST_TOKEN.md +++ b/docs/TEST_TOKEN.md @@ -1,23 +1,23 @@ # Test / incubation deployments (mainnet) -## Mine and burn this: **mWLOTUS** +## Mine and burn this: **mWLPOW** Incubation token ≈ **1/1000** of future `WLOTUS` energy/price. | Field | Value | |-------|-------| -| Ticker | `mWLOTUS` | -| Decimals | **2** | -| Tokens / remint | **Always 100.00** | +| Ticker | `mWLPOW` | +| Decimals | **0** | +| Tokens / remint | **Always 100** | | PoW | 1 leading zero byte | | Target | ~**$0.00001** / token | -| Conversion | 1000 mWLOTUS ≈ 1 WLOTUS (later) | +| Conversion | 1000 mWLPOW ≈ 1 WLOTUS (later) | -Record: [`deployments/mainnet-mwlotus.json`](../deployments/mainnet-mwlotus.json) (also `mainnet-pow-token.json`). +Record: [`deployments/mainnet-mwlpow.json`](../deployments/mainnet-mwlpow.json) (also `mainnet-pow-token.json`). ```bash -npm run create-pow-token # genesis + baton handoff -npm run mine-once # one PoW remint +npm run create-pow-token +npm run mine-once ``` Economics: [ECONOMICS.md](./ECONOMICS.md) @@ -26,8 +26,8 @@ Economics: [ECONOMICS.md](./ECONOMICS.md) | Token | Notes | |-------|-------| -| WLPOW | Prior PoW plumbing tests (6 decimals / fixed D) | -| WLTEST | Custodial only | +| mWLOTUS | Accidental 2-dec deploy while waiting on funding | +| WLPOW / WLTEST | Earlier plumbing / custodial tests | ## Chronik diff --git a/scripts/create-pow-token.ts b/scripts/create-pow-token.ts index 9ca8d4f..60c4488 100644 --- a/scripts/create-pow-token.ts +++ b/scripts/create-pow-token.ts @@ -1,8 +1,8 @@ #!/usr/bin/env tsx /** - * Create mWLOTUS (incubation) PoW token and lock batons to the Spedn covenant. + * Create mWLPOW (incubation) PoW token and lock batons to the Spedn covenant. * - * Economics: always 100.00 / remint @ 2 decimals, ~$1e-5/token target, + * Economics: always 100 / remint @ 0 decimals, ~$1e-5/token target, * 1 leading zero byte PoW. See docs/ECONOMICS.md. */ import { resolve } from 'node:path'; @@ -27,7 +27,7 @@ import { broadcastAlpGenesis } from '../src/genesis/broadcastGenesis.js'; import { createPowRemintContract } from '../src/covenant/powRemintScript.js'; import { BASE_MINT_ATOMS, - MWLOTUS_PER_WLOTUS, + MWLPOW_PER_WLOTUS, POW_LEADING_ZERO_BYTES, TOKEN_DECIMALS, TOKEN_NAME, @@ -59,7 +59,7 @@ async function main(): Promise { balanceXec: Number(wallet.balanceSats) / 100, ticker: TOKEN_TICKER, decimals: TOKEN_DECIMALS, - mintPerRemint: Number(BASE_MINT_ATOMS) / 10 ** TOKEN_DECIMALS, + mintPerRemint: Number(BASE_MINT_ATOMS), targetUsdPerToken: TEST_TARGET_USD_PER_TOKEN, }, null, @@ -141,9 +141,9 @@ async function main(): Promise { redeemScriptHex: contract.redeemHex, difficultyLeadingZeroBytes: POW_LEADING_ZERO_BYTES, mintAtomsPerRemint: BASE_MINT_ATOMS.toString(), - tokensPerRemint: Number(BASE_MINT_ATOMS) / 10 ** TOKEN_DECIMALS, + tokensPerRemint: Number(BASE_MINT_ATOMS), targetUsdPerToken: TEST_TARGET_USD_PER_TOKEN, - mwlotusPerWlotus: Number(MWLOTUS_PER_WLOTUS), + mwlpowPerWlotus: Number(MWLPOW_PER_WLOTUS), initialMintAtoms: TEST_INITIAL_MINT_ATOMS.toString(), powBatonCount: TEST_POW_BATON_COUNT, genesisTxid: genesis.tokenId, @@ -154,7 +154,7 @@ async function main(): Promise { explorer: `https://explorer.e.cash/tx/${genesis.tokenId}`, cashtab: `https://cashtab.com/#/token/${genesis.tokenId}`, notes: [ - 'mWLOTUS incubation: always 100.00/remint, 2 decimals, 1-byte PoW.', + 'mWLPOW incubation: always 100/remint, 0 decimals, 1-byte PoW.', 'Target ~$0.00001/token (~1/1000 of future WLOTUS at ~$0.01).', 'Moore δ=99918/100000 applies to work schedule (lib); mint size fixed.', 'Burn = sacrifice; remint = pure PoW. See docs/ECONOMICS.md.', @@ -163,10 +163,10 @@ async function main(): Promise { writeFileSync(livePath, `${JSON.stringify(record, null, 2)}\n`); writeFileSync( - resolve(depDir, 'mainnet-mwlotus.json'), + resolve(depDir, 'mainnet-mwlpow.json'), `${JSON.stringify(record, null, 2)}\n`, ); - console.log('\nmWLOTUS PoW token ready'); + console.log('\nmWLPOW PoW token ready'); console.log(JSON.stringify(record, null, 2)); } diff --git a/scripts/mine-once.ts b/scripts/mine-once.ts index 4c6b69b..a0cf9fa 100644 --- a/scripts/mine-once.ts +++ b/scripts/mine-once.ts @@ -1,12 +1,15 @@ #!/usr/bin/env tsx /** - * Mine one PoW remint against WLPOW batons in the Spedn covenant. + * Mine one PoW remint against mWLPOW batons. + * + * The covenant fixes exactly 3 outputs (OP_RETURN + miner mint + baton), so + * excess fuel becomes fee. We therefore split a small pure-XEC UTXO first. */ import { resolve } from 'node:path'; import { readFileSync, writeFileSync, existsSync } from 'node:fs'; import { config as loadEnv } from 'dotenv'; import { Wallet } from 'ecash-wallet'; -import { fromHex, toHex } from 'ecash-lib'; +import { fromHex, payment, toHex } from 'ecash-lib'; import { createChronik } from '../src/network/createChronik.js'; import { buildMinedRemintTx, @@ -16,6 +19,43 @@ import { loadEnv({ path: resolve(process.cwd(), '.env') }); +/** Small fuel for remint — keeps covenant fee sane (no change output allowed). */ +const REMINT_FUEL_SATS = 3_000n; + +async function ensureSmallFuel(wallet: Wallet): Promise { + await wallet.sync(); + const small = wallet.utxos.find( + u => + !u.token && + u.sats >= REMINT_FUEL_SATS && + u.sats <= REMINT_FUEL_SATS + 2_000n, + ); + if (small) return; + + const big = wallet.utxos + .filter(u => !u.token && u.sats > REMINT_FUEL_SATS + 5_000n) + .sort((a, b) => (a.sats < b.sats ? 1 : -1))[0]; + if (!big) { + throw new Error( + `Need a pure XEC UTXO ≥ ${REMINT_FUEL_SATS + 5_000n} sats to split remint fuel`, + ); + } + + console.log( + `Splitting fuel: ${big.sats} → ${REMINT_FUEL_SATS} + change at ${wallet.address}`, + ); + // Pure XEC tx — no blank OP_RETURN (wallet forbids it on non-token txs). + const action: payment.Action = { + outputs: [{ sats: REMINT_FUEL_SATS, script: wallet.script }], + }; + const resp = await wallet.action(action).build().broadcast(); + if (!resp.success || !resp.broadcasted?.length) { + throw new Error(`Fuel split failed: ${JSON.stringify(resp)}`); + } + console.log('Fuel split tx', resp.broadcasted[0]); + await wallet.sync(); +} + async function main(): Promise { console.log(minerBanner()); const skHex = process.env.GENESIS_SK_HEX?.trim(); @@ -25,16 +65,18 @@ async function main(): Promise { const depPath = resolve(process.cwd(), 'deployments/mainnet-pow-token.json'); if (!existsSync(depPath)) { - throw new Error('Missing deployments/mainnet-pow-token.json — run npm run create-pow-token'); + throw new Error( + 'Missing deployments/mainnet-pow-token.json — run npm run create-pow-token', + ); } const dep = JSON.parse(readFileSync(depPath, 'utf8')); const tokenId = process.env.TOKEN_ID?.trim() || dep.tokenId; const chronik = await createChronik('closest'); const wallet = Wallet.fromSk(fromHex(skHex), chronik); - await wallet.sync(); - const contract = await contractForToken(tokenId); + await ensureSmallFuel(wallet); + const contract = await contractForToken(tokenId); if (dep.powAddress && dep.powAddress !== contract.address) { throw new Error( `Address mismatch: dep=${dep.powAddress} computed=${contract.address}`, @@ -62,9 +104,11 @@ async function main(): Promise { vout: b.outpoint.outIdx as number, }; - const fuelUtxo = wallet.utxos.find(u => !u.token && u.sats >= 2_000n); + const fuelUtxo = wallet.utxos + .filter(u => !u.token && u.sats >= REMINT_FUEL_SATS) + .sort((a, b) => (a.sats < b.sats ? -1 : 1))[0]; if (!fuelUtxo) { - throw new Error('Need a ≥20 XEC pure XEC UTXO for fees'); + throw new Error(`Need a ≥${REMINT_FUEL_SATS} pure XEC UTXO for fees`); } console.log( diff --git a/scripts/wait-create-mwlotus.ts b/scripts/wait-create-mwlotus.ts index af9e2c9..e2eb6db 100644 --- a/scripts/wait-create-mwlotus.ts +++ b/scripts/wait-create-mwlotus.ts @@ -1,6 +1,6 @@ #!/usr/bin/env tsx /** - * Wait until genesis wallet has enough pure XEC, then create mWLOTUS + mine once. + * Wait until genesis wallet has enough pure XEC, then create mWLPOW + mine once. */ import { resolve } from 'node:path'; import { config as loadEnv } from 'dotenv'; @@ -11,8 +11,8 @@ import { createChronik } from '../src/network/createChronik.js'; loadEnv({ path: resolve(process.cwd(), '.env') }); -const NEED_SATS = 10_000n; // ~100 XEC headroom -const POLL_MS = 15_000; +const NEED_SATS = 15_000n; // ~150 XEC headroom (genesis + handoffs + fuel split) +const POLL_MS = 10_000; function run(script: string): Promise { return new Promise((resolveP, reject) => { @@ -35,7 +35,12 @@ async function main(): Promise { const chronik = await createChronik('closest'); const wallet = Wallet.fromSk(fromHex(skHex), chronik); - console.log('Waiting for ≥', Number(NEED_SATS) / 100, 'XEC at', wallet.address); + console.log( + 'Waiting for ≥', + Number(NEED_SATS) / 100, + 'XEC at', + wallet.address, + ); for (;;) { await wallet.sync(); const pure = wallet.utxos diff --git a/src/miner/remint.ts b/src/miner/remint.ts index 2b1dfc6..5a0d19b 100644 --- a/src/miner/remint.ts +++ b/src/miner/remint.ts @@ -43,9 +43,9 @@ export { contractForToken }; export function minerBanner(): string { return [ - 'mWLOTUS PoW remint miner', + 'mWLPOW PoW remint miner', `powLeadingZeroBytes=${POW_LEADING_ZERO_BYTES}`, - `mintAtoms=${BASE_MINT_ATOMS} (always 100.00 @ 2 decimals)`, + `mintAtoms=${BASE_MINT_ATOMS} (always 100 @ 0 decimals)`, 'covenant: Spedn Mist-style BIP143 preimage (eCash)', ].join(' | '); } diff --git a/src/params/consensus.ts b/src/params/consensus.ts index cb6e964..48a0322 100644 --- a/src/params/consensus.ts +++ b/src/params/consensus.ts @@ -1,47 +1,44 @@ /** - * WLOTUS / mWLOTUS consensus parameters. + * WLOTUS / mWLPOW consensus parameters. * - * Incubation token **mWLOTUS** ≈ 1/1000 energy of future **WLOTUS**. + * Incubation token **mWLPOW** ≈ 1/1000 energy of future **WLOTUS**. * Freeze only at GENESIS; until then values may change. */ -/** Incubation ticker (milli-WLOTUS). */ -export const TOKEN_TICKER = 'mWLOTUS'; +/** Incubation ticker (milli-WLPOW test). */ +export const TOKEN_TICKER = 'mWLPOW'; /** Human-readable name. */ -export const TOKEN_NAME = 'milli White Lotus'; +export const TOKEN_NAME = 'milli White Lotus PoW'; /** * Future production ticker (not this genesis). - * Nominal energy peg: 1000 mWLOTUS ≈ 1 WLOTUS. + * Nominal energy peg: 1000 mWLPOW ≈ 1 WLOTUS. */ export const PROD_TOKEN_TICKER = 'WLOTUS'; export const PROD_TOKEN_NAME = 'White Lotus'; /** - * Decimals for mWLOTUS. Mint amount is fixed (no Moore on atoms), - * so 2 decimals is enough for UX (100.00 per remint). + * Decimals for mWLPOW incubation. Whole tokens only (no fractional). + * Mint is always 100 tokens per remint. */ -export const TOKEN_DECIMALS = 2; +export const TOKEN_DECIMALS = 0; -/** - * Future WLOTUS decimals (same fixed-100 mint model). - */ -export const PROD_TOKEN_DECIMALS = 2; +/** Future WLOTUS decimals (same fixed-100 mint model). */ +export const PROD_TOKEN_DECIMALS = 0; /** * Leading zero *bytes* on hash256(preimage ‖ nonce) at incubation genesis. * 1 byte ⇒ ~1/256 — cheap dogfood so anyone can mine/burn. - * WLOTUS later raises this (~1000× energy ⇒ roughly +10 bits / ~1–2 bytes). */ export const POW_LEADING_ZERO_BYTES = 1; /** - * Fixed mint per remint (atoms). Always 100.00 tokens @ 2 decimals. + * Fixed mint per remint (atoms). Always 100 tokens @ 0 decimals. * Moore / Koomey adjusts **difficulty**, not this amount. */ -export const BASE_MINT_ATOMS = 10_000n; // 100.00 +export const BASE_MINT_ATOMS = 100n; /** Parallel PoW mint batons (N ≥ 2). */ export const POW_BATON_COUNT = 4; @@ -49,7 +46,6 @@ export const POW_BATON_COUNT = 4; /** * Ergon post-fix Moore daily factor numerator (~2.3y half-life). * Applied to **required work / difficulty**, not to mint atoms. - * @see https://github.com/Ergon-moe/Bitcoin-Static/blob/2e8d5f7635c899cc99e71f06dedbe72b3ff7f07b/src/validation.cpp#L978 */ export const MOORE_NUM = 99918n; @@ -61,17 +57,12 @@ export const MOORE_NUM_OBSOLETE = 99826n; /** Host blocks per Moore day-step (~10 min × 144). */ export const MOORE_DAY_BLOCKS = 144; -/** - * Wall-seconds per Moore day (unix-time schedule). - * Incubation covenants may use height or time; miner uses time. - */ +/** Wall-seconds per Moore day. */ export const MOORE_DAY_SECONDS = 86_400; /** * Extra leading zero *bits* of PoW required per this many Moore days. - * ≈ Ergon half-life (~840d): +1 bit ≈ 2× work when hardware efficiency doubles. - * Full on-chain bit schedule needs stateful difficulty (see docs/ECONOMICS.md); - * incubation mWLOTUS ships fixed genesis bytes and this constant for the library. + * ≈ Ergon half-life (~840d): +1 bit ≈ 2× work. */ export const MOORE_DAYS_PER_EXTRA_BIT = 840; @@ -80,9 +71,12 @@ export const POW_BASE_ZERO_BITS = POW_LEADING_ZERO_BYTES * 8; /** * Nominal energy conversion when WLOTUS launches: - * 1000 mWLOTUS ↔ 1 WLOTUS (live or burned ledger). + * 1000 mWLPOW ↔ 1 WLOTUS. */ export const MWLOTUS_PER_WLOTUS = 1000n; +/** Alias for the same peg. */ +export const MWLPOW_PER_WLOTUS = MWLOTUS_PER_WLOTUS; + /** Document URL. */ export const TOKEN_URL = 'https://github.com/bcProFoundation/wlotus'; diff --git a/src/params/testEconomics.ts b/src/params/testEconomics.ts index d83e791..a480de3 100644 --- a/src/params/testEconomics.ts +++ b/src/params/testEconomics.ts @@ -1,41 +1,35 @@ /** - * Incubation (mWLOTUS) vs production (WLOTUS) economics. + * Incubation (mWLPOW) vs production (WLOTUS) economics. * * Ritual loop: burn = sacrifice (destroy supply); remint = pure PoW rebirth. - * Burns create scarcity → support price → pull miners back. - * - * Price targets are **market** aims (energy + fees + hardware amortisation + - * miner margin), not an on-chain USD oracle. */ -/** mWLOTUS target ≈ $0.00001 / token ≈ 1/1000 of WLOTUS $0.01. */ +/** mWLPOW target ≈ $0.00001 / token ≈ 1/1000 of WLOTUS $0.01. */ export const TEST_TARGET_USD_PER_TOKEN = 0.00001; /** Future WLOTUS target ≈ $0.01 / token ≈ $1 / remint (100 tokens). */ export const PROD_TARGET_USD_PER_TOKEN = 0.01; -/** Fixed tokens per remint (both mWLOTUS and WLOTUS). */ +/** Fixed tokens per remint (both mWLPOW and WLOTUS). */ export const TOKENS_PER_REMINT = 100; -/** @deprecated use POW_LEADING_ZERO_BYTES from consensus — incubation genesis. */ +/** @deprecated use POW_LEADING_ZERO_BYTES from consensus. */ export const TEST_POW_LEADING_ZERO_BYTES = 1; /** - * Bootstrap fungible supply for burn UX before heavy reminting. - * 1_000_000 mWLOTUS @ 2 decimals = 100_000_000 atoms. + * Bootstrap fungible supply for burn UX. + * 1_000_000 mWLPOW @ 0 decimals = 1_000_000 atoms. */ -export const TEST_INITIAL_MINT_ATOMS = 100_000_000n; +export const TEST_INITIAL_MINT_ATOMS = 1_000_000n; export const TEST_POW_BATON_COUNT = 4; -export const TEST_TOKEN_TICKER = 'mWLOTUS'; +export const TEST_TOKEN_TICKER = 'mWLPOW'; -export const TEST_TOKEN_NAME = 'milli White Lotus'; +export const TEST_TOKEN_NAME = 'milli White Lotus PoW'; -/** Per-remint USD target at incubation (100 × $1e-5). */ export const TEST_TARGET_USD_PER_REMINT = TEST_TARGET_USD_PER_TOKEN * TOKENS_PER_REMINT; -/** Per-remint USD target at production (100 × $0.01). */ export const PROD_TARGET_USD_PER_REMINT = PROD_TARGET_USD_PER_TOKEN * TOKENS_PER_REMINT; diff --git a/tests/moore.test.ts b/tests/moore.test.ts index 24ef56d..8a2e7be 100644 --- a/tests/moore.test.ts +++ b/tests/moore.test.ts @@ -57,11 +57,12 @@ describe('moore decay (Ergon 99918/100000) on work', () => { expect(years).toBeLessThan(2.4); }); - test('after ~2.3y work scale is near half (not zero)', () => { + test('after ~2.3y large work scale is near half (not zero)', () => { + const work0 = 100_000_000n; // not mint atoms — work scale must stay large const days = Math.round(approxHalfLifeYears() * 365.25); - const half = mooreAfterDays(days, BASE_MINT_ATOMS); - expect(half).toBeGreaterThan(BASE_MINT_ATOMS / 3n); - expect(half).toBeLessThan((BASE_MINT_ATOMS * 2n) / 3n); + const half = mooreAfterDays(days, work0); + expect(half).toBeGreaterThan(work0 / 3n); + expect(half).toBeLessThan((work0 * 2n) / 3n); }); test('required zero bits grow with Moore day schedule', () => { @@ -89,17 +90,17 @@ describe('genesis multi-baton', () => { }); }); -describe('mWLOTUS incubation economics', () => { - test('cheap target, fixed 100.00 mint, 2 decimals', async () => { +describe('mWLPOW incubation economics', () => { + test('cheap target, fixed 100 mint, 0 decimals', async () => { const econ = await import('../src/params/testEconomics.js'); - expect(TOKEN_TICKER).toBe('mWLOTUS'); - expect(TOKEN_DECIMALS).toBe(2); - expect(BASE_MINT_ATOMS).toBe(10_000n); + expect(TOKEN_TICKER).toBe('mWLPOW'); + expect(TOKEN_DECIMALS).toBe(0); + expect(BASE_MINT_ATOMS).toBe(100n); expect(econ.TEST_POW_LEADING_ZERO_BYTES).toBe(1); expect(econ.TEST_TARGET_USD_PER_TOKEN).toBe(0.00001); expect(econ.PROD_TARGET_USD_PER_TOKEN).toBe(0.01); expect(econ.TOKENS_PER_REMINT).toBe(100); expect(econ.TEST_POW_BATON_COUNT).toBeGreaterThanOrEqual(2); - expect(econ.TEST_INITIAL_MINT_ATOMS).toBe(100_000_000n); + expect(econ.TEST_INITIAL_MINT_ATOMS).toBe(1_000_000n); }); });