envio 3.7.0 → 3.9.0-resolvers.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/README.md +2 -2
- package/evm.schema.json +7 -0
- package/fuel.schema.json +7 -0
- package/index.d.ts +674 -161
- package/index.js +10 -0
- package/package.json +6 -7
- package/src/AddressRows.res +121 -0
- package/src/AddressRows.res.mjs +143 -0
- package/src/Batch.res +11 -0
- package/src/Batch.res.mjs +2 -1
- package/src/Bin.res +47 -0
- package/src/Bin.res.mjs +34 -1
- package/src/ChainState.res +108 -98
- package/src/ChainState.res.mjs +86 -67
- package/src/ChainState.resi +28 -15
- package/src/Config.res +61 -131
- package/src/Config.res.mjs +47 -79
- package/src/ContractMapping.res +66 -0
- package/src/ContractMapping.res.mjs +73 -0
- package/src/Core.res +24 -0
- package/src/Core.res.mjs +4 -0
- package/src/Ecosystem.res +7 -2
- package/src/Env.res +128 -1
- package/src/Env.res.mjs +123 -1
- package/src/Envio.res +54 -76
- package/src/EventConfigBuilder.res +316 -46
- package/src/EventConfigBuilder.res.mjs +231 -28
- package/src/FetchState.res +59 -67
- package/src/FetchState.res.mjs +34 -44
- package/src/HandlerRegister.res +26 -15
- package/src/HandlerRegister.res.mjs +27 -7
- package/src/Hasura.res +30 -22
- package/src/Hasura.res.mjs +11 -5
- package/src/InMemoryStore.res +23 -38
- package/src/InMemoryStore.res.mjs +13 -27
- package/src/IndexerState.res +40 -3
- package/src/IndexerState.res.mjs +30 -4
- package/src/IndexerState.resi +4 -1
- package/src/Internal.res +49 -30
- package/src/Internal.res.mjs +12 -16
- package/src/Main.res +27 -20
- package/src/Main.res.mjs +19 -14
- package/src/Metrics.res +15 -1
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +46 -21
- package/src/Persistence.res.mjs +8 -5
- package/src/PgStorage.res +238 -79
- package/src/PgStorage.res.mjs +115 -73
- package/src/PruneStaleHistory.res +1 -1
- package/src/PruneStaleHistory.res.mjs +1 -1
- package/src/Rollback.res +62 -41
- package/src/Rollback.res.mjs +61 -19
- package/src/RollbackCommit.res +7 -9
- package/src/RollbackCommit.res.mjs +5 -6
- package/src/SimulateItems.res +254 -9
- package/src/SimulateItems.res.mjs +214 -47
- package/src/Sink.res +35 -26
- package/src/Sink.res.mjs +20 -16
- package/src/TestIndexer.res +121 -123
- package/src/TestIndexer.res.mjs +97 -102
- package/src/Utils.res +38 -0
- package/src/Utils.res.mjs +39 -2
- package/src/Writing.res +4 -2
- package/src/Writing.res.mjs +3 -2
- package/src/bindings/ClickHouse.res +311 -656
- package/src/bindings/ClickHouse.res.mjs +294 -395
- package/src/bindings/ClickHouseSink.res +303 -0
- package/src/bindings/ClickHouseSink.res.mjs +216 -0
- package/src/bindings/NodeJs.res +9 -0
- package/src/bindings/NodeJs.res.mjs +8 -1
- package/src/bindings/Postgres.res +9 -0
- package/src/bindings/Postgres.res.mjs +3 -0
- package/src/db/EntityHistory.res +29 -24
- package/src/db/EntityHistory.res.mjs +11 -19
- package/src/db/InternalTable.res +258 -83
- package/src/db/InternalTable.res.mjs +223 -85
- package/src/db/RollbackScope.res +29 -0
- package/src/db/RollbackScope.res.mjs +31 -0
- package/src/db/Table.res +28 -1
- package/src/db/Table.res.mjs +26 -2
- package/src/resolvers/ResolverProcess.res +809 -0
- package/src/resolvers/ResolverProcess.res.mjs +667 -0
- package/src/resolvers/ResolverQuery.res +317 -0
- package/src/resolvers/ResolverQuery.res.mjs +220 -0
- package/src/resolvers/collisions.js +108 -0
- package/src/resolvers/db.js +363 -0
- package/src/resolvers/dispatch.js +165 -0
- package/src/resolvers/errors.js +30 -0
- package/src/resolvers/graphqlSelection.js +292 -0
- package/src/resolvers/hasuraAction.js +84 -0
- package/src/resolvers/hasuraApply.js +323 -0
- package/src/resolvers/hasuraMetadata.js +119 -0
- package/src/resolvers/index.js +95 -0
- package/src/resolvers/manifest.js +370 -0
- package/src/resolvers/server.js +270 -0
- package/src/sources/AddressSet.res +0 -22
- package/src/sources/AddressStore.res +48 -88
- package/src/sources/AddressStore.res.mjs +11 -22
- package/src/sources/Evm.res +2 -0
- package/src/sources/Evm.res.mjs +2 -0
- package/src/sources/EvmHyperSyncSource.res +3 -2
- package/src/sources/Fuel.res +2 -0
- package/src/sources/Fuel.res.mjs +2 -0
- package/src/sources/SimulateSource.res +8 -4
- package/src/sources/SimulateSource.res.mjs +7 -3
- package/src/sources/Svm.res +36 -7
- package/src/sources/Svm.res.mjs +34 -4
- package/src/sources/SvmHyperSyncClient.res +20 -116
- package/src/sources/SvmHyperSyncClient.res.mjs +5 -7
- package/src/sources/SvmHyperSyncSource.res +89 -37
- package/src/sources/SvmHyperSyncSource.res.mjs +71 -39
- package/src/sources/TransactionStore.res +38 -0
- package/src/sources/TransactionStore.res.mjs +5 -0
- package/src/tui/Tui.res +1 -1
- package/src/tui/Tui.res.mjs +1 -1
- package/svm.schema.json +44 -156
- package/src/MemoryStorage.res +0 -724
- package/src/MemoryStorage.res.mjs +0 -601
package/index.d.ts
CHANGED
|
@@ -1160,152 +1160,392 @@ export type SvmOnSlotOptions<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
|
1160
1160
|
|
|
1161
1161
|
// ============== SVM onInstruction types ==============
|
|
1162
1162
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
readonly accounts: Readonly<Record<string, string>>;
|
|
1176
|
-
/** Accounts beyond the schema's named list (Anchor `remaining_accounts`,
|
|
1177
|
-
* IDL drift). Empty when counts match the schema. */
|
|
1178
|
-
readonly extraAccounts: readonly string[];
|
|
1163
|
+
export type SvmLogKind =
|
|
1164
|
+
| "invoke"
|
|
1165
|
+
| "success"
|
|
1166
|
+
| "failed"
|
|
1167
|
+
| "consumed"
|
|
1168
|
+
| "log"
|
|
1169
|
+
| "data"
|
|
1170
|
+
| (string & {});
|
|
1171
|
+
|
|
1172
|
+
export type SvmAllLogFields = {
|
|
1173
|
+
readonly kind: SvmLogKind;
|
|
1174
|
+
readonly message: string;
|
|
1179
1175
|
};
|
|
1180
1176
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1177
|
+
export type SvmAllAccountLamportsFields = {
|
|
1178
|
+
readonly pre: bigint;
|
|
1179
|
+
readonly post: bigint;
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
export type SvmAllAccountTokenActivityFields = {
|
|
1183
|
+
readonly mint: string;
|
|
1184
|
+
readonly owner: string;
|
|
1185
|
+
readonly decimals: number;
|
|
1186
|
+
readonly preAmount: bigint | undefined;
|
|
1187
|
+
readonly postAmount: bigint | undefined;
|
|
1188
|
+
};
|
|
1189
|
+
|
|
1190
|
+
export type SvmAllAccountActivityFields = {
|
|
1191
|
+
readonly address: string;
|
|
1192
|
+
readonly transactionAccountIndex: number;
|
|
1193
|
+
readonly isSigner: boolean;
|
|
1194
|
+
readonly isWritable: boolean;
|
|
1195
|
+
readonly lamports: SvmAllAccountLamportsFields | undefined;
|
|
1196
|
+
readonly token: SvmAllAccountTokenActivityFields | undefined;
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
export type SvmAllBlockFields = {
|
|
1187
1200
|
readonly slot: number;
|
|
1188
|
-
|
|
1189
|
-
* block time for this slot. */
|
|
1190
|
-
readonly time?: number;
|
|
1191
|
-
/** Block hash. */
|
|
1201
|
+
readonly time: number;
|
|
1192
1202
|
readonly hash: string;
|
|
1193
|
-
|
|
1194
|
-
readonly
|
|
1195
|
-
|
|
1196
|
-
readonly parentSlot?: number;
|
|
1197
|
-
/** Parent block hash. Select via `field_selection.block_fields`. */
|
|
1198
|
-
readonly parentHash?: string;
|
|
1199
|
-
};
|
|
1200
|
-
|
|
1201
|
-
export type SvmTokenBalance = {
|
|
1202
|
-
readonly account?: string;
|
|
1203
|
-
readonly mint?: string;
|
|
1204
|
-
/** Owner at the end of the transaction, falling back to the owner on entry
|
|
1205
|
-
* when the account was closed during it. Pre and post owners differ only
|
|
1206
|
-
* when a `SetAuthority(AccountOwner)` runs mid-transaction. */
|
|
1207
|
-
readonly owner?: string;
|
|
1208
|
-
/** Mint decimals, for scaling the raw amounts below. */
|
|
1209
|
-
readonly decimals?: number;
|
|
1210
|
-
/** Raw amount in base units before the transaction. Absent when the token
|
|
1211
|
-
* account was created during it. */
|
|
1212
|
-
readonly preAmount?: bigint;
|
|
1213
|
-
/** Raw amount in base units after the transaction. Absent when the token
|
|
1214
|
-
* account was closed during it. */
|
|
1215
|
-
readonly postAmount?: bigint;
|
|
1216
|
-
};
|
|
1217
|
-
|
|
1218
|
-
export type SvmLog = {
|
|
1219
|
-
readonly kind: string;
|
|
1220
|
-
readonly message: string;
|
|
1203
|
+
readonly height: number;
|
|
1204
|
+
readonly parentSlot: number;
|
|
1205
|
+
readonly parentHash: string;
|
|
1221
1206
|
};
|
|
1222
1207
|
|
|
1223
|
-
/**
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1208
|
+
/** All SVM parent-transaction fields. Handler `fields.transaction` narrows
|
|
1209
|
+
* this via {@link SvmTransaction}; `accountActivities` is implied by
|
|
1210
|
+
* `fields.accountActivity`. */
|
|
1211
|
+
export type SvmAllTransactionFields = {
|
|
1212
|
+
readonly transactionIndex: number;
|
|
1213
|
+
readonly signature: string;
|
|
1214
|
+
readonly feePayer: string;
|
|
1215
|
+
readonly success: boolean;
|
|
1216
|
+
readonly err: string | undefined;
|
|
1217
|
+
readonly fee: bigint;
|
|
1218
|
+
readonly computeUnitsConsumed: bigint | undefined;
|
|
1219
|
+
readonly accountKeys: readonly string[];
|
|
1220
|
+
readonly recentBlockhash: string;
|
|
1221
|
+
readonly version: string | undefined;
|
|
1222
|
+
readonly allSignatures: readonly string[];
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
export type SvmInstructionFieldName =
|
|
1226
|
+
| "args"
|
|
1227
|
+
| "accounts"
|
|
1228
|
+
| "accountArguments"
|
|
1229
|
+
| "programId"
|
|
1230
|
+
| "data"
|
|
1231
|
+
| "path"
|
|
1232
|
+
| "isInner";
|
|
1233
|
+
export type SvmTransactionFieldName =
|
|
1234
|
+
| "transactionIndex"
|
|
1235
|
+
| "signature"
|
|
1236
|
+
| "feePayer"
|
|
1237
|
+
| "success"
|
|
1238
|
+
| "err"
|
|
1239
|
+
| "fee"
|
|
1240
|
+
| "computeUnitsConsumed"
|
|
1241
|
+
| "accountKeys"
|
|
1242
|
+
| "recentBlockhash"
|
|
1243
|
+
| "version"
|
|
1244
|
+
| "allSignatures";
|
|
1245
|
+
export type SvmAccountActivityFieldName =
|
|
1246
|
+
| "address"
|
|
1247
|
+
| "transactionAccountIndex"
|
|
1248
|
+
| "isSigner"
|
|
1249
|
+
| "isWritable"
|
|
1250
|
+
| "lamports.pre"
|
|
1251
|
+
| "lamports.post"
|
|
1252
|
+
| "token.mint"
|
|
1253
|
+
| "token.owner"
|
|
1254
|
+
| "token.decimals"
|
|
1255
|
+
| "token.preAmount"
|
|
1256
|
+
| "token.postAmount";
|
|
1257
|
+
export type SvmBlockFieldName =
|
|
1258
|
+
| "slot"
|
|
1259
|
+
| "time"
|
|
1260
|
+
| "hash"
|
|
1261
|
+
| "height"
|
|
1262
|
+
| "parentSlot"
|
|
1263
|
+
| "parentHash";
|
|
1264
|
+
export type SvmLogFieldName = "kind" | "message";
|
|
1265
|
+
|
|
1266
|
+
export type SvmFieldsSelection = {
|
|
1267
|
+
readonly instruction?: readonly SvmInstructionFieldName[];
|
|
1268
|
+
readonly transaction?: readonly SvmTransactionFieldName[];
|
|
1269
|
+
readonly accountActivity?: readonly SvmAccountActivityFieldName[];
|
|
1270
|
+
readonly block?: readonly SvmBlockFieldName[];
|
|
1271
|
+
readonly log?: readonly SvmLogFieldName[];
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
/** A {@link SvmFieldsSelection} with every field selected.
|
|
1231
1275
|
*
|
|
1232
|
-
*
|
|
1233
|
-
*
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1276
|
+
* Type-level only — its knobs are field-name arrays rather than literals, so it
|
|
1277
|
+
* describes a payload (`SvmInstruction<SvmAllFieldsSelection>`) but can't be
|
|
1278
|
+
* passed as a registration's `fields` value. */
|
|
1279
|
+
export type SvmAllFieldsSelection = {
|
|
1280
|
+
readonly instruction: readonly SvmInstructionFieldName[];
|
|
1281
|
+
readonly transaction: readonly SvmTransactionFieldName[];
|
|
1282
|
+
readonly accountActivity: readonly SvmAccountActivityFieldName[];
|
|
1283
|
+
readonly block: readonly SvmBlockFieldName[];
|
|
1284
|
+
readonly log: readonly SvmLogFieldName[];
|
|
1285
|
+
};
|
|
1286
|
+
|
|
1287
|
+
type SvmListedArray<Fields, Knob extends keyof SvmFieldsSelection> = Fields[Knob &
|
|
1288
|
+
keyof Fields];
|
|
1289
|
+
type SvmListedFields<Fields, Knob extends keyof SvmFieldsSelection> = NonNullable<
|
|
1290
|
+
SvmListedArray<Fields, Knob>
|
|
1291
|
+
>[number] &
|
|
1292
|
+
string;
|
|
1293
|
+
|
|
1294
|
+
type SvmFieldsLiteralCheck<Fields> = [Fields] extends [undefined]
|
|
1295
|
+
? unknown
|
|
1296
|
+
: IsWidenedArray<SvmListedArray<Fields, "instruction">> extends true
|
|
1297
|
+
? EvmFieldsMustBeLiteral<"instruction">
|
|
1298
|
+
: IsWidenedArray<SvmListedArray<Fields, "transaction">> extends true
|
|
1299
|
+
? EvmFieldsMustBeLiteral<"transaction">
|
|
1300
|
+
: IsWidenedArray<SvmListedArray<Fields, "accountActivity">> extends true
|
|
1301
|
+
? EvmFieldsMustBeLiteral<"accountActivity">
|
|
1302
|
+
: IsWidenedArray<SvmListedArray<Fields, "block">> extends true
|
|
1303
|
+
? EvmFieldsMustBeLiteral<"block">
|
|
1304
|
+
: IsWidenedArray<SvmListedArray<Fields, "log">> extends true
|
|
1305
|
+
? EvmFieldsMustBeLiteral<"log">
|
|
1306
|
+
: unknown;
|
|
1307
|
+
|
|
1308
|
+
type SvmActivityListed<Fields> = SvmListedFields<Fields, "accountActivity">;
|
|
1309
|
+
type SvmActivityHas<Fields, Name extends string> = [SvmActivityListed<Fields>] extends [never]
|
|
1310
|
+
? false
|
|
1311
|
+
: Name extends SvmActivityListed<Fields>
|
|
1312
|
+
? true
|
|
1313
|
+
: false;
|
|
1314
|
+
|
|
1315
|
+
type SvmActivityField<Fields, Name extends string, T> = SvmActivityHas<
|
|
1316
|
+
Fields,
|
|
1317
|
+
Name
|
|
1318
|
+
> extends true
|
|
1319
|
+
? T
|
|
1320
|
+
: FieldNotSelected<`Field '${Name}' is not selected for this handler. Add it to fields.accountActivity in the registration options.`>;
|
|
1321
|
+
|
|
1322
|
+
/** The pre/post lamport balances of a {@link SvmAccountActivity}, narrowed to
|
|
1323
|
+
* the registration's fields selection. */
|
|
1324
|
+
export type SvmAccountLamports<Fields extends SvmFieldsSelection> = [
|
|
1325
|
+
SvmActivityListed<Fields> & `lamports.${string}`,
|
|
1326
|
+
] extends [never]
|
|
1327
|
+
? FieldNotSelected<`Field 'lamports' is not selected for this handler. Add it to fields.accountActivity in the registration options.`>
|
|
1328
|
+
: {
|
|
1329
|
+
readonly [K in keyof SvmAllAccountLamportsFields]: SvmActivityHas<Fields, `lamports.${K & string}`> extends true
|
|
1330
|
+
? SvmAllAccountLamportsFields[K]
|
|
1331
|
+
: FieldNotSelected<`Field 'lamports.${K & string}' is not selected for this handler. Add it to fields.accountActivity in the registration options.`>;
|
|
1332
|
+
} | undefined;
|
|
1333
|
+
|
|
1334
|
+
/** The token activity of a {@link SvmAccountActivity}, narrowed to the
|
|
1335
|
+
* registration's fields selection. */
|
|
1336
|
+
export type SvmAccountTokenActivity<Fields extends SvmFieldsSelection> = [SvmActivityListed<Fields> & `token.${string}`] extends [never]
|
|
1337
|
+
? FieldNotSelected<`Field 'token' is not selected for this handler. Add it to fields.accountActivity in the registration options.`>
|
|
1338
|
+
: {
|
|
1339
|
+
readonly [K in keyof SvmAllAccountTokenActivityFields]: SvmActivityHas<Fields, `token.${K & string}`> extends true
|
|
1340
|
+
? SvmAllAccountTokenActivityFields[K]
|
|
1341
|
+
: FieldNotSelected<`Field 'token.${K & string}' is not selected for this handler. Add it to fields.accountActivity in the registration options.`>;
|
|
1342
|
+
} | undefined;
|
|
1343
|
+
|
|
1344
|
+
/** An account activity of a {@link SvmTransaction}, narrowed to the
|
|
1345
|
+
* registration's fields selection. */
|
|
1346
|
+
export type SvmAccountActivity<Fields extends SvmFieldsSelection> = {
|
|
1347
|
+
readonly address: string;
|
|
1348
|
+
readonly transactionAccountIndex: SvmActivityField<Fields, "transactionAccountIndex", number>;
|
|
1349
|
+
readonly isSigner: SvmActivityField<Fields, "isSigner", boolean>;
|
|
1350
|
+
readonly isWritable: SvmActivityField<Fields, "isWritable", boolean>;
|
|
1351
|
+
readonly lamports: SvmAccountLamports<Fields>;
|
|
1352
|
+
readonly token: SvmAccountTokenActivity<Fields>;
|
|
1353
|
+
};
|
|
1354
|
+
|
|
1355
|
+
type SvmInstrListed<Fields> = SvmListedFields<Fields, "instruction">;
|
|
1356
|
+
type SvmInstrField<Fields, Name extends SvmInstructionFieldName, T> = Name extends SvmInstrListed<Fields>
|
|
1357
|
+
? T
|
|
1358
|
+
: FieldNotSelected<`Field '${Name}' is not selected for this handler. Add it to fields.instruction in the registration options.`>;
|
|
1359
|
+
|
|
1360
|
+
/** A named account of a {@link SvmInstruction}. Its `activity` narrows to the
|
|
1361
|
+
* registration's fields selection. */
|
|
1362
|
+
export type SvmInstructionAccount<
|
|
1363
|
+
Fields extends SvmFieldsSelection,
|
|
1364
|
+
Name extends string = string,
|
|
1238
1365
|
> = {
|
|
1239
|
-
|
|
1366
|
+
readonly address: string;
|
|
1367
|
+
readonly accountName: Name;
|
|
1368
|
+
readonly instructionAccountIndex: number;
|
|
1369
|
+
readonly activity:
|
|
1370
|
+
| ([SvmActivityListed<Fields>] extends [never]
|
|
1371
|
+
? FieldNotSelected<`Field 'activity' is not selected for this handler. Add fields.accountActivity in the registration options.`>
|
|
1372
|
+
: SvmAccountActivity<Fields>)
|
|
1373
|
+
| undefined;
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
type SvmNamedAccounts<
|
|
1377
|
+
Acc extends Readonly<Record<string, unknown>>,
|
|
1378
|
+
Fields extends SvmFieldsSelection,
|
|
1379
|
+
> = {
|
|
1380
|
+
readonly [K in keyof Acc & string]: SvmInstructionAccount<Fields, K>;
|
|
1381
|
+
};
|
|
1382
|
+
|
|
1383
|
+
/** The parent transaction of a {@link SvmInstruction}, narrowed to the
|
|
1384
|
+
* registration's fields selection. */
|
|
1385
|
+
export type SvmTransaction<Fields extends SvmFieldsSelection> = {
|
|
1386
|
+
readonly [K in keyof SvmAllTransactionFields]: K extends SvmListedFields<Fields, "transaction">
|
|
1387
|
+
? SvmAllTransactionFields[K]
|
|
1388
|
+
: FieldNotSelected<`Field '${K & string}' is not selected for this handler. Add it to fields.transaction in the registration options.`>;
|
|
1389
|
+
} & {
|
|
1390
|
+
readonly accountActivities: [SvmActivityListed<Fields>] extends [never]
|
|
1391
|
+
? FieldNotSelected<`Field 'accountActivities' is not selected for this handler. Add fields.accountActivity in the registration options.`>
|
|
1392
|
+
: readonly SvmAccountActivity<Fields>[];
|
|
1393
|
+
};
|
|
1394
|
+
|
|
1395
|
+
/** The block of a {@link SvmInstruction}, narrowed to the registration's
|
|
1396
|
+
* fields selection. `slot` is always selected. */
|
|
1397
|
+
export type SvmBlock<Fields extends SvmFieldsSelection> = {
|
|
1398
|
+
readonly [K in keyof SvmAllBlockFields]: K extends "slot"
|
|
1399
|
+
? SvmAllBlockFields[K]
|
|
1400
|
+
: K extends SvmListedFields<Fields, "block">
|
|
1401
|
+
? SvmAllBlockFields[K]
|
|
1402
|
+
: FieldNotSelected<`Field '${K & string}' is not selected for this handler. Add it to fields.block in the registration options.`>;
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
/** A log of a {@link SvmInstruction}, narrowed to the registration's fields
|
|
1406
|
+
* selection. */
|
|
1407
|
+
export type SvmLog<Fields extends SvmFieldsSelection> = {
|
|
1408
|
+
readonly kind: "kind" extends SvmListedFields<Fields, "log">
|
|
1409
|
+
? SvmLogKind
|
|
1410
|
+
: FieldNotSelected<`Field 'kind' is not selected for this handler. Add it to fields.log in the registration options.`>;
|
|
1411
|
+
readonly message: "message" extends SvmListedFields<Fields, "log">
|
|
1412
|
+
? string
|
|
1413
|
+
: FieldNotSelected<`Field 'message' is not selected for this handler. Add it to fields.log in the registration options.`>;
|
|
1414
|
+
};
|
|
1415
|
+
|
|
1416
|
+
type SvmAnyProgramInstruction = {
|
|
1417
|
+
readonly args: unknown;
|
|
1418
|
+
readonly accounts: Readonly<Record<string, string>>;
|
|
1419
|
+
};
|
|
1420
|
+
|
|
1421
|
+
type SvmSelectedInstruction<Fields extends SvmFieldsSelection, ProgInstr> = {
|
|
1240
1422
|
readonly programName: string;
|
|
1241
|
-
/** Instruction name as declared under `instructions[].name` in
|
|
1242
|
-
* `config.yaml`. */
|
|
1243
1423
|
readonly instructionName: string;
|
|
1244
|
-
readonly
|
|
1245
|
-
readonly
|
|
1246
|
-
readonly
|
|
1247
|
-
readonly
|
|
1248
|
-
readonly isInner: boolean
|
|
1249
|
-
readonly
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
readonly
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
readonly logs
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1424
|
+
readonly discriminator: string;
|
|
1425
|
+
readonly programId: SvmInstrField<Fields, "programId", string>;
|
|
1426
|
+
readonly data: SvmInstrField<Fields, "data", string>;
|
|
1427
|
+
readonly path: SvmInstrField<Fields, "path", readonly number[]>;
|
|
1428
|
+
readonly isInner: SvmInstrField<Fields, "isInner", boolean>;
|
|
1429
|
+
readonly args: SvmInstrField<
|
|
1430
|
+
Fields,
|
|
1431
|
+
"args",
|
|
1432
|
+
ProgInstr extends { readonly args: infer A } ? A : unknown
|
|
1433
|
+
>;
|
|
1434
|
+
readonly accounts: SvmInstrField<
|
|
1435
|
+
Fields,
|
|
1436
|
+
"accounts",
|
|
1437
|
+
ProgInstr extends { readonly accounts: infer Acc extends Readonly<Record<string, unknown>> }
|
|
1438
|
+
? SvmNamedAccounts<Acc, Fields>
|
|
1439
|
+
: SvmNamedAccounts<Readonly<Record<string, string>>, Fields>
|
|
1440
|
+
>;
|
|
1441
|
+
readonly accountArguments: SvmInstrField<Fields, "accountArguments", readonly string[]>;
|
|
1442
|
+
readonly logs: [SvmListedFields<Fields, "log">] extends [never]
|
|
1443
|
+
? FieldNotSelected<`Field 'logs' is not selected for this handler. Add fields.log in the registration options.`>
|
|
1444
|
+
: readonly SvmLog<Fields>[];
|
|
1445
|
+
readonly transaction: SvmTransaction<Fields>;
|
|
1446
|
+
readonly block: SvmBlock<Fields>;
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1449
|
+
type SvmConfiguredInstruction<Program extends string, Instruction extends string> = [
|
|
1450
|
+
Program,
|
|
1451
|
+
] extends [never]
|
|
1452
|
+
? SvmAnyProgramInstruction
|
|
1453
|
+
: Program extends keyof SvmProgramsT
|
|
1454
|
+
? Instruction extends keyof SvmProgramsT[Program]
|
|
1455
|
+
? SvmProgramsT[Program][Instruction]
|
|
1456
|
+
: SvmAnyProgramInstruction
|
|
1457
|
+
: SvmAnyProgramInstruction;
|
|
1458
|
+
|
|
1459
|
+
/** The `instruction` payload of an `indexer.onInstruction` handler. `Fields`
|
|
1460
|
+
* must be the registration's fields selection (use `typeof fields` on a
|
|
1461
|
+
* `const fields = {...} as const satisfies SvmFieldsSelection`, or
|
|
1462
|
+
* {@link SvmAllFieldsSelection}). Pass the config-declared program and
|
|
1463
|
+
* instruction names to type `args` and `accounts`. */
|
|
1464
|
+
export type SvmInstruction<
|
|
1465
|
+
Fields extends SvmFieldsSelection,
|
|
1466
|
+
Program extends keyof SvmProgramsT & string = never,
|
|
1467
|
+
Instruction extends keyof SvmProgramsT[Program] & string = never,
|
|
1468
|
+
> = SvmSelectedInstruction<Fields, SvmConfiguredInstruction<Program, Instruction>>;
|
|
1469
|
+
|
|
1470
|
+
type SvmOnInstructionArgsFor<Instr, Config extends IndexerConfigTypes> = {
|
|
1276
1471
|
readonly instruction: Instr;
|
|
1277
1472
|
readonly context: SvmOnSlotContext<Config>;
|
|
1278
1473
|
};
|
|
1279
1474
|
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1475
|
+
type SvmOnInstructionHandlerFor<Instr, Config extends IndexerConfigTypes> = (
|
|
1476
|
+
args: SvmOnInstructionArgsFor<Instr, Config>,
|
|
1477
|
+
) => Promise<void>;
|
|
1478
|
+
|
|
1479
|
+
/** Arguments passed to handlers registered via `indexer.onInstruction`.
|
|
1480
|
+
* Takes the same type arguments as {@link SvmInstruction}. */
|
|
1481
|
+
export type SvmOnInstructionHandlerArgs<
|
|
1482
|
+
Fields extends SvmFieldsSelection,
|
|
1483
|
+
Program extends keyof SvmProgramsT & string = never,
|
|
1484
|
+
Instruction extends keyof SvmProgramsT[Program] & string = never,
|
|
1485
|
+
> = SvmOnInstructionArgsFor<SvmInstruction<Fields, Program, Instruction>, GlobalConfig>;
|
|
1486
|
+
|
|
1487
|
+
/** The named accounts of a configured instruction. Falls back to an open
|
|
1488
|
+
* record when the instruction carries no resolved schema, so its filter keys
|
|
1489
|
+
* are unconstrained rather than unusable. */
|
|
1490
|
+
type SvmAccountsOf<Program extends string, Instruction extends string> =
|
|
1491
|
+
SvmConfiguredInstruction<Program, Instruction>["accounts"];
|
|
1492
|
+
|
|
1493
|
+
/** One AND-group of account narrowings: every named account must match one of
|
|
1494
|
+
* its listed pubkeys. Names are the instruction's own account names. */
|
|
1495
|
+
export type SvmAccountsFilter<Accounts> = {
|
|
1496
|
+
readonly [K in keyof Accounts]?: string | readonly string[];
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
/** The `where` option value of `indexer.onInstruction`.
|
|
1500
|
+
*
|
|
1501
|
+
* `accounts` accepts either a single AND-group of account narrowings, or an
|
|
1502
|
+
* array of them (OR semantics). `block.slot._gte` promotes to the
|
|
1503
|
+
* registration's startBlock and overrides the chain-level `start_block` — use
|
|
1504
|
+
* it to restrict per-instruction processing without touching `config.yaml`.
|
|
1505
|
+
* Only `_gte` is supported here; use `indexer.onSlot` for `_lte` / `_every`. */
|
|
1506
|
+
export type SvmOnInstructionWhere<Accounts> = {
|
|
1507
|
+
/** Match only inner (CPI-invoked) or only outer instructions. Absent
|
|
1508
|
+
* matches both. */
|
|
1509
|
+
readonly isInner?: boolean;
|
|
1510
|
+
readonly accounts?: SvmAccountsFilter<Accounts> | readonly SvmAccountsFilter<Accounts>[];
|
|
1511
|
+
readonly block?: {
|
|
1512
|
+
readonly slot?: {
|
|
1513
|
+
readonly _gte?: number;
|
|
1514
|
+
};
|
|
1515
|
+
};
|
|
1516
|
+
};
|
|
1294
1517
|
|
|
1295
1518
|
/** Options for an SVM `indexer.onInstruction` registration. */
|
|
1296
|
-
export type SvmOnInstructionOptions<
|
|
1519
|
+
export type SvmOnInstructionOptions<
|
|
1520
|
+
P extends string = string,
|
|
1521
|
+
I extends string = string,
|
|
1522
|
+
Fields extends SvmFieldsSelection = {},
|
|
1523
|
+
> = {
|
|
1297
1524
|
/** Program name as declared under `chains[].programs[].name` in
|
|
1298
1525
|
* `config.yaml`. */
|
|
1299
1526
|
readonly program: P;
|
|
1300
1527
|
/** Instruction name as declared under
|
|
1301
1528
|
* `chains[].programs[].instructions[].name` in `config.yaml`. */
|
|
1302
1529
|
readonly instruction: I;
|
|
1530
|
+
readonly fields?: Fields & SvmFieldsLiteralCheck<Fields>;
|
|
1531
|
+
readonly where?: SvmOnInstructionWhere<SvmAccountsOf<P, I>>;
|
|
1303
1532
|
};
|
|
1304
1533
|
|
|
1305
|
-
/** Handler function for an SVM `indexer.onInstruction` registration.
|
|
1534
|
+
/** Handler function for an SVM `indexer.onInstruction` registration. Takes
|
|
1535
|
+
* the same type arguments as {@link SvmInstruction}, so a standalone handler
|
|
1536
|
+
* needs a single annotation:
|
|
1537
|
+
*
|
|
1538
|
+
* const handleSwap: SvmOnInstructionHandler<typeof fields, "Swapper", "swap"> =
|
|
1539
|
+
* async ({ instruction, context }) => { ... };
|
|
1540
|
+
*/
|
|
1306
1541
|
export type SvmOnInstructionHandler<
|
|
1307
|
-
|
|
1308
|
-
|
|
1542
|
+
Fields extends SvmFieldsSelection,
|
|
1543
|
+
Program extends keyof SvmProgramsT & string = never,
|
|
1544
|
+
Instruction extends keyof SvmProgramsT[Program] & string = never,
|
|
1545
|
+
> = SvmOnInstructionHandlerFor<
|
|
1546
|
+
SvmInstruction<Fields, Program, Instruction>,
|
|
1547
|
+
GlobalConfig
|
|
1548
|
+
>;
|
|
1309
1549
|
|
|
1310
1550
|
// ============== Indexer Types ==============
|
|
1311
1551
|
|
|
@@ -1530,28 +1770,18 @@ type SvmEcosystem<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
|
1530
1770
|
/**
|
|
1531
1771
|
* Register an instruction handler. Dispatch matches on
|
|
1532
1772
|
* `(programId, discriminator)` from the YAML config.
|
|
1533
|
-
* `
|
|
1534
|
-
* `instruction.params.accounts` are typed from the
|
|
1535
|
-
* program's Borsh schema (Anchor IDL, bundled, or
|
|
1536
|
-
* hand-written `accounts`/`args` in YAML). `params` stays
|
|
1537
|
-
* optional at runtime because schema-matching can fail on
|
|
1538
|
-
* IDL drift or unknown discriminators.
|
|
1773
|
+
* Handler `fields` is the only source of payload selection.
|
|
1539
1774
|
*/
|
|
1540
1775
|
readonly onInstruction: <
|
|
1541
1776
|
P extends keyof Programs & string,
|
|
1542
1777
|
I extends keyof Programs[P] & string,
|
|
1778
|
+
const F extends SvmFieldsSelection = {},
|
|
1543
1779
|
>(
|
|
1544
|
-
options: SvmOnInstructionOptions<P, I>,
|
|
1545
|
-
handler:
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
SvmParamsFromProgramTable<Programs[P][I]>,
|
|
1550
|
-
Programs[P][I]["transaction"],
|
|
1551
|
-
Programs[P][I]["block"]
|
|
1552
|
-
>
|
|
1553
|
-
>,
|
|
1554
|
-
) => Promise<void>,
|
|
1780
|
+
options: SvmOnInstructionOptions<P, I, F>,
|
|
1781
|
+
handler: SvmOnInstructionHandlerFor<
|
|
1782
|
+
SvmSelectedInstruction<F, Programs[P][I]>,
|
|
1783
|
+
Config
|
|
1784
|
+
>,
|
|
1555
1785
|
) => void;
|
|
1556
1786
|
}
|
|
1557
1787
|
: {
|
|
@@ -1691,14 +1921,71 @@ type FuelTestIndexerChainConfig<Config extends IndexerConfigTypes = GlobalConfig
|
|
|
1691
1921
|
simulate?: FuelSimulateItem<Config>[];
|
|
1692
1922
|
};
|
|
1693
1923
|
|
|
1694
|
-
/**
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1924
|
+
/** Simulate item type for SVM ecosystem. */
|
|
1925
|
+
type SvmSimulateItem<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
1926
|
+
Config["svm"] extends { programs: infer Programs extends Record<string, Record<string, any>> }
|
|
1927
|
+
? {
|
|
1928
|
+
[P in keyof Programs]: {
|
|
1929
|
+
[I in keyof Programs[P]]: {
|
|
1930
|
+
/** Program name as declared under `chains[].programs[].name`. */
|
|
1931
|
+
program: P;
|
|
1932
|
+
/** Instruction name as declared under the program. */
|
|
1933
|
+
instruction: I;
|
|
1934
|
+
/** Override the slot. Auto-increments by default. */
|
|
1935
|
+
slot?: number;
|
|
1936
|
+
/** Instruction path in the CPI tree. Defaults to `[0]`. */
|
|
1937
|
+
path?: readonly number[];
|
|
1938
|
+
/** Override the program id. Defaults to the configured `program_id`. */
|
|
1939
|
+
programId?: string;
|
|
1940
|
+
/** Raw instruction data, `0x`-prefixed hex. */
|
|
1941
|
+
data?: string;
|
|
1942
|
+
/** Whether this is a CPI-invoked inner instruction. */
|
|
1943
|
+
isInner?: boolean;
|
|
1944
|
+
/** Decoded args. Keys match the instruction's arg names. */
|
|
1945
|
+
args?: Programs[P][I] extends { args: infer A } ? A : unknown;
|
|
1946
|
+
/** Named accounts. Keys match the instruction's account names. */
|
|
1947
|
+
accounts?: Programs[P][I] extends { accounts: infer Acc extends Record<string, unknown> }
|
|
1948
|
+
? { readonly [K in keyof Acc]?: { readonly address: string } }
|
|
1949
|
+
: Record<string, { readonly address: string }>;
|
|
1950
|
+
/** Positional account addresses, zipped onto IDL names when `accounts` is omitted. */
|
|
1951
|
+
accountArguments?: readonly string[];
|
|
1952
|
+
/** Logs scoped to this instruction. */
|
|
1953
|
+
logs?: readonly { readonly kind?: string; readonly message?: string }[];
|
|
1954
|
+
/** Override block fields. */
|
|
1955
|
+
block?: Partial<SvmAllBlockFields>;
|
|
1956
|
+
/** Override transaction fields. `accountActivities` are joined onto named accounts at process time. */
|
|
1957
|
+
transaction?: Partial<SvmAllTransactionFields> & {
|
|
1958
|
+
readonly accountActivities?: readonly {
|
|
1959
|
+
readonly address: string;
|
|
1960
|
+
readonly transactionAccountIndex?: number;
|
|
1961
|
+
readonly isSigner?: boolean;
|
|
1962
|
+
readonly isWritable?: boolean;
|
|
1963
|
+
readonly lamports?: {
|
|
1964
|
+
readonly pre?: bigint;
|
|
1965
|
+
readonly post?: bigint;
|
|
1966
|
+
};
|
|
1967
|
+
readonly token?: {
|
|
1968
|
+
readonly mint?: string;
|
|
1969
|
+
readonly owner?: string;
|
|
1970
|
+
readonly decimals?: number;
|
|
1971
|
+
readonly preAmount?: bigint;
|
|
1972
|
+
readonly postAmount?: bigint;
|
|
1973
|
+
};
|
|
1974
|
+
}[];
|
|
1975
|
+
};
|
|
1976
|
+
};
|
|
1977
|
+
}[keyof Programs[P]];
|
|
1978
|
+
}[keyof Programs]
|
|
1979
|
+
: never;
|
|
1980
|
+
|
|
1981
|
+
/** Configuration for a single SVM chain in the test indexer. */
|
|
1982
|
+
type SvmTestIndexerChainConfig<Config extends IndexerConfigTypes = GlobalConfig> = {
|
|
1698
1983
|
/** The slot number to start processing from. Defaults to config startBlock or progressBlock+1. */
|
|
1699
1984
|
startBlock?: number;
|
|
1700
|
-
/** The slot number to stop processing at. */
|
|
1985
|
+
/** The slot number to stop processing at. Defaults to max simulate slot when simulate is provided. */
|
|
1701
1986
|
endBlock?: number;
|
|
1987
|
+
/** Simulate items to process instead of fetching from real sources. */
|
|
1988
|
+
simulate?: SvmSimulateItem<Config>[];
|
|
1702
1989
|
};
|
|
1703
1990
|
|
|
1704
1991
|
/** Entity change value containing sets and/or deleted IDs. */
|
|
@@ -1725,10 +2012,10 @@ type ConfigEntities<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
|
1725
2012
|
type PerChainEntityNames<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
1726
2013
|
Config extends { perChainEntities: infer Names extends string } ? Names : never;
|
|
1727
2014
|
|
|
1728
|
-
/** The row shape
|
|
1729
|
-
*
|
|
1730
|
-
*
|
|
1731
|
-
type
|
|
2015
|
+
/** The row shape chain-agnostic APIs exchange. A per-chain entity's row is
|
|
2016
|
+
* only identified together with its chain, so the chain id travels alongside
|
|
2017
|
+
* the entity fields. */
|
|
2018
|
+
type ChainScopedEntityRow<
|
|
1732
2019
|
Config extends IndexerConfigTypes,
|
|
1733
2020
|
Name,
|
|
1734
2021
|
Entity
|
|
@@ -1806,7 +2093,7 @@ type FuelTestChains<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
|
1806
2093
|
|
|
1807
2094
|
type SvmTestChains<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
1808
2095
|
HasSvm<Config> extends true
|
|
1809
|
-
? { [K in SvmChainIds<Config>]?: SvmTestIndexerChainConfig }
|
|
2096
|
+
? { [K in SvmChainIds<Config>]?: SvmTestIndexerChainConfig<Config> }
|
|
1810
2097
|
: {};
|
|
1811
2098
|
|
|
1812
2099
|
/** Process configuration for the test indexer, with chains keyed by chain ID. */
|
|
@@ -1922,7 +2209,7 @@ export type TestIndexerFromConfig<Config extends IndexerConfigTypes = GlobalConf
|
|
|
1922
2209
|
} & SingleEcosystemTestChains<Config> & {
|
|
1923
2210
|
/** Entity operations for direct manipulation outside of handlers. */
|
|
1924
2211
|
readonly [K in keyof ConfigEntities<Config>]: TestIndexerEntityOperations<
|
|
1925
|
-
|
|
2212
|
+
ChainScopedEntityRow<Config, K, ConfigEntities<Config>[K]>
|
|
1926
2213
|
>;
|
|
1927
2214
|
};
|
|
1928
2215
|
|
|
@@ -1958,18 +2245,6 @@ export type FuelChainId = IsEmptyObject<FuelChainsT> extends true ? NotConfigure
|
|
|
1958
2245
|
/** Union of all configured SVM chain IDs. */
|
|
1959
2246
|
export type SvmChainId = IsEmptyObject<SvmChainsT> extends true ? NotConfigured<"SvmChainId", "Configure SVM chains"> : SvmChainsT [keyof SvmChainsT ]["id"];
|
|
1960
2247
|
|
|
1961
|
-
/** The SVM parent-transaction type generated from this project's
|
|
1962
|
-
* `field_selection`: the union of every instruction's `transaction` shape,
|
|
1963
|
-
* with unselected fields typed as `FieldNotSelected<...>`. Resolves to a
|
|
1964
|
-
* `NotConfigured` hint until `envio codegen` augments {@link Global}. */
|
|
1965
|
-
export type SvmTransaction = IsEmptyObject<SvmProgramsT> extends true
|
|
1966
|
-
? NotConfigured<"SvmTransaction", "Configure SVM programs">
|
|
1967
|
-
: {
|
|
1968
|
-
[P in keyof SvmProgramsT]: {
|
|
1969
|
-
[I in keyof SvmProgramsT[P]]: SvmProgramsT[P][I]["transaction"];
|
|
1970
|
-
}[keyof SvmProgramsT[P]];
|
|
1971
|
-
}[keyof SvmProgramsT];
|
|
1972
|
-
|
|
1973
2248
|
/** Lookup an EVM event type by contract and event name. Without generics,
|
|
1974
2249
|
* resolves to the discriminated union of every EVM event in the project. */
|
|
1975
2250
|
export type EvmEvent<
|
|
@@ -2008,6 +2283,244 @@ export type EnumName = keyof EnumsT & string;
|
|
|
2008
2283
|
/** Lookup an enum value type by name (e.g. `Enum<"AccountType">`). */
|
|
2009
2284
|
export type Enum<TName extends EnumName> = EnumsT[TName];
|
|
2010
2285
|
|
|
2286
|
+
// ============== Custom Resolver Types ==============
|
|
2287
|
+
|
|
2288
|
+
/** Handle for a custom GraphQL resolver created via {@link createResolver}. */
|
|
2289
|
+
export declare abstract class Resolver<Args, Output> {
|
|
2290
|
+
protected opaque: Args | Output;
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
/** The selection the caller asked for: field names and their nesting, with
|
|
2294
|
+
* aliases and fragments already resolved away. A resolver may use it to skip
|
|
2295
|
+
* work it wasn't asked for — the response is projected against the declared
|
|
2296
|
+
* schema either way, so correctness never depends on honouring it. */
|
|
2297
|
+
export type ResolverSelection = { readonly [field: string]: ResolverSelection };
|
|
2298
|
+
|
|
2299
|
+
/** Request metadata, forwarded by envio-serve. */
|
|
2300
|
+
export type ResolverContext = {
|
|
2301
|
+
/** The role the operation was executed under. `admin: true` resolvers are
|
|
2302
|
+
* only reachable as `"admin"`. */
|
|
2303
|
+
readonly role: "public" | "admin";
|
|
2304
|
+
/** Correlates this field's work with the operation it belongs to. */
|
|
2305
|
+
readonly requestId: string;
|
|
2306
|
+
/** W3C trace context of the incoming request, when the caller sent one. */
|
|
2307
|
+
readonly traceparent?: string;
|
|
2308
|
+
};
|
|
2309
|
+
|
|
2310
|
+
/** How far a chain has been indexed. Read it to refuse to answer from a stale
|
|
2311
|
+
* index — `sourceBlock - progressBlock` is how far behind the head the
|
|
2312
|
+
* indexer is. */
|
|
2313
|
+
export type ChainHeight = {
|
|
2314
|
+
readonly chainId: number;
|
|
2315
|
+
/** `"evm"`, `"fuel"` or `"svm"`. Chain ids are only unique within one. */
|
|
2316
|
+
readonly ecosystem: string;
|
|
2317
|
+
readonly startBlock: number;
|
|
2318
|
+
readonly endBlock: number | null;
|
|
2319
|
+
/** The latest block seen on the chain. */
|
|
2320
|
+
readonly sourceBlock: number;
|
|
2321
|
+
/** The latest block fetched from the source. */
|
|
2322
|
+
readonly bufferBlock: number;
|
|
2323
|
+
/** The latest block whose events have been processed and committed. */
|
|
2324
|
+
readonly progressBlock: number;
|
|
2325
|
+
/** When the chain first caught up to the head, or null while it hasn't. */
|
|
2326
|
+
readonly readyAt: Date | null;
|
|
2327
|
+
readonly isReady: boolean;
|
|
2328
|
+
};
|
|
2329
|
+
|
|
2330
|
+
/** Raw SQL, run under the resolver's `statement_timeout` and against its
|
|
2331
|
+
* bounded pool. */
|
|
2332
|
+
export type ResolverSql = {
|
|
2333
|
+
/** ``db.sql`select 1` `` */
|
|
2334
|
+
<Row = Record<string, unknown>>(
|
|
2335
|
+
strings: TemplateStringsArray,
|
|
2336
|
+
...values: readonly unknown[]
|
|
2337
|
+
): Promise<Row[]>;
|
|
2338
|
+
/** `db.sql.unsafe(text, params)` — the direct lift for a query built as a
|
|
2339
|
+
* string with positional parameters. */
|
|
2340
|
+
unsafe<Row = Record<string, unknown>>(
|
|
2341
|
+
text: string,
|
|
2342
|
+
params?: readonly unknown[],
|
|
2343
|
+
options?: { readonly prepare?: boolean }
|
|
2344
|
+
): Promise<Row[]>;
|
|
2345
|
+
};
|
|
2346
|
+
|
|
2347
|
+
/** Options accepted by `db.find`. */
|
|
2348
|
+
export type ResolverFindOptions<Entity> = {
|
|
2349
|
+
/** Filter by field, with the same operators as `context.<Entity>.getWhere`.
|
|
2350
|
+
* Unlike `getWhere`, any field can be filtered on here — it is a query
|
|
2351
|
+
* against the table, so an unindexed field is a slow one, not an error. */
|
|
2352
|
+
readonly where?: GetWhereFilter<Entity>;
|
|
2353
|
+
readonly orderBy?: readonly {
|
|
2354
|
+
readonly field: keyof Entity & string;
|
|
2355
|
+
readonly direction: "asc" | "desc";
|
|
2356
|
+
}[];
|
|
2357
|
+
readonly limit?: number;
|
|
2358
|
+
readonly offset?: number;
|
|
2359
|
+
};
|
|
2360
|
+
|
|
2361
|
+
/** The database a resolver reads through. Every query it runs carries the
|
|
2362
|
+
* resolver's `timeoutMs` as a `statement_timeout` and takes one of the
|
|
2363
|
+
* process's bounded connections. */
|
|
2364
|
+
export type ResolverDb<Config extends IndexerConfigTypes = GlobalConfig> = {
|
|
2365
|
+
/** Entities matching `where`, decoded exactly as a handler sees them. */
|
|
2366
|
+
readonly find: <Name extends keyof ConfigEntities<Config> & string>(
|
|
2367
|
+
entityName: Name,
|
|
2368
|
+
options?: ResolverFindOptions<
|
|
2369
|
+
ChainScopedEntityRow<Config, Name, ConfigEntities<Config>[Name]>
|
|
2370
|
+
>
|
|
2371
|
+
) => Promise<
|
|
2372
|
+
ChainScopedEntityRow<Config, Name, ConfigEntities<Config>[Name]>[]
|
|
2373
|
+
>;
|
|
2374
|
+
/** One entity by id, or null. Not available for per-chain entities, whose
|
|
2375
|
+
* key is the id together with a chain — use {@link ResolverDb.find}. */
|
|
2376
|
+
readonly get: <
|
|
2377
|
+
Name extends Exclude<
|
|
2378
|
+
keyof ConfigEntities<Config> & string,
|
|
2379
|
+
PerChainEntityNames<Config>
|
|
2380
|
+
>
|
|
2381
|
+
>(
|
|
2382
|
+
entityName: Name,
|
|
2383
|
+
id: EntityId<ConfigEntities<Config>[Name]>
|
|
2384
|
+
) => Promise<ConfigEntities<Config>[Name] | null>;
|
|
2385
|
+
/** Raw SQL, for what the loaders don't express. */
|
|
2386
|
+
readonly sql: ResolverSql;
|
|
2387
|
+
/** The Postgres schema the indexer's tables live in. Raw SQL has to qualify
|
|
2388
|
+
* table names with it — it is not `"public"` on a hosted deployment. */
|
|
2389
|
+
readonly pgSchema: string;
|
|
2390
|
+
/** Several queries on one connection, under one timeout. */
|
|
2391
|
+
readonly transaction: <T>(work: (sql: ResolverSql) => Promise<T>) => Promise<T>;
|
|
2392
|
+
/** How far each chain has been indexed, keyed by chain id. */
|
|
2393
|
+
readonly chainHeights: () => Promise<Record<string, ChainHeight>>;
|
|
2394
|
+
};
|
|
2395
|
+
|
|
2396
|
+
/** Arguments passed to a {@link Resolver}'s handler. */
|
|
2397
|
+
export type ResolverHandlerArgs<
|
|
2398
|
+
Args,
|
|
2399
|
+
Config extends IndexerConfigTypes = GlobalConfig
|
|
2400
|
+
> = {
|
|
2401
|
+
/** Coerced and validated against the declared arg schemas before the
|
|
2402
|
+
* resolver is reached. */
|
|
2403
|
+
readonly args: Args;
|
|
2404
|
+
readonly db: ResolverDb<Config>;
|
|
2405
|
+
readonly selection: ResolverSelection;
|
|
2406
|
+
readonly ctx: ResolverContext;
|
|
2407
|
+
};
|
|
2408
|
+
|
|
2409
|
+
/**
|
|
2410
|
+
* Declares a custom GraphQL resolver: a root query field served alongside the
|
|
2411
|
+
* generated entity fields, backed by TypeScript in this project.
|
|
2412
|
+
*
|
|
2413
|
+
* Arguments and result are declared with the same `S` schemas effects use, and
|
|
2414
|
+
* the GraphQL types are derived from them. A field is non-null unless its
|
|
2415
|
+
* schema is optional. Object types must be named with {@link defineType} —
|
|
2416
|
+
* GraphQL has no anonymous types.
|
|
2417
|
+
*
|
|
2418
|
+
* ```ts
|
|
2419
|
+
* export const marketsAprByPeriod = createResolver({
|
|
2420
|
+
* name: "marketsAprByPeriod",
|
|
2421
|
+
* args: { periodStart: S.int32, periodEnd: S.int32 },
|
|
2422
|
+
* output: S.array(defineType("MarketApr", { marketAddress: S.string })),
|
|
2423
|
+
* timeoutMs: 30_000,
|
|
2424
|
+
* handler: async ({ args, db }) => db.find("MarketInfo"),
|
|
2425
|
+
* });
|
|
2426
|
+
* ```
|
|
2427
|
+
*/
|
|
2428
|
+
export function createResolver<
|
|
2429
|
+
// Both are schemas at runtime: `createResolver` reads `output.t` and walks
|
|
2430
|
+
// every argument with `toGraphQLType` while the module is being imported, so
|
|
2431
|
+
// anything else fails at indexer startup rather than in the editor.
|
|
2432
|
+
AS extends Record<string, Sury.Schema<unknown>>,
|
|
2433
|
+
OS extends Sury.Schema<unknown>,
|
|
2434
|
+
A = UnknownToOutput<AS>,
|
|
2435
|
+
O = UnknownToOutput<OS>,
|
|
2436
|
+
// A hack to enforce that the inferred return type matches the output schema.
|
|
2437
|
+
R extends O = O
|
|
2438
|
+
>(options: {
|
|
2439
|
+
/** The GraphQL field name. Must not collide with a generated one. */
|
|
2440
|
+
readonly name: string;
|
|
2441
|
+
/** Shown in the schema, for the people querying it. */
|
|
2442
|
+
readonly description?: string;
|
|
2443
|
+
/** Argument schemas, keyed by argument name. */
|
|
2444
|
+
readonly args?: AS;
|
|
2445
|
+
/** The result schema. Determines the field's GraphQL type. */
|
|
2446
|
+
readonly output: OS;
|
|
2447
|
+
/** Register the field on the admin schema only: it stays out of public
|
|
2448
|
+
* introspection and is unexecutable without the admin secret. */
|
|
2449
|
+
readonly admin?: boolean;
|
|
2450
|
+
/** The `statement_timeout` every query this resolver runs is bounded by.
|
|
2451
|
+
* Required: it is the only thing bounding a runaway query. */
|
|
2452
|
+
readonly timeoutMs: number;
|
|
2453
|
+
readonly handler: (args: ResolverHandlerArgs<A>) => Promise<R>;
|
|
2454
|
+
}): Resolver<A, O>;
|
|
2455
|
+
|
|
2456
|
+
/**
|
|
2457
|
+
* Thrown by a resolver to put a specific error on the client's response.
|
|
2458
|
+
*
|
|
2459
|
+
* Anything else a handler throws is reported as an internal failure with its
|
|
2460
|
+
* message withheld — a driver error can carry a connection string, and the
|
|
2461
|
+
* caller is the public internet — so this is how a resolver says more than
|
|
2462
|
+
* that. envio-serve carries the extensions through unchanged.
|
|
2463
|
+
*
|
|
2464
|
+
* ```ts
|
|
2465
|
+
* throw new ResolverError("Service is syncing", {
|
|
2466
|
+
* code: "SERVICE_UNAVAILABLE",
|
|
2467
|
+
* httpStatus: 503,
|
|
2468
|
+
* });
|
|
2469
|
+
* ```
|
|
2470
|
+
*/
|
|
2471
|
+
export declare class ResolverError extends Error {
|
|
2472
|
+
constructor(
|
|
2473
|
+
message: string,
|
|
2474
|
+
options?: {
|
|
2475
|
+
/** Becomes `extensions.code`. Defaults to `"INTERNAL_SERVER_ERROR"`. */
|
|
2476
|
+
readonly code?: string;
|
|
2477
|
+
/** Becomes `extensions.http.status`. */
|
|
2478
|
+
readonly httpStatus?: number;
|
|
2479
|
+
/** Merged into `extensions` alongside `code`. */
|
|
2480
|
+
readonly extensions?: Record<string, unknown>;
|
|
2481
|
+
}
|
|
2482
|
+
);
|
|
2483
|
+
readonly code: string;
|
|
2484
|
+
readonly httpStatus?: number;
|
|
2485
|
+
readonly extensions?: Record<string, unknown>;
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
/** Names a schema so it can appear in the GraphQL schema as an object type. */
|
|
2489
|
+
export function defineType<F extends Record<string, unknown>>(
|
|
2490
|
+
name: string,
|
|
2491
|
+
fields: F
|
|
2492
|
+
): Sury.Schema<UnknownToOutput<F>>;
|
|
2493
|
+
|
|
2494
|
+
/**
|
|
2495
|
+
* Names a schema that appears in an argument.
|
|
2496
|
+
*
|
|
2497
|
+
* GraphQL keeps input and output types in a separate namespace from object
|
|
2498
|
+
* types, so a `where` argument is declared with this rather than with
|
|
2499
|
+
* {@link defineType}.
|
|
2500
|
+
*/
|
|
2501
|
+
export function defineInput<F extends Record<string, unknown>>(
|
|
2502
|
+
name: string,
|
|
2503
|
+
fields: F
|
|
2504
|
+
): Sury.Schema<UnknownToOutput<F>>;
|
|
2505
|
+
|
|
2506
|
+
/** Every resolver declared so far, in declaration order. */
|
|
2507
|
+
export function getRegisteredResolvers(): readonly Resolver<unknown, unknown>[];
|
|
2508
|
+
|
|
2509
|
+
/** The manifest and SDL for everything declared so far. */
|
|
2510
|
+
export function buildRegisteredManifest(): { manifest: unknown; sdl: string };
|
|
2511
|
+
|
|
2512
|
+
/** Names a schema representing a GraphQL enum. */
|
|
2513
|
+
export function defineEnum<const V extends readonly string[]>(
|
|
2514
|
+
name: string,
|
|
2515
|
+
values: V
|
|
2516
|
+
): Sury.Schema<V[number]>;
|
|
2517
|
+
|
|
2518
|
+
/** Names a schema representing a custom GraphQL scalar, such as `BigInt`. */
|
|
2519
|
+
export function defineScalar<T>(
|
|
2520
|
+
name: string,
|
|
2521
|
+
schema: Sury.Schema<T>
|
|
2522
|
+
): Sury.Schema<T>;
|
|
2523
|
+
|
|
2011
2524
|
// ============== Runtime values ==============
|
|
2012
2525
|
|
|
2013
2526
|
/** The indexer instance. Register handlers with `indexer.onEvent`,
|