envio 3.7.0 → 3.9.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/index.d.ts +399 -156
- package/package.json +6 -6
- package/src/AddressRows.res +121 -0
- package/src/AddressRows.res.mjs +143 -0
- package/src/Batch.res +2 -0
- package/src/Batch.res.mjs +2 -1
- package/src/ChainState.res +82 -68
- package/src/ChainState.res.mjs +81 -65
- package/src/ChainState.resi +14 -9
- package/src/Config.res +41 -91
- package/src/Config.res.mjs +34 -68
- package/src/ContractMapping.res +66 -0
- package/src/ContractMapping.res.mjs +73 -0
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +4 -0
- package/src/Envio.res +54 -76
- package/src/EventConfigBuilder.res +157 -30
- package/src/EventConfigBuilder.res.mjs +118 -24
- package/src/FetchState.res +59 -67
- package/src/FetchState.res.mjs +34 -44
- package/src/HandlerRegister.res +20 -11
- package/src/HandlerRegister.res.mjs +22 -5
- package/src/Hasura.res +30 -22
- package/src/Hasura.res.mjs +11 -5
- package/src/InMemoryStore.res +18 -36
- package/src/InMemoryStore.res.mjs +12 -26
- package/src/IndexerState.res +21 -1
- package/src/IndexerState.res.mjs +9 -3
- package/src/IndexerState.resi +1 -0
- package/src/Internal.res +33 -13
- package/src/Internal.res.mjs +12 -16
- package/src/Main.res +27 -20
- package/src/Main.res.mjs +19 -14
- package/src/MemoryStorage.res +78 -73
- package/src/MemoryStorage.res.mjs +66 -81
- package/src/Metrics.res +15 -1
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +34 -18
- package/src/Persistence.res.mjs +8 -5
- package/src/PgStorage.res +189 -66
- package/src/PgStorage.res.mjs +93 -59
- package/src/Rollback.res +14 -10
- package/src/Rollback.res.mjs +4 -2
- package/src/SimulateItems.res +254 -9
- package/src/SimulateItems.res.mjs +214 -47
- package/src/TestIndexer.res +119 -121
- package/src/TestIndexer.res.mjs +95 -100
- package/src/Utils.res +7 -0
- package/src/Utils.res.mjs +9 -2
- package/src/Writing.res +2 -0
- package/src/Writing.res.mjs +2 -1
- package/src/bindings/ClickHouse.res +39 -6
- package/src/bindings/ClickHouse.res.mjs +29 -4
- 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 +12 -18
- package/src/db/EntityHistory.res.mjs +3 -14
- package/src/db/InternalTable.res +182 -65
- package/src/db/InternalTable.res.mjs +183 -73
- package/src/db/Table.res +24 -0
- package/src/db/Table.res.mjs +20 -1
- 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/EvmHyperSyncSource.res +3 -2
- package/src/sources/SimulateSource.res +8 -4
- package/src/sources/SimulateSource.res.mjs +7 -3
- package/src/sources/Svm.res +34 -7
- package/src/sources/Svm.res.mjs +32 -4
- package/src/sources/SvmHyperSyncClient.res +24 -30
- package/src/sources/SvmHyperSyncClient.res.mjs +3 -2
- package/src/sources/SvmHyperSyncSource.res +88 -36
- package/src/sources/SvmHyperSyncSource.res.mjs +71 -39
- package/src/sources/TransactionStore.res +38 -0
- package/src/sources/TransactionStore.res.mjs +5 -0
- package/svm.schema.json +37 -82
package/src/SimulateItems.res
CHANGED
|
@@ -174,6 +174,8 @@ type rawSimulateItem
|
|
|
174
174
|
|
|
175
175
|
@get external getContract: rawSimulateItem => option<string> = "contract"
|
|
176
176
|
@get external getEvent: rawSimulateItem => option<string> = "event"
|
|
177
|
+
@get external getProgram: rawSimulateItem => option<string> = "program"
|
|
178
|
+
@get external getInstruction: rawSimulateItem => option<string> = "instruction"
|
|
177
179
|
|
|
178
180
|
let findEventConfig = (~config: Config.t, ~contractName: string, ~eventName: string) => {
|
|
179
181
|
let found = ref(None)
|
|
@@ -240,18 +242,71 @@ let deriveSrcAddress = (
|
|
|
240
242
|
}
|
|
241
243
|
}
|
|
242
244
|
|
|
245
|
+
type parseResult = {
|
|
246
|
+
items: array<Internal.item>,
|
|
247
|
+
transactionStore: option<TransactionStore.t>,
|
|
248
|
+
blockStore: option<BlockStore.t>,
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
type svmSimActivity = {
|
|
252
|
+
address: string,
|
|
253
|
+
transactionAccountIndex?: int,
|
|
254
|
+
isSigner?: bool,
|
|
255
|
+
isWritable?: bool,
|
|
256
|
+
lamports?: {pre?: bigint, post?: bigint},
|
|
257
|
+
token?: {
|
|
258
|
+
mint?: string,
|
|
259
|
+
owner?: string,
|
|
260
|
+
decimals?: int,
|
|
261
|
+
preAmount?: bigint,
|
|
262
|
+
postAmount?: bigint,
|
|
263
|
+
},
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
type svmSimTransaction = {
|
|
267
|
+
transactionIndex?: int,
|
|
268
|
+
signature?: string,
|
|
269
|
+
allSignatures?: array<string>,
|
|
270
|
+
feePayer?: string,
|
|
271
|
+
success?: bool,
|
|
272
|
+
err?: string,
|
|
273
|
+
fee?: bigint,
|
|
274
|
+
computeUnitsConsumed?: bigint,
|
|
275
|
+
accountKeys?: array<string>,
|
|
276
|
+
recentBlockhash?: string,
|
|
277
|
+
version?: string,
|
|
278
|
+
accountActivities?: array<svmSimActivity>,
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
let liveRegistrationsFor = (
|
|
282
|
+
~config: Config.t,
|
|
283
|
+
~chainId: ChainId.t,
|
|
284
|
+
~eventConfig: Internal.eventConfig,
|
|
285
|
+
) =>
|
|
286
|
+
HandlerRegister.getSimulateOnEventRegistrations(
|
|
287
|
+
~config,
|
|
288
|
+
~chainId,
|
|
289
|
+
~eventConfig,
|
|
290
|
+
)->Array.filter(reg =>
|
|
291
|
+
(reg.handler->Option.isSome || reg.contractRegister->Option.isSome) &&
|
|
292
|
+
!HandlerRegister.isDroppedByWhere(~config, reg)
|
|
293
|
+
)
|
|
294
|
+
|
|
243
295
|
let parse = (
|
|
244
296
|
~simulateItems: array<JSON.t>,
|
|
245
297
|
~config: Config.t,
|
|
246
298
|
~chainConfig: Config.chain,
|
|
247
299
|
~onEventRegistrations: array<Internal.onEventRegistration>,
|
|
248
|
-
):
|
|
300
|
+
): parseResult => {
|
|
249
301
|
let chainId = chainConfig.id
|
|
250
302
|
let startBlock = chainConfig.startBlock
|
|
251
303
|
let currentBlock = ref(startBlock)
|
|
252
304
|
let currentLogIndex = ref(0)
|
|
253
305
|
|
|
254
306
|
let items = []
|
|
307
|
+
let svmTxs: array<TransactionStore.svmTxInput> = []
|
|
308
|
+
let svmActivities: array<TransactionStore.svmActivityInput> = []
|
|
309
|
+
let svmBlocks: array<BlockStore.inputBlock> = []
|
|
255
310
|
// Coordinate "block:logIndex" -> the index of the first item that claimed it,
|
|
256
311
|
// used to reject two items resolving to the same (block, logIndex).
|
|
257
312
|
let seenCoordinates = Dict.make()
|
|
@@ -259,8 +314,182 @@ let parse = (
|
|
|
259
314
|
simulateItems->Array.forEachWithIndex((rawJson, itemIndex) => {
|
|
260
315
|
let raw = rawJson->(Utils.magic: JSON.t => rawSimulateItem)
|
|
261
316
|
|
|
262
|
-
switch (raw->
|
|
263
|
-
| (Some(
|
|
317
|
+
switch (config.ecosystem.name, raw->getProgram, raw->getInstruction) {
|
|
318
|
+
| (Svm, Some(programName), Some(instructionName)) =>
|
|
319
|
+
let eventConfig = switch findEventConfig(
|
|
320
|
+
~config,
|
|
321
|
+
~contractName=programName,
|
|
322
|
+
~eventName=instructionName,
|
|
323
|
+
) {
|
|
324
|
+
| Some(ec) => ec
|
|
325
|
+
| None =>
|
|
326
|
+
JsError.throwWithMessage(
|
|
327
|
+
`simulate: Instruction "${instructionName}" not found on program "${programName}". ` ++ `Check that the program and instruction names match your config.yaml.`,
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
let svmEventConfig =
|
|
331
|
+
eventConfig->(Utils.magic: Internal.eventConfig => Internal.svmInstructionEventConfig)
|
|
332
|
+
let item = rawJson->(Utils.magic: JSON.t => Envio.svmSimulateItem)
|
|
333
|
+
let rawItem = rawJson->(Utils.magic: JSON.t => {..})
|
|
334
|
+
let blockJson: option<JSON.t> =
|
|
335
|
+
rawItem["block"]->(Utils.magic: 'a => Nullable.t<JSON.t>)->Nullable.toOption
|
|
336
|
+
let slot = switch item.slot {
|
|
337
|
+
| Some(s) => s
|
|
338
|
+
| None =>
|
|
339
|
+
switch blockJson {
|
|
340
|
+
| Some(bj) =>
|
|
341
|
+
switch (bj->(Utils.magic: JSON.t => dict<JSON.t>))->Dict.get("slot") {
|
|
342
|
+
| Some(v) =>
|
|
343
|
+
v->(Utils.magic: JSON.t => Nullable.t<int>)->Nullable.toOption->Option.getOr(
|
|
344
|
+
currentBlock.contents,
|
|
345
|
+
)
|
|
346
|
+
| None => currentBlock.contents
|
|
347
|
+
}
|
|
348
|
+
| None => currentBlock.contents
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
currentBlock := slot
|
|
352
|
+
let transaction = switch item.transaction {
|
|
353
|
+
| Some(tx) => tx->(Utils.magic: unknown => svmSimTransaction)
|
|
354
|
+
| None => {}
|
|
355
|
+
}
|
|
356
|
+
let transactionIndex = transaction.transactionIndex->Option.getOr(0)
|
|
357
|
+
let path = item.path->Option.getOr([0])
|
|
358
|
+
let programId =
|
|
359
|
+
item.programId->Option.getOr(svmEventConfig.programId->SvmTypes.Pubkey.toString)
|
|
360
|
+
let accountArguments = switch item.accountArguments {
|
|
361
|
+
| Some(args) => args
|
|
362
|
+
| None =>
|
|
363
|
+
switch item.accounts {
|
|
364
|
+
| Some(named) =>
|
|
365
|
+
svmEventConfig.accounts->Array.map(name =>
|
|
366
|
+
switch named->Dict.get(name) {
|
|
367
|
+
| Some({address}) => address
|
|
368
|
+
| None => ""
|
|
369
|
+
}
|
|
370
|
+
)
|
|
371
|
+
| None => []
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
let data = item.data->Option.getOr(svmEventConfig.discriminator->Option.getOr("0x"))
|
|
375
|
+
let argsJson = item.args->Option.mapOr("{}", args => args->JSON.stringify)
|
|
376
|
+
let logs = item.logs->Option.map(logs =>
|
|
377
|
+
logs->Array.map((log): SvmHyperSyncClient.EventItems.log => {
|
|
378
|
+
kind: log.kind->Null.fromOption,
|
|
379
|
+
message: log.message->Null.fromOption,
|
|
380
|
+
})
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
let liveRegistrations = liveRegistrationsFor(~config, ~chainId, ~eventConfig)
|
|
384
|
+
if liveRegistrations->Utils.Array.isEmpty {
|
|
385
|
+
JsError.throwWithMessage(
|
|
386
|
+
`simulate: no handler runs for instruction "${instructionName}" on program "${programName}". Register a handler with indexer.onInstruction before simulating it.`,
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
svmTxs
|
|
391
|
+
->Array.push({
|
|
392
|
+
slot,
|
|
393
|
+
transactionIndex,
|
|
394
|
+
signature: ?transaction.signature,
|
|
395
|
+
allSignatures: ?transaction.allSignatures,
|
|
396
|
+
feePayer: ?transaction.feePayer,
|
|
397
|
+
success: ?transaction.success,
|
|
398
|
+
err: ?transaction.err,
|
|
399
|
+
fee: ?transaction.fee,
|
|
400
|
+
computeUnitsConsumed: ?transaction.computeUnitsConsumed,
|
|
401
|
+
accountKeys: ?transaction.accountKeys,
|
|
402
|
+
recentBlockhash: ?transaction.recentBlockhash,
|
|
403
|
+
version: ?transaction.version,
|
|
404
|
+
})
|
|
405
|
+
->ignore
|
|
406
|
+
switch transaction.accountActivities {
|
|
407
|
+
| Some(rows) =>
|
|
408
|
+
rows->Array.forEach(activity =>
|
|
409
|
+
svmActivities
|
|
410
|
+
->Array.push({
|
|
411
|
+
TransactionStore.slot,
|
|
412
|
+
transactionIndex,
|
|
413
|
+
account: activity.address,
|
|
414
|
+
accountIndex: ?activity.transactionAccountIndex,
|
|
415
|
+
isSigner: ?activity.isSigner,
|
|
416
|
+
isWritable: ?activity.isWritable,
|
|
417
|
+
preBalance: ?activity.lamports->Option.flatMap(l => l.pre),
|
|
418
|
+
postBalance: ?activity.lamports->Option.flatMap(l => l.post),
|
|
419
|
+
mint: ?activity.token->Option.flatMap(t => t.mint),
|
|
420
|
+
owner: ?activity.token->Option.flatMap(t => t.owner),
|
|
421
|
+
decimals: ?activity.token->Option.flatMap(t => t.decimals),
|
|
422
|
+
preAmount: ?activity.token->Option.flatMap(t => t.preAmount),
|
|
423
|
+
postAmount: ?activity.token->Option.flatMap(t => t.postAmount),
|
|
424
|
+
})
|
|
425
|
+
->ignore
|
|
426
|
+
)
|
|
427
|
+
| None => ()
|
|
428
|
+
}
|
|
429
|
+
let blockTime = switch item.block {
|
|
430
|
+
| Some(block) => block.time
|
|
431
|
+
| None => None
|
|
432
|
+
}
|
|
433
|
+
let blockHash = switch item.block {
|
|
434
|
+
| Some(block) => block.hash
|
|
435
|
+
| None => None
|
|
436
|
+
}
|
|
437
|
+
svmBlocks
|
|
438
|
+
->Array.push({
|
|
439
|
+
blockNumber: slot,
|
|
440
|
+
?blockHash,
|
|
441
|
+
blockTimestamp: ?blockTime,
|
|
442
|
+
})
|
|
443
|
+
->ignore
|
|
444
|
+
|
|
445
|
+
liveRegistrations->Array.forEach(reg => {
|
|
446
|
+
let onEventRegistrationIndex = onEventRegistrations->Array.length
|
|
447
|
+
let onEventRegistration = {...reg, index: onEventRegistrationIndex}
|
|
448
|
+
onEventRegistrations->Array.push(onEventRegistration)->ignore
|
|
449
|
+
let payload = SvmHyperSyncSource.toSvmInstruction(
|
|
450
|
+
{
|
|
451
|
+
onEventRegistrationIndex,
|
|
452
|
+
slot,
|
|
453
|
+
transactionIndex,
|
|
454
|
+
path,
|
|
455
|
+
programId,
|
|
456
|
+
accounts: accountArguments,
|
|
457
|
+
data,
|
|
458
|
+
isInner: item.isInner->Option.getOr(false),
|
|
459
|
+
argsJson,
|
|
460
|
+
logs: logs->Null.fromOption,
|
|
461
|
+
},
|
|
462
|
+
~programName,
|
|
463
|
+
~instructionName,
|
|
464
|
+
~eventConfig=svmEventConfig,
|
|
465
|
+
~fieldSelection=onEventRegistration.fieldSelection,
|
|
466
|
+
)
|
|
467
|
+
let payloadDict = payload->(Utils.magic: Envio.svmInstruction => dict<unknown>)
|
|
468
|
+
payloadDict->Dict.set("srcAddress", programId->(Utils.magic: string => unknown))
|
|
469
|
+
items
|
|
470
|
+
->Array.push(
|
|
471
|
+
Internal.Event({
|
|
472
|
+
onEventRegistration,
|
|
473
|
+
chainId,
|
|
474
|
+
blockNumber: slot,
|
|
475
|
+
logIndex: transactionIndex,
|
|
476
|
+
orderPath: path,
|
|
477
|
+
transactionIndex,
|
|
478
|
+
payload: payload->(Utils.magic: Envio.svmInstruction => Internal.eventPayload),
|
|
479
|
+
}),
|
|
480
|
+
)
|
|
481
|
+
->ignore
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
| (Svm, _, _) =>
|
|
485
|
+
JsError.throwWithMessage(`simulate: Invalid item. Each item must have "program" and "instruction" fields.`)
|
|
486
|
+
|
|
487
|
+
| (_, _, _) =>
|
|
488
|
+
let (contractName, eventName) = switch (raw->getContract, raw->getEvent) {
|
|
489
|
+
| (Some(c), Some(e)) => (c, e)
|
|
490
|
+
| _ =>
|
|
491
|
+
JsError.throwWithMessage(`simulate: Invalid item. Each item must have "contract" and "event" fields.`)
|
|
492
|
+
}
|
|
264
493
|
// Event simulate item
|
|
265
494
|
let eventConfig = switch findEventConfig(~config, ~contractName, ~eventName) {
|
|
266
495
|
| Some(ec) => ec
|
|
@@ -399,13 +628,21 @@ let parse = (
|
|
|
399
628
|
)
|
|
400
629
|
->ignore
|
|
401
630
|
})
|
|
402
|
-
|
|
403
|
-
| _ =>
|
|
404
|
-
JsError.throwWithMessage(`simulate: Invalid item. Each item must have "contract" and "event" fields.`)
|
|
405
631
|
}
|
|
406
632
|
})
|
|
407
633
|
|
|
408
|
-
|
|
634
|
+
switch config.ecosystem.name {
|
|
635
|
+
| Svm => {
|
|
636
|
+
items,
|
|
637
|
+
transactionStore: Some(TransactionStore.fromSvmJs(svmTxs, svmActivities)),
|
|
638
|
+
blockStore: Some(BlockStore.fromJs(svmBlocks, ~ecosystem=Svm, ~shouldChecksum=false)),
|
|
639
|
+
}
|
|
640
|
+
| _ => {
|
|
641
|
+
items,
|
|
642
|
+
transactionStore: None,
|
|
643
|
+
blockStore: None,
|
|
644
|
+
}
|
|
645
|
+
}
|
|
409
646
|
}
|
|
410
647
|
|
|
411
648
|
// Apply simulate source config from processConfig JSON to a Config.t
|
|
@@ -444,13 +681,21 @@ let patchConfig = (
|
|
|
444
681
|
// Parse with the process's startBlock so items default into the range
|
|
445
682
|
// the source will be queried over; the source now filters by range.
|
|
446
683
|
let chainConfig = {...chainConfig, startBlock, endBlock}
|
|
447
|
-
let items = parse(
|
|
684
|
+
let {items, transactionStore, blockStore} = parse(
|
|
448
685
|
~simulateItems,
|
|
449
686
|
~config,
|
|
450
687
|
~chainConfig,
|
|
451
688
|
~onEventRegistrations=chainRegistrations.onEventRegistrations,
|
|
452
689
|
)
|
|
453
|
-
{
|
|
690
|
+
{
|
|
691
|
+
...chainConfig,
|
|
692
|
+
sourceConfig: Config.SimulateSourceConfig({
|
|
693
|
+
items,
|
|
694
|
+
endBlock,
|
|
695
|
+
?transactionStore,
|
|
696
|
+
?blockStore,
|
|
697
|
+
}),
|
|
698
|
+
}
|
|
454
699
|
| None => chainConfig
|
|
455
700
|
}
|
|
456
701
|
| None => chainConfig
|
|
@@ -5,11 +5,15 @@ import * as Config from "./Config.res.mjs";
|
|
|
5
5
|
import * as Address from "./Address.res.mjs";
|
|
6
6
|
import * as ChainId from "./ChainId.res.mjs";
|
|
7
7
|
import * as ChainMap from "./ChainMap.res.mjs";
|
|
8
|
+
import * as BlockStore from "./sources/BlockStore.res.mjs";
|
|
9
|
+
import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
|
|
8
10
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
9
11
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
10
12
|
import * as HandlerRegister from "./HandlerRegister.res.mjs";
|
|
11
13
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
12
14
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
15
|
+
import * as TransactionStore from "./sources/TransactionStore.res.mjs";
|
|
16
|
+
import * as SvmHyperSyncSource from "./sources/SvmHyperSyncSource.res.mjs";
|
|
13
17
|
|
|
14
18
|
let evmSimulateBlockSchema = S$RescriptSchema.schema(s => ({
|
|
15
19
|
number: s.m(S$RescriptSchema.Option.getOr(S$RescriptSchema.$$null(S$RescriptSchema.int), 0)),
|
|
@@ -168,6 +172,16 @@ function deriveSrcAddress(providedSrcAddress, eventConfig, chainConfig, config)
|
|
|
168
172
|
}
|
|
169
173
|
}
|
|
170
174
|
|
|
175
|
+
function liveRegistrationsFor(config, chainId, eventConfig) {
|
|
176
|
+
return HandlerRegister.getSimulateOnEventRegistrations(config, chainId, eventConfig).filter(reg => {
|
|
177
|
+
if (Stdlib_Option.isSome(reg.handler) || Stdlib_Option.isSome(reg.contractRegister)) {
|
|
178
|
+
return !HandlerRegister.isDroppedByWhere(config, reg);
|
|
179
|
+
} else {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
171
185
|
function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
172
186
|
let chainId = chainConfig.id;
|
|
173
187
|
let startBlock = chainConfig.startBlock;
|
|
@@ -178,21 +192,156 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
178
192
|
contents: 0
|
|
179
193
|
};
|
|
180
194
|
let items = [];
|
|
195
|
+
let svmTxs = [];
|
|
196
|
+
let svmActivities = [];
|
|
197
|
+
let svmBlocks = [];
|
|
181
198
|
let seenCoordinates = {};
|
|
182
199
|
simulateItems.forEach((rawJson, itemIndex) => {
|
|
183
|
-
let match =
|
|
184
|
-
let match$1 = rawJson.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
200
|
+
let match = config.ecosystem.name;
|
|
201
|
+
let match$1 = rawJson.program;
|
|
202
|
+
let match$2 = rawJson.instruction;
|
|
203
|
+
switch (match) {
|
|
204
|
+
case "evm" :
|
|
205
|
+
case "fuel" :
|
|
206
|
+
break;
|
|
207
|
+
case "svm" :
|
|
208
|
+
if (match$1 === undefined) {
|
|
209
|
+
return Stdlib_JsError.throwWithMessage(`simulate: Invalid item. Each item must have "program" and "instruction" fields.`);
|
|
210
|
+
}
|
|
211
|
+
if (match$2 === undefined) {
|
|
212
|
+
return Stdlib_JsError.throwWithMessage(`simulate: Invalid item. Each item must have "program" and "instruction" fields.`);
|
|
213
|
+
}
|
|
214
|
+
let ec = findEventConfig(config, match$1, match$2);
|
|
215
|
+
let eventConfig = ec !== undefined ? ec : Stdlib_JsError.throwWithMessage(`simulate: Instruction "` + match$2 + `" not found on program "` + match$1 + `". Check that the program and instruction names match your config.yaml.`);
|
|
216
|
+
let blockJson = rawJson.block;
|
|
217
|
+
let s = rawJson.slot;
|
|
218
|
+
let slot;
|
|
219
|
+
if (s !== undefined) {
|
|
220
|
+
slot = s;
|
|
221
|
+
} else if (blockJson == null) {
|
|
222
|
+
slot = currentBlock.contents;
|
|
223
|
+
} else {
|
|
224
|
+
let v = blockJson["slot"];
|
|
225
|
+
slot = v !== undefined ? Stdlib_Option.getOr((v == null) ? undefined : Primitive_option.some(v), currentBlock.contents) : currentBlock.contents;
|
|
226
|
+
}
|
|
227
|
+
currentBlock.contents = slot;
|
|
228
|
+
let tx = rawJson.transaction;
|
|
229
|
+
let transaction = tx !== undefined ? Primitive_option.valFromOption(tx) : ({});
|
|
230
|
+
let transactionIndex = Stdlib_Option.getOr(transaction.transactionIndex, 0);
|
|
231
|
+
let path = Stdlib_Option.getOr(rawJson.path, [0]);
|
|
232
|
+
let programId = Stdlib_Option.getOr(rawJson.programId, eventConfig.programId);
|
|
233
|
+
let args = rawJson.accountArguments;
|
|
234
|
+
let accountArguments;
|
|
235
|
+
if (args !== undefined) {
|
|
236
|
+
accountArguments = args;
|
|
237
|
+
} else {
|
|
238
|
+
let named = rawJson.accounts;
|
|
239
|
+
accountArguments = named !== undefined ? eventConfig.accounts.map(name => {
|
|
240
|
+
let match = named[name];
|
|
241
|
+
if (match !== undefined) {
|
|
242
|
+
return match.address;
|
|
243
|
+
} else {
|
|
244
|
+
return "";
|
|
245
|
+
}
|
|
246
|
+
}) : [];
|
|
247
|
+
}
|
|
248
|
+
let data = Stdlib_Option.getOr(rawJson.data, Stdlib_Option.getOr(eventConfig.discriminator, "0x"));
|
|
249
|
+
let argsJson = Stdlib_Option.mapOr(rawJson.args, "{}", args => JSON.stringify(args));
|
|
250
|
+
let logs = Stdlib_Option.map(rawJson.logs, logs => logs.map(log => ({
|
|
251
|
+
kind: Stdlib_Null.fromOption(log.kind),
|
|
252
|
+
message: Stdlib_Null.fromOption(log.message)
|
|
253
|
+
})));
|
|
254
|
+
let liveRegistrations = liveRegistrationsFor(config, chainId, eventConfig);
|
|
255
|
+
if (Utils.$$Array.isEmpty(liveRegistrations)) {
|
|
256
|
+
Stdlib_JsError.throwWithMessage(`simulate: no handler runs for instruction "` + match$2 + `" on program "` + match$1 + `". Register a handler with indexer.onInstruction before simulating it.`);
|
|
257
|
+
}
|
|
258
|
+
svmTxs.push({
|
|
259
|
+
slot: slot,
|
|
260
|
+
transactionIndex: transactionIndex,
|
|
261
|
+
signature: transaction.signature,
|
|
262
|
+
allSignatures: transaction.allSignatures,
|
|
263
|
+
feePayer: transaction.feePayer,
|
|
264
|
+
success: transaction.success,
|
|
265
|
+
err: transaction.err,
|
|
266
|
+
fee: transaction.fee,
|
|
267
|
+
computeUnitsConsumed: transaction.computeUnitsConsumed,
|
|
268
|
+
accountKeys: transaction.accountKeys,
|
|
269
|
+
recentBlockhash: transaction.recentBlockhash,
|
|
270
|
+
version: transaction.version
|
|
271
|
+
});
|
|
272
|
+
let rows = transaction.accountActivities;
|
|
273
|
+
if (rows !== undefined) {
|
|
274
|
+
rows.forEach(activity => {
|
|
275
|
+
svmActivities.push({
|
|
276
|
+
slot: slot,
|
|
277
|
+
transactionIndex: transactionIndex,
|
|
278
|
+
account: activity.address,
|
|
279
|
+
accountIndex: activity.transactionAccountIndex,
|
|
280
|
+
isSigner: activity.isSigner,
|
|
281
|
+
isWritable: activity.isWritable,
|
|
282
|
+
preBalance: Stdlib_Option.flatMap(activity.lamports, l => l.pre),
|
|
283
|
+
postBalance: Stdlib_Option.flatMap(activity.lamports, l => l.post),
|
|
284
|
+
mint: Stdlib_Option.flatMap(activity.token, t => t.mint),
|
|
285
|
+
owner: Stdlib_Option.flatMap(activity.token, t => t.owner),
|
|
286
|
+
decimals: Stdlib_Option.flatMap(activity.token, t => t.decimals),
|
|
287
|
+
preAmount: Stdlib_Option.flatMap(activity.token, t => t.preAmount),
|
|
288
|
+
postAmount: Stdlib_Option.flatMap(activity.token, t => t.postAmount)
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
let block = rawJson.block;
|
|
293
|
+
let blockTime = block !== undefined ? block.time : undefined;
|
|
294
|
+
let block$1 = rawJson.block;
|
|
295
|
+
let blockHash = block$1 !== undefined ? block$1.hash : undefined;
|
|
296
|
+
svmBlocks.push({
|
|
297
|
+
blockNumber: slot,
|
|
298
|
+
blockHash: blockHash,
|
|
299
|
+
blockTimestamp: blockTime
|
|
300
|
+
});
|
|
301
|
+
liveRegistrations.forEach(reg => {
|
|
302
|
+
let onEventRegistrationIndex = onEventRegistrations.length;
|
|
303
|
+
let newrecord = {...reg};
|
|
304
|
+
newrecord.index = onEventRegistrationIndex;
|
|
305
|
+
onEventRegistrations.push(newrecord);
|
|
306
|
+
let payload = SvmHyperSyncSource.toSvmInstruction({
|
|
307
|
+
onEventRegistrationIndex: onEventRegistrationIndex,
|
|
308
|
+
slot: slot,
|
|
309
|
+
transactionIndex: transactionIndex,
|
|
310
|
+
path: path,
|
|
311
|
+
programId: programId,
|
|
312
|
+
accounts: accountArguments,
|
|
313
|
+
data: data,
|
|
314
|
+
isInner: Stdlib_Option.getOr(rawJson.isInner, false),
|
|
315
|
+
argsJson: argsJson,
|
|
316
|
+
logs: Stdlib_Null.fromOption(logs)
|
|
317
|
+
}, match$1, match$2, eventConfig, newrecord.fieldSelection);
|
|
318
|
+
payload["srcAddress"] = programId;
|
|
319
|
+
items.push({
|
|
320
|
+
kind: 0,
|
|
321
|
+
onEventRegistration: newrecord,
|
|
322
|
+
chainId: chainId,
|
|
323
|
+
blockNumber: slot,
|
|
324
|
+
logIndex: transactionIndex,
|
|
325
|
+
orderPath: path,
|
|
326
|
+
transactionIndex: transactionIndex,
|
|
327
|
+
payload: payload
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
return;
|
|
190
331
|
}
|
|
191
|
-
let
|
|
192
|
-
let
|
|
332
|
+
let match$3 = rawJson.contract;
|
|
333
|
+
let match$4 = rawJson.event;
|
|
334
|
+
let match$5 = match$3 !== undefined && match$4 !== undefined ? [
|
|
335
|
+
match$3,
|
|
336
|
+
match$4
|
|
337
|
+
] : Stdlib_JsError.throwWithMessage(`simulate: Invalid item. Each item must have "contract" and "event" fields.`);
|
|
338
|
+
let eventName = match$5[1];
|
|
339
|
+
let contractName = match$5[0];
|
|
340
|
+
let ec$1 = findEventConfig(config, contractName, eventName);
|
|
341
|
+
let eventConfig$1 = ec$1 !== undefined ? ec$1 : Stdlib_JsError.throwWithMessage(`simulate: Event "` + eventName + `" not found on contract "` + contractName + `". Check that the contract and event names match your config.yaml.`);
|
|
193
342
|
let json = rawJson.params;
|
|
194
343
|
let paramsJson = json !== undefined ? json : ({});
|
|
195
|
-
let params = S$RescriptSchema.convertOrThrow(paramsJson, eventConfig.simulateParamsSchema);
|
|
344
|
+
let params = S$RescriptSchema.convertOrThrow(paramsJson, eventConfig$1.simulateParamsSchema);
|
|
196
345
|
let li = rawJson.logIndex;
|
|
197
346
|
let logIndex;
|
|
198
347
|
if (li !== undefined) {
|
|
@@ -205,45 +354,45 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
205
354
|
currentLogIndex.contents = li$1 + 1 | 0;
|
|
206
355
|
logIndex = li$1;
|
|
207
356
|
}
|
|
208
|
-
let srcAddress = deriveSrcAddress(rawJson.srcAddress, eventConfig, chainConfig, config);
|
|
209
|
-
let blockJson = rawJson.block;
|
|
210
|
-
let blockJson$
|
|
357
|
+
let srcAddress = deriveSrcAddress(rawJson.srcAddress, eventConfig$1, chainConfig, config);
|
|
358
|
+
let blockJson$1 = rawJson.block;
|
|
359
|
+
let blockJson$2 = (blockJson$1 == null) ? undefined : Primitive_option.some(blockJson$1);
|
|
211
360
|
let transactionJson = rawJson.transaction;
|
|
212
361
|
let transactionJson$1 = (transactionJson == null) ? undefined : Primitive_option.some(transactionJson);
|
|
213
|
-
let match$
|
|
214
|
-
let match$
|
|
215
|
-
switch (match$
|
|
362
|
+
let match$6 = config.ecosystem.name;
|
|
363
|
+
let match$7;
|
|
364
|
+
switch (match$6) {
|
|
216
365
|
case "evm" :
|
|
217
|
-
let block = parseEvmSimulateBlock(currentBlock.contents, blockJson$
|
|
218
|
-
match$
|
|
219
|
-
block,
|
|
220
|
-
block.number
|
|
366
|
+
let block$2 = parseEvmSimulateBlock(currentBlock.contents, blockJson$2);
|
|
367
|
+
match$7 = [
|
|
368
|
+
block$2,
|
|
369
|
+
block$2.number
|
|
221
370
|
];
|
|
222
371
|
break;
|
|
223
372
|
case "fuel" :
|
|
224
|
-
let block$
|
|
225
|
-
match$
|
|
226
|
-
block$
|
|
227
|
-
block$
|
|
373
|
+
let block$3 = parseFuelSimulateBlock(currentBlock.contents, blockJson$2);
|
|
374
|
+
match$7 = [
|
|
375
|
+
block$3,
|
|
376
|
+
block$3.height
|
|
228
377
|
];
|
|
229
378
|
break;
|
|
230
379
|
case "svm" :
|
|
231
|
-
match$
|
|
380
|
+
match$7 = Stdlib_JsError.throwWithMessage("simulate is not supported for SVM ecosystem");
|
|
232
381
|
break;
|
|
233
382
|
}
|
|
234
|
-
let blockNumber = match$
|
|
235
|
-
let block$
|
|
236
|
-
let match$
|
|
237
|
-
let transaction;
|
|
238
|
-
switch (match$
|
|
383
|
+
let blockNumber = match$7[1];
|
|
384
|
+
let block$4 = match$7[0];
|
|
385
|
+
let match$8 = config.ecosystem.name;
|
|
386
|
+
let transaction$1;
|
|
387
|
+
switch (match$8) {
|
|
239
388
|
case "evm" :
|
|
240
|
-
transaction = parseEvmSimulateTransaction(transactionJson$1);
|
|
389
|
+
transaction$1 = parseEvmSimulateTransaction(transactionJson$1);
|
|
241
390
|
break;
|
|
242
391
|
case "fuel" :
|
|
243
|
-
transaction = parseFuelSimulateTransaction(transactionJson$1);
|
|
392
|
+
transaction$1 = parseFuelSimulateTransaction(transactionJson$1);
|
|
244
393
|
break;
|
|
245
394
|
case "svm" :
|
|
246
|
-
transaction = Stdlib_JsError.throwWithMessage("simulate is not supported for SVM ecosystem");
|
|
395
|
+
transaction$1 = Stdlib_JsError.throwWithMessage("simulate is not supported for SVM ecosystem");
|
|
247
396
|
break;
|
|
248
397
|
}
|
|
249
398
|
currentBlock.contents = blockNumber;
|
|
@@ -254,20 +403,20 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
254
403
|
} else {
|
|
255
404
|
seenCoordinates[coordinate] = itemIndex;
|
|
256
405
|
}
|
|
257
|
-
let liveRegistrations = HandlerRegister.getSimulateOnEventRegistrations(config, chainId, eventConfig).filter(reg => {
|
|
406
|
+
let liveRegistrations$1 = HandlerRegister.getSimulateOnEventRegistrations(config, chainId, eventConfig$1).filter(reg => {
|
|
258
407
|
if (Stdlib_Option.isSome(reg.handler) || Stdlib_Option.isSome(reg.contractRegister)) {
|
|
259
408
|
return !HandlerRegister.isDroppedByWhere(config, reg);
|
|
260
409
|
} else {
|
|
261
410
|
return false;
|
|
262
411
|
}
|
|
263
412
|
});
|
|
264
|
-
if (Utils.$$Array.isEmpty(liveRegistrations)) {
|
|
265
|
-
let match$
|
|
266
|
-
Stdlib_JsError.throwWithMessage(`simulate: no handler runs for event "` +
|
|
267
|
-
match$
|
|
413
|
+
if (Utils.$$Array.isEmpty(liveRegistrations$1)) {
|
|
414
|
+
let match$9 = ChainMap.values(config.chainMap).length;
|
|
415
|
+
Stdlib_JsError.throwWithMessage(`simulate: no handler runs for event "` + eventName + `" on contract "` + contractName + `"` + (
|
|
416
|
+
match$9 !== 1 ? ` on chain ` + ChainId.toString(chainId) : ""
|
|
268
417
|
) + `. Register a handler with indexer.onEvent (and check any \`where\` filter isn't excluding this chain) before simulating it.`);
|
|
269
418
|
}
|
|
270
|
-
liveRegistrations.forEach(reg => {
|
|
419
|
+
liveRegistrations$1.forEach(reg => {
|
|
271
420
|
let onEventRegistrationIndex = onEventRegistrations.length;
|
|
272
421
|
let newrecord = {...reg};
|
|
273
422
|
newrecord.index = onEventRegistrationIndex;
|
|
@@ -280,19 +429,34 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
280
429
|
logIndex: logIndex,
|
|
281
430
|
transactionIndex: 0,
|
|
282
431
|
payload: {
|
|
283
|
-
contractName: eventConfig.contractName,
|
|
284
|
-
eventName: eventConfig.name,
|
|
432
|
+
contractName: eventConfig$1.contractName,
|
|
433
|
+
eventName: eventConfig$1.name,
|
|
285
434
|
params: params,
|
|
286
435
|
chainId: chainId,
|
|
287
436
|
srcAddress: srcAddress,
|
|
288
437
|
logIndex: logIndex,
|
|
289
|
-
transaction: Primitive_option.some(transaction),
|
|
290
|
-
block: Primitive_option.some(block$
|
|
438
|
+
transaction: Primitive_option.some(transaction$1),
|
|
439
|
+
block: Primitive_option.some(block$4)
|
|
291
440
|
}
|
|
292
441
|
});
|
|
293
442
|
});
|
|
294
443
|
});
|
|
295
|
-
|
|
444
|
+
let match = config.ecosystem.name;
|
|
445
|
+
switch (match) {
|
|
446
|
+
case "evm" :
|
|
447
|
+
case "fuel" :
|
|
448
|
+
return {
|
|
449
|
+
items: items,
|
|
450
|
+
transactionStore: undefined,
|
|
451
|
+
blockStore: undefined
|
|
452
|
+
};
|
|
453
|
+
case "svm" :
|
|
454
|
+
return {
|
|
455
|
+
items: items,
|
|
456
|
+
transactionStore: Primitive_option.some(TransactionStore.fromSvmJs(svmTxs, svmActivities)),
|
|
457
|
+
blockStore: Primitive_option.some(BlockStore.fromJs(svmBlocks, "svm", false))
|
|
458
|
+
};
|
|
459
|
+
}
|
|
296
460
|
}
|
|
297
461
|
|
|
298
462
|
function patchConfig(config, processConfig, registrationsByChainId) {
|
|
@@ -329,12 +493,14 @@ function patchConfig(config, processConfig, registrationsByChainId) {
|
|
|
329
493
|
let newrecord = {...chainConfig};
|
|
330
494
|
newrecord.endBlock = endBlock;
|
|
331
495
|
newrecord.startBlock = startBlock;
|
|
332
|
-
let
|
|
496
|
+
let match = parse(simulateRaw, config, newrecord, chainRegistrations.onEventRegistrations);
|
|
333
497
|
let newrecord$1 = {...newrecord};
|
|
334
498
|
newrecord$1.sourceConfig = {
|
|
335
499
|
TAG: "SimulateSourceConfig",
|
|
336
|
-
items: items,
|
|
337
|
-
endBlock: endBlock
|
|
500
|
+
items: match.items,
|
|
501
|
+
endBlock: endBlock,
|
|
502
|
+
transactionStore: match.transactionStore,
|
|
503
|
+
blockStore: match.blockStore
|
|
338
504
|
};
|
|
339
505
|
return newrecord$1;
|
|
340
506
|
});
|
|
@@ -356,6 +522,7 @@ export {
|
|
|
356
522
|
dummySrcAddress,
|
|
357
523
|
firstContractAddress,
|
|
358
524
|
deriveSrcAddress,
|
|
525
|
+
liveRegistrationsFor,
|
|
359
526
|
parse,
|
|
360
527
|
patchConfig,
|
|
361
528
|
}
|