builderApprovedNonFundingLedgerUpdatesByTime
Deposits, withdrawals, transfers and other non-funding ledger updates made by users who had an active builder-fee approval for your builder address.
The ledger counterpart of builderApprovedFillsByTime: every non-funding ledger update — deposits, withdrawals, transfers, vault flows, liquidations and the rest — made by a user while they had approved your builder, across all of those users at once. Each row is exactly a userNonFundingLedgerUpdates row with the user it was attributed to, their role, and the txIndex needed to page added.
Why you need this
Deposits and withdrawals are the earliest and latest signals you have about a user: a first deposit precedes any fill, and a withdrawal often precedes churn. Funding aside, this is the rest of the money movement for the users who approved you, without polling userNonFundingLedgerUpdates per user.
POST Request
type
string
Required. "builderApprovedNonFundingLedgerUpdatesByTime"
builder
string
Required. Builder address, 42-char hex.
startTime
number
Required unless cursor is given. Inclusive, milliseconds.
endTime
number
Optional. Inclusive, milliseconds.
cursor
string
Optional. Continue from a previous page. Format "{time}_{txIndex}_{user}_{role}".
limit
number
Optional. Default and maximum 2000.
Results are returned oldest-first, ordered by (time, txIndex, user, role).
curl -X POST https://api.hydromancer.xyz/info \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"type": "builderApprovedNonFundingLedgerUpdatesByTime",
"builder": "0x1924b8561eef20e70ede628a296175d358be80e5",
"startTime": 1786000000000,
"limit": 100
}'import requests
resp = requests.post(
"https://api.hydromancer.xyz/info",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"type": "builderApprovedNonFundingLedgerUpdatesByTime",
"builder": "0x1924b8561eef20e70ede628a296175d358be80e5",
"startTime": 1786000000000,
"limit": 100,
},
)
updates = resp.json()Pagination
Take the last returned row and build cursor as "{time}_{txIndex}_{user}_{role}", then repeat the request with that cursor instead of startTime. A page shorter than limit means you have reached the end of the range.
Several updates land in one block and share time, and a self-transfer even shares txIndex and user across its two rows, so the cursor carries all four parts: it resumes exactly after the last row you saw without repeating or skipping the rest of the block.
Semantics
One row per participating approving user. A transfer names two users, and each is attributed independently. If the sender approved you, you get their row with
role: "sender"; if the receiver approved you, you get theirs withrole: "receiver"; if both did, you get both.deltais whatuserNonFundingLedgerUpdatesshows that participant:useris always the sender anddestinationthe receiver on either row, and the fee appears on the sender's row only —roleis what tells you which side the row is for. Single-party updates such as deposits carryrole: "user".Attributed at the block. An approval applies from the block it lands in, and a revocation likewise. An update that happened while an approval was active stays attributed permanently — revoking does not remove past rows from this endpoint.
Same row as
userNonFundingLedgerUpdates.time,hashanddeltaare byte-for-byte what userNonFundingLedgerUpdates returns for that user; onlyuser,roleandtxIndexare added. Funding is excluded here exactly as it is there — use builderApprovedFundingByTime for it.
Response Fields
user
string
The participant this row is attributed to, who had approved your builder at the time.
role
string
"user" for single-party updates; "sender" or "receiver" for the side of a transfer this row is for.
time
int
Block timestamp (ms).
txIndex
int
Position of the update within its block. Needed only to build cursor.
hash
string
Transaction hash.
delta
object
Ledger update details, identical to userNonFundingLedgerUpdates. Fields vary by delta.type; see that page for every delta type.
Last updated