Repository navigation
chore: versioning alignment - #194
Conversation
feat: 💚 added gitlab ci See merge request fireblocks/key-backup/recovery-utility!1
test: new-version label test See merge request fireblocks/key-backup/recovery-utility!2
Merge Hidden branch into Main See merge request fireblocks/key-backup/recovery-utility!12
Feat/btc api key See merge request fireblocks/key-backup/recovery-utility!14
Fix: missing evm keys See merge request fireblocks/key-backup/recovery-utility!13
Feat/mobile key share v2 See merge request fireblocks/key-backup/recovery-utility!21
…address calculation
Fix/tron address y coordinate padding See merge request fireblocks/key-backup/recovery-utility!23
Fix two bugs preventing NCW recovery from working: - RecoveryForm checked for 'ncwMaster' but recoverKeys returns 'ncwWalletMaster' - useBaseWorkspace placed ncwMaster at the workspace top-level instead of on extendedKeys where all consumers (Layout, /ncw page, wallet derivation) read it Add EdDSA (MPC_EDDSA_ED25519) support to NCW wallet share derivation: - BIP-32 hardened child derivation always uses secp256k1 (matches cloud cosigner) - SHA-512 expansion reduced directly mod the target curve order (ed25519.CURVE.n) - Export both ECDSA and EdDSA shares per wallet in the derive output JSON - Fix leading-zero padding in hex-encoded wallet shares
# Conflicts: # apps/recovery-relay/package.json # apps/recovery-utility/package.json
feat: fix NCW recovery and add EdDSA wallet share derivation See merge request fireblocks/key-backup/recovery-utility!24
| ncwWalletMasters: masterKeys, | ||
| keysetThMapping, | ||
| maxKeysetId, | ||
| } = parseMetadataFile(metadataFile.getData().toString()); |
There was a problem hiding this comment.
Risk: Affected versions of adm-zip are vulnerable to Memory Allocation with Excessive Size Value. adm-zip allocates a ZIP entry's output buffer with Buffer.alloc() sized from the uncompressed size declared in the archive's central directory, before validating that value against the data actually present. Reading, testing, or extracting a crafted archive via readFile(), readFileAsync(), readAsText(), readAsTextAsync(), extractEntryTo(), extractAllTo(), extractAllToAsync(), test(), or a per-entry getData()/getDataAsync() therefore commits the attacker-declared allocation before any CRC or size check runs. A 105-byte ZIP with a single stored entry declaring a size of 1,774,399,200 commits roughly 1.8 GB of resident memory — about 16 million times the input size — which can exhaust process memory and deny service, and will OOM-kill the process outright on memory-constrained hosts such as containers or serverless runtimes.
Fix: Upgrade this library to at least version 0.6.1 at recovery/yarn.lock:5131.
Reference(s): https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-83170, GHSA-7q85-xj36-vmfc
🌟 Fixed in commit 6a09be8 🌟
| for (const file of zipFiles) { | ||
| if (file.entryName.startsWith('MOBILE')) { | ||
| const { keyId, playerId, value } = recoverMobileKeyShare(signingKeys, file.getData().toString(), mobilePass); | ||
| const { keyId, playerId, value } = recoverMobileKeyShare(signingKeys, file.getData().toString(), mobilePass, onLog); |
There was a problem hiding this comment.
Risk: Affected versions of adm-zip are vulnerable to Memory Allocation with Excessive Size Value. adm-zip allocates a ZIP entry's output buffer with Buffer.alloc() sized from the uncompressed size declared in the archive's central directory, before validating that value against the data actually present. Reading, testing, or extracting a crafted archive via readFile(), readFileAsync(), readAsText(), readAsTextAsync(), extractEntryTo(), extractAllTo(), extractAllToAsync(), test(), or a per-entry getData()/getDataAsync() therefore commits the attacker-declared allocation before any CRC or size check runs. A 105-byte ZIP with a single stored entry declaring a size of 1,774,399,200 commits roughly 1.8 GB of resident memory — about 16 million times the input size — which can exhaust process memory and deny service, and will OOM-kill the process outright on memory-constrained hosts such as containers or serverless runtimes.
Fix: Upgrade this library to at least version 0.6.1 at recovery/yarn.lock:5131.
Reference(s): https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-83170, GHSA-7q85-xj36-vmfc
🌟 Fixed in commit 6a09be8 🌟
| ncwWalletMasters: masterKeys, | ||
| keysetThMapping, | ||
| maxKeysetId, | ||
| } = parseMetadataFile(metadataFile.getData().toString()); |
There was a problem hiding this comment.
Risk: Affected versions of adm-zip are vulnerable to Memory Allocation with Excessive Size Value / Uncontrolled Resource Consumption. adm-zip allocates a decompression buffer sized directly from the untrusted uncompressed-size field in a ZIP entry header without validating it against the actual compressed data. When reading, testing, or extracting a crafted archive via readFile(), readAsText(), readAsTextAsync(), extractEntryTo(), extractAllTo(), extractAllToAsync(), test(), or a per-entry getData(), a tiny (~120-byte) ZIP declaring a multi-gigabyte uncompressed size forces an enormous Buffer.alloc, exhausting process memory and causing a denial of service.
Fix: Upgrade this library to at least version 0.6.0 at recovery/yarn.lock:5131.
Reference(s): https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-42960, GHSA-xcpc-8h2w-3j85, CVE-2026-39244
🧼 Fixed in commit 6a09be8 🧼
| for (const file of zipFiles) { | ||
| if (file.entryName.startsWith('MOBILE')) { | ||
| const { keyId, playerId, value } = recoverMobileKeyShare(signingKeys, file.getData().toString(), mobilePass); | ||
| const { keyId, playerId, value } = recoverMobileKeyShare(signingKeys, file.getData().toString(), mobilePass, onLog); |
There was a problem hiding this comment.
Risk: Affected versions of adm-zip are vulnerable to Memory Allocation with Excessive Size Value / Uncontrolled Resource Consumption. adm-zip allocates a decompression buffer sized directly from the untrusted uncompressed-size field in a ZIP entry header without validating it against the actual compressed data. When reading, testing, or extracting a crafted archive via readFile(), readAsText(), readAsTextAsync(), extractEntryTo(), extractAllTo(), extractAllToAsync(), test(), or a per-entry getData(), a tiny (~120-byte) ZIP declaring a multi-gigabyte uncompressed size forces an enormous Buffer.alloc, exhausting process memory and causing a denial of service.
Fix: Upgrade this library to at least version 0.6.0 at recovery/yarn.lock:5131.
Reference(s): https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-42960, GHSA-xcpc-8h2w-3j85, CVE-2026-39244
🍰 Fixed in commit 6a09be8 🍰
|
Semgrep found 1 Risk: Affected versions of node-forge are vulnerable to Interpretation Conflict. An attacker can craft malicious ASN.1 data that desynchronizes node-forge's asn1.validate on optional field boundaries, causing subsequent mandatory fields—such as digital signatures or MACs in X.509, PKCS#7, PKCS#12 and related protocols—to be skipped or verified against attacker-controlled bytes, effectively bypassing critical integrity checks. Fix: Upgrade this library to at least version 1.3.2 at recovery/yarn.lock:11168. Reference(s): https://euvd.enisa.europa.eu/vulnerability/EUVD-2025-199630, GHSA-5gfm-wpxj-wjgq Semgrep found 1 Risk: Affected versions of node-forge are vulnerable to Uncontrolled Recursion. Unbounded recursion in node-forge's ASN.1 DER parser ( Fix: Upgrade this library to at least version 1.3.2 at recovery/yarn.lock:11168. Reference(s): https://euvd.enisa.europa.eu/vulnerability/EUVD-2025-199767, GHSA-554w-wpv2-vw27 |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved critical CI, security, build, and wallet/signing issues block approval.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 24
Open (33)
Avoid persisting GITHUB_TOKEN in Git remote URL · New TRIGGER dotenv variable is unavailable in this job · New Missing TRIGGER dotenv dependency skips GitHub sync · New Bash-only syntax fails under Alpine BusyBox shell · New Cherry-pick failures are swallowed, producing incomplete mirrors · New Derivation interface lacks setAPIKey capability · New Relay wallet union lacks setAPIKey · New API keys are exposed in settings logs · New Relay page uses utility settings and main-process context · New RawSigningForm wallet type is incompatible with relay accounts · New API key is exposed in browser console logging · New Logs IPC handler returns no archive data · New Renderer imports non-safe main-process DeploymentStore · New Relay response QR payload lacks required metadata · New Dual algorithm selections are silently collapsed · New Duplicate signing enums cause incompatible types · New Unmapped keyset sentinel can be selected · New EdDSA keyset uses the wrong private key field · New ECDSA-only and EdDSA-only keysets are rejected · New Shared hook imports Electron main-process code · New
And 13 more that still need to be addressed.
What changed in this PR
This PR removes outdated GitHub release links while adding multi-keyset recovery, raw signing, expanded wallet/token support, API-key settings, logging, and CI/build automation. Unresolved correctness, security, compatibility, and pipeline issues remain.
Changes:
- Adds algorithm-aware recovery and account-specific key derivation.
- Adds raw-signing flows and broader blockchain asset support.
- Updates logging, RPC/API-key handling, builds, and CI mirroring.
| File | Reviewed change |
|---|---|
test.txt |
Adds sync marker. |
scripts/build-cross-platform.sh |
Adds cross-platform build script. |
README.md |
Removes release link. |
packages/wallet-derivation/wallets/NCWallet.ts |
Adds EdDSA NCW derivation. |
packages/wallet-derivation/wallets/EdDSAWallet.ts |
Updates byte handling. |
packages/wallet-derivation/wallets/ECDSAWallet.ts |
Adds message signing. |
packages/wallet-derivation/wallets/chains/XRP.ts |
Updates XRP reserve configuration. |
packages/wallet-derivation/wallets/chains/Tron.ts |
Pads public-key coordinates. |
packages/wallet-derivation/wallets/chains/EVM.ts |
Supports configurable chain IDs. |
packages/wallet-derivation/wallets/BaseWallet.ts |
Selects account keysets. |
packages/wallet-derivation/types.ts |
Updates key and share types. |
packages/shared/schemas/settingsInput.ts |
Adds API-key settings. |
packages/shared/schemas/relayUrl.ts |
Adds raw-signing schemas. |
packages/shared/schemas/recoverKeysInput.ts |
Adds JSON passphrases. |
packages/shared/schemas/recoverAccountInput.ts |
Adds keyset mapping inputs. |
packages/shared/schemas/extendedKeys.ts |
Adds keyset schemas. |
packages/shared/reducers/rawSignReducer.ts |
Adds raw-signing state. |
packages/shared/pages/keys.tsx |
Removes shared keys page. |
packages/shared/pages/csv.tsx |
Updates key types. |
packages/shared/pages/accounts/vault/index.tsx |
Adds keyset props. |
packages/shared/lib/validateAddress.ts |
Updates validator patching. |
packages/shared/lib/relayUrl.ts |
Routes raw-signing messages. |
packages/shared/lib/getLogger.ts |
Adds daily log folders. |
packages/shared/index.ts |
Updates exports. |
packages/shared/hooks/useRawSignMessage.ts |
Implements signing flow. |
packages/shared/hooks/useRawSign.ts |
Adds raw-sign state hook. |
packages/shared/hooks/useBaseWorkspace/types.ts |
Adds app-specific key types. |
packages/shared/hooks/useBaseWorkspace/reduceDerivations.ts |
Selects mapped keysets. |
packages/shared/hooks/useBaseWorkspace/index.ts |
Adds keyset workspace handling. |
packages/shared/components/TextField/index.tsx |
Fixes controlled values. |
packages/shared/components/RelayRxTx/index.tsx |
Enables QR URL input. |
packages/shared/components/RawSigningForm/Signature/index.tsx |
Displays signatures. |
packages/shared/components/RawSigningForm/index.tsx |
Adds signing form. |
packages/shared/components/Modals/RecoverAccountModal/index.tsx |
Adds keyset mapping UI. |
packages/shared/components/Modals/AddressesModal/index.tsx |
Updates address keys. |
packages/shared/components/index.ts |
Exports new components. |
packages/shared/components/DerivationPathInput/index.tsx |
Adds path input. |
packages/extended-key-recovery/src/types.ts |
Adds keyset metadata types. |
packages/extended-key-recovery/src/reconstructKeys.ts |
Reconstructs keyed results. |
packages/extended-key-recovery/src/ncw.ts |
Updates buffer casts. |
packages/extended-key-recovery/src/mobileKey.ts |
Adds V2 decryption. |
packages/extended-key-recovery/src/metadata.ts |
Parses keyset metadata. |
packages/extended-key-recovery/src/decrypt.ts |
Implements V2 decryption. |
packages/extended-key-recovery/src/algorithms.ts |
Adds algorithm helpers. |
packages/e2e-tests/utils.ts |
Updates ZIP writing. |
packages/asset-config/util.ts |
Recognizes account explorers. |
packages/asset-config/types.ts |
Adds account explorer types. |
packages/asset-config/index.ts |
Exports SPL assets. |
packages/asset-config/data/globalAssets.ts |
Adds assets. |
packages/asset-config/config/patches.ts |
Adds explorer and RPC patches. |
packages/asset-config/assets.ts |
Registers SPL and token assets. |
package.json |
Adds all-platform build command. |
docs/CODEOWNERS |
Updates owners. |
apps/recovery-utility/renderer/pages/setup.tsx |
Updates RSA encryption. |
apps/recovery-utility/renderer/pages/settings.tsx |
Adjusts settings layout. |
apps/recovery-utility/renderer/pages/raw-signing.tsx |
Adds utility raw signing. |
apps/recovery-utility/renderer/pages/ncw.tsx |
Derives both NCW algorithms. |
apps/recovery-utility/renderer/pages/keys.tsx |
Uses local keys page. |
apps/recovery-utility/renderer/pages/index.tsx |
Adds keyset lookup. |
apps/recovery-utility/renderer/pages/csv.tsx |
Uses account keysets. |
apps/recovery-utility/renderer/pages/accounts/vault/index.tsx |
Adds keyset mapping data. |
apps/recovery-utility/renderer/pages/accounts/vault/[accountId]/index.tsx |
Uses account keys. |
apps/recovery-utility/renderer/lib/wallets/XLM/index.ts |
Handles account creation. |
apps/recovery-utility/renderer/lib/wallets/SPL/index.ts |
Adds SPL signing. |
apps/recovery-utility/renderer/lib/wallets/index.ts |
Registers new wallets. |
apps/recovery-utility/renderer/lib/wallets/FLR/index.ts |
Adds Flare wallet. |
apps/recovery-utility/renderer/lib/wallets/EVM/index.ts |
Supports chain IDs. |
apps/recovery-utility/renderer/lib/wallets/ERC20/index.ts |
Caps priority fees. |
apps/recovery-utility/renderer/lib/recoverExtendedKeys.ts |
Adds recovery logging. |
apps/recovery-utility/renderer/context/Workspace.tsx |
Uses account keysets. |
apps/recovery-utility/renderer/components/RecoveryForm/index.tsx |
Adds passphrase JSON handling. |
apps/recovery-utility/renderer/components/Modals/WithdrawModal/SignTransaction/index.tsx |
Signs with account keys. |
apps/recovery-utility/renderer/components/Modals/WithdrawModal/index.tsx |
Uses account-specific keys. |
apps/recovery-utility/renderer/components/Modals/RawSigningModal/index.tsx |
Adds QR signing. |
apps/recovery-utility/renderer/components/Layout/index.tsx |
Adds raw-sign navigation. |
apps/recovery-utility/README.md |
Removes release links. |
apps/recovery-utility/package.json |
Adds build target. |
apps/recovery-utility/main/ipc/getLogs.ts |
Changes log paths. |
apps/recovery-utility/main/background.ts |
Updates log resets. |
apps/recovery-utility/electron-builder.json |
Adds architecture targets. |
apps/recovery-relay/pages/settings.tsx |
Adds API-key editing. |
apps/recovery-relay/pages/raw-signing.tsx |
Adds relay raw signing. |
apps/recovery-relay/package.json |
Adds SPL dependency. |
apps/recovery-relay/lib/wallets/XRP/index.ts |
Calculates dynamic reserves. |
apps/recovery-relay/lib/wallets/XLM/index.ts |
Detects new destinations. |
apps/recovery-relay/lib/wallets/SPL/unsupported_solana_assets.ts |
Adds unsupported asset metadata. |
apps/recovery-relay/lib/wallets/SPL/index.ts |
Adds SPL relay support. |
apps/recovery-relay/lib/wallets/index.ts |
Registers relay wallets. |
apps/recovery-relay/lib/wallets/EVM/FLR.ts |
Adds Flare relay support. |
apps/recovery-relay/lib/wallets/ERC20/index.ts |
Validates token decimals. |
apps/recovery-relay/lib/wallets/ConnectedWallet.ts |
Extends broadcast signature. |
apps/recovery-relay/lib/wallets/BTCBased/ZEC.ts |
Adds API-key support. |
apps/recovery-relay/lib/wallets/BTCBased/LTC.ts |
Adds API-key support. |
apps/recovery-relay/lib/wallets/BTCBased/DOGE.ts |
Adds API-key support. |
apps/recovery-relay/lib/wallets/BTCBased/DASH.ts |
Adds API-key support. |
apps/recovery-relay/lib/wallets/BTCBased/BTCRelayWalletUtils.ts |
Adds API-key requests. |
apps/recovery-relay/lib/wallets/BTCBased/BTCRelayWallet.ts |
Propagates API keys. |
apps/recovery-relay/lib/wallets/BTCBased/BTC.ts |
Updates BTC relay handling. |
apps/recovery-relay/lib/defaultRPCs.ts |
Adds RPC and API-key metadata. |
apps/recovery-relay/context/Workspace.tsx |
Integrates keyset workspace. |
apps/recovery-relay/context/Settings.tsx |
Persists settings. |
apps/recovery-relay/components/WithdrawModal/index.tsx |
Uses API-key RPC data. |
apps/recovery-relay/components/WithdrawModal/CreateTransaction/index.tsx |
Adds API-key setup. |
apps/recovery-relay/components/RawSigningModal/index.tsx |
Displays signed QR results. |
apps/recovery-relay/components/Layout/index.tsx |
Adds raw-sign navigation. |
.gitlab-ci.yml |
Adds version, build, and mirror pipeline. |
.gitignore |
Ignores Claude files. |
.changeset/wild-timers-think.md |
Documents keyset derivation. |
.changeset/violet-ducks-joke.md |
Documents multi-keyset recovery. |
.changeset/tender-turtles-destroy.md |
Documents keys-page relocation. |
.changeset/orange-bobcats-taste.md |
Documents test updates. |
.changeset/old-drinks-camp.md |
Documents workspace typing. |
.changeset/giant-cups-explode.md |
Documents keyset mapping. |
.changeset/eleven-cheetahs-rest.md |
Documents account key selection. |
.changeset/dry-paws-thank.md |
Documents keyset display. |
.changeset/blue-gorillas-rush.md |
Documents key type updates. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| description: "Checkpoint from which to start mirroring to github from main branch" | ||
| value: "" | ||
| EXECUTABLES_DIR: "apps/recovery-utility/dist" | ||
| GITHUB_REPO: "https://oauth2:${GITHUB_TOKEN}@github.com/fireblocks/mirror-test.git" |
|
|
||
| build_linux: | ||
| stage: build | ||
| needs: [version_packages] |
| sync_to_github: | ||
| stage: sync | ||
| image: alpine:latest | ||
| needs: [build_linux] |
| if [[ "$TAGS" != *"${EXCLUDE_TAG}"* ]]; then | ||
| echo $COMMIT >> selected_commits.txt; | ||
| fi; |
|
|
||
| - | | ||
| while read COMMIT; do | ||
| git cherry-pick $COMMIT || echo "Cherry-pick failed or already applied: $COMMIT"; |
| mobilePassphrase: | ||
| formData.passphraseJson !== null | ||
| ? formData.passphraseJson.passphrase | ||
| : formData.autoGeneratedPass | ||
| ? formData.agpRsaPassphrase | ||
| : formData.passphrase, |
| if (!xpub || !fpub) { | ||
| return undefined; | ||
| } |
|
|
||
| if (ecdsa) { | ||
| (extendedKeys as Record<number, RecoveredKey>)[Number(entry[0])].ecdsaMinAccount = | ||
| !newAccountId || newAccountId < 0 ? accounts.size : newAccountId; |
| selectedWallet.path = { | ||
| ...selectedWallet.path, | ||
| changeIndex: inputChangeIndex, | ||
| addressIndex: inputAdressIndex, | ||
| }; |
| public isValidAddress(address: string, networkProtocol: string | undefined, assetId: string): boolean { | ||
| try { | ||
| this.patchValidator(); | ||
| // this.patchValidator(); |
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|


No description provided.