@sentio/sdk 2.43.3-rc.3 → 2.44.0-rc.10

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.
Files changed (65) hide show
  1. package/lib/btc/btc-plugin.d.ts +3 -1
  2. package/lib/btc/btc-plugin.d.ts.map +1 -1
  3. package/lib/btc/btc-plugin.js +41 -3
  4. package/lib/btc/btc-plugin.js.map +1 -1
  5. package/lib/btc/btc-processor.d.ts +7 -2
  6. package/lib/btc/btc-processor.d.ts.map +1 -1
  7. package/lib/btc/btc-processor.js +40 -1
  8. package/lib/btc/btc-processor.js.map +1 -1
  9. package/lib/btc/types.d.ts +29 -10
  10. package/lib/btc/types.d.ts.map +1 -1
  11. package/lib/btc/types.js +29 -0
  12. package/lib/btc/types.js.map +1 -1
  13. package/lib/fuel/asset-processor.d.ts.map +1 -1
  14. package/lib/fuel/asset-processor.js +7 -1
  15. package/lib/fuel/asset-processor.js.map +1 -1
  16. package/lib/fuel/base-processor.d.ts.map +1 -1
  17. package/lib/fuel/base-processor.js +2 -3
  18. package/lib/fuel/base-processor.js.map +1 -1
  19. package/lib/fuel/codegen/codegen.js +50 -9
  20. package/lib/fuel/codegen/codegen.js.map +1 -1
  21. package/lib/fuel/context.d.ts +6 -6
  22. package/lib/fuel/context.d.ts.map +1 -1
  23. package/lib/fuel/context.js.map +1 -1
  24. package/lib/fuel/fuel-processor-template.d.ts +42 -0
  25. package/lib/fuel/fuel-processor-template.d.ts.map +1 -0
  26. package/lib/fuel/fuel-processor-template.js +109 -0
  27. package/lib/fuel/fuel-processor-template.js.map +1 -0
  28. package/lib/fuel/fuel-processor.d.ts +5 -2
  29. package/lib/fuel/fuel-processor.d.ts.map +1 -1
  30. package/lib/fuel/fuel-processor.js +26 -1
  31. package/lib/fuel/fuel-processor.js.map +1 -1
  32. package/lib/fuel/global-processor.d.ts.map +1 -1
  33. package/lib/fuel/global-processor.js +7 -1
  34. package/lib/fuel/global-processor.js.map +1 -1
  35. package/lib/fuel/index.d.ts +1 -0
  36. package/lib/fuel/index.d.ts.map +1 -1
  37. package/lib/fuel/index.js +1 -0
  38. package/lib/fuel/index.js.map +1 -1
  39. package/lib/fuel/types.d.ts +2 -2
  40. package/lib/fuel/types.d.ts.map +1 -1
  41. package/lib/fuel/types.js +2 -2
  42. package/lib/fuel/types.js.map +1 -1
  43. package/lib/sui/sui-object-processor-template.d.ts +1 -0
  44. package/lib/sui/sui-object-processor-template.d.ts.map +1 -1
  45. package/lib/sui/sui-object-processor-template.js +63 -4
  46. package/lib/sui/sui-object-processor-template.js.map +1 -1
  47. package/lib/sui/sui-object-processor.d.ts +1 -0
  48. package/lib/sui/sui-object-processor.d.ts.map +1 -1
  49. package/lib/sui/sui-object-processor.js +1 -0
  50. package/lib/sui/sui-object-processor.js.map +1 -1
  51. package/package.json +3 -3
  52. package/src/btc/btc-plugin.ts +50 -3
  53. package/src/btc/btc-processor.ts +79 -2
  54. package/src/btc/types.ts +51 -10
  55. package/src/fuel/asset-processor.ts +8 -1
  56. package/src/fuel/base-processor.ts +3 -3
  57. package/src/fuel/codegen/codegen.ts +55 -11
  58. package/src/fuel/context.ts +4 -4
  59. package/src/fuel/fuel-processor-template.ts +161 -0
  60. package/src/fuel/fuel-processor.ts +32 -3
  61. package/src/fuel/global-processor.ts +8 -2
  62. package/src/fuel/index.ts +1 -0
  63. package/src/fuel/types.ts +2 -2
  64. package/src/sui/sui-object-processor-template.ts +79 -4
  65. package/src/sui/sui-object-processor.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentio/sdk",
