Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,6 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(git log:*),Bash(git diff:*),Bash(git blame:*),Read,Glob,Grep"
5 changes: 5 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,11 @@ swift.swiftdoc
# Ignore LDKNodeFFI.xcframework files
/bindings/swift/LDKNodeFFI.xcframework

# Build artifacts
Comment thread
ovitrif marked this conversation as resolved.
*.o
*.a
*.d

# IDE and local files
.idea
.build
Expand Down
48 changes: 32 additions & 16 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,18 +54,11 @@ cargo clippy --fix

### Language Bindings
```bash
# Generate Kotlin bindings
./scripts/uniffi_bindgen_generate_kotlin.sh

# Generate Android bindings
./scripts/uniffi_bindgen_generate_kotlin_android.sh

# Generate Python bindings
./scripts/uniffi_bindgen_generate_python.sh

# Generate Swift bindings
./scripts/uniffi_bindgen_generate_swift.sh
# Generate ALL bindings (Swift, Kotlin, Python) + xcframework archive
./bindgen.sh
```
Individual scripts live under `scripts/` but should NOT be run directly —
`bindgen.sh` installs shared tooling once and sets the correct build profile.

## Architecture

Expand DownExpand Up@@ -122,7 +115,17 @@ You are an extremely strict senior Rust systems engineer with 15+ years shipping

Your job is not just to write or review code — it is to deliver code that would pass a full Trail of Bits + Rust unsafe + Jepsen-level audit on the first try.

Follow this exact multi-stage process and never skip or summarize any stage:
Follow this exact multi-stage process and never skip or summarize any stage, with
one exception for automated CI reviews (see below):

**Automated CI code reviews (GitHub Actions):** When running as the `code-review`
plugin in GitHub Actions, build and test tools (Bash, cargo, etc.) are unavailable.
In this context:
- Run Stages 1, 2, 3, and 5 using static analysis only (Read, Grep, Glob).
- Skip Stage 4 (Testing) and Stage 6 (Build & CI Verification) entirely.
Do NOT attempt to run cargo, build, or test commands.
- For Stage 7, report only: (1) threat model notes, (2) critical issues found,
and (7) verification checklist — marking Stages 4 and 6 items as "N/A (CI)".

Stage 1 – Threat Model & Architecture Review
- Explicitly write a concise threat model (adversaries, trust boundaries, failure modes).
Expand DownExpand Up@@ -187,7 +190,8 @@ Only after completing all stages above, output in this exact order:
- Architecture is minimal and correct

Never say "trust me" or "in practice this would pass". You must demonstrate everything above explicitly.
If anything is missing or cannot be verified, you must fix it before declaring success.
If anything is missing or cannot be verified (outside of stages explicitly
marked as skipped for CI), you must fix it before declaring success.

---
## RULES
Expand All@@ -196,7 +200,7 @@ If anything is missing or cannot be verified, you must fix it before declaring s
- NEVER suggest manually adding @Serializable annotations to generated Kotlin bindings
- ALWAYS run `cargo fmt` before committing to ensure consistent code formatting
- ALWAYS move imports to the top of the file when applicable (no inline imports in functions)
- NEVER run binding generation scripts yourself - always ask the user to run them (they are long-running and resource-intensive)
- Run `./bindgen.sh` in the background when bindings need regeneration (it is long-running)

## Bindings Generation Command
To regenerate ALL bindings (Swift, Kotlin, Python), run from the repo root:
Expand All@@ -215,21 +219,33 @@ When bumping the version, ALWAYS update ALL of these files:

## CHANGELOG
- The Synonym fork maintains a SINGLE section at the top: `# X.X.X (Synonym Fork)`
- This section is **cumulative** — it contains ALL changes across ALL rc versions for this fork
- When bumping version, update the version in the existing heading (don't create new sections)
- All Synonym fork additions go under ONE `## Synonym Fork Additions` subsection
- New additions should be added at the TOP of the Synonym Fork Additions list
- Do NOT create separate sections for each rc version
- Use the CHANGELOG content as the GitHub release notes body
- **GitHub release notes are NOT the full CHANGELOG** — see PR Release Workflow below

## PR Release Workflow
- For PRs that bump version, ALWAYS create a release on the PR branch BEFORE merge
- **CRITICAL: Commit and push ALL changes to the branch BEFORE tagging.** The tag must
point to a commit that contains every change included in the release (CHANGELOG, version
bumps, bindings, etc.). Never tag uncommitted or unpushed work.
- Tag the last commit on the PR branch with the version from Cargo.toml (e.g., `v0.7.0-rc.6`)
- **CRITICAL: Before uploading `LDKNodeFFI.xcframework.zip`, ALWAYS verify the checksum matches `Package.swift`:**
```bash
shasum -a 256 bindings/swift/LDKNodeFFI.xcframework.zip
# Compare output with the checksum value in Package.swift - they MUST match
```
- Create GitHub release with same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- Create GitHub release as **published** (not draft) and **set as latest release**, with
same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- **Release notes = DELTA only.** Describe only what changed since the previous release
(e.g., rc.31 notes list only changes since rc.30). Do NOT paste the full cumulative
CHANGELOG section — that covers all rc versions combined. Write concise notes covering
the PR's changes: bug fixes, features, optimizations, and binding/version updates.
- Release notes are for **consumers of the bindings** — cover only Rust code changes,
FFI changes, and binding updates. Do NOT include internal CI, documentation, or
workflow changes.
- **ALWAYS add release link at the end of PR description** (use `gh pr edit` to update the body):
```
### Release
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
# 0.7.0-rc.29 (Synonym Fork)
# 0.7.0-rc.32 (Synonym Fork)

## Bug Fixes

- Fixed cumulative change-address derivation index leak during fee estimation and dry-run
transaction builds. BDK's `TxBuilder::finish()` advances the internal (change) keychain index
each time it's called; repeated fee estimations would burn through change addresses without
broadcasting any transaction. All dry-run and error-after-`finish()` paths now cancel the PSBT
to unmark the change address for reuse.
- Bumped `FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS` and `TX_BROADCAST_TIMEOUT_SECS` from 5s to 15s.
The 5s node-level timeout fires before Electrum can complete a request (10s timeout), causing
`FeerateEstimationUpdateTimeout` on node start.
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,6 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(git log:*),Bash(git diff:*),Bash(git blame:*),Read,Glob,Grep"
5 changes: 5 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,11 @@ swift.swiftdoc
# Ignore LDKNodeFFI.xcframework files
/bindings/swift/LDKNodeFFI.xcframework

# Build artifacts
Comment thread
ovitrif marked this conversation as resolved.
*.o
*.a
*.d

# IDE and local files
.idea
.build
Expand Down
48 changes: 32 additions & 16 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,18 +54,11 @@ cargo clippy --fix

### Language Bindings
```bash
# Generate Kotlin bindings
./scripts/uniffi_bindgen_generate_kotlin.sh

# Generate Android bindings
./scripts/uniffi_bindgen_generate_kotlin_android.sh

# Generate Python bindings
./scripts/uniffi_bindgen_generate_python.sh

# Generate Swift bindings
./scripts/uniffi_bindgen_generate_swift.sh
# Generate ALL bindings (Swift, Kotlin, Python) + xcframework archive
./bindgen.sh
```
Individual scripts live under `scripts/` but should NOT be run directly —
`bindgen.sh` installs shared tooling once and sets the correct build profile.

## Architecture

Expand DownExpand Up@@ -122,7 +115,17 @@ You are an extremely strict senior Rust systems engineer with 15+ years shipping

Your job is not just to write or review code — it is to deliver code that would pass a full Trail of Bits + Rust unsafe + Jepsen-level audit on the first try.

Follow this exact multi-stage process and never skip or summarize any stage:
Follow this exact multi-stage process and never skip or summarize any stage, with
one exception for automated CI reviews (see below):

**Automated CI code reviews (GitHub Actions):** When running as the `code-review`
plugin in GitHub Actions, build and test tools (Bash, cargo, etc.) are unavailable.
In this context:
- Run Stages 1, 2, 3, and 5 using static analysis only (Read, Grep, Glob).
- Skip Stage 4 (Testing) and Stage 6 (Build & CI Verification) entirely.
Do NOT attempt to run cargo, build, or test commands.
- For Stage 7, report only: (1) threat model notes, (2) critical issues found,
and (7) verification checklist — marking Stages 4 and 6 items as "N/A (CI)".

Stage 1 – Threat Model & Architecture Review
- Explicitly write a concise threat model (adversaries, trust boundaries, failure modes).
Expand DownExpand Up@@ -187,7 +190,8 @@ Only after completing all stages above, output in this exact order:
- Architecture is minimal and correct

Never say "trust me" or "in practice this would pass". You must demonstrate everything above explicitly.
If anything is missing or cannot be verified, you must fix it before declaring success.
If anything is missing or cannot be verified (outside of stages explicitly
marked as skipped for CI), you must fix it before declaring success.

---
## RULES
Expand All@@ -196,7 +200,7 @@ If anything is missing or cannot be verified, you must fix it before declaring s
- NEVER suggest manually adding @Serializable annotations to generated Kotlin bindings
- ALWAYS run `cargo fmt` before committing to ensure consistent code formatting
- ALWAYS move imports to the top of the file when applicable (no inline imports in functions)
- NEVER run binding generation scripts yourself - always ask the user to run them (they are long-running and resource-intensive)
- Run `./bindgen.sh` in the background when bindings need regeneration (it is long-running)

## Bindings Generation Command
To regenerate ALL bindings (Swift, Kotlin, Python), run from the repo root:
Expand All@@ -215,21 +219,33 @@ When bumping the version, ALWAYS update ALL of these files:

## CHANGELOG
- The Synonym fork maintains a SINGLE section at the top: `# X.X.X (Synonym Fork)`
- This section is **cumulative** — it contains ALL changes across ALL rc versions for this fork
- When bumping version, update the version in the existing heading (don't create new sections)
- All Synonym fork additions go under ONE `## Synonym Fork Additions` subsection
- New additions should be added at the TOP of the Synonym Fork Additions list
- Do NOT create separate sections for each rc version
- Use the CHANGELOG content as the GitHub release notes body
- **GitHub release notes are NOT the full CHANGELOG** — see PR Release Workflow below

## PR Release Workflow
- For PRs that bump version, ALWAYS create a release on the PR branch BEFORE merge
- **CRITICAL: Commit and push ALL changes to the branch BEFORE tagging.** The tag must
point to a commit that contains every change included in the release (CHANGELOG, version
bumps, bindings, etc.). Never tag uncommitted or unpushed work.
- Tag the last commit on the PR branch with the version from Cargo.toml (e.g., `v0.7.0-rc.6`)
- **CRITICAL: Before uploading `LDKNodeFFI.xcframework.zip`, ALWAYS verify the checksum matches `Package.swift`:**
```bash
shasum -a 256 bindings/swift/LDKNodeFFI.xcframework.zip
# Compare output with the checksum value in Package.swift - they MUST match
```
- Create GitHub release with same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- Create GitHub release as **published** (not draft) and **set as latest release**, with
same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- **Release notes = DELTA only.** Describe only what changed since the previous release
(e.g., rc.31 notes list only changes since rc.30). Do NOT paste the full cumulative
CHANGELOG section — that covers all rc versions combined. Write concise notes covering
the PR's changes: bug fixes, features, optimizations, and binding/version updates.
- Release notes are for **consumers of the bindings** — cover only Rust code changes,
FFI changes, and binding updates. Do NOT include internal CI, documentation, or
workflow changes.
- **ALWAYS add release link at the end of PR description** (use `gh pr edit` to update the body):
```
### Release
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
# 0.7.0-rc.29 (Synonym Fork)
# 0.7.0-rc.32 (Synonym Fork)

## Bug Fixes

- Fixed cumulative change-address derivation index leak during fee estimation and dry-run
transaction builds. BDK's `TxBuilder::finish()` advances the internal (change) keychain index
each time it's called; repeated fee estimations would burn through change addresses without
broadcasting any transaction. All dry-run and error-after-`finish()` paths now cancel the PSBT
to unmark the change address for reuse.
- Bumped `FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS` and `TX_BROADCAST_TIMEOUT_SECS` from 5s to 15s.
The 5s node-level timeout fires before Electrum can complete a request (10s timeout), causing
`FeerateEstimationUpdateTimeout` on node start.
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,6 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(git log:*),Bash(git diff:*),Bash(git blame:*),Read,Glob,Grep"
5 changes: 5 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,11 @@ swift.swiftdoc
# Ignore LDKNodeFFI.xcframework files
/bindings/swift/LDKNodeFFI.xcframework

# Build artifacts
Comment thread
ovitrif marked this conversation as resolved.
*.o
*.a
*.d

# IDE and local files
.idea
.build
Expand Down
48 changes: 32 additions & 16 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,18 +54,11 @@ cargo clippy --fix

### Language Bindings
```bash
# Generate Kotlin bindings
./scripts/uniffi_bindgen_generate_kotlin.sh

# Generate Android bindings
./scripts/uniffi_bindgen_generate_kotlin_android.sh

# Generate Python bindings
./scripts/uniffi_bindgen_generate_python.sh

# Generate Swift bindings
./scripts/uniffi_bindgen_generate_swift.sh
# Generate ALL bindings (Swift, Kotlin, Python) + xcframework archive
./bindgen.sh
```
Individual scripts live under `scripts/` but should NOT be run directly —
`bindgen.sh` installs shared tooling once and sets the correct build profile.

## Architecture

Expand DownExpand Up@@ -122,7 +115,17 @@ You are an extremely strict senior Rust systems engineer with 15+ years shipping

Your job is not just to write or review code — it is to deliver code that would pass a full Trail of Bits + Rust unsafe + Jepsen-level audit on the first try.

Follow this exact multi-stage process and never skip or summarize any stage:
Follow this exact multi-stage process and never skip or summarize any stage, with
one exception for automated CI reviews (see below):

**Automated CI code reviews (GitHub Actions):** When running as the `code-review`
plugin in GitHub Actions, build and test tools (Bash, cargo, etc.) are unavailable.
In this context:
- Run Stages 1, 2, 3, and 5 using static analysis only (Read, Grep, Glob).
- Skip Stage 4 (Testing) and Stage 6 (Build & CI Verification) entirely.
Do NOT attempt to run cargo, build, or test commands.
- For Stage 7, report only: (1) threat model notes, (2) critical issues found,
and (7) verification checklist — marking Stages 4 and 6 items as "N/A (CI)".

Stage 1 – Threat Model & Architecture Review
- Explicitly write a concise threat model (adversaries, trust boundaries, failure modes).
Expand DownExpand Up@@ -187,7 +190,8 @@ Only after completing all stages above, output in this exact order:
- Architecture is minimal and correct

Never say "trust me" or "in practice this would pass". You must demonstrate everything above explicitly.
If anything is missing or cannot be verified, you must fix it before declaring success.
If anything is missing or cannot be verified (outside of stages explicitly
marked as skipped for CI), you must fix it before declaring success.

---
## RULES
Expand All@@ -196,7 +200,7 @@ If anything is missing or cannot be verified, you must fix it before declaring s
- NEVER suggest manually adding @Serializable annotations to generated Kotlin bindings
- ALWAYS run `cargo fmt` before committing to ensure consistent code formatting
- ALWAYS move imports to the top of the file when applicable (no inline imports in functions)
- NEVER run binding generation scripts yourself - always ask the user to run them (they are long-running and resource-intensive)
- Run `./bindgen.sh` in the background when bindings need regeneration (it is long-running)

## Bindings Generation Command
To regenerate ALL bindings (Swift, Kotlin, Python), run from the repo root:
Expand All@@ -215,21 +219,33 @@ When bumping the version, ALWAYS update ALL of these files:

## CHANGELOG
- The Synonym fork maintains a SINGLE section at the top: `# X.X.X (Synonym Fork)`
- This section is **cumulative** — it contains ALL changes across ALL rc versions for this fork
- When bumping version, update the version in the existing heading (don't create new sections)
- All Synonym fork additions go under ONE `## Synonym Fork Additions` subsection
- New additions should be added at the TOP of the Synonym Fork Additions list
- Do NOT create separate sections for each rc version
- Use the CHANGELOG content as the GitHub release notes body
- **GitHub release notes are NOT the full CHANGELOG** — see PR Release Workflow below

## PR Release Workflow
- For PRs that bump version, ALWAYS create a release on the PR branch BEFORE merge
- **CRITICAL: Commit and push ALL changes to the branch BEFORE tagging.** The tag must
point to a commit that contains every change included in the release (CHANGELOG, version
bumps, bindings, etc.). Never tag uncommitted or unpushed work.
- Tag the last commit on the PR branch with the version from Cargo.toml (e.g., `v0.7.0-rc.6`)
- **CRITICAL: Before uploading `LDKNodeFFI.xcframework.zip`, ALWAYS verify the checksum matches `Package.swift`:**
```bash
shasum -a 256 bindings/swift/LDKNodeFFI.xcframework.zip
# Compare output with the checksum value in Package.swift - they MUST match
```
- Create GitHub release with same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- Create GitHub release as **published** (not draft) and **set as latest release**, with
same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- **Release notes = DELTA only.** Describe only what changed since the previous release
(e.g., rc.31 notes list only changes since rc.30). Do NOT paste the full cumulative
CHANGELOG section — that covers all rc versions combined. Write concise notes covering
the PR's changes: bug fixes, features, optimizations, and binding/version updates.
- Release notes are for **consumers of the bindings** — cover only Rust code changes,
FFI changes, and binding updates. Do NOT include internal CI, documentation, or
workflow changes.
- **ALWAYS add release link at the end of PR description** (use `gh pr edit` to update the body):
```
### Release
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
# 0.7.0-rc.29 (Synonym Fork)
# 0.7.0-rc.32 (Synonym Fork)

## Bug Fixes

- Fixed cumulative change-address derivation index leak during fee estimation and dry-run
transaction builds. BDK's `TxBuilder::finish()` advances the internal (change) keychain index
each time it's called; repeated fee estimations would burn through change addresses without
broadcasting any transaction. All dry-run and error-after-`finish()` paths now cancel the PSBT
to unmark the change address for reuse.
- Bumped `FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS` and `TX_BROADCAST_TIMEOUT_SECS` from 5s to 15s.
The 5s node-level timeout fires before Electrum can complete a request (10s timeout), causing
`FeerateEstimationUpdateTimeout` on node start.
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,6 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(git log:*),Bash(git diff:*),Bash(git blame:*),Read,Glob,Grep"
5 changes: 5 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,11 @@ swift.swiftdoc
# Ignore LDKNodeFFI.xcframework files
/bindings/swift/LDKNodeFFI.xcframework

# Build artifacts
Comment thread
ovitrif marked this conversation as resolved.
*.o
*.a
*.d

# IDE and local files
.idea
.build
Expand Down
48 changes: 32 additions & 16 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,18 +54,11 @@ cargo clippy --fix

### Language Bindings
```bash
# Generate Kotlin bindings
./scripts/uniffi_bindgen_generate_kotlin.sh

# Generate Android bindings
./scripts/uniffi_bindgen_generate_kotlin_android.sh

# Generate Python bindings
./scripts/uniffi_bindgen_generate_python.sh

# Generate Swift bindings
./scripts/uniffi_bindgen_generate_swift.sh
# Generate ALL bindings (Swift, Kotlin, Python) + xcframework archive
./bindgen.sh
```
Individual scripts live under `scripts/` but should NOT be run directly —
`bindgen.sh` installs shared tooling once and sets the correct build profile.

## Architecture

Expand DownExpand Up@@ -122,7 +115,17 @@ You are an extremely strict senior Rust systems engineer with 15+ years shipping

Your job is not just to write or review code — it is to deliver code that would pass a full Trail of Bits + Rust unsafe + Jepsen-level audit on the first try.

Follow this exact multi-stage process and never skip or summarize any stage:
Follow this exact multi-stage process and never skip or summarize any stage, with
one exception for automated CI reviews (see below):

**Automated CI code reviews (GitHub Actions):** When running as the `code-review`
plugin in GitHub Actions, build and test tools (Bash, cargo, etc.) are unavailable.
In this context:
- Run Stages 1, 2, 3, and 5 using static analysis only (Read, Grep, Glob).
- Skip Stage 4 (Testing) and Stage 6 (Build & CI Verification) entirely.
Do NOT attempt to run cargo, build, or test commands.
- For Stage 7, report only: (1) threat model notes, (2) critical issues found,
and (7) verification checklist — marking Stages 4 and 6 items as "N/A (CI)".

Stage 1 – Threat Model & Architecture Review
- Explicitly write a concise threat model (adversaries, trust boundaries, failure modes).
Expand DownExpand Up@@ -187,7 +190,8 @@ Only after completing all stages above, output in this exact order:
- Architecture is minimal and correct

Never say "trust me" or "in practice this would pass". You must demonstrate everything above explicitly.
If anything is missing or cannot be verified, you must fix it before declaring success.
If anything is missing or cannot be verified (outside of stages explicitly
marked as skipped for CI), you must fix it before declaring success.

---
## RULES
Expand All@@ -196,7 +200,7 @@ If anything is missing or cannot be verified, you must fix it before declaring s
- NEVER suggest manually adding @Serializable annotations to generated Kotlin bindings
- ALWAYS run `cargo fmt` before committing to ensure consistent code formatting
- ALWAYS move imports to the top of the file when applicable (no inline imports in functions)
- NEVER run binding generation scripts yourself - always ask the user to run them (they are long-running and resource-intensive)
- Run `./bindgen.sh` in the background when bindings need regeneration (it is long-running)

## Bindings Generation Command
To regenerate ALL bindings (Swift, Kotlin, Python), run from the repo root:
Expand All@@ -215,21 +219,33 @@ When bumping the version, ALWAYS update ALL of these files:

## CHANGELOG
- The Synonym fork maintains a SINGLE section at the top: `# X.X.X (Synonym Fork)`
- This section is **cumulative** — it contains ALL changes across ALL rc versions for this fork
- When bumping version, update the version in the existing heading (don't create new sections)
- All Synonym fork additions go under ONE `## Synonym Fork Additions` subsection
- New additions should be added at the TOP of the Synonym Fork Additions list
- Do NOT create separate sections for each rc version
- Use the CHANGELOG content as the GitHub release notes body
- **GitHub release notes are NOT the full CHANGELOG** — see PR Release Workflow below

## PR Release Workflow
- For PRs that bump version, ALWAYS create a release on the PR branch BEFORE merge
- **CRITICAL: Commit and push ALL changes to the branch BEFORE tagging.** The tag must
point to a commit that contains every change included in the release (CHANGELOG, version
bumps, bindings, etc.). Never tag uncommitted or unpushed work.
- Tag the last commit on the PR branch with the version from Cargo.toml (e.g., `v0.7.0-rc.6`)
- **CRITICAL: Before uploading `LDKNodeFFI.xcframework.zip`, ALWAYS verify the checksum matches `Package.swift`:**
```bash
shasum -a 256 bindings/swift/LDKNodeFFI.xcframework.zip
# Compare output with the checksum value in Package.swift - they MUST match
```
- Create GitHub release with same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- Create GitHub release as **published** (not draft) and **set as latest release**, with
same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- **Release notes = DELTA only.** Describe only what changed since the previous release
(e.g., rc.31 notes list only changes since rc.30). Do NOT paste the full cumulative
CHANGELOG section — that covers all rc versions combined. Write concise notes covering
the PR's changes: bug fixes, features, optimizations, and binding/version updates.
- Release notes are for **consumers of the bindings** — cover only Rust code changes,
FFI changes, and binding updates. Do NOT include internal CI, documentation, or
workflow changes.
- **ALWAYS add release link at the end of PR description** (use `gh pr edit` to update the body):
```
### Release
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
# 0.7.0-rc.29 (Synonym Fork)
# 0.7.0-rc.32 (Synonym Fork)

## Bug Fixes

- Fixed cumulative change-address derivation index leak during fee estimation and dry-run
transaction builds. BDK's `TxBuilder::finish()` advances the internal (change) keychain index
each time it's called; repeated fee estimations would burn through change addresses without
broadcasting any transaction. All dry-run and error-after-`finish()` paths now cancel the PSBT
to unmark the change address for reuse.
- Bumped `FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS` and `TX_BROADCAST_TIMEOUT_SECS` from 5s to 15s.
The 5s node-level timeout fires before Electrum can complete a request (10s timeout), causing
`FeerateEstimationUpdateTimeout` on node start.
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,6 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(git log:*),Bash(git diff:*),Bash(git blame:*),Read,Glob,Grep"
5 changes: 5 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,11 @@ swift.swiftdoc
# Ignore LDKNodeFFI.xcframework files
/bindings/swift/LDKNodeFFI.xcframework

# Build artifacts
Comment thread
ovitrif marked this conversation as resolved.
*.o
*.a
*.d

# IDE and local files
.idea
.build
Expand Down
48 changes: 32 additions & 16 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,18 +54,11 @@ cargo clippy --fix

### Language Bindings
```bash
# Generate Kotlin bindings
./scripts/uniffi_bindgen_generate_kotlin.sh

# Generate Android bindings
./scripts/uniffi_bindgen_generate_kotlin_android.sh

# Generate Python bindings
./scripts/uniffi_bindgen_generate_python.sh

# Generate Swift bindings
./scripts/uniffi_bindgen_generate_swift.sh
# Generate ALL bindings (Swift, Kotlin, Python) + xcframework archive
./bindgen.sh
```
Individual scripts live under `scripts/` but should NOT be run directly —
`bindgen.sh` installs shared tooling once and sets the correct build profile.

## Architecture

Expand DownExpand Up@@ -122,7 +115,17 @@ You are an extremely strict senior Rust systems engineer with 15+ years shipping

Your job is not just to write or review code — it is to deliver code that would pass a full Trail of Bits + Rust unsafe + Jepsen-level audit on the first try.

Follow this exact multi-stage process and never skip or summarize any stage:
Follow this exact multi-stage process and never skip or summarize any stage, with
one exception for automated CI reviews (see below):

**Automated CI code reviews (GitHub Actions):** When running as the `code-review`
plugin in GitHub Actions, build and test tools (Bash, cargo, etc.) are unavailable.
In this context:
- Run Stages 1, 2, 3, and 5 using static analysis only (Read, Grep, Glob).
- Skip Stage 4 (Testing) and Stage 6 (Build & CI Verification) entirely.
Do NOT attempt to run cargo, build, or test commands.
- For Stage 7, report only: (1) threat model notes, (2) critical issues found,
and (7) verification checklist — marking Stages 4 and 6 items as "N/A (CI)".

Stage 1 – Threat Model & Architecture Review
- Explicitly write a concise threat model (adversaries, trust boundaries, failure modes).
Expand DownExpand Up@@ -187,7 +190,8 @@ Only after completing all stages above, output in this exact order:
- Architecture is minimal and correct

Never say "trust me" or "in practice this would pass". You must demonstrate everything above explicitly.
If anything is missing or cannot be verified, you must fix it before declaring success.
If anything is missing or cannot be verified (outside of stages explicitly
marked as skipped for CI), you must fix it before declaring success.

---
## RULES
Expand All@@ -196,7 +200,7 @@ If anything is missing or cannot be verified, you must fix it before declaring s
- NEVER suggest manually adding @Serializable annotations to generated Kotlin bindings
- ALWAYS run `cargo fmt` before committing to ensure consistent code formatting
- ALWAYS move imports to the top of the file when applicable (no inline imports in functions)
- NEVER run binding generation scripts yourself - always ask the user to run them (they are long-running and resource-intensive)
- Run `./bindgen.sh` in the background when bindings need regeneration (it is long-running)

## Bindings Generation Command
To regenerate ALL bindings (Swift, Kotlin, Python), run from the repo root:
Expand All@@ -215,21 +219,33 @@ When bumping the version, ALWAYS update ALL of these files:

## CHANGELOG
- The Synonym fork maintains a SINGLE section at the top: `# X.X.X (Synonym Fork)`
- This section is **cumulative** — it contains ALL changes across ALL rc versions for this fork
- When bumping version, update the version in the existing heading (don't create new sections)
- All Synonym fork additions go under ONE `## Synonym Fork Additions` subsection
- New additions should be added at the TOP of the Synonym Fork Additions list
- Do NOT create separate sections for each rc version
- Use the CHANGELOG content as the GitHub release notes body
- **GitHub release notes are NOT the full CHANGELOG** — see PR Release Workflow below

## PR Release Workflow
- For PRs that bump version, ALWAYS create a release on the PR branch BEFORE merge
- **CRITICAL: Commit and push ALL changes to the branch BEFORE tagging.** The tag must
point to a commit that contains every change included in the release (CHANGELOG, version
bumps, bindings, etc.). Never tag uncommitted or unpushed work.
- Tag the last commit on the PR branch with the version from Cargo.toml (e.g., `v0.7.0-rc.6`)
- **CRITICAL: Before uploading `LDKNodeFFI.xcframework.zip`, ALWAYS verify the checksum matches `Package.swift`:**
```bash
shasum -a 256 bindings/swift/LDKNodeFFI.xcframework.zip
# Compare output with the checksum value in Package.swift - they MUST match
```
- Create GitHub release with same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- Create GitHub release as **published** (not draft) and **set as latest release**, with
same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- **Release notes = DELTA only.** Describe only what changed since the previous release
(e.g., rc.31 notes list only changes since rc.30). Do NOT paste the full cumulative
CHANGELOG section — that covers all rc versions combined. Write concise notes covering
the PR's changes: bug fixes, features, optimizations, and binding/version updates.
- Release notes are for **consumers of the bindings** — cover only Rust code changes,
FFI changes, and binding updates. Do NOT include internal CI, documentation, or
workflow changes.
- **ALWAYS add release link at the end of PR description** (use `gh pr edit` to update the body):
```
### Release
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
# 0.7.0-rc.29 (Synonym Fork)
# 0.7.0-rc.32 (Synonym Fork)

## Bug Fixes

- Fixed cumulative change-address derivation index leak during fee estimation and dry-run
transaction builds. BDK's `TxBuilder::finish()` advances the internal (change) keychain index
each time it's called; repeated fee estimations would burn through change addresses without
broadcasting any transaction. All dry-run and error-after-`finish()` paths now cancel the PSBT
to unmark the change address for reuse.
- Bumped `FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS` and `TX_BROADCAST_TIMEOUT_SECS` from 5s to 15s.
The 5s node-level timeout fires before Electrum can complete a request (10s timeout), causing
`FeerateEstimationUpdateTimeout` on node start.
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,6 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(git log:*),Bash(git diff:*),Bash(git blame:*),Read,Glob,Grep"
5 changes: 5 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,11 @@ swift.swiftdoc
# Ignore LDKNodeFFI.xcframework files
/bindings/swift/LDKNodeFFI.xcframework

# Build artifacts
Comment thread
ovitrif marked this conversation as resolved.
*.o
*.a
*.d

# IDE and local files
.idea
.build
Expand Down
48 changes: 32 additions & 16 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,18 +54,11 @@ cargo clippy --fix

### Language Bindings
```bash
# Generate Kotlin bindings
./scripts/uniffi_bindgen_generate_kotlin.sh

# Generate Android bindings
./scripts/uniffi_bindgen_generate_kotlin_android.sh

# Generate Python bindings
./scripts/uniffi_bindgen_generate_python.sh

# Generate Swift bindings
./scripts/uniffi_bindgen_generate_swift.sh
# Generate ALL bindings (Swift, Kotlin, Python) + xcframework archive
./bindgen.sh
```
Individual scripts live under `scripts/` but should NOT be run directly —
`bindgen.sh` installs shared tooling once and sets the correct build profile.

## Architecture

Expand DownExpand Up@@ -122,7 +115,17 @@ You are an extremely strict senior Rust systems engineer with 15+ years shipping

Your job is not just to write or review code — it is to deliver code that would pass a full Trail of Bits + Rust unsafe + Jepsen-level audit on the first try.

Follow this exact multi-stage process and never skip or summarize any stage:
Follow this exact multi-stage process and never skip or summarize any stage, with
one exception for automated CI reviews (see below):

**Automated CI code reviews (GitHub Actions):** When running as the `code-review`
plugin in GitHub Actions, build and test tools (Bash, cargo, etc.) are unavailable.
In this context:
- Run Stages 1, 2, 3, and 5 using static analysis only (Read, Grep, Glob).
- Skip Stage 4 (Testing) and Stage 6 (Build & CI Verification) entirely.
Do NOT attempt to run cargo, build, or test commands.
- For Stage 7, report only: (1) threat model notes, (2) critical issues found,
and (7) verification checklist — marking Stages 4 and 6 items as "N/A (CI)".

Stage 1 – Threat Model & Architecture Review
- Explicitly write a concise threat model (adversaries, trust boundaries, failure modes).
Expand DownExpand Up@@ -187,7 +190,8 @@ Only after completing all stages above, output in this exact order:
- Architecture is minimal and correct

Never say "trust me" or "in practice this would pass". You must demonstrate everything above explicitly.
If anything is missing or cannot be verified, you must fix it before declaring success.
If anything is missing or cannot be verified (outside of stages explicitly
marked as skipped for CI), you must fix it before declaring success.

---
## RULES
Expand All@@ -196,7 +200,7 @@ If anything is missing or cannot be verified, you must fix it before declaring s
- NEVER suggest manually adding @Serializable annotations to generated Kotlin bindings
- ALWAYS run `cargo fmt` before committing to ensure consistent code formatting
- ALWAYS move imports to the top of the file when applicable (no inline imports in functions)
- NEVER run binding generation scripts yourself - always ask the user to run them (they are long-running and resource-intensive)
- Run `./bindgen.sh` in the background when bindings need regeneration (it is long-running)

## Bindings Generation Command
To regenerate ALL bindings (Swift, Kotlin, Python), run from the repo root:
Expand All@@ -215,21 +219,33 @@ When bumping the version, ALWAYS update ALL of these files:

## CHANGELOG
- The Synonym fork maintains a SINGLE section at the top: `# X.X.X (Synonym Fork)`
- This section is **cumulative** — it contains ALL changes across ALL rc versions for this fork
- When bumping version, update the version in the existing heading (don't create new sections)
- All Synonym fork additions go under ONE `## Synonym Fork Additions` subsection
- New additions should be added at the TOP of the Synonym Fork Additions list
- Do NOT create separate sections for each rc version
- Use the CHANGELOG content as the GitHub release notes body
- **GitHub release notes are NOT the full CHANGELOG** — see PR Release Workflow below

## PR Release Workflow
- For PRs that bump version, ALWAYS create a release on the PR branch BEFORE merge
- **CRITICAL: Commit and push ALL changes to the branch BEFORE tagging.** The tag must
point to a commit that contains every change included in the release (CHANGELOG, version
bumps, bindings, etc.). Never tag uncommitted or unpushed work.
- Tag the last commit on the PR branch with the version from Cargo.toml (e.g., `v0.7.0-rc.6`)
- **CRITICAL: Before uploading `LDKNodeFFI.xcframework.zip`, ALWAYS verify the checksum matches `Package.swift`:**
```bash
shasum -a 256 bindings/swift/LDKNodeFFI.xcframework.zip
# Compare output with the checksum value in Package.swift - they MUST match
```
- Create GitHub release with same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- Create GitHub release as **published** (not draft) and **set as latest release**, with
same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- **Release notes = DELTA only.** Describe only what changed since the previous release
(e.g., rc.31 notes list only changes since rc.30). Do NOT paste the full cumulative
CHANGELOG section — that covers all rc versions combined. Write concise notes covering
the PR's changes: bug fixes, features, optimizations, and binding/version updates.
- Release notes are for **consumers of the bindings** — cover only Rust code changes,
FFI changes, and binding updates. Do NOT include internal CI, documentation, or
workflow changes.
- **ALWAYS add release link at the end of PR description** (use `gh pr edit` to update the body):
```
### Release
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
# 0.7.0-rc.29 (Synonym Fork)
# 0.7.0-rc.32 (Synonym Fork)

## Bug Fixes

- Fixed cumulative change-address derivation index leak during fee estimation and dry-run
transaction builds. BDK's `TxBuilder::finish()` advances the internal (change) keychain index
each time it's called; repeated fee estimations would burn through change addresses without
broadcasting any transaction. All dry-run and error-after-`finish()` paths now cancel the PSBT
to unmark the change address for reuse.
- Bumped `FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS` and `TX_BROADCAST_TIMEOUT_SECS` from 5s to 15s.
The 5s node-level timeout fires before Electrum can complete a request (10s timeout), causing
`FeerateEstimationUpdateTimeout` on node start.
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,6 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(git log:*),Bash(git diff:*),Bash(git blame:*),Read,Glob,Grep"
5 changes: 5 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,11 @@ swift.swiftdoc
# Ignore LDKNodeFFI.xcframework files
/bindings/swift/LDKNodeFFI.xcframework

# Build artifacts
Comment thread
ovitrif marked this conversation as resolved.
*.o
*.a
*.d

# IDE and local files
.idea
.build
Expand Down
48 changes: 32 additions & 16 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,18 +54,11 @@ cargo clippy --fix

### Language Bindings
```bash
# Generate Kotlin bindings
./scripts/uniffi_bindgen_generate_kotlin.sh

# Generate Android bindings
./scripts/uniffi_bindgen_generate_kotlin_android.sh

# Generate Python bindings
./scripts/uniffi_bindgen_generate_python.sh

# Generate Swift bindings
./scripts/uniffi_bindgen_generate_swift.sh
# Generate ALL bindings (Swift, Kotlin, Python) + xcframework archive
./bindgen.sh
```
Individual scripts live under `scripts/` but should NOT be run directly —
`bindgen.sh` installs shared tooling once and sets the correct build profile.

## Architecture

Expand DownExpand Up@@ -122,7 +115,17 @@ You are an extremely strict senior Rust systems engineer with 15+ years shipping

Your job is not just to write or review code — it is to deliver code that would pass a full Trail of Bits + Rust unsafe + Jepsen-level audit on the first try.

Follow this exact multi-stage process and never skip or summarize any stage:
Follow this exact multi-stage process and never skip or summarize any stage, with
one exception for automated CI reviews (see below):

**Automated CI code reviews (GitHub Actions):** When running as the `code-review`
plugin in GitHub Actions, build and test tools (Bash, cargo, etc.) are unavailable.
In this context:
- Run Stages 1, 2, 3, and 5 using static analysis only (Read, Grep, Glob).
- Skip Stage 4 (Testing) and Stage 6 (Build & CI Verification) entirely.
Do NOT attempt to run cargo, build, or test commands.
- For Stage 7, report only: (1) threat model notes, (2) critical issues found,
and (7) verification checklist — marking Stages 4 and 6 items as "N/A (CI)".

Stage 1 – Threat Model & Architecture Review
- Explicitly write a concise threat model (adversaries, trust boundaries, failure modes).
Expand DownExpand Up@@ -187,7 +190,8 @@ Only after completing all stages above, output in this exact order:
- Architecture is minimal and correct

Never say "trust me" or "in practice this would pass". You must demonstrate everything above explicitly.
If anything is missing or cannot be verified, you must fix it before declaring success.
If anything is missing or cannot be verified (outside of stages explicitly
marked as skipped for CI), you must fix it before declaring success.

---
## RULES
Expand All@@ -196,7 +200,7 @@ If anything is missing or cannot be verified, you must fix it before declaring s
- NEVER suggest manually adding @Serializable annotations to generated Kotlin bindings
- ALWAYS run `cargo fmt` before committing to ensure consistent code formatting
- ALWAYS move imports to the top of the file when applicable (no inline imports in functions)
- NEVER run binding generation scripts yourself - always ask the user to run them (they are long-running and resource-intensive)
- Run `./bindgen.sh` in the background when bindings need regeneration (it is long-running)

## Bindings Generation Command
To regenerate ALL bindings (Swift, Kotlin, Python), run from the repo root:
Expand All@@ -215,21 +219,33 @@ When bumping the version, ALWAYS update ALL of these files:

## CHANGELOG
- The Synonym fork maintains a SINGLE section at the top: `# X.X.X (Synonym Fork)`
- This section is **cumulative** — it contains ALL changes across ALL rc versions for this fork
- When bumping version, update the version in the existing heading (don't create new sections)
- All Synonym fork additions go under ONE `## Synonym Fork Additions` subsection
- New additions should be added at the TOP of the Synonym Fork Additions list
- Do NOT create separate sections for each rc version
- Use the CHANGELOG content as the GitHub release notes body
- **GitHub release notes are NOT the full CHANGELOG** — see PR Release Workflow below

## PR Release Workflow
- For PRs that bump version, ALWAYS create a release on the PR branch BEFORE merge
- **CRITICAL: Commit and push ALL changes to the branch BEFORE tagging.** The tag must
point to a commit that contains every change included in the release (CHANGELOG, version
bumps, bindings, etc.). Never tag uncommitted or unpushed work.
- Tag the last commit on the PR branch with the version from Cargo.toml (e.g., `v0.7.0-rc.6`)
- **CRITICAL: Before uploading `LDKNodeFFI.xcframework.zip`, ALWAYS verify the checksum matches `Package.swift`:**
```bash
shasum -a 256 bindings/swift/LDKNodeFFI.xcframework.zip
# Compare output with the checksum value in Package.swift - they MUST match
```
- Create GitHub release with same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- Create GitHub release as **published** (not draft) and **set as latest release**, with
same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- **Release notes = DELTA only.** Describe only what changed since the previous release
(e.g., rc.31 notes list only changes since rc.30). Do NOT paste the full cumulative
CHANGELOG section — that covers all rc versions combined. Write concise notes covering
the PR's changes: bug fixes, features, optimizations, and binding/version updates.
- Release notes are for **consumers of the bindings** — cover only Rust code changes,
FFI changes, and binding updates. Do NOT include internal CI, documentation, or
workflow changes.
- **ALWAYS add release link at the end of PR description** (use `gh pr edit` to update the body):
```
### Release
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
# 0.7.0-rc.29 (Synonym Fork)
# 0.7.0-rc.32 (Synonym Fork)

## Bug Fixes

- Fixed cumulative change-address derivation index leak during fee estimation and dry-run
transaction builds. BDK's `TxBuilder::finish()` advances the internal (change) keychain index
each time it's called; repeated fee estimations would burn through change addresses without
broadcasting any transaction. All dry-run and error-after-`finish()` paths now cancel the PSBT
to unmark the change address for reuse.
- Bumped `FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS` and `TX_BROADCAST_TIMEOUT_SECS` from 5s to 15s.
The 5s node-level timeout fires before Electrum can complete a request (10s timeout), causing
`FeerateEstimationUpdateTimeout` on node start.
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,6 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(git log:*),Bash(git diff:*),Bash(git blame:*),Read,Glob,Grep"
5 changes: 5 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,11 @@ swift.swiftdoc
# Ignore LDKNodeFFI.xcframework files
/bindings/swift/LDKNodeFFI.xcframework

# Build artifacts
Comment thread
ovitrif marked this conversation as resolved.
*.o
*.a
*.d

# IDE and local files
.idea
.build
Expand Down
48 changes: 32 additions & 16 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,18 +54,11 @@ cargo clippy --fix

### Language Bindings
```bash
# Generate Kotlin bindings
./scripts/uniffi_bindgen_generate_kotlin.sh

# Generate Android bindings
./scripts/uniffi_bindgen_generate_kotlin_android.sh

# Generate Python bindings
./scripts/uniffi_bindgen_generate_python.sh

# Generate Swift bindings
./scripts/uniffi_bindgen_generate_swift.sh
# Generate ALL bindings (Swift, Kotlin, Python) + xcframework archive
./bindgen.sh
```
Individual scripts live under `scripts/` but should NOT be run directly —
`bindgen.sh` installs shared tooling once and sets the correct build profile.

## Architecture

Expand DownExpand Up@@ -122,7 +115,17 @@ You are an extremely strict senior Rust systems engineer with 15+ years shipping

Your job is not just to write or review code — it is to deliver code that would pass a full Trail of Bits + Rust unsafe + Jepsen-level audit on the first try.

Follow this exact multi-stage process and never skip or summarize any stage:
Follow this exact multi-stage process and never skip or summarize any stage, with
one exception for automated CI reviews (see below):

**Automated CI code reviews (GitHub Actions):** When running as the `code-review`
plugin in GitHub Actions, build and test tools (Bash, cargo, etc.) are unavailable.
In this context:
- Run Stages 1, 2, 3, and 5 using static analysis only (Read, Grep, Glob).
- Skip Stage 4 (Testing) and Stage 6 (Build & CI Verification) entirely.
Do NOT attempt to run cargo, build, or test commands.
- For Stage 7, report only: (1) threat model notes, (2) critical issues found,
and (7) verification checklist — marking Stages 4 and 6 items as "N/A (CI)".

Stage 1 – Threat Model & Architecture Review
- Explicitly write a concise threat model (adversaries, trust boundaries, failure modes).
Expand DownExpand Up@@ -187,7 +190,8 @@ Only after completing all stages above, output in this exact order:
- Architecture is minimal and correct

Never say "trust me" or "in practice this would pass". You must demonstrate everything above explicitly.
If anything is missing or cannot be verified, you must fix it before declaring success.
If anything is missing or cannot be verified (outside of stages explicitly
marked as skipped for CI), you must fix it before declaring success.

---
## RULES
Expand All@@ -196,7 +200,7 @@ If anything is missing or cannot be verified, you must fix it before declaring s
- NEVER suggest manually adding @Serializable annotations to generated Kotlin bindings
- ALWAYS run `cargo fmt` before committing to ensure consistent code formatting
- ALWAYS move imports to the top of the file when applicable (no inline imports in functions)
- NEVER run binding generation scripts yourself - always ask the user to run them (they are long-running and resource-intensive)
- Run `./bindgen.sh` in the background when bindings need regeneration (it is long-running)

## Bindings Generation Command
To regenerate ALL bindings (Swift, Kotlin, Python), run from the repo root:
Expand All@@ -215,21 +219,33 @@ When bumping the version, ALWAYS update ALL of these files:

## CHANGELOG
- The Synonym fork maintains a SINGLE section at the top: `# X.X.X (Synonym Fork)`
- This section is **cumulative** — it contains ALL changes across ALL rc versions for this fork
- When bumping version, update the version in the existing heading (don't create new sections)
- All Synonym fork additions go under ONE `## Synonym Fork Additions` subsection
- New additions should be added at the TOP of the Synonym Fork Additions list
- Do NOT create separate sections for each rc version
- Use the CHANGELOG content as the GitHub release notes body
- **GitHub release notes are NOT the full CHANGELOG** — see PR Release Workflow below

## PR Release Workflow
- For PRs that bump version, ALWAYS create a release on the PR branch BEFORE merge
- **CRITICAL: Commit and push ALL changes to the branch BEFORE tagging.** The tag must
point to a commit that contains every change included in the release (CHANGELOG, version
bumps, bindings, etc.). Never tag uncommitted or unpushed work.
- Tag the last commit on the PR branch with the version from Cargo.toml (e.g., `v0.7.0-rc.6`)
- **CRITICAL: Before uploading `LDKNodeFFI.xcframework.zip`, ALWAYS verify the checksum matches `Package.swift`:**
```bash
shasum -a 256 bindings/swift/LDKNodeFFI.xcframework.zip
# Compare output with the checksum value in Package.swift - they MUST match
```
- Create GitHub release with same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- Create GitHub release as **published** (not draft) and **set as latest release**, with
same name as the tag, upload `LDKNodeFFI.xcframework.zip`
- **Release notes = DELTA only.** Describe only what changed since the previous release
(e.g., rc.31 notes list only changes since rc.30). Do NOT paste the full cumulative
CHANGELOG section — that covers all rc versions combined. Write concise notes covering
the PR's changes: bug fixes, features, optimizations, and binding/version updates.
- Release notes are for **consumers of the bindings** — cover only Rust code changes,
FFI changes, and binding updates. Do NOT include internal CI, documentation, or
workflow changes.
- **ALWAYS add release link at the end of PR description** (use `gh pr edit` to update the body):
```
### Release
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
# 0.7.0-rc.29 (Synonym Fork)
# 0.7.0-rc.32 (Synonym Fork)

## Bug Fixes

- Fixed cumulative change-address derivation index leak during fee estimation and dry-run
transaction builds. BDK's `TxBuilder::finish()` advances the internal (change) keychain index
each time it's called; repeated fee estimations would burn through change addresses without
broadcasting any transaction. All dry-run and error-after-`finish()` paths now cancel the PSBT
to unmark the change address for reuse.
- Bumped `FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS` and `TX_BROADCAST_TIMEOUT_SECS` from 5s to 15s.
The 5s node-level timeout fires before Electrum can complete a request (10s timeout), causing
`FeerateEstimationUpdateTimeout` on node start.
Expand Down
Loading
Loading