What are we trying to do?
Build a production bridge / capacity-exchange service on Midnight Preprod that uses a shared bridge claimer wallet to submit Ethereum- and BNB-originated claim transactions on Midnight (via @midnight-ntwrk/midnight-js ethereum-bridge-claim). The same claimer seed is used by three scripts:
register-bridge-claimer-dust.ts— registers unshielded coins for dust generationcheck-bridge-claimer-dust-balance.ts— read-only dust snapshot- live claim submit path:
submitEthereumClaimReal → sdkSubmitEthereumClaim → buildEthereumSdkProviders → getEthereumBridgeClaimerSeed() + initFacadeWallet
Claimer address (shared between all three paths):
mn_addr_preprod1yr0f5cqps3rmtfarhtkrrhqka5slrufax46uy3w333e7y63xarqsuddncn
What’s not working or unclear?
Two related errors, both on Preprod:
1. Dust-registration submit fails with Custom error 173
RPC-CORE: submitAndWatchExtrinsic(extrinsic: Extrinsic): ExtrinsicStatus:: 1010: Invalid Transaction: Custom error: 173
[info] Dust submit returned non-fatal node response: Transaction submission error
I’ve seen this same error in the #dev-chat thread “If a wallet has sufficient DUST balance” (by Cadalt, 04-04-2026). In that thread norm explained the related 170 error is caused by a 1–3h gap between root pruning in root_history (~1h) and OutOfDustValidityWindow kicking in (~3h). It’s unclear whether 173 is in the same family, a different check, or something else — please confirm.
2. Live claim submit fails with Wallet.InsufficientFunds: could not balance dust
After facade.waitForSyncedState() + dust.waitForSyncedState() complete, a read-only snapshot of the same claimer shows:
usable_dust_balance_specks:9225916793000000000(large, non-zero)- Unshielded summary:
{"totalCoins":2,"registeredCount":2,"unregisteredCount":0,"unregisteredValueSum":"0"}
A separate run of register-bridge-claimer-dust.ts after long sync confirmed two coins both registered: totalCoins: 2, registeredCount: 2, unregisteredCount: 0.
Yet a live BNB claim submit against this same wallet fails with:
Wallet.InsufficientFunds: could not balance dust
Originating from @midnight-ntwrk/wallet-sdk-dust-wallet / the transacting path used when balancing the scoped claim transaction.
Live BNB smoke evidence:
- Deposit id:
bnb_7eb008c69866af1fdfb63c4b643459d40ceadc30e3c9c7b2caf01b955e1963a9_21 - EVM tx hash:
0x7eb008c69866af1fdfb63c4b643459d40ceadc30e3c9c7b2caf01b955e1963a9 - Observed state:
CREDIT_READY; process reaches real Midnight ethereum-bridge-claim submission before failing.
What have you tried so far?
- Confirmed the seed is identical between registration, read-only balance check, and submit (same
getEthereumBridgeClaimerSeed()+initFacadeWalleteverywhere). - Resolved a prior
INVALID_SIGNATUREBNB attestation issue (witness/message alignment) — not the current failure. - Ruled out “no dust at all” —
dust.balance(now)shows a large value. - Let
dust.waitForSyncedState()run for several minutes on Preprod and re-checked — dust is visible and registered. - Read the
#dev-chatDiscord discussion wherenorm(Midnight mod) andFacu | Midnamesadvised on the 170 variant: “keep the wallet synced and submit fast. If the wallet sat idle between building the proof and submitting, that’s usually the cause.” I will try tightening our submit-after-proof window, but our service is a long-lived shared claimer that must handle bursts of claims, so a “submit within seconds of sync” pattern is fragile for production. - Verified the SDK-known
isStrictlyComplete()hang on idle chains; using index check (appliedIndex >= highestRelevantWalletIndex) as backup.
Any relevant code or error messages?
Key error, verbatim, from the POST .../process call:
Wallet.InsufficientFunds: could not balance dust
Key error from dust-registration submit:
1010: Invalid Transaction: Custom error: 173
[info] Dust submit returned non-fatal node response: Transaction submission error
Full evidence packages attached:
MIDNIGHT_DUST_USABILITY_BLOCKER.md173-PREPROD-SUPPORT-POST.md
Questions for the Midnight team
- Is Custom error 173 in the 1010 extrinsic family the same root-pruning /
OutOfDustValidityWindowcause as 170, or a different check? What does 173 specifically indicate? - How should operators reconcile a large
dust.balance(now)snapshot with aWallet.InsufficientFundsat balancing on the same wallet, same moment, same seed? What is the dust-wallet balancer actually checking thatdust.balance(now)is not? - Is there a recommended pattern for a long-lived, always-on shared bridge claimer on Preprod/Mainnet — one that doesn’t rely on “build proof and submit within seconds”? E.g. a sync-before-each-submit pattern, a keepalive pattern, or a scoped-transaction rebuild on every attempt?
- Will the upcoming V5 indexer (server-side viewing-key scan) or the larger-proof allowance mentioned in
#dev-chatchange any of the above?
Where are you asking from?
- Network: Preprod
- SDKs:
@midnight-ntwrk/midnight-js,@midnight-ntwrk/wallet-sdk-dust-wallet(exact versions in attached files) - Proof server: self-hosted,
docker run -p 6300:6300 midnightntwrk/proof-server:latest - Service: shared bridge claimer for Ethereum + BNB, capacity-exchange rollout currently paused pending this clarification
Happy to provide more logs, a minimal repro, or a private session if useful.