@dust-dice/verifier 0.4.2 → 0.4.4
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/dist/contracts.d.ts +22 -4
- package/dist/contracts.js +34 -16
- package/dist/contracts.js.map +1 -1
- package/dist/indexer.d.ts +18 -13
- package/dist/indexer.js +110 -43
- package/dist/indexer.js.map +1 -1
- package/dist/verify.js +257 -68
- package/dist/verify.js.map +1 -1
- package/package.json +8 -8
- package/src/contracts.ts +41 -17
- package/src/indexer.ts +145 -55
- package/src/verify.ts +6 -6
package/dist/contracts.d.ts
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* combinator is `withWitnesses` (`withVacantWitnesses` is for contracts that declare none).
|
|
12
12
|
*/
|
|
13
13
|
import { CompiledContract } from '@midnight-ntwrk/midnight-js-protocol/compact-js';
|
|
14
|
-
import {
|
|
14
|
+
import { ContractState } from '@midnight-ntwrk/midnight-js-protocol/compact-runtime';
|
|
15
|
+
import { Table, Lobby, type UnshieldedBalances, type TablePrivateState, type LobbyPrivateState } from '@dust-dice/contract';
|
|
15
16
|
export { Table, Lobby };
|
|
16
17
|
/**
|
|
17
18
|
* The exported circuit names, spelled out.
|
|
@@ -29,6 +30,10 @@ export declare const CompiledTableContract: CompiledContract.CompiledContract<Ta
|
|
|
29
30
|
export declare const CompiledLobbyContract: CompiledContract.CompiledContract<Lobby.Contract<LobbyPrivateState, Lobby.Witnesses<LobbyPrivateState>>, LobbyPrivateState, never>;
|
|
30
31
|
export type TableLedger = Table.Ledger;
|
|
31
32
|
export type LobbyLedger = Lobby.Ledger;
|
|
33
|
+
/** Which state to read: the latest, or the one a specific transaction left behind. */
|
|
34
|
+
export type LedgerAt = {
|
|
35
|
+
txHash: string;
|
|
36
|
+
};
|
|
32
37
|
/**
|
|
33
38
|
* Read a table's ledger with a ONE-SHOT query.
|
|
34
39
|
*
|
|
@@ -37,11 +42,24 @@ export type LobbyLedger = Lobby.Ledger;
|
|
|
37
42
|
* driver -- and there is one after almost every transaction -- has to use `queryContractState`.
|
|
38
43
|
* (bugs-found.md §0 #10; the same reason probes/gate0/src/step.ts reads this way.)
|
|
39
44
|
*
|
|
40
|
-
* `
|
|
41
|
-
* game with.
|
|
45
|
+
* `at.txHash` pins the read to the state a transaction left, which is what the chain-only
|
|
46
|
+
* verifier walks the game with. By TRANSACTION, not by block: on this indexer (4.3.x) a block
|
|
47
|
+
* offset means "the action in that block", and with simultaneous rounds several of a table's
|
|
48
|
+
* transactions routinely share one -- a block-keyed read cannot say which it returned. The SDK
|
|
49
|
+
* offers no transaction-hash offset, so that read goes straight to the indexer.
|
|
42
50
|
*/
|
|
43
|
-
export declare function
|
|
51
|
+
export declare function readContractState(address: string, at?: LedgerAt): Promise<ContractState>;
|
|
52
|
+
export declare function readTableLedger(address: string, at?: LedgerAt): Promise<TableLedger>;
|
|
44
53
|
export declare function readLobbyLedger(address: string): Promise<LobbyLedger>;
|
|
54
|
+
/**
|
|
55
|
+
* What the LEDGER says the contract holds, for checking against the `pot` it claims.
|
|
56
|
+
*
|
|
57
|
+
* Read out of the contract's own state, NOT out of the indexer's
|
|
58
|
+
* `contractAction { unshieldedBalances }` -- that field answers `[]` on this indexer even for a
|
|
59
|
+
* table sitting on a pot, which reads as a solvency alarm instead of a balance. See
|
|
60
|
+
* `@dust-dice/contract`'s `custody.ts` and the test that pins it.
|
|
61
|
+
*/
|
|
62
|
+
export declare function contractUnshieldedBalances(address: string, at?: LedgerAt): Promise<UnshieldedBalances>;
|
|
45
63
|
/** `Dice` as the plain five-element array everything else in this repo speaks. */
|
|
46
64
|
export declare function diceToArray(d: Table.Dice): number[];
|
|
47
65
|
/** Rounds per seat: 0..12, thirteen of them, one category each. `roundCount()`. */
|
package/dist/contracts.js
CHANGED
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
* combinator is `withWitnesses` (`withVacantWitnesses` is for contracts that declare none).
|
|
14
14
|
*/
|
|
15
15
|
import { CompiledContract } from '@midnight-ntwrk/midnight-js-protocol/compact-js';
|
|
16
|
+
import { ContractState } from '@midnight-ntwrk/midnight-js-protocol/compact-runtime';
|
|
16
17
|
import { indexerPublicDataProvider } from '@midnight-ntwrk/midnight-js-indexer-public-data-provider';
|
|
17
|
-
import { Table, Lobby, tableWitnesses, lobbyWitnesses, } from '@dust-dice/contract';
|
|
18
|
+
import { Table, Lobby, tableWitnesses, lobbyWitnesses, unshieldedBalances, } from '@dust-dice/contract';
|
|
18
19
|
import { NETWORK } from "./config.js";
|
|
20
|
+
import { contractStateHexAt } from "./indexer.js";
|
|
19
21
|
export { Table, Lobby };
|
|
20
22
|
export const CompiledTableContract = CompiledContract.make('Table', (Table.Contract)).pipe(CompiledContract.withWitnesses(tableWitnesses), CompiledContract.withCompiledFileAssets('./table'));
|
|
21
23
|
export const CompiledLobbyContract = CompiledContract.make('Lobby', (Lobby.Contract)).pipe(CompiledContract.withWitnesses(lobbyWitnesses), CompiledContract.withCompiledFileAssets('./lobby'));
|
|
@@ -27,25 +29,41 @@ export const CompiledLobbyContract = CompiledContract.make('Lobby', (Lobby.Contr
|
|
|
27
29
|
* driver -- and there is one after almost every transaction -- has to use `queryContractState`.
|
|
28
30
|
* (bugs-found.md §0 #10; the same reason probes/gate0/src/step.ts reads this way.)
|
|
29
31
|
*
|
|
30
|
-
* `
|
|
31
|
-
* game with.
|
|
32
|
+
* `at.txHash` pins the read to the state a transaction left, which is what the chain-only
|
|
33
|
+
* verifier walks the game with. By TRANSACTION, not by block: on this indexer (4.3.x) a block
|
|
34
|
+
* offset means "the action in that block", and with simultaneous rounds several of a table's
|
|
35
|
+
* transactions routinely share one -- a block-keyed read cannot say which it returned. The SDK
|
|
36
|
+
* offers no transaction-hash offset, so that read goes straight to the indexer.
|
|
32
37
|
*/
|
|
33
|
-
export async function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
export async function readContractState(address, at) {
|
|
39
|
+
if (at === undefined) {
|
|
40
|
+
const pdp = indexerPublicDataProvider(NETWORK.indexer, NETWORK.indexerWS);
|
|
41
|
+
const state = await pdp.queryContractState(address);
|
|
42
|
+
if (!state)
|
|
43
|
+
throw new Error(`no contract state at ${address}`);
|
|
44
|
+
return state;
|
|
40
45
|
}
|
|
41
|
-
|
|
46
|
+
const hex = await contractStateHexAt(address, at.txHash);
|
|
47
|
+
if (!hex)
|
|
48
|
+
throw new Error(`no contract state at ${address} after tx ${at.txHash}`);
|
|
49
|
+
return ContractState.deserialize(Buffer.from(hex.replace(/^0x/, ''), 'hex'));
|
|
50
|
+
}
|
|
51
|
+
export async function readTableLedger(address, at) {
|
|
52
|
+
return Table.ledger((await readContractState(address, at)).data);
|
|
42
53
|
}
|
|
43
54
|
export async function readLobbyLedger(address) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
return Lobby.ledger((await readContractState(address)).data);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* What the LEDGER says the contract holds, for checking against the `pot` it claims.
|
|
59
|
+
*
|
|
60
|
+
* Read out of the contract's own state, NOT out of the indexer's
|
|
61
|
+
* `contractAction { unshieldedBalances }` -- that field answers `[]` on this indexer even for a
|
|
62
|
+
* table sitting on a pot, which reads as a solvency alarm instead of a balance. See
|
|
63
|
+
* `@dust-dice/contract`'s `custody.ts` and the test that pins it.
|
|
64
|
+
*/
|
|
65
|
+
export async function contractUnshieldedBalances(address, at) {
|
|
66
|
+
return unshieldedBalances(await readContractState(address, at));
|
|
49
67
|
}
|
|
50
68
|
/** `Dice` as the plain five-element array everything else in this repo speaks. */
|
|
51
69
|
export function diceToArray(d) {
|
package/dist/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,sCAAsC;AAEtC;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iDAAiD,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,0DAA0D,CAAC;AACrG,OAAO,EACL,KAAK,EACL,KAAK,EACL,cAAc,EACd,cAAc,
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
|
package/dist/indexer.d.ts
CHANGED
|
@@ -25,20 +25,13 @@ export interface ContractAction {
|
|
|
25
25
|
blockHeight: number;
|
|
26
26
|
blockTimestamp: number;
|
|
27
27
|
}
|
|
28
|
-
/** The native (NIGHT) token type is 32 zero bytes. Matches Compact's `nativeToken()`. */
|
|
29
|
-
export declare const NATIVE_TOKEN_HEX: string;
|
|
30
|
-
export declare function sumNative(utxos: GqlUnshieldedUtxo[]): bigint;
|
|
31
|
-
export declare function sumNativeFor(utxos: GqlUnshieldedUtxo[], owner: string): bigint;
|
|
32
28
|
/**
|
|
33
|
-
* The
|
|
34
|
-
*
|
|
35
|
-
* `unshieldedBalances` hangs off `ContractAction`, NOT off `Contract` -- `contract(address)`
|
|
36
|
-
* returns a `Contract` whose only fields are address/state/maintenanceAuthority/actions.
|
|
37
|
-
* `contractAction(address)` returns the latest action, which is what carries the running
|
|
38
|
-
* balances, and all three action variants declare the field so it selects on the interface.
|
|
29
|
+
* The token-type constant and the balance decode live with the contract package, next to the
|
|
30
|
+
* ledger layout they read; re-exported here so callers of this module keep one import.
|
|
39
31
|
*/
|
|
40
|
-
export
|
|
41
|
-
export declare function
|
|
32
|
+
export { NATIVE_TOKEN_HEX, nativeBalance } from '@dust-dice/contract';
|
|
33
|
+
export declare function sumNative(utxos: GqlUnshieldedUtxo[]): bigint;
|
|
34
|
+
export declare function sumNativeFor(utxos: GqlUnshieldedUtxo[], owner: string): bigint;
|
|
42
35
|
/**
|
|
43
36
|
* One transaction by hash, with its UTXO deltas and its raw bytes.
|
|
44
37
|
*
|
|
@@ -67,9 +60,21 @@ export declare const ADMISSION_FLOOR_BYTES = 7984;
|
|
|
67
60
|
*
|
|
68
61
|
* This is the ONLY thing `verify.ts` is given beyond the table's address: every join, every
|
|
69
62
|
* turn and the settlement are recovered from these actions and the contract states they point
|
|
70
|
-
* at.
|
|
63
|
+
* at.
|
|
64
|
+
*
|
|
65
|
+
* The indexer this build talks to (4.3.x, the preprod line) has no query that LISTS a contract's
|
|
66
|
+
* actions -- the ledger-9 `contract(address){ actions }` is gone. It has the `contractActions`
|
|
67
|
+
* SUBSCRIPTION, which replays every action from a block offset and then stays open for new ones;
|
|
68
|
+
* it is what midnight-js's own provider uses. The stream has no "caught up" marker of its own,
|
|
69
|
+
* so the latest action is fetched first over plain HTTP and its transaction ends the collection
|
|
70
|
+
* -- after as many rows as that transaction has actions on this contract, because a fast turn is
|
|
71
|
+
* one transaction carrying up to seven calls and stopping at the first would drop the rest. The
|
|
72
|
+
* deploy block comes from the same query (`ContractCall.deploy`), so nothing from before the
|
|
73
|
+
* contract existed is streamed.
|
|
71
74
|
*/
|
|
72
75
|
export declare function contractActions(address: string, limit?: number): Promise<ContractAction[]>;
|
|
76
|
+
/** The state a specific transaction left the contract in, as the indexer's hex; null if none. */
|
|
77
|
+
export declare function contractStateHexAt(address: string, txHash: string): Promise<string | null>;
|
|
73
78
|
/** Current chain tip, for sanity-checking that blocks are being produced. */
|
|
74
79
|
export declare function tip(): Promise<{
|
|
75
80
|
height: number;
|
package/dist/indexer.js
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
* 4,900,000 in exactly this situation (docs/bugs-found.md §9). PER-TRANSACTION UTXO MOVEMENT IS
|
|
10
10
|
* THE ONLY TRUSTWORTHY MEASURE, and it is what these queries read:
|
|
11
11
|
*
|
|
12
|
-
* - `contractAction(address){ unshieldedBalances }` what the LEDGER says the contract holds
|
|
13
12
|
* - `transactions(offset:{hash}){ unshieldedCreatedOutputs / unshieldedSpentOutputs }`
|
|
14
13
|
* who actually received or spent what, with
|
|
15
14
|
* `registeredForDustGeneration` per created
|
|
@@ -17,13 +16,15 @@
|
|
|
17
16
|
* - `transactions(offset:{hash}){ raw }` the transaction's byte size, which is what
|
|
18
17
|
* the `OutsideTimeToDismiss` admission check
|
|
19
18
|
* measures
|
|
20
|
-
* - `
|
|
19
|
+
* - `contractActions(address, offset)` subscription the table's whole public history, which is
|
|
21
20
|
* all the chain-only verifier is given
|
|
21
|
+
* - `contractAction(address, offset:{transactionOffset})` the state one transaction left
|
|
22
22
|
*
|
|
23
23
|
* There is no user-address balance query in this indexer's schema (checked by introspecting
|
|
24
24
|
* `__schema.queryType.fields`: only `bridgeBalance(address)` takes an address, and that is the
|
|
25
25
|
* Cardano bridge, not NIGHT), so per-address totals are derived from the UTXO sets above.
|
|
26
26
|
*/
|
|
27
|
+
import { NATIVE_TOKEN_HEX } from '@dust-dice/contract';
|
|
27
28
|
import { NETWORK } from "./config.js";
|
|
28
29
|
async function gql(query, variables = {}) {
|
|
29
30
|
const res = await fetch(NETWORK.indexer, {
|
|
@@ -41,8 +42,11 @@ async function gql(query, variables = {}) {
|
|
|
41
42
|
throw new Error('indexer returned no data');
|
|
42
43
|
return body.data;
|
|
43
44
|
}
|
|
44
|
-
/**
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The token-type constant and the balance decode live with the contract package, next to the
|
|
47
|
+
* ledger layout they read; re-exported here so callers of this module keep one import.
|
|
48
|
+
*/
|
|
49
|
+
export { NATIVE_TOKEN_HEX, nativeBalance } from '@dust-dice/contract';
|
|
46
50
|
const isNative = (u) => u.tokenType.replace(/^0x/, '').toLowerCase() === NATIVE_TOKEN_HEX;
|
|
47
51
|
export function sumNative(utxos) {
|
|
48
52
|
return utxos.filter(isNative).reduce((acc, u) => acc + BigInt(u.value), 0n);
|
|
@@ -50,30 +54,11 @@ export function sumNative(utxos) {
|
|
|
50
54
|
export function sumNativeFor(utxos, owner) {
|
|
51
55
|
return sumNative(utxos.filter((u) => u.owner === owner));
|
|
52
56
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* `contractAction(address)` returns the latest action, which is what carries the running
|
|
59
|
-
* balances, and all three action variants declare the field so it selects on the interface.
|
|
60
|
-
*/
|
|
61
|
-
export async function contractUnshieldedBalances(address) {
|
|
62
|
-
const data = await gql(`query ($address: HexEncoded!) {
|
|
63
|
-
contractAction(address: $address) { unshieldedBalances { tokenType amount } }
|
|
64
|
-
}`, { address });
|
|
65
|
-
const out = {};
|
|
66
|
-
for (const b of data.contractAction?.unshieldedBalances ?? [])
|
|
67
|
-
out[b.tokenType] = BigInt(b.amount);
|
|
68
|
-
return out;
|
|
69
|
-
}
|
|
70
|
-
export function nativeBalance(balances) {
|
|
71
|
-
for (const [k, v] of Object.entries(balances)) {
|
|
72
|
-
if (k.replace(/^0x/, '').toLowerCase() === NATIVE_TOKEN_HEX)
|
|
73
|
-
return v;
|
|
74
|
-
}
|
|
75
|
-
return 0n;
|
|
76
|
-
}
|
|
57
|
+
// What the contract HOLDS is deliberately NOT read here. The schema does offer
|
|
58
|
+
// `contractAction { unshieldedBalances }`, and it answers `[]` for every action of every
|
|
59
|
+
// contract on this indexer -- tables sitting on a pot included -- so a custody check built on
|
|
60
|
+
// it reports a solvent table as empty, which is the shape of a solvency alarm. Custody comes
|
|
61
|
+
// from the contract's own state: `contracts.ts`'s `contractUnshieldedBalances`.
|
|
77
62
|
/**
|
|
78
63
|
* One transaction by hash, with its UTXO deltas and its raw bytes.
|
|
79
64
|
*
|
|
@@ -118,35 +103,117 @@ export function transactionBytes(tx) {
|
|
|
118
103
|
export const allowanceMs = (bytes) => Math.max(15.0, 0.002 * bytes);
|
|
119
104
|
/** The floor a contract call must clear to be admitted at all, in bytes. */
|
|
120
105
|
export const ADMISSION_FLOOR_BYTES = 7984;
|
|
106
|
+
/**
|
|
107
|
+
* One graphql-transport-ws subscription, collected until `done` accepts a row (that row included)
|
|
108
|
+
* or `max` rows have arrived.
|
|
109
|
+
*
|
|
110
|
+
* A raw WebSocket on purpose: the protocol is four message types -- init, ack, subscribe, next --
|
|
111
|
+
* and a client library would be a second copy of what the SDK already bundles. Node's global
|
|
112
|
+
* WebSocket (22+, this package's floor) is all it needs.
|
|
113
|
+
*/
|
|
114
|
+
function subscribeUntil(query, variables, field, done, max, timeoutMs = 60_000) {
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
const ws = new WebSocket(NETWORK.indexerWS, 'graphql-transport-ws');
|
|
117
|
+
const rows = [];
|
|
118
|
+
let settled = false;
|
|
119
|
+
const finish = (err) => {
|
|
120
|
+
if (settled)
|
|
121
|
+
return;
|
|
122
|
+
settled = true;
|
|
123
|
+
clearTimeout(timer);
|
|
124
|
+
ws.close();
|
|
125
|
+
if (err)
|
|
126
|
+
reject(err);
|
|
127
|
+
else
|
|
128
|
+
resolve(rows);
|
|
129
|
+
};
|
|
130
|
+
const timer = setTimeout(() => finish(new Error(`indexer subscription ${field}: still open after ${timeoutMs} ms`)), timeoutMs);
|
|
131
|
+
ws.onopen = () => ws.send(JSON.stringify({ type: 'connection_init' }));
|
|
132
|
+
ws.onerror = () => finish(new Error(`indexer subscription ${field}: websocket error`));
|
|
133
|
+
ws.onclose = () => finish(new Error(`indexer subscription ${field}: closed after ${rows.length} rows`));
|
|
134
|
+
ws.onmessage = (ev) => {
|
|
135
|
+
const m = JSON.parse(String(ev.data));
|
|
136
|
+
if (m.type === 'connection_ack') {
|
|
137
|
+
ws.send(JSON.stringify({ id: '1', type: 'subscribe', payload: { query, variables } }));
|
|
138
|
+
}
|
|
139
|
+
else if (m.type === 'next') {
|
|
140
|
+
const p = m.payload;
|
|
141
|
+
if (p.errors?.length) {
|
|
142
|
+
finish(new Error(`indexer GraphQL: ${p.errors.map((e) => e.message).join('; ')}`));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const row = p.data?.[field];
|
|
146
|
+
if (row === undefined)
|
|
147
|
+
return;
|
|
148
|
+
rows.push(row);
|
|
149
|
+
if (done(row) || rows.length >= max)
|
|
150
|
+
finish();
|
|
151
|
+
}
|
|
152
|
+
else if (m.type === 'error') {
|
|
153
|
+
finish(new Error(`indexer subscription ${field}: ${JSON.stringify(m.payload).slice(0, 300)}`));
|
|
154
|
+
}
|
|
155
|
+
else if (m.type === 'complete') {
|
|
156
|
+
finish();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const sameAddress = (a, b) => a.replace(/^0x/, '').toLowerCase() === b.replace(/^0x/, '').toLowerCase();
|
|
121
162
|
/**
|
|
122
163
|
* A contract's whole public history, oldest first.
|
|
123
164
|
*
|
|
124
165
|
* This is the ONLY thing `verify.ts` is given beyond the table's address: every join, every
|
|
125
166
|
* turn and the settlement are recovered from these actions and the contract states they point
|
|
126
|
-
* at.
|
|
167
|
+
* at.
|
|
168
|
+
*
|
|
169
|
+
* The indexer this build talks to (4.3.x, the preprod line) has no query that LISTS a contract's
|
|
170
|
+
* actions -- the ledger-9 `contract(address){ actions }` is gone. It has the `contractActions`
|
|
171
|
+
* SUBSCRIPTION, which replays every action from a block offset and then stays open for new ones;
|
|
172
|
+
* it is what midnight-js's own provider uses. The stream has no "caught up" marker of its own,
|
|
173
|
+
* so the latest action is fetched first over plain HTTP and its transaction ends the collection
|
|
174
|
+
* -- after as many rows as that transaction has actions on this contract, because a fast turn is
|
|
175
|
+
* one transaction carrying up to seven calls and stopping at the first would drop the rest. The
|
|
176
|
+
* deploy block comes from the same query (`ContractCall.deploy`), so nothing from before the
|
|
177
|
+
* contract existed is streamed.
|
|
127
178
|
*/
|
|
128
179
|
export async function contractActions(address, limit = 1000) {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
... on ContractDeploy { transaction { hash block { height timestamp } } }
|
|
135
|
-
... on ContractUpdate { transaction { hash block { height timestamp } } }
|
|
136
|
-
}
|
|
180
|
+
const head = await gql(`query ($address: HexEncoded!) {
|
|
181
|
+
contractAction(address: $address) {
|
|
182
|
+
__typename
|
|
183
|
+
transaction { hash block { height timestamp } }
|
|
184
|
+
... on ContractCall { deploy { transaction { block { height } } } }
|
|
137
185
|
}
|
|
138
|
-
}`, { address
|
|
139
|
-
if (!
|
|
186
|
+
}`, { address });
|
|
187
|
+
if (!head.contractAction)
|
|
140
188
|
throw new Error(`no contract at ${address}`);
|
|
141
|
-
|
|
142
|
-
|
|
189
|
+
const latest = head.contractAction;
|
|
190
|
+
const fromHeight = latest.deploy?.transaction.block.height ?? latest.transaction.block.height;
|
|
191
|
+
const lastTx = await gql(`query ($hash: HexEncoded!) {
|
|
192
|
+
transactions(offset: { hash: $hash }) { contractActions { address } }
|
|
193
|
+
}`, { hash: latest.transaction.hash });
|
|
194
|
+
const lastTxActions = (lastTx.transactions[0]?.contractActions ?? []).filter((a) => sameAddress(a.address, address)).length;
|
|
195
|
+
let seenOfLast = 0;
|
|
196
|
+
const rows = await subscribeUntil(`subscription ($address: HexEncoded!, $offset: BlockOffset) {
|
|
197
|
+
contractActions(address: $address, offset: $offset) {
|
|
198
|
+
__typename
|
|
199
|
+
... on ContractCall { entryPoint }
|
|
200
|
+
transaction { hash block { height timestamp } }
|
|
201
|
+
}
|
|
202
|
+
}`, { address, offset: { height: fromHeight } }, 'contractActions', (row) => row.transaction.hash === latest.transaction.hash && ++seenOfLast >= lastTxActions, limit);
|
|
203
|
+
return rows.map((a) => ({
|
|
143
204
|
kind: a.__typename,
|
|
144
205
|
entryPoint: a.entryPoint,
|
|
145
206
|
txHash: a.transaction.hash,
|
|
146
207
|
blockHeight: a.transaction.block.height,
|
|
147
208
|
blockTimestamp: Number(a.transaction.block.timestamp),
|
|
148
|
-
}))
|
|
149
|
-
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
/** The state a specific transaction left the contract in, as the indexer's hex; null if none. */
|
|
212
|
+
export async function contractStateHexAt(address, txHash) {
|
|
213
|
+
const data = await gql(`query ($address: HexEncoded!, $hash: HexEncoded!) {
|
|
214
|
+
contractAction(address: $address, offset: { transactionOffset: { hash: $hash } }) { state }
|
|
215
|
+
}`, { address, hash: txHash });
|
|
216
|
+
return data.contractAction?.state ?? null;
|
|
150
217
|
}
|
|
151
218
|
/** Current chain tip, for sanity-checking that blocks are being produced. */
|
|
152
219
|
export async function tip() {
|
package/dist/indexer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,sCAAsC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA6BtC,KAAK,UAAU,GAAG,CAAI,KAAa,EAAE,YAAqC,EAAE;IAC1E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE;QACvC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KAC3C,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAiD,CAAC;IAChF,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}
|