Skip to content

feat: index routed-deposit destinationOwner on Deposit - #7

Merged
piotr-roslaniec merged 4 commits into
threshold-network:masterfrom
mswilkison:feat/index-routed-deposit-destination
Aug 7, 2026
Merged

feat: index routed-deposit destinationOwner on Deposit#7
piotr-roslaniec merged 4 commits into
threshold-network:masterfrom
mswilkison:feat/index-routed-deposit-destination

Conversation

@mswilkison

@mswilkison mswilkison commented Jul 24, 2026

Copy link
Copy Markdown

Why

The tBTC dapp resolves and searches routed (gasless / direct-mint) deposits by their destination-chain owner. Because the subgraph doesn't index that owner today, the frontend does it on-chain: searchRoutedDepositIdsByDestination runs a ~45–95-request chunked eth_getLogs scan (5 contracts, 3 topics) for every destination search. That's slow, hammers the client RPC key, and can't be cached well.

This indexes the destination owner so the whole scan collapses into one deposits(where: { destinationOwner }) query.

How

The five L1 depositor proxies — gasless, Arbitrum, Base, Sui, StarkNet — all inherit AbstractL1BTCDepositor. Both event eras are indexed:

// Current (bytes32 owner) — topic0 e96a7294… / 3ce59c3f…
event DepositInitialized(uint256 indexed depositKey, bytes32 indexed destinationChainDepositOwner, address indexed l1Sender);
event DepositFinalized(uint256 indexed depositKey, bytes32 indexed destinationChainDepositOwner, address indexed l1Sender, uint256 initialAmount, uint256 tbtcAmount);

// Legacy (address owner, pre-V2 upgrade) — topic0 04870363… / 94d36bc0…
event DepositInitialized(uint256 indexed depositKey, address indexed destinationChainDepositOwner, address indexed l1Sender);
event DepositFinalized(uint256 indexed depositKey, address indexed destinationChainDepositOwner, address indexed l1Sender, uint256 initialAmount, uint256 tbtcAmount);

The legacy era is not an edge case — it's the majority of Arbitrum/Base routed history (Arbitrum: 723 of 833 initializations; Base: 303 of 338; counted on-chain). Those deposits were initialized and finalized under the legacy implementation, so indexing only the bytes32 variant would silently drop ~87–90% of Arbitrum/Base routed deposits from destination search. The legacy handlers left-pad the 20-byte address owner to the same 32-byte form the bytes32 era stores, so one where: { destinationOwner } filter matches both eras.

