Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## next #462 +/- ##
==========================================
+ Coverage 89.23% 89.68% +0.44%
==========================================
Files 61 61
Lines 5074 5111 +37
Branches 949 963 +14
==========================================
+ Hits 4528 4584 +56
+ Misses 421 409 -12
+ Partials 125 118 -7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
- Each input is now debugged with the artifact of its own contract, looked up by its exact unlocking script ID. The artifact was found by contract name prefix, so with contracts `Vault` and `VaultSidecar` in one transaction the sidecar input could be debugged with Vault's artifact: logs printed for code that did not run, and a failing require crashed the debugger instead of being reported. - A failing final `require(f(x))` where `f` is defined with OP_DEFINE was located using steps of the function body as well, giving an ip that does not point into the contract's own bytecode. The failure was reported against an unrelated statement without its require message. Only the steps of the failing frame are used now. - `console.log` statements were matched against the step that raised the error and against libauth's repeated final state, so a log after a failing instruction was printed (twice), and a log after a division by zero made debug() throw a plain Error. Steps with an error and the repeated final state are skipped now. - formatBitAuthScript read past the end of the script when nothing follows the parameter type checks (e.g. `require(b)` for a `bool b`), so debug(), send() and getBitauthUri() threw a TypeError for a valid spend. The anchor is now clamped to the last opcode. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…audit
- send() wrapped every broadcast error in a FailedTransactionError without a
cause, so the documented NetworkProvider*Error classes could not be caught.
A NetworkProviderError is now thrown as it is, the ElectrumNetworkProvider
falls back to a NetworkProviderError (not a plain Error) for unrecognised
rejections, and the MockNetworkProvider throws a
NetworkProviderMissingInputsError for a missing or spent UTXO.
- addBchChangeOutputIfNeeded() calculated the fee from ECDSA signatures made
before the change output existed. Signing again can make an ECDSA signature
a byte longer, so about a quarter of transactions with one ECDSA input and
a fee rate of 1 ended up below 1 sat/byte and failed to build. ECDSA
signatures are now sized at their maximum length (73 bytes) for the change
calculation. The docs mention that placeholder inputs assume Schnorr.
- addOpReturnOutput() silently encoded invalid hex ('0xabc' became ab0c,
'0xzz' became 00), like function arguments did before #454. It now throws.
- Hex strings were compared case-sensitively when matching UTXOs to unlockers,
token categories for token change and implicit burn checks, change locks and
gatherFungibleTokenUtxos(). An upper case category passed to
addTokenChangeOutputIfNeeded() added no change output, so with
allowImplicitFungibleTokenBurn the tokens were burned. They are now compared
case-insensitively.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
asmToBytecode encoded an unknown opcode name as OP_0 and decoded invalid hex data tokens leniently. An artifact that uses an opcode the installed libauth version does not know would silently get a different bytecode and address, and funds sent there may be unspendable. Unknown opcode names and data tokens that are not hex with an even number of digits now throw an error. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
mr-zwets
force-pushed
the
fix/sdk-audit-remaining
branch
from
September 29, 2026 09:58
8cfeafb to
230d098
Compare
Pull request stats
Reviewable churn: 448 lines (net +374), version bumps and generated files excluded. Package source changed without an update to |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Opened on behalf of Mathieu G. (mr-zwets), written by Claude Opus 5.5.
Replaces #460, which was opened from the wrong branch by mistake.
Follow-up to the 0.14 audit, meant to land after the 0.14.0 release, with the SDK findings that were left out to keep the release's scope small. Rebased on
next(including #457 and #463); every fix below still has a test that fails on the currentnext.Changes
VaultandVaultSidecarin one transaction the sidecar input could use Vault's artifact: logs printed for code that didn't run, and a failing require crashed the debugger.require(f(x))with a non-inlinedfis reported at its own line and message.console.logstatements after a failing instruction are no longer printed (twice), and a log after a division by zero no longer makesdebug()throw a plainError.require(b)forbool b) no longer crashesdebug(),send()andgetBitauthUri().send(): aNetworkProviderErroris thrown as it is instead of being wrapped in aFailedTransactionError, so the documented error classes can be caught. Unrecognised Electrum rejections are aNetworkProviderError, andMockNetworkProviderthrowsNetworkProviderMissingInputsErrorfor missing or spent UTXOs. This is breaking for code that catchesFailedTransactionErrorfor network rejections, so it fits 0.15 rather than a 0.14.x patch (or can be split out).addBchChangeOutputIfNeeded(): ECDSA signatures are sized at their maximum length, since re-signing after adding the change output could push the fee below 1 sat/byte (about 1 in 4 builds with one ECDSA input). The docs note that placeholder inputs assume Schnorr.addOpReturnOutput(): invalid hex ('0xabc','0xzz') now throws instead of being mis-encoded.addTokenChangeOutputIfNeeded()used to add no change output, so withallowImplicitFungibleTokenBurnthe tokens were burned.asmToBytecode: unknown opcode names (previously encoded asOP_0) and invalid data tokens now throw, so an artifact with an opcode the installed libauth doesn't know no longer silently gets a different address.No release or migration notes yet, since the 0.14 sections will be closed by then. For the
send()change, a BREAKING release note and a migration note along these lines: "send()now throws the provider'sNetworkProviderError(or a subclass such asNetworkProviderMissingInputsError) when the network rejects a transaction; catch it in addition toFailedTransactionError."Tests
require(f(x))withdisableInlining, logs after a failed require and after a division by zero, and a parameter-check-only function through the SDK.MockNetworkProviderand a fake Electrum client, both throughsend().asmToBytecode.yarn build,yarn test,yarn lintandyarn spellcheckpass.🤖 Generated with Claude Code