3
- "version": "2.43.3-rc.3",
3
+ "version": "2.44.0-rc.10",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -84,8 +84,8 @@
84
84
  "typechain": "^8.3.2",
85
85
  "utility-types": "^3.11.0",
86
86
  "yaml": "^2.3.4",
87
- "@sentio/protos": "2.43.3-rc.3",
88
- "@sentio/runtime": "^2.43.3-rc.3"
87
+ "@sentio/protos": "2.44.0-rc.10",
88
+ "@sentio/runtime": "^2.44.0-rc.10"
89
89
  },
90
90
  "peerDependencies": {
91
91
  "tsup": "npm:@sentio/tsup@^6.7.5"
@@ -1,6 +1,7 @@
1
1
  import { errorString, GLOBAL_CONFIG, mergeProcessResults, Plugin, PluginManager, USER_PROCESSOR } from '@sentio/runtime'
2
2
  import {
3
3
  ContractConfig,
4
+ Data_BTCBlock,
4
5
  Data_BTCTransaction,
5
6
  DataBinding,
6
7
  HandlerType,
@@ -16,17 +17,20 @@ import { filters2Proto, TransactionFilter } from './filter.js'
16
17
 
17
18
  interface Handlers {
18
19
  txHandlers: ((trace: Data_BTCTransaction) => Promise<ProcessResult>)[]
20
+ blockHandlers: ((trace: Data_BTCBlock) => Promise<ProcessResult>)[]
19
21
  }
20
22
 
21
23
  export class BTCPlugin extends Plugin {
22
24
  name: string = 'BTCPlugin'
23
25
  handlers: Handlers = {
24
- txHandlers: []
26
+ txHandlers: [],
27
+ blockHandlers: []
25
28
  }
26
29
 
27
30
  async configure(config: ProcessConfigResponse) {
28
31
  const handlers: Handlers = {
29
- txHandlers: []
32
+ txHandlers: [],
33
+ blockHandlers: []
30
34
  }
31
35
 
32
36
  for (const processor of BTCProcessorState.INSTANCE.getValues()) {
@@ -61,6 +65,24 @@ export class BTCPlugin extends Plugin {
61
65
  }
62
66
  }
63
67
 
68
+ for (const blockHandler of processor.blockHandlers) {
69
+ const handlerId = handlers.blockHandlers.push(blockHandler.handler) - 1
70
+ contractConfig.intervalConfigs.push({
71
+ slot: 0,
72
+ slotInterval: blockHandler.blockInterval,
73
+ minutes: 0,
74
+ minutesInterval: blockHandler.timeIntervalInMinutes,
75
+ handlerId,
76
+ fetchConfig: {
77
+ transaction: blockHandler.fetchConfig?.getTransactions ?? false,
78
+ trace: false,
79
+ block: true,
80
+ transactionReceipt: false,
81
+ transactionReceiptLogs: false
82
+ }
83
+ })
84
+ }
85
+
64
86
  // Finish up a contract
65
87
  config.contractConfigs.push(contractConfig)
66
88
  }
@@ -68,12 +90,14 @@ export class BTCPlugin extends Plugin {
68
90
  this.handlers = handlers
69
91
  }
70
92
 
71
- supportedHandlers = [HandlerType.BTC_TRANSACTION]
93
+ supportedHandlers = [HandlerType.BTC_TRANSACTION, HandlerType.BTC_BLOCK]
72
94
 
73
95
  processBinding(request: DataBinding): Promise<ProcessResult> {
74
96
  switch (request.handlerType) {
75
97
  case HandlerType.BTC_TRANSACTION:
76
98
  return this.processTransaction(request)
99
+ case HandlerType.BTC_BLOCK:
100
+ return this.processBlock(request)
77
101
  default:
78
102
  throw new ServerError(Status.INVALID_ARGUMENT, 'No handle type registered ' + request.handlerType)
79
103
  }
@@ -108,6 +132,29 @@ export class BTCPlugin extends Plugin {
108
132
  }
109
133
  return mergeProcessResults(await Promise.all(promises))
110
134
  }
135
+
136
+ private async processBlock(request: DataBinding) {
137
+ if (!request.data?.btcBlock) {
138
+ throw new ServerError(Status.INVALID_ARGUMENT, "Block can't be empty")
139
+ }
140
+
141
+ const block = request.data.btcBlock
142
+
143
+ const promises: Promise<ProcessResult>[] = []
144
+ for (const handlerId of request.handlerIds) {
145
+ const promise = this.handlers.blockHandlers[handlerId](block).catch((e) => {
146
+ throw new ServerError(
147
+ Status.INTERNAL,
148
+ 'error processing block: ' + JSON.stringify(block) + '\n' + errorString(e)
149
+ )
150
+ })
151
+ if (GLOBAL_CONFIG.execution.sequential) {
152
+ await promise
153
+ }
154
+ promises.push(promise)
155
+ }
156
+ return mergeProcessResults(await Promise.all(promises))
157
+ }
111
158
  }
112
159
 
113
160
  PluginManager.INSTANCE.register(new BTCPlugin())
@@ -1,7 +1,9 @@
1
1
  import { ListStateStorage } from '@sentio/runtime'
2
- import { BTCContext, Transaction } from './types.js'
3
- import { Data_BTCTransaction, ProcessResult } from '@sentio/protos'
2
+ import { BlockHandler, BTCBlock, BTCBlockContext, BTCContext, BTCOnIntervalFetchConfig, Transaction } from './types.js'
3
+ import { Data_BTCBlock, Data_BTCTransaction, HandleInterval, ProcessResult } from '@sentio/protos'
4
4
  import { TransactionFilters } from './filter.js'
5
+ import { PromiseOrVoid } from '../core/index.js'
6
+ import { ServerError, Status } from 'nice-grpc'
5
7
 
6
8
  export class BTCProcessorState extends ListStateStorage<BTCProcessor> {
7
9
  static INSTANCE = new BTCProcessorState()
@@ -9,6 +11,7 @@ export class BTCProcessorState extends ListStateStorage<BTCProcessor> {
9
11
 
10
12
  export class BTCProcessor {
11
13
  callHandlers: CallHandler<Data_BTCTransaction>[] = []
14
+ blockHandlers: BlockHandler[] = []
12
15
 
13
16
  constructor(readonly config: BTCProcessorConfig) {}
14
17
 
@@ -40,6 +43,80 @@ export class BTCProcessor {
40
43
  this.callHandlers.push(callHandler)
41
44
  return this
42
45
  }
46
+
47
+ public onInterval(
48
+ handler: (block: BTCBlock, ctx: BTCBlockContext) => PromiseOrVoid,
49
+ timeInterval: HandleInterval | undefined,
50
+ blockInterval: HandleInterval | undefined,
51
+ fetchConfig?: BTCOnIntervalFetchConfig
52
+ ): this {
53
+ if (timeInterval) {
54
+ if (timeInterval.backfillInterval < timeInterval.recentInterval) {
55
+ timeInterval.backfillInterval = timeInterval.recentInterval
56
+ }
57
+ }
58
+
59
+ const processor = this
60
+
61
+ this.blockHandlers.push({
62
+ blockInterval,
63
+ timeIntervalInMinutes: timeInterval,
64
+ handler: async function (data: Data_BTCBlock) {
65
+ const header = data.block
66
+ if (!header) {
67
+ throw new ServerError(Status.INVALID_ARGUMENT, 'Block is empty')
68
+ }
69
+
70
+ const block = {
71
+ ...header
72
+ } as BTCBlock
73
+ if (fetchConfig?.getTransactions) {
74
+ block.tx = header.rawtx?.map((tx: any) => tx as Transaction)
75
+ }
76
+
77
+ const ctx = new BTCBlockContext(
78
+ processor.config.chainId,
79
+ processor.config.name ?? processor.config.address ?? '',
80
+ block,
81
+ processor.config.address
82
+ )
83
+ await handler(block, ctx)
84
+ return ctx.stopAndGetResult()
85
+ }
86
+ })
87
+ return this
88
+ }
89
+
90
+ public onBlockInterval(
91
+ handler: (block: BTCBlock, ctx: BTCBlockContext) => PromiseOrVoid,
92
+ blockInterval = 250,
93
+ backfillBlockInterval = 1000,
94
+ fetchConfig?: BTCOnIntervalFetchConfig
95
+ ): this {
96
+ return this.onInterval(
97
+ handler,
98
+ undefined,
99
+ {
100
+ recentInterval: blockInterval,
101
+ backfillInterval: backfillBlockInterval
102
+ },
103
+ fetchConfig
104
+ )
105
+ }
106
+
107
+ public onTimeInterval(
108
+ handler: (block: BTCBlock, ctx: BTCBlockContext) => PromiseOrVoid,
109
+ timeIntervalInMinutes = 60,
110
+ backfillTimeIntervalInMinutes = 240,
111
+ fetchConfig?: BTCOnIntervalFetchConfig
112
+ ): this {
113
+ return this.onInterval(
114
+ handler,
115
+ { recentInterval: timeIntervalInMinutes, backfillInterval: backfillTimeIntervalInMinutes },
116
+ undefined,
117
+ fetchConfig
118
+ )
119
+ }
43
120
  }
44
121
 
45
122
  interface BTCProcessorConfig {
package/src/btc/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BaseContext, Labels, normalizeLabels } from '../core/index.js'
2
- import { RecordMetaData } from '@sentio/protos'
2
+ import { Data_BTCBlock, HandleInterval, ProcessResult, RecordMetaData } from '@sentio/protos'
3
3
  import { ChainId } from '@sentio/chain'
4
4
 
5
5
  export type Transaction = {
@@ -44,21 +44,22 @@ export type Vout = {
44
44
  }
45
45
  }
46
46
 
47
- export type Block = {
48
- block_hash: string
49
- block_number: number
50
- block_timestamp: Date
47
+ export type BTCBlock = {
48
+ hash: string
49
+ confirmations: number
50
+ strippedsize: number
51
51
  size: number
52
- stripped_size: number
53
52
  weight: number
53
+ height: number
54
54
  version: number
55
- merkle_root: string
55
+ merkleroot: string
56
+ tx?: Transaction[]
57
+ time: number
56
58
  nonce: number
57
59
  bits: string
58
60
  difficulty: number
59
- previous_hash: string
60
- next_hash: string
61
- transaction_count: number
61
+ previousblockhash: string
62
+ nextblockhash: string
62
63
  }
63
64
 
64
65
  export class BTCContext extends BaseContext {
@@ -89,3 +90,43 @@ export class BTCContext extends BaseContext {
89
90
  return this.chainId as ChainId
90
91
  }
91
92
  }
93
+
94
+ export class BTCBlockContext extends BaseContext {
95
+ constructor(
96
+ readonly chainId: string,
97
+ readonly name: string,
98
+ readonly block: BTCBlock,
99
+ readonly address?: string
100
+ ) {
101
+ super({})
102
+ }
103
+
104
+ protected getMetaDataInternal(name: string, labels: Labels): RecordMetaData {
105
+ return {
106
+ address: this.address ?? '',
107
+ contractName: this.name,
108
+ blockNumber: BigInt(this.block.height ?? 0),
109
+ transactionIndex: 0,
110
+ transactionHash: '',
111
+ chainId: this.getChainId(),
112
+ name: name,
113
+ logIndex: 0,
114
+ labels: normalizeLabels(labels)
115
+ }
116
+ }
117
+
118
+ getChainId(): ChainId {
119
+ return this.chainId as ChainId
120
+ }
121
+ }
122
+
123
+ export type BlockHandler = {
124
+ blockInterval?: HandleInterval
125
+ timeIntervalInMinutes?: HandleInterval
126
+ handler: (block: Data_BTCBlock) => Promise<ProcessResult>
127
+ fetchConfig?: BTCOnIntervalFetchConfig
128
+ }
129
+
130
+ export type BTCOnIntervalFetchConfig = {
131
+ getTransactions: boolean
132
+ }
@@ -4,6 +4,7 @@ import { FuelNetwork, getRpcEndpoint } from './network.js'
4
4
  import { FuelContext } from './context.js'
5
5
  import { decodeFuelTransaction } from './transaction.js'
6
6
  import { Provider, InputType, OutputType } from 'fuels'
7
+ import { getOptionsSignature } from './fuel-processor.js'
7
8
 
8
9
  export class FuelAssetProcessor implements FuelBaseProcessor<FuelAssetProcessorConfig> {
9
10
  callHandlers: CallHandler<Data_FuelCall>[] = []
@@ -12,7 +13,13 @@ export class FuelAssetProcessor implements FuelBaseProcessor<FuelAssetProcessorC
12
13
 
13
14
  static bind(config: FuelAssetProcessorConfig): FuelAssetProcessor {
14
15
  const processor = new FuelAssetProcessor(config)
15
- FuelProcessorState.INSTANCE.addValue(processor)
16
+ const sig =
17
+ 'assets_' +
18
+ getOptionsSignature({
19
+ ...config,
20
+ address: '*'
21
+ })
22
+ FuelProcessorState.INSTANCE.getOrSetValue(sig, processor)
16
23
  return processor
17
24
  }
18
25
 
@@ -1,8 +1,8 @@
1
- import { FuelProcessor, FuelProcessorConfig } from './fuel-processor.js'
1
+ import { addFuelProcessor, FuelProcessor, FuelProcessorConfig } from './fuel-processor.js'
2
2
  import { Contract, JsonAbi } from 'fuels'
3
3
  // import { FuelCall } from './context.js'
4
4
  import { FuelChainId } from '@sentio/chain'
5
- import { FuelLog, FuelProcessorState } from './types.js'
5
+ import { FuelLog } from './types.js'
6
6
 
7
7
  export abstract class FuelAbstractProcessor<TContract extends Contract> extends FuelProcessor<TContract> {
8
8
  protected constructor(abi: JsonAbi, config?: Omit<FuelProcessorConfig, 'abi'>) {
@@ -16,7 +16,7 @@ export abstract class FuelAbstractProcessor<TContract extends Contract> extends
16
16
  ...config,
17
17
  abi
18
18
  })
19
- FuelProcessorState.INSTANCE.addValue(this)
19
+ addFuelProcessor(config, this)
20
20
  }
21
21
  }
22
22
 
@@ -115,7 +115,7 @@ async function codegenInternal(abisDir: string, outDir: string): Promise<number>
115
115
  /* tslint:disable */
116
116
  /* eslint-disable */
117
117
 
118
- import { FuelAbstractProcessor, FuelContractContext, FuelProcessorConfig, TypedCall, FuelFetchConfig, FuelCall, FuelLog} from '@sentio/sdk/fuel'
118
+ import { FuelAbstractProcessor, FuelContractContext, FuelProcessorConfig, TypedCall, FuelFetchConfig, FuelCall, FuelLog, addFuelProcessor, getFuelProcessor, FuelBaseProcessorTemplate } from '@sentio/sdk/fuel'
119
119
  import {${abi.commonTypesInUse.join(',')}} from './common.js'
120
120
  import {${importedTypes.join(',')}, ${abi.capitalizedName}} from './${abi.capitalizedName}.js'
121
121
 
@@ -144,12 +144,23 @@ ${
144
144
  }
145
145
  }
146
146
 
147
+ type LogIdFilter<T> = T | T[]
148
+ ${getLogConstants(logByTypes)}
149
+
147
150
  export class ${name}Processor extends FuelAbstractProcessor<${name}> {
148
- static bind(config: Omit<FuelProcessorConfig, 'abi'>) {
149
- return new ${name}Processor(${abi.capitalizedName}.abi, {
150
- name: '${name}',
151
- ...config,
152
- })
151
+ static bind(options: Omit<FuelProcessorConfig, 'abi'>) {
152
+ if (!options.name) {
153
+ options.name = "${name}"
154
+ }
155
+ let processor = getFuelProcessor(options) as ${name}Processor
156
+ if (!processor) {
157
+ processor = new ${name}Processor(${abi.capitalizedName}.abi, {
158
+ name: '${name}',
159
+ ...options,
160
+ })
161
+ addFuelProcessor(options, processor)
162
+ }
163
+ return processor
153
164
  }
154
165
 
155
166
  ${
@@ -158,11 +169,22 @@ ${
158
169
  abi.functions.map((f) => genOnCallFunction(name, f)).join('\n') */
159
170
  }
160
171
 
161
- ${Object.entries(logByTypes)
162
- .map((e) => genOnLogFunction(name, e))
163
- .join('\n')}
172
+ ${Object.entries(logByTypes)
173
+ .map((e) => genOnLogFunction(name, e))
174
+ .join('\n')}
175
+
176
+ }
177
+
178
+ export class ${name}ProcessorTemplate extends FuelBaseProcessorTemplate<${name}> {
179
+ bindInternal(options: Omit<FuelProcessorConfig, 'abi'>) {
180
+ return ${name}Processor.bind(options)
181
+ }
164
182
 
183
+ ${Object.entries(logByTypes)
184
+ .map((e) => genOnLogFunction(name, e))
185
+ .join('\n')}
165
186
  }
187
+
166
188
  `
167
189
  writeFileSync(filePath, content)
168
190
  count++
@@ -215,11 +237,33 @@ function collectImportedTypes(types: any[]): string[] {
215
237
  return Array.from(ret)
216
238
  }
217
239
 
240
+ function getLogConstants(logByTypes: Record<string, string[]>) {
241
+ return Object.entries(logByTypes)
242
+ .map(([t, ids]) => {
243
+ const name = getTypeName(t)
244
+ if (ids.length == 1) {
245
+ return `const Log${name}Id = "${ids[0]}"`
246
+ }
247
+ return ids.map((id, idx) => `const Log${name}Id${idx} = "${id}"`).join('\n')
248
+ })
249
+ .join('\n')
250
+ }
251
+
218
252
  function genOnLogFunction(contractName: string, [type, ids]: [string, string[]]) {
219
253
  const name = getTypeName(type)
254
+
255
+ if (ids.length == 1) {
256
+ return `
257
+ onLog${name}(handler: (log: FuelLog<${type}>, ctx: FuelContractContext<${contractName}>) => void | Promise<void>) {
258
+ return super.onLog<${type}>([Log${name}Id], (log, ctx) => handler(log, ctx))
259
+ }`
260
+ }
261
+ const logIdFilterValues = ids.map((_, idx) => `Log${name}Id${idx}`)
262
+
220
263
  return `
221
- onLog${name}(handler: (log: FuelLog<${type}>, ctx: FuelContractContext<${contractName}>) => void | Promise<void>, logIdFilter?: string | string[]) {
222
- return super.onLog<${type}>(logIdFilter ?? [${ids.map((id) => `"${id}"`).join(', ')}], (log, ctx) => handler(log, ctx))
264
+ onLog${name}(handler: (log: FuelLog<${type}>, ctx: FuelContractContext<${contractName}>) => void | Promise<void>,
265
+ logIdFilter?: LogIdFilter<${logIdFilterValues.map((d) => `typeof ${d}`).join(' | ')}> ) {
266
+ return super.onLog<${type}>(logIdFilter ?? [${logIdFilterValues.join(', ')}], (log, ctx) => handler(log, ctx))
223
267
  }`
224
268
  }
225
269
 
@@ -1,5 +1,5 @@
1
1
  import { BaseContext, Labels, normalizeLabels } from '../core/index.js'
2
- import { ChainId } from '@sentio/chain'
2
+ import { FuelChainId } from '@sentio/chain'
3
3
  import { RecordMetaData } from '@sentio/protos'
4
4
  import type { CallResult, Contract } from 'fuels'
5
5
  import { InvocationScopeLike } from 'fuels'
@@ -20,7 +20,7 @@ export class FuelCall {
20
20
  export class FuelContext extends BaseContext {
21
21
  private logIndex: number = -1
22
22
  constructor(
23
- readonly chainId: ChainId,
23
+ readonly chainId: FuelChainId,
24
24
  readonly contractAddress: string,
25
25
  readonly contractName: string,
26
26
  readonly timestamp: Date,
@@ -30,7 +30,7 @@ export class FuelContext extends BaseContext {
30
30
  super({})
31
31
  }
32
32
 
33
- getChainId(): ChainId {
33
+ getChainId(): FuelChainId {
34
34
  return this.chainId
35
35
  }
36
36
 
@@ -55,7 +55,7 @@ export class FuelContext extends BaseContext {
55
55
 
56
56
  export class FuelContractContext<TContract extends Contract> extends FuelContext {
57
57
  constructor(
58
- readonly chainId: ChainId,
58
+ readonly chainId: FuelChainId,
59
59
  readonly contract: TContract,
60
60
  readonly contractAddress: string,
61
61
  readonly contractName: string,
@@ -0,0 +1,161 @@
1
+ import { FuelContext, FuelContractContext } from './context.js'
2
+ import { HandleInterval, TemplateInstance } from '@sentio/protos'
3
+ import { PromiseOrVoid } from '../core/promises.js'
4
+ import { ListStateStorage } from '@sentio/runtime'
5
+ import { TemplateInstanceState } from '../core/template.js'
6
+ import { Contract } from 'fuels'
7
+ import { FuelBlock, FuelLog, FuelTransaction } from './types.js'
8
+ import { DEFAULT_FUEL_FETCH_CONFIG, FuelFetchConfig } from './transaction.js'
9
+ import { FuelProcessor, FuelProcessorConfig, getOptionsSignature } from './fuel-processor.js'
10
+
11
+ export class FuelProcessorTemplateProcessorState extends ListStateStorage<FuelBaseProcessorTemplate<Contract>> {
12
+ static INSTANCE = new FuelProcessorTemplateProcessorState()
13
+ }
14
+
15
+ export abstract class FuelBaseProcessorTemplate<TContract extends Contract> {
16
+ id: number
17
+ binds = new Set<string>()
18
+ blockHandlers: {
19
+ handler: (block: FuelBlock, ctx: FuelContractContext<TContract>) => PromiseOrVoid
20
+ blockInterval?: HandleInterval
21
+ timeIntervalInMinutes?: HandleInterval
22
+ // fetchConfig?: FuelFetchConfig
23
+ }[] = []
24
+
25
+ logHandlers: {
26
+ logIdFilter: string | string[]
27
+ handler: (logs: FuelLog<any>, ctx: FuelContractContext<TContract>) => PromiseOrVoid
28
+ // fetchConfig?: FuelFetchConfig
29
+ }[] = []
30
+
31
+ transactionHandlers: {
32
+ handler: (transaction: FuelTransaction, ctx: FuelContractContext<TContract>) => PromiseOrVoid
33
+ fetchConfig: FuelFetchConfig
34
+ }[] = []
35
+
36
+ constructor() {
37
+ this.id = FuelProcessorTemplateProcessorState.INSTANCE.getValues().length
38
+ FuelProcessorTemplateProcessorState.INSTANCE.addValue(this)
39
+ }
40
+
41
+ /**
42
+ * Bind template using {@param options}, using {@param ctx}'s network value if not provided in the option
43
+ * @param options
44
+ * @param ctx
45
+ */
46
+ public bind(options: Omit<Omit<FuelProcessorConfig, 'chainId'>, 'abi'>, ctx: FuelContext): void {
47
+ const sig = getOptionsSignature({
48
+ address: options.address,
49
+ chainId: ctx.chainId
50
+ })
51
+ if (this.binds.has(sig)) {
52
+ console.log(`Same address can be bind to one template only once, ignore duplicate bind: ${sig}`)
53
+ return
54
+ }
55
+ this.binds.add(sig)
56
+
57
+ const processor = this.bindInternal({ ...options, chainId: ctx.chainId })
58
+
59
+ for (const eh of this.logHandlers) {
60
+ processor.onLog(eh.logIdFilter, eh.handler)
61
+ }
62
+ for (const bh of this.blockHandlers) {
63
+ processor.onInterval(bh.handler, bh.timeIntervalInMinutes, bh.blockInterval)
64
+ }
65
+ for (const th of this.transactionHandlers) {
66
+ processor.onTransaction(th.handler)
67
+ }
68
+
69
+ const instance: TemplateInstance = {
70
+ templateId: this.id,
71
+ contract: {
72
+ address: options.address,
73
+ name: options.name || '',
74
+ chainId: ctx.chainId,
75
+ abi: ''
76
+ },
77
+ startBlock: BigInt(options.startBlock || 0),
78
+ endBlock: BigInt(options.endBlock || 0),
79
+ baseLabels: {}
80
+ // baseLabels: options.baseLabels
81
+ }
82
+ TemplateInstanceState.INSTANCE.addValue(instance)
83
+ ctx.update({
84
+ states: {
85
+ configUpdated: true
86
+ }
87
+ })
88
+ }
89
+
90
+ protected onLog<T>(
91
+ logIdFilter: string | string[],
92
+ handler: (logs: FuelLog<T>, ctx: FuelContractContext<TContract>) => PromiseOrVoid
93
+ // fetchConfig?: Partial<FuelFetchConfig>
94
+ ) {
95
+ this.logHandlers.push({
96
+ logIdFilter,
97
+ handler
98
+ // fetchConfig: { ...fetchConfig}
99
+ })
100
+ return this
101
+ }
102
+
103
+ public onBlockInterval(
104
+ handler: (block: FuelBlock, ctx: FuelContractContext<TContract>) => PromiseOrVoid,
105
+ blockInterval = 1000,
106
+ backfillBlockInterval = 4000
107
+ // fetchConfig?: Partial<FuelFetchConfig>
108
+ ) {
109
+ return this.onInterval(
110
+ handler,
111
+ undefined,
112
+ {
113
+ recentInterval: blockInterval,
114
+ backfillInterval: backfillBlockInterval
115
+ }
116
+ // fetchConfig
117
+ )
118
+ }
119
+
120
+ public onTimeInterval(
121
+ handler: (block: FuelBlock, ctx: FuelContractContext<TContract>) => PromiseOrVoid,
122
+ timeIntervalInMinutes = 60,
123
+ backfillBlockInterval = 240
124
+ // fetchConfig?: Partial<FuelFetchConfig>
125
+ ) {
126
+ return this.onInterval(
127
+ handler,
128
+ { recentInterval: timeIntervalInMinutes, backfillInterval: backfillBlockInterval },
129
+ undefined
130
+ // fetchConfig
131
+ )
132
+ }
133
+
134
+ public onInterval(
135
+ handler: (block: FuelBlock, ctx: FuelContractContext<TContract>) => PromiseOrVoid,
136
+ timeInterval: HandleInterval | undefined,
137
+ blockInterval: HandleInterval | undefined
138
+ // fetchConfig?: FuelFetchConfig
139
+ ) {
140
+ this.blockHandlers.push({
141
+ handler,
142
+ timeIntervalInMinutes: timeInterval,
143
+ blockInterval
144
+ // fetchConfig: { ...fetchConfig }
145
+ })
146
+ return this
147
+ }
148
+
149
+ protected onTransaction(
150
+ handler: (transaction: FuelTransaction, ctx: FuelContractContext<TContract>) => PromiseOrVoid,
151
+ config: FuelFetchConfig = DEFAULT_FUEL_FETCH_CONFIG
152
+ ) {
153
+ this.transactionHandlers.push({
154
+ handler,
155
+ fetchConfig: config
156
+ })
157
+ return this
158
+ }
159
+
160
+ protected abstract bindInternal(options: Omit<FuelProcessorConfig, 'abi'>): FuelProcessor<TContract>
161
+ }