The key enabling fact: depositKey (uint256) is byte-identical to the Bridge deposit key, which is already Deposit.id (keccak256(fundingTxHash | fundingOutputIndex)). The mapping attaches the owner onto the existing Deposit — no new entity, no join (id conversion reuses the repo's proven convertDepositKeyToHex). It loads-and-skips (with a warning) rather than get-or-creates: if a routed event ever arrived for an unknown key, creating a Deposit missing non-nullable fields would halt the whole subgraph, so dropping one attachment is strictly safer.

Changes

  • schema.graphqlDeposit gains destinationOwner: Bytes, l1Sender: Bytes (the sender of the first routed event seen — a later permissionless finalizeDeposit no longer overwrites the initializer), isRouted: Boolean.
  • abis/RoutedDepositor.json — all four events (both eras).
  • subgraph.yaml — five ethereum datasources with per-contract deploy blocks (gasless 23,576,205 · arbitrum 20,632,547 · base 21,961,116 · sui 22,842,726 · starknet 22,671,770), four event handlers each. The Arbitrum block fixes a real gap — it deployed 17,453 blocks below the previous uniform 20,650,000 floor.
  • networks.json — the five datasources added for mainnet (same deploy blocks) and sepolia (real testnet deployments from the tbtc-v2 artifacts, cross-checked on-chain), so yarn build-mainnet / yarn build-sepolia work — graph build --network hard-fails on any manifest datasource missing from the network config, which the previous revision hit.
  • src/mappingRoutedDeposit.ts — handlers for both eras; documents the AssemblyScript 0.19 gotcha that == null on a nullable Bytes field crashes the compiler (truthiness check used instead).

Verification

  • Topic0s recomputed by keccak256 for all four signatures; the legacy DepositInitialized hash byte-matches the third topic in the dapp's ROUTED_DEPOSIT_EVENT_TOPICS scan list.
  • On-chain event counts per era per contract (Blockscout, paginated + deduped) — the basis for the legacy-coverage claim above.
  • graph codegen, graph build, yarn build-mainnet, and yarn build-sepolia all pass on this branch. Note for maintainers: graph build --network … rewrites subgraph.yaml in place (drops comments / swaps addresses) — that mutation is a build side effect, don't commit it.

Drop-in client query (follow-up in the dapp)

query RoutedDepositIdsByDestination($owner: Bytes!) {
  deposits(where: { destinationOwner: $owner }, first: 1000,
           orderBy: depositTimestamp, orderDirection: desc) { id }
}

$owner is exactly normalizeDestinationTopic(searchQuery) — valid for both event eras thanks to the left-padding; deposit.id equals the old topics[1], so searchRoutedDepositIdsByDestination becomes deposits.map(d => d.id). (I'll open that dapp PR once this is deployed — it can't return results before the reindex completes.)

Deploy notes — maintainer / Threshold action (I can't do these)

  • Adding datasources changes the deployment hash → a full historical resync from the manifest's min startBlock (Bridge 16,397,413). Expect multi-hour to ~1–2 day mainnet reindex depending on the indexer. (A graft at head would skip pre-graft routed history, so a full resync is preferable for backfill.)
  • Deploy via Subgraph Studio under Threshold's account (yarn build-mainnet && yarn deploy-mainnet → bump version → publish). Version updates keep the same subgraph id, so the api.threshold.network proxy's gateway secret needs no change.

Summary by CodeRabbit

  • New Features
    • Added support for tracking routed deposits, including destination ownership, originating sender, and routed status.
    • Added routed deposit monitoring for gasless, Arbitrum, Base, Sui, and StarkNet depositors.
    • Added support for both current and legacy routed deposit event formats.
    • Added network configuration for routed depositor contracts on Sepolia and mainnet.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@piotr-roslaniec, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 24 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 38e387a8-2fce-4a9f-a61a-b4a93d4f8829

📥 Commits

Reviewing files that changed from the base of the PR and between eedebe1 and d77e39d.

📒 Files selected for processing (3)
  • networks.json
  • schema.graphql
  • subgraph.yaml
📝 Walkthrough

Walkthrough

Routed depositor ABIs, schema fields, mapping handlers, network addresses, and five subgraph data sources were added. Current and legacy event variants attach destination ownership and sender data to existing Deposit entities.

Changes

Routed deposit indexing

Layer / File(s) Summary
Routed event attachment
schema.graphql, abis/RoutedDepositor.json, src/mappingRoutedDeposit.ts
The Deposit entity gains routed fields; four event variants are defined; handlers normalize legacy owners, find deposits by depositKey, and update routed metadata.
Routed depositor data sources
subgraph.yaml, networks.json
Gasless, Arbitrum, Base, Sui, and StarkNet depositor contracts are configured for Sepolia and mainnet with current and legacy event handlers.
Estimated code review effort: 3 (Moderate) ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RoutedDepositor
  participant mappingRoutedDeposit
  participant Deposit
  RoutedDepositor->>mappingRoutedDeposit: Emit routed deposit event
  mappingRoutedDeposit->>mappingRoutedDeposit: Normalize owner and derive deposit id
  mappingRoutedDeposit->>Deposit: Update destinationOwner, l1Sender, and isRouted
  Deposit-->>mappingRoutedDeposit: Persist entity
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding indexed routed-deposit destinationOwner support on Deposit.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mswilkison
mswilkison marked this pull request as ready for review July 24, 2026 21:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/mappingRoutedDeposit.ts`:
- Around line 30-32: Update leftPadAddressTo32Bytes to use a Bytes-typed 12-byte
padding value before concatenating with address, ensuring the returned
concatenation is accepted as Bytes rather than ByteArray.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 31d5d11f-3076-40a3-8af5-1dcc6b24b0b3

📥 Commits

Reviewing files that changed from the base of the PR and between e5606a6 and eedebe1.

📒 Files selected for processing (5)
  • abis/RoutedDepositor.json
  • networks.json
  • schema.graphql
  • src/mappingRoutedDeposit.ts
  • subgraph.yaml

Comment on lines +30 to +32
function leftPadAddressTo32Bytes(address: Bytes): Bytes {
return new Bytes(12).concat(address)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

curl -fsSL \
  https://registry.npmjs.org/@graphprotocol/graph-ts/-/graph-ts-0.31.0.tgz |
  tar -xz -C "$tmp"

rg -n -A4 -B4 'concat\(other: ByteArray\)' "$tmp/package/common"

Repository: threshold-network/tbtc-subgraph

Length of output: 956


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked files matching mappingRoutedDeposit.ts:"
git ls-files | grep -E '(^|/)mappingRoutedDeposit\.ts$' || true

file="$(git ls-files | grep -E '(^|/)mappingRoutedDeposit\.ts$' | head -n 1)"
if [ -n "${file:-}" ]; then
  echo
  echo "File: $file"
  wc -l "$file"
  echo
  sed -n '1,80p' "$file" | cat -n
fi

echo
echo "Lock/package graph-ts references:"
rg -n '"`@graphprotocol/graph-ts`"|graph-ts' package.json package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null || true

Repository: threshold-network/tbtc-subgraph

Length of output: 4602


🌐 Web query:

AssemblyScript class inheritance subclass as superclass return type method compatible

💡 Result:

In AssemblyScript, method overriding and return type compatibility follow strict rules influenced by the language's static compilation and the lack of traditional virtual function lookup found in higher-level languages [1]. Regarding the return type of overridden methods: - Historically, using this as a return type in a base class method was problematic because the compiler resolved it as the base class type rather than the inheriting subclass type [2][3]. - Updates have been made to support the polymorphic this type on class methods [3]. If you define a method to return this, the compiler is intended to resolve it to the calling instance type [3]. - If you encounter issues where an overridden method is not correctly returning the subclass type, ensure you are using a recent version of the AssemblyScript compiler, as improvements to this type resolution were implemented to address this specific limitation [2][3]. Important considerations for inheritance in AssemblyScript: - Type Casting: AssemblyScript supports upcasting (subclass to superclass) implicitly or with the as operator [4][5]. For downcasting (superclass to subclass) or casting between siblings, you must use changetype<T>(...), as the compiler does not perform runtime type checks for these casts [5]. - Overriding: AssemblyScript does not implement standard virtual function lookups; therefore, overriding methods must be carefully managed [1]. When a subclass overrides a method, it is best practice to ensure the signature matches precisely. Issues can arise when attempting to override methods with incompatible types or mixing generic and non-generic method signatures [6][7]. - Properties: Note that overriding class properties is not directly supported in the same way as methods; developers often use the constructor to initialize or reassign inherited properties as a workaround [8]. For the most reliable behavior, always explicitly define return types and avoid relying on complex implicit polymorphism, as the language prioritizes clear, static resolution to maintain WebAssembly performance [9][1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

VERSION="$(sed -n 's/^  "version": "\(.*\)",/\1/p' package.json | head -n 1)"
VERSION="${VERSION:-19.0}"

if [ -x "$(command -v npm)" ]; then
  npm --silent pack "assemblyscript@$VERSION" > "$tmp/npm-pack-name"
  tar -xzf "$tmp/$(cat "$tmp/npm-pack-name")" -C "$tmp"
  echo "Packed and extracted AssemblyScript@" >&2
else
  echo "npm unavailable" >&2
  exit 0
fi

cat > "$tmp/concat-as-upcast.as" <<'AS'
class ByteArray {
  length: i32
  constructor(length: i32) { this.length = length }
  // Type-safe concat matching our code is not required for this probe;
  // the compiler rejects returning a subclass where a superclass is expected.
  concat(_: ByteArray): ByteArray { return changetype<ByteArray>(this) }
}
class Bytes extends ByteArray {
  concat(_: ByteArray): Bytes { return changetype<Bytes>(this) }
}
function leftPadAddressTo32Bytes(address: Bytes): Bytes {
  return new ByteArray(12).concat(address)
}
export function result(): Bytes {
  return leftPadAddressTo32Bytes(changetype<Bytes>(new ByteArray(20)))
}
AS

node "$tmp/assemblyscript-$VERSION/bin/asc.js" "$tmp/concat-as-upcast.as" --exportRuntime --textFile /dev/null \
  2>&1 | sed -n '1,80p'

echo
echo "If the return type matches via subclass-to-superclass upcast, removing this block would be appropriate:"

python3 - <<'PY'
from pathlib import Path
p = next(Path('/tmp/asm-as-upcast').glob('package/*'), None)
print('assemblyscript package location:', p)
print('assemblyscript.js exists:', (p / 'assemblyscript.js').exists())
PY

Repository: assemblyscript/assemblyscript

Length of output: 388


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Dependencies:"
cat package.json | python3 - <<'PY'
import json, sys
data=json.load(sys.stdin)
for sect in ['dependencies','devDependencies','packageManager']:
    if sect in data:
        print(f'[{sect}]')
        for k,v in data[sect].items():
            if 'assemblyscript' in k.lower() or 'graph-ts' in k.lower():
                print(f'{k}: {v}')
PY

echo
echo "Search for assemblyscript/graph-ts config/tooling:"
git ls-files | rg -i 'assemblyscript|graph-ts|tsconfig|yarn|package-lock|pnpm' || true

echo
echo "Inspect relevant tsconfig files:"
for f in $(git ls-files | rg -i 'tsconfig.*\.json$'); do
  echo "--- $f"
  sed -n '1,160p' "$f" | cat -n
done

Repository: threshold-network/tbtc-subgraph

Length of output: 904


🌐 Web query:

AssemblyScript return subclass where base class expected type error

💡 Result:

In AssemblyScript, encountering a type error when returning a subclass where a base class is expected—or when expecting a subclass type from a method declared to return a base class—often stems from differences between AssemblyScript's strict type system and TypeScript's more flexible, often bivariant, type system [1][2]. If you are experiencing issues where a method returning this or a subclass is not recognized as the subclass type, here are the primary factors and workarounds: 1. Type Inference Limitations: AssemblyScript requires explicit type annotations because its type inference is more limited than TypeScript's [2]. The compiler does not always automatically narrow return types to a subclass, even if the runtime object is an instance of that subclass [1]. 2. Method Return Types: If a base class method is declared to return the base type (e.g., : Base), the compiler treats the return value as the base type [1]. Even if you return this (which can be typed as this in some contexts), usage of subsequent subclass-specific properties may fail because the compiler's static analysis only sees the base class definition [1]. 3. Explicit Casting: Unlike TypeScript, which allows for implicit subtyping in many scenarios, AssemblyScript often requires explicit casting to treat a base class instance as a subclass [3]. Use the as operator for downcasting: const mySubclass = myBaseInstance as Subclass; [3]. 4. Alternative Pattern: To avoid type errors, ensure your methods are explicitly typed to return the specific subclass, or use generics if you are writing reusable base class logic that needs to return the derived type [4]. AssemblyScript also has known limitations regarding inheritance, such as inability to easily override class properties [5] and specific challenges with how this is resolved in static contexts [6]. If you believe the compiler is failing to recognize a valid subclass return in a way that should be supported, verify if your code triggers one of the documented compiler restrictions or report it as an issue if it diverges from standard behavior [1].

Citations:


🌐 Web query:

"@graphprotocol/graph-ts" "ByteArray.concat" "0.31.0" "Bytes"

💡 Result:

In the @graphprotocol/graph-ts library, including version 0.31.0, the ByteArray.concat method is an available API used to combine byte arrays [1][2][3]. The ByteArray.concat(other: ByteArray): ByteArray method returns a new ByteArray consisting of the original ByteArray followed directly by the other ByteArray provided as an argument [1][2][3]. Additionally, the library supports the following related concatenation operations: - concatI32(other: i32): ByteArray: Returns a new ByteArray consisting of the original ByteArray followed by the byte representation of the provided i32 integer [1][2][3]. - b.concat(other: Bytes): Bytes: For Bytes objects, this returns a new Bytes object consisting of the original Bytes followed by the other Bytes [1][3]. These functions are part of the AssemblyScript API for writing subgraph mappings [2][4]. The library's development has been unified within the graph-tooling monorepo [4].

Citations:


🌐 Web query:

AssemblyScript "ByteArray" "Bytes" "@graphprotocol/graph-ts"

💡 Result:

In the @graphprotocol/graph-ts library used for writing subgraph mappings, both ByteArray and Bytes are classes used to handle byte data, but they serve slightly different semantic purposes [1][2]. ByteArray The ByteArray class is designed to represent a generic array of bytes (u8) [1][3]. It provides utility methods for common operations such as conversion to/from hexadecimal strings, base58 encoding, and conversion to numeric types (u32, i32) [1][2]. Bytes The Bytes class is a subclass of ByteArray and is specifically used to represent arbitrary-length arrays of bytes, such as Ethereum types like bytes and bytes32 [1][4]. Because it extends ByteArray, it inherits all of its functionality [1][4]. In practice, Bytes is the standard type used for handling Ethereum-related byte values, such as contract addresses and event data [1][5]. Key Technical Points Relationship: Since Bytes extends ByteArray (and both extend the standard AssemblyScript Uint8Array), they share a common base [1][4]. Casting: Because they share a superclass (Uint8Array) but are distinct classes, direct casting using the 'as' keyword is often not safe [6][7]. The library provides the changetype function for safe conversion between these types, as well as specific static methods like Bytes.fromByteArray and ByteArray.fromBigInt to facilitate conversions [6][7]. Usage: It is generally recommended to use the Bytes type for entity IDs and Ethereum data types [5]. In the source code, Bytes is defined simply as an extension of ByteArray [4]: export class Bytes extends ByteArray {} For most subgraph development, Bytes is the preferred class to use unless a specific API requirement calls for a ByteArray [5].

Citations:


Return a Bytes value from the legacy padding helper.

new Bytes(12).concat(address) returns ByteArray, and AssemblyScript does not treat that ByteArray result as the Bytes return type. Use a Bytes-typed pad before returning it.

Proposed fix
 function left_padAddressTo32Bytes(address: Bytes): Bytes {
-    return new Bytes(12).concat(address)
+    let padded = new Bytes(32)
+    for (let i = 0; i < 20; i++) {
+        padded[i + 12] = address[i]
+    }
+    return padded
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mappingRoutedDeposit.ts` around lines 30 - 32, Update
leftPadAddressTo32Bytes to use a Bytes-typed 12-byte padding value before
concatenating with address, ensuring the returned concatenation is accepted as
Bytes rather than ByteArray.

mswilkison and others added 4 commits August 7, 2026 12:26
Adds server-side indexing of the routed (gasless / direct-mint) deposit
destination owner so a `deposits(where: { destinationOwner })` query can replace
the dapp's client-side ~45-95-request chunked eth_getLogs scan
(searchRoutedDepositIdsByDestination).

The five L1 depositor proxies (gasless, Arbitrum, Base, Sui, StarkNet) all
inherit AbstractL1BTCDepositor and emit:
  DepositInitialized(uint256 indexed depositKey,
                     bytes32 indexed destinationChainDepositOwner,
                     address indexed l1Sender)
  DepositFinalized(...same three indexed..., uint256 initialAmount, uint256 tbtcAmount)
depositKey is byte-identical to the Bridge deposit key = Deposit.id
(keccak256(fundingTxHash|fundingOutputIndex)), so the mapping attaches
destinationOwner straight onto the existing Deposit via getOrCreateDeposit — no
new entity or join. destinationChainDepositOwner is already the 32-byte form the
dapp's normalizeDestinationTopic() searches on (EVM address left-padded;
Sui/StarkNet raw bytes32), so the lookup is a drop-in.

- schema.graphql: Deposit gains destinationOwner, l1Sender, isRouted.
- abis/RoutedDepositor.json: the two events (all three leading params indexed).
- subgraph.yaml: five ethereum datasources (startBlock 20,650,000).
- src/mappingRoutedDeposit.ts: attaches destinationOwner/l1Sender/isRouted.

Topic0s verified via keccak256: e96a7294=DepositInitialized(uint256,bytes32,address),
3ce59c3f=DepositFinalized(...). `graph codegen` + `graph build` pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The L1 depositors emitted a legacy DepositInitialized/DepositFinalized
overload (owner as an indexed address) before switching to the current
bytes32 form, and the legacy era covers roughly 87-90% of Arbitrum/Base
routed deposits. Index both overloads on every depositor datasource and
left-pad legacy owners to the same 32-byte destinationOwner form the
current events store, so one where-filter matches both eras.

Also:
- set each datasource startBlock to the contract's real deploy block
  (the Arbitrum depositor deployed at 20,632,547, below the previous
  20,650,000 floor) and register all five depositors in networks.json
  for mainnet and sepolia so graph build --network keeps working
- keep the l1Sender recorded by the first routed event seen instead of
  letting a permissionless finalization overwrite the initializer
- reuse Utils.convertDepositKeyToHex for the deposit id conversion
getOrCreateDeposit would save a Deposit missing non-nullable fields if a
routed event ever arrived before the Bridge's DepositRevealed, and a
failed save halts the entire subgraph. The same-transaction ordering
makes that unreachable today, but load-and-skip with a warning is
strictly safer insurance ahead of a multi-day resync.
…Depositors

After rebase onto master (which introduced L1BTCRedeemerWormhole via
PR threshold-network#3), the conflict resolution left L1BTCRedeemerWormhole's mapping
block nested inside the GaslessDepositor data source, causing a
duplicate-key YAML parse error.

Restructure: L1BTCRedeemerWormhole now has its own complete data
source block, followed by the 5 RoutedDepositor data sources from
PR threshold-network#7.
@piotr-roslaniec
piotr-roslaniec force-pushed the feat/index-routed-deposit-destination branch from eedebe1 to d77e39d Compare August 7, 2026 12:39
@piotr-roslaniec
piotr-roslaniec merged commit 90d4188 into threshold-network:master Aug 7, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants