@gibs/bridge-indexer 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +62 -0
- package/dist/bridge-status.d.ts +58 -0
- package/dist/bridge-status.js +23 -0
- package/dist/endpoint.d.ts +49 -0
- package/dist/endpoint.js +59 -0
- package/dist/graphql.d.ts +2537 -0
- package/dist/graphql.js +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +23 -0
- package/dist/live-status.d.ts +18 -0
- package/dist/live-status.js +178 -0
- package/dist/transfers.d.ts +147 -0
- package/dist/transfers.js +711 -0
- package/package.json +104 -0
- package/schema.graphql +2047 -0
package/dist/graphql.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a Gibs Finance bridge indexer.
|
|
3
|
+
*
|
|
4
|
+
* WHAT THIS PACKAGE IS FOR. The bridge's quote maths, chain metadata, ABIs and
|
|
5
|
+
* transaction building have been publishable for a long time; the ability to
|
|
6
|
+
* ask what happened to a transfer has not. That half lived inside the interface
|
|
7
|
+
* — and, independently, inside a second, older interface — so anybody building
|
|
8
|
+
* on the bridge could construct a crossing and then had no supported way to
|
|
9
|
+
* find out whether it landed. This package is that missing half.
|
|
10
|
+
*
|
|
11
|
+
* WHAT IT DOES NOT DO. It reads. Nothing here signs, broadcasts, or holds a
|
|
12
|
+
* wallet, and nothing here renders. A transfer's status arrives as data — a
|
|
13
|
+
* record, a count of affirmations, a delivery flag — and the words a person
|
|
14
|
+
* reads are the consumer's to choose, because a library cannot own somebody
|
|
15
|
+
* else's message catalogue.
|
|
16
|
+
*
|
|
17
|
+
* Point it somewhere with {@link setIndexerEndpoint} before the first query; it
|
|
18
|
+
* defaults to the next indexer (https://next-indexer.gibs.finance).
|
|
19
|
+
*/
|
|
20
|
+
export { DEFAULT_INDEXER_ENDPOINT, indexerClient, indexerEndpoint, setIndexerEndpoint } from './endpoint.js';
|
|
21
|
+
export { bridgeStatuses, statusList, statusToIndex, type BridgeStatus, type ContinuedLiveBridgeStatusParams, type LiveBridgeStatusParams, } from './bridge-status.js';
|
|
22
|
+
export { buildBridgeFilter, fetchBridgeTransactions, fetchDeliveredMessageHashes, forgetDeliveredMessageHashes, loadTokenMetadataForBridges, peekDeliveredMessageHashes, type BridgeData, type BridgeFilterMode, type DeliveredMessageHashes, type FeeData, type LoadBridgesParams, } from './transfers.js';
|
|
23
|
+
export { liveBridgeStatusStageOne, liveBridgeStatusStageTwo } from './live-status.js';
|
|
24
|
+
export type { UserRequest, UserRequestFilter } from './graphql.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a Gibs Finance bridge indexer.
|
|
3
|
+
*
|
|
4
|
+
* WHAT THIS PACKAGE IS FOR. The bridge's quote maths, chain metadata, ABIs and
|
|
5
|
+
* transaction building have been publishable for a long time; the ability to
|
|
6
|
+
* ask what happened to a transfer has not. That half lived inside the interface
|
|
7
|
+
* — and, independently, inside a second, older interface — so anybody building
|
|
8
|
+
* on the bridge could construct a crossing and then had no supported way to
|
|
9
|
+
* find out whether it landed. This package is that missing half.
|
|
10
|
+
*
|
|
11
|
+
* WHAT IT DOES NOT DO. It reads. Nothing here signs, broadcasts, or holds a
|
|
12
|
+
* wallet, and nothing here renders. A transfer's status arrives as data — a
|
|
13
|
+
* record, a count of affirmations, a delivery flag — and the words a person
|
|
14
|
+
* reads are the consumer's to choose, because a library cannot own somebody
|
|
15
|
+
* else's message catalogue.
|
|
16
|
+
*
|
|
17
|
+
* Point it somewhere with {@link setIndexerEndpoint} before the first query; it
|
|
18
|
+
* defaults to the next indexer (https://next-indexer.gibs.finance).
|
|
19
|
+
*/
|
|
20
|
+
export { DEFAULT_INDEXER_ENDPOINT, indexerClient, indexerEndpoint, setIndexerEndpoint } from './endpoint.js';
|
|
21
|
+
export { bridgeStatuses, statusList, statusToIndex, } from './bridge-status.js';
|
|
22
|
+
export { buildBridgeFilter, fetchBridgeTransactions, fetchDeliveredMessageHashes, forgetDeliveredMessageHashes, loadTokenMetadataForBridges, peekDeliveredMessageHashes, } from './transfers.js';
|
|
23
|
+
export { liveBridgeStatusStageOne, liveBridgeStatusStageTwo } from './live-status.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ContinuedLiveBridgeStatusParams, type LiveBridgeStatusParams } from './bridge-status.js';
|
|
2
|
+
/** Clears the in-memory indexer cache. Exported for test isolation. */
|
|
3
|
+
export declare const _clearLiveBridgeStatusCache: () => void;
|
|
4
|
+
/**
|
|
5
|
+
* Stage one of the live bridge-status pipeline. Reads the origination receipt
|
|
6
|
+
* to decide between SUBMITTED (not yet mined) and MINED (receipt available).
|
|
7
|
+
* @param params - the hash, ticker block, and bridge key to inspect
|
|
8
|
+
* @returns the params extended with the resolved status (and receipt when mined)
|
|
9
|
+
*/
|
|
10
|
+
export declare const liveBridgeStatusStageOne: (params: LiveBridgeStatusParams) => Promise<ContinuedLiveBridgeStatusParams>;
|
|
11
|
+
/**
|
|
12
|
+
* Stage two of the live bridge-status pipeline. Waits for finalization of the
|
|
13
|
+
* origination receipt, then reads the indexer to advance the status through
|
|
14
|
+
* FINALIZED, VALIDATING, and AFFIRMED.
|
|
15
|
+
* @param params - the stage-one output, or null when the pipeline was cleared
|
|
16
|
+
* @returns the params advanced to its next status, or unchanged when not ready
|
|
17
|
+
*/
|
|
18
|
+
export declare const liveBridgeStatusStageTwo: (params: ContinuedLiveBridgeStatusParams | null) => Promise<ContinuedLiveBridgeStatusParams | null>;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { gql } from 'graphql-request';
|
|
2
|
+
import { indexerClient } from './endpoint.js';
|
|
3
|
+
import { clientFromChain } from '@gibs/bridge-client/client';
|
|
4
|
+
import { bridgeStatuses, statusToIndex, } from './bridge-status.js';
|
|
5
|
+
import { Cache } from '@gibs/bridge-client/cache';
|
|
6
|
+
/** Single shared indexer client, mirroring the construction in history.ts. */
|
|
7
|
+
/**
|
|
8
|
+
* Every request here goes through {@link indexerClient}, which is a FUNCTION
|
|
9
|
+
* rather than a held client: a consumer configures the address during startup,
|
|
10
|
+
* and a client captured at module-evaluation time would have frozen the default
|
|
11
|
+
* before they got the chance.
|
|
12
|
+
*/
|
|
13
|
+
const client = () => indexerClient();
|
|
14
|
+
const liveBridgeStatusQuery = gql `
|
|
15
|
+
query LiveBridgeStatus($hash: String!) {
|
|
16
|
+
userRequests(where: { transactionHash: $hash }) {
|
|
17
|
+
items {
|
|
18
|
+
messageId
|
|
19
|
+
confirmedSignatures
|
|
20
|
+
finishedSigning
|
|
21
|
+
requiredSignatures {
|
|
22
|
+
value
|
|
23
|
+
}
|
|
24
|
+
delivery {
|
|
25
|
+
transactionHash
|
|
26
|
+
}
|
|
27
|
+
feeDirector {
|
|
28
|
+
feeType
|
|
29
|
+
}
|
|
30
|
+
type
|
|
31
|
+
encodedData
|
|
32
|
+
signatures
|
|
33
|
+
destinationAmbAddress
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
/** Time-to-live cache that collapses identical indexer reads within five seconds. */
|
|
39
|
+
const gqlCache = new Cache(5 * 1_000);
|
|
40
|
+
/** Clears the in-memory indexer cache. Exported for test isolation. */
|
|
41
|
+
export const _clearLiveBridgeStatusCache = () => {
|
|
42
|
+
gqlCache.cache.clear();
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Requests the live bridge status for an origination transaction hash, reusing
|
|
46
|
+
* an in-flight or recently resolved promise within the cache time-to-live so
|
|
47
|
+
* repeated polls of the same hash collapse to a single network read.
|
|
48
|
+
* @param hash - the origination transaction hash to look up
|
|
49
|
+
* @returns the indexer's user-request payload for the hash
|
|
50
|
+
*/
|
|
51
|
+
const requestBridgeStatus = (hash) => {
|
|
52
|
+
const key = JSON.stringify(['live-bridge-status', hash]);
|
|
53
|
+
const now = gqlCache.clearStale();
|
|
54
|
+
const cached = gqlCache.cache.get(key);
|
|
55
|
+
if (cached) {
|
|
56
|
+
return cached.value;
|
|
57
|
+
}
|
|
58
|
+
const result = client().request(liveBridgeStatusQuery, { hash });
|
|
59
|
+
gqlCache.cache.set(key, { time: now, value: result });
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Stage one of the live bridge-status pipeline. Reads the origination receipt
|
|
64
|
+
* to decide between SUBMITTED (not yet mined) and MINED (receipt available).
|
|
65
|
+
* @param params - the hash, ticker block, and bridge key to inspect
|
|
66
|
+
* @returns the params extended with the resolved status (and receipt when mined)
|
|
67
|
+
*/
|
|
68
|
+
export const liveBridgeStatusStageOne = async (params) => {
|
|
69
|
+
const { hash, bridgeKey } = params;
|
|
70
|
+
const [, fromChain] = bridgeKey;
|
|
71
|
+
const client = clientFromChain(Number(fromChain));
|
|
72
|
+
const receipt = await client
|
|
73
|
+
.getTransactionReceipt({
|
|
74
|
+
hash,
|
|
75
|
+
})
|
|
76
|
+
.catch(() => null);
|
|
77
|
+
if (!receipt) {
|
|
78
|
+
// transaction has not yet been mined — getTransaction may throw if the node
|
|
79
|
+
// hasn't propagated it yet (mempool lag), so we catch and still return SUBMITTED
|
|
80
|
+
await Promise.all([
|
|
81
|
+
client
|
|
82
|
+
.getTransaction({ hash })
|
|
83
|
+
.then((transaction) => {
|
|
84
|
+
client.getBlock({ blockTag: 'latest' }).then((latest) => {
|
|
85
|
+
console.log('transaction has not yet been mined', hash, transaction?.maxFeePerGas ?? transaction?.gasPrice, latest.baseFeePerGas);
|
|
86
|
+
});
|
|
87
|
+
})
|
|
88
|
+
.catch(() => {
|
|
89
|
+
// transaction not yet visible to this node — normal during mempool propagation
|
|
90
|
+
}),
|
|
91
|
+
]);
|
|
92
|
+
return {
|
|
93
|
+
...params,
|
|
94
|
+
status: bridgeStatuses.SUBMITTED,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
...params,
|
|
99
|
+
status: bridgeStatuses.MINED,
|
|
100
|
+
receipt,
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Stage two of the live bridge-status pipeline. Waits for finalization of the
|
|
105
|
+
* origination receipt, then reads the indexer to advance the status through
|
|
106
|
+
* FINALIZED, VALIDATING, and AFFIRMED.
|
|
107
|
+
* @param params - the stage-one output, or null when the pipeline was cleared
|
|
108
|
+
* @returns the params advanced to its next status, or unchanged when not ready
|
|
109
|
+
*/
|
|
110
|
+
export const liveBridgeStatusStageTwo = async (params) => {
|
|
111
|
+
if (!params)
|
|
112
|
+
return null;
|
|
113
|
+
const { status, receipt, bridgeKey } = params;
|
|
114
|
+
if (statusToIndex(status) < statusToIndex(bridgeStatuses.MINED)) {
|
|
115
|
+
return params;
|
|
116
|
+
}
|
|
117
|
+
const client = clientFromChain(Number(bridgeKey[1]));
|
|
118
|
+
const finalizedBlock = await client.getBlock({ blockTag: 'finalized' });
|
|
119
|
+
params.finalizedBlock = finalizedBlock;
|
|
120
|
+
if (finalizedBlock.number < receipt.blockNumber) {
|
|
121
|
+
console.log('transaction has been mined, not yet finalized hash=%o current=%o finalized=%o receipt=%o', receipt?.transactionHash, params.ticker.number, finalizedBlock.number, receipt.blockNumber);
|
|
122
|
+
return params;
|
|
123
|
+
}
|
|
124
|
+
const result = await requestBridgeStatus(receipt.transactionHash);
|
|
125
|
+
const userRequest = result.userRequests.items?.[0];
|
|
126
|
+
if (!userRequest?.messageId)
|
|
127
|
+
return params;
|
|
128
|
+
const count = Number(userRequest.confirmedSignatures ?? 0);
|
|
129
|
+
const requiredSignatures = userRequest.requiredSignatures?.value != null
|
|
130
|
+
? Number(userRequest.requiredSignatures.value)
|
|
131
|
+
: null;
|
|
132
|
+
const deliveryType = userRequest.feeDirector?.feeType ?? null;
|
|
133
|
+
if (userRequest.delivery?.transactionHash) {
|
|
134
|
+
// AFFIRMED here means DELIVERED — a delivery transaction hash exists. This
|
|
135
|
+
// is the canonical meaning: it matches the on-chain event that produces
|
|
136
|
+
// it (`HomeAMB:AffirmationCompleted`). `bridge-history-item-utils.ts`
|
|
137
|
+
// once used AFFIRMED for the opposite fact (signed but not delivered);
|
|
138
|
+
// that collision is fixed there in favor of THIS meaning — see the
|
|
139
|
+
// comment on `createBridgeStatusFromHistory` and docs/transfer-states.md
|
|
140
|
+
// section 1. Do not reintroduce a second meaning for this value.
|
|
141
|
+
return {
|
|
142
|
+
...params,
|
|
143
|
+
messageId: userRequest.messageId,
|
|
144
|
+
status: bridgeStatuses.AFFIRMED,
|
|
145
|
+
deliveredHash: userRequest.delivery.transactionHash,
|
|
146
|
+
count,
|
|
147
|
+
requiredSignatures,
|
|
148
|
+
deliveryType,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (userRequest.finishedSigning) {
|
|
152
|
+
return {
|
|
153
|
+
...params,
|
|
154
|
+
messageId: userRequest.messageId,
|
|
155
|
+
status: bridgeStatuses.VALIDATING,
|
|
156
|
+
count,
|
|
157
|
+
requiredSignatures,
|
|
158
|
+
deliveryType,
|
|
159
|
+
// Only attached once the request is actually releasable (finished
|
|
160
|
+
// signing, not yet delivered) — the one lifecycle point a manual
|
|
161
|
+
// release calldata could be built and broadcast.
|
|
162
|
+
release: {
|
|
163
|
+
requestType: userRequest.type,
|
|
164
|
+
encodedData: userRequest.encodedData,
|
|
165
|
+
signatures: userRequest.signatures ?? [],
|
|
166
|
+
destinationAmbAddress: userRequest.destinationAmbAddress,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
...params,
|
|
172
|
+
messageId: userRequest.messageId,
|
|
173
|
+
status: bridgeStatuses.FINALIZED,
|
|
174
|
+
count,
|
|
175
|
+
requiredSignatures,
|
|
176
|
+
deliveryType,
|
|
177
|
+
};
|
|
178
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { TokenMetadata } from '@gibs/bridge-sdk/types';
|
|
2
|
+
import { type Hex } from 'viem';
|
|
3
|
+
import type { UserRequest, UserRequestFilter } from './graphql.js';
|
|
4
|
+
export interface FeeData {
|
|
5
|
+
tokenAddress: Hex;
|
|
6
|
+
feeManagerContract: {
|
|
7
|
+
chainId: string;
|
|
8
|
+
address: Hex;
|
|
9
|
+
omnibridgeAddress: Hex;
|
|
10
|
+
};
|
|
11
|
+
feeUpdate: {
|
|
12
|
+
feeType: Hex;
|
|
13
|
+
fee: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface BridgeData {
|
|
17
|
+
userRequests: UserRequest[];
|
|
18
|
+
tokenMetadata: Map<string, TokenMetadata>;
|
|
19
|
+
feeData: FeeData[];
|
|
20
|
+
pageInfo?: {
|
|
21
|
+
hasNextPage: boolean;
|
|
22
|
+
hasPreviousPage: boolean;
|
|
23
|
+
startCursor?: string | null;
|
|
24
|
+
endCursor?: string | null;
|
|
25
|
+
};
|
|
26
|
+
totalCount?: number;
|
|
27
|
+
/**
|
|
28
|
+
* How many bridges this account released FOR SOMEONE ELSE the archive could
|
|
29
|
+
* not be asked about, because the fold-in list is capped at
|
|
30
|
+
* {@link DELIVERED_HASHES_LIMIT}.
|
|
31
|
+
*
|
|
32
|
+
* Reported so the interface can SAY SO. The cap used to reach a
|
|
33
|
+
* `console.warn` and nothing else, so a delivery account whose released
|
|
34
|
+
* bridges run into the thousands was shown a page footer that read as the
|
|
35
|
+
* whole archive. A count that is silently short is worse than one that is
|
|
36
|
+
* absent: the reader trusts it.
|
|
37
|
+
*/
|
|
38
|
+
releasedForOthersOmitted: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Loads token metadata for unique token/chain combinations found in a set of bridges.
|
|
42
|
+
* Exported for independent testability.
|
|
43
|
+
*/
|
|
44
|
+
export declare function loadTokenMetadataForBridges(bridges: UserRequest[]): Promise<Map<string, TokenMetadata>>;
|
|
45
|
+
/**
|
|
46
|
+
* Which part of the archive a browse asks for.
|
|
47
|
+
*
|
|
48
|
+
* `pending` and `completed` are a genuine partition of every request, so
|
|
49
|
+
* switching always changes what is on screen. `all` asks for both and is
|
|
50
|
+
* coherent only BECAUSE of that partition — it carries no `delivered` filter at
|
|
51
|
+
* all rather than a third value of one.
|
|
52
|
+
*/
|
|
53
|
+
export type BridgeFilterMode = 'pending' | 'completed' | 'all';
|
|
54
|
+
export type LoadBridgesParams = {
|
|
55
|
+
address: Hex | null | undefined;
|
|
56
|
+
hash?: Hex | null | undefined;
|
|
57
|
+
limit?: number;
|
|
58
|
+
after?: string;
|
|
59
|
+
before?: string;
|
|
60
|
+
filterMode?: BridgeFilterMode;
|
|
61
|
+
/**
|
|
62
|
+
* Chain ids whose transfers must not appear, sorted. Omit or leave empty to
|
|
63
|
+
* ask for every network.
|
|
64
|
+
*
|
|
65
|
+
* IT IS THE INDEXER THAT APPLIES THIS, not the browser, and that is the whole
|
|
66
|
+
* reason it is here. A network filter applied to the page after it arrives
|
|
67
|
+
* would draw three rows under a count of ten while thousands more matched on
|
|
68
|
+
* pages the reader never reached — a silently capped list reads as the whole
|
|
69
|
+
* answer.
|
|
70
|
+
*/
|
|
71
|
+
hiddenChainIds?: readonly number[];
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Builds the GraphQL filter for user request queries from bridge loading params.
|
|
75
|
+
* Pure function — no side effects, exported for independent testability.
|
|
76
|
+
*/
|
|
77
|
+
export declare function buildBridgeFilter(params: LoadBridgesParams, deliveredMessageHashes?: Hex[]): UserRequestFilter | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* What one account has released on behalf of other people, as the archive query
|
|
80
|
+
* needs it: the hashes to fold in, and how many did not fit.
|
|
81
|
+
*/
|
|
82
|
+
export interface DeliveredMessageHashes {
|
|
83
|
+
/** The lowercased message hashes, newest first, at most {@link DELIVERED_HASHES_LIMIT}. */
|
|
84
|
+
readonly hashes: Hex[];
|
|
85
|
+
/** How many further released bridges the cap left out. Zero when none. */
|
|
86
|
+
readonly omitted: number;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Drops one account's cached delivered-hash list, so the next history fetch
|
|
90
|
+
* resolves it again.
|
|
91
|
+
*
|
|
92
|
+
* Called when the reader's own transaction is mined. A release the READER just
|
|
93
|
+
* made is the one change this list can undergo while they are watching it, and
|
|
94
|
+
* making them wait out the cache to see it would defeat the burst poll that
|
|
95
|
+
* exists for exactly that moment.
|
|
96
|
+
*
|
|
97
|
+
* @param address - the account whose list to forget. No address forgets nothing.
|
|
98
|
+
*/
|
|
99
|
+
export declare const forgetDeliveredMessageHashes: (address: Hex | null | undefined) => void;
|
|
100
|
+
/** Clears every cached delivered-hash list. Exported for test isolation. */
|
|
101
|
+
export declare const _clearDeliveredHashesCache: () => void;
|
|
102
|
+
/**
|
|
103
|
+
* One account's delivered-hash list IF it is already resolved and still fresh,
|
|
104
|
+
* without starting a fetch for it.
|
|
105
|
+
*
|
|
106
|
+
* WHY LOOKING IS A DIFFERENT QUESTION FROM ASKING. `fetchBridgeTransactions`
|
|
107
|
+
* needs to know whether waiting for this list is free before it decides whether
|
|
108
|
+
* to run the archive query alongside it or after it. A cached list costs
|
|
109
|
+
* nothing to wait for, so the archive query can be built widened straight away;
|
|
110
|
+
* an unresolved one costs a whole round trip, and that is the round trip the
|
|
111
|
+
* page used to sit through before it asked for a single transfer.
|
|
112
|
+
*
|
|
113
|
+
* A STALE ENTRY READS AS ABSENT. `fetchDeliveredMessageHashes` sweeps expired
|
|
114
|
+
* entries on its way past, so an entry can outlive its window between sweeps.
|
|
115
|
+
* Returning one would hand the caller a list it believes is current.
|
|
116
|
+
*
|
|
117
|
+
* @param address - the account to look up. No address has no list.
|
|
118
|
+
* @returns the resolved list's promise, or null when there is no fresh one.
|
|
119
|
+
*/
|
|
120
|
+
export declare const peekDeliveredMessageHashes: (address: Hex | null | undefined) => Promise<DeliveredMessageHashes> | null;
|
|
121
|
+
/**
|
|
122
|
+
* Fetches the message hashes of bridges this account RELEASED on behalf of others —
|
|
123
|
+
* the on-chain `deliverer` (the account that submitted the release transaction).
|
|
124
|
+
* Those bridges never match the history query's from/to scope, so without this they
|
|
125
|
+
* are invisible in the account's history.
|
|
126
|
+
*
|
|
127
|
+
* Ponder stores hex columns lowercase but does not normalize the query side, so the
|
|
128
|
+
* deliverer is queried lowercased to match (the same normalization the from/to scope
|
|
129
|
+
* relies on). Returns lowercased message hashes; nothing when no address.
|
|
130
|
+
*
|
|
131
|
+
* The answer is cached per account for {@link DELIVERED_HASHES_CACHE_TTL}. See
|
|
132
|
+
* that constant for why: this is the query that was reading hundreds of records
|
|
133
|
+
* in front of every ten-row page.
|
|
134
|
+
*
|
|
135
|
+
* Resilient by design: a failure here returns an empty list rather than throwing, so
|
|
136
|
+
* a deliveries-query problem degrades history to the from/to scope instead of blanking
|
|
137
|
+
* the whole panel. A failure is NEVER cached — a reader whose network blipped once
|
|
138
|
+
* would otherwise lose their released bridges for the full minute.
|
|
139
|
+
*/
|
|
140
|
+
export declare function fetchDeliveredMessageHashes(address: Hex | null | undefined): Promise<DeliveredMessageHashes>;
|
|
141
|
+
/** Clears the in-memory bridge cache. Exported for test isolation. */
|
|
142
|
+
export declare const _clearBridgeCache: () => void;
|
|
143
|
+
/**
|
|
144
|
+
* Inner fetching logic for loadBridgeTransactions.
|
|
145
|
+
* Exported so it can be tested independently of the Svelte loading store wrapper.
|
|
146
|
+
*/
|
|
147
|
+
export declare function fetchBridgeTransactions(rawParams: LoadBridgesParams, controller: AbortController): Promise<BridgeData | null>;
|