@sentio/sdk 2.36.0-rc.1 → 2.36.0-rc.11

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 (50) hide show
  1. package/lib/fuel/asset-processor.d.ts +36 -0
  2. package/lib/fuel/asset-processor.d.ts.map +1 -0
  3. package/lib/fuel/asset-processor.js +87 -0
  4. package/lib/fuel/asset-processor.js.map +1 -0
  5. package/lib/fuel/base-processor.d.ts +8 -6
  6. package/lib/fuel/base-processor.d.ts.map +1 -1
  7. package/lib/fuel/base-processor.js +14 -11
  8. package/lib/fuel/base-processor.js.map +1 -1
  9. package/lib/fuel/codegen/codegen.js +78 -15
  10. package/lib/fuel/codegen/codegen.js.map +1 -1
  11. package/lib/fuel/context.d.ts +12 -4
  12. package/lib/fuel/context.d.ts.map +1 -1
  13. package/lib/fuel/context.js +21 -7
  14. package/lib/fuel/context.js.map +1 -1
  15. package/lib/fuel/fuel-plugin.d.ts.map +1 -1
  16. package/lib/fuel/fuel-plugin.js +27 -30
  17. package/lib/fuel/fuel-plugin.js.map +1 -1
  18. package/lib/fuel/fuel-processor.d.ts +5 -11
  19. package/lib/fuel/fuel-processor.d.ts.map +1 -1
  20. package/lib/fuel/fuel-processor.js +30 -12
  21. package/lib/fuel/fuel-processor.js.map +1 -1
  22. package/lib/fuel/index.d.ts +2 -0
  23. package/lib/fuel/index.d.ts.map +1 -1
  24. package/lib/fuel/index.js +2 -0
  25. package/lib/fuel/index.js.map +1 -1
  26. package/lib/fuel/network.js +1 -1
  27. package/lib/fuel/network.js.map +1 -1
  28. package/lib/fuel/transaction.d.ts +8 -3
  29. package/lib/fuel/transaction.d.ts.map +1 -1
  30. package/lib/fuel/transaction.js +63 -15
  31. package/lib/fuel/transaction.js.map +1 -1
  32. package/lib/fuel/types.d.ts +23 -0
  33. package/lib/fuel/types.d.ts.map +1 -0
  34. package/lib/fuel/types.js +5 -0
  35. package/lib/fuel/types.js.map +1 -0
  36. package/lib/testing/fuel-facet.d.ts.map +1 -1
  37. package/lib/testing/fuel-facet.js +31 -0
  38. package/lib/testing/fuel-facet.js.map +1 -1
  39. package/package.json +9 -5
  40. package/src/fuel/asset-processor.ts +122 -0
  41. package/src/fuel/base-processor.ts +16 -21
  42. package/src/fuel/codegen/codegen.ts +93 -16
  43. package/src/fuel/context.ts +22 -8
  44. package/src/fuel/fuel-plugin.ts +24 -33
  45. package/src/fuel/fuel-processor.ts +61 -21
  46. package/src/fuel/index.ts +3 -1
  47. package/src/fuel/network.ts +1 -1
  48. package/src/fuel/transaction.ts +76 -26
  49. package/src/fuel/types.ts +26 -0
  50. package/src/testing/fuel-facet.ts +35 -0
@@ -15,7 +15,22 @@ export async function codegen(abisDir: string, outDir: string) {
15
15
  }
16
16
 
17
17
  function patchImport(contents: string) {
18
- return contents.replace(/from\s+['"](\..+)['"]/g, `from '\$1.js'`)
18
+ return contents
19
+ .replace(
20
+ `import { Interface, Contract, ContractFactory } from "fuels";`,
21
+ `import { Contract, } from "@fuel-ts/program";
22
+ import { ContractFactory } from "@fuel-ts/contract";
23
+ import { Interface } from "@fuel-ts/abi-coder";`
24
+ )
25
+ .replace(
26
+ `import type { Provider, Account, AbstractAddress, BytesLike, DeployContractOptions, StorageSlot } from "fuels";
27
+ `,
28
+ `import type { Provider, Account } from "@fuel-ts/account";
29
+ import type { AbstractAddress, BytesLike } from "@fuel-ts/interfaces";
30
+ import type { DeployContractOptions } from "@fuel-ts/contract";
31
+ import type { StorageSlot } from "@fuel-ts/transactions";`
32
+ )
33
+ .replace(/from\s+['"](\..+)['"]/g, `from '\$1.js'`)
19
34
  }
20
35
 
21
36
  function patchEnumType(contents: string) {
@@ -65,38 +80,71 @@ async function codegenInternal(abisDir: string, outDir: string): Promise<number>
65
80
 
66
81
  mkdirp.sync(outDir)
67
82
  mkdirp.sync(path.join(outDir, 'factories'))
68
-
83
+ let count = 0
69
84
  abiTypeGen.files.forEach((file) => {
70
85
  if (!file.path.endsWith('.hex.ts')) {
71
86
  let content = patchImport(file.contents)
72
87
  content = patchEnumType(content)
73
88
  writeFileSync(file.path, content)
89
+ count++
74
90
  }
75
91
  })
76
92
 
93
+ // for (const file of abiTypeGen.files) {
94
+ // const jsonAbi: JsonAbi = JSON.parse(file.contents)
95
+ // for (const logType of jsonAbi.loggedTypes) {
96
+ // logType.loggedType.name
97
+ //
98
+ // }
99
+ // }
100
+
77
101
  for (const abi of abiTypeGen.abis) {
78
102
  const name = abi.name.endsWith('Abi') ? abi.name.slice(0, -3) : abi.name
79
103
  const filePath = path.join(outDir, `${name}Processor.ts`)
80
104
  const importedTypes = collectImportedTypes(abi.types)
81
105
 
106
+ const logByTypes: Record<string, string[]> = {}
107
+
108
+ for (const logType of abi.rawContents.loggedTypes) {
109
+ // @ts-ignore - we know that the type is in the abi
110
+ const t = abi.types.find((t) => t.rawAbiType.typeId == logType.loggedType?.type)
111
+ // @ts-ignore - we know that the type is in the abi
112
+ const typeName = t?.attributes?.outputLabel
113
+ if (typeName) {
114
+ if (!logByTypes[typeName]) {
115
+ logByTypes[typeName] = []
116
+ }
117
+ logByTypes[typeName].push(logType.logId)
118
+ }
119
+ }
120
+
82
121
  const content = `/* Autogenerated file. Do not edit manually. */
83
122
 
84
123
  /* tslint:disable */
85
124
  /* eslint-disable */
86
125
 
87
- import { FuelAbstractProcessor, FuelContext, FuelProcessorConfig, TypedCall, FuelFetchConfig} from '@sentio/sdk/fuel'
126
+ import { FuelAbstractProcessor, FuelContext, FuelProcessorConfig, TypedCall, FuelFetchConfig, FuelCall} from '@sentio/sdk/fuel'
88
127
  import {${abi.name}__factory } from './factories/${abi.name}__factory.js'
89
128
  import {${abi.commonTypesInUse.join(',')}} from './common.js'
90
129
  import {${importedTypes.join(',')}} from './${abi.name}.js'
91
130
 
92
- import type {
93
- BigNumberish,
94
- BN,
95
- BytesLike,
96
- } from 'fuels';
131
+ import type { BigNumberish, BN } from '@fuel-ts/math';
132
+ import type { BytesLike } from '@fuel-ts/interfaces';
97
133
 
98
134
 
99
135
  namespace ${name} {
136
+ export abstract class CallWithLogs<T extends Array<any>, R> extends TypedCall<T, R> {
137
+ ${Object.entries(logByTypes)
138
+ .flatMap(([t, ids]) =>
139
+ ids.map(
140
+ (id) => ` getLog${id}(): Array<${t}> {
141
+ return this.logs?.filter(l => l.logId == ${id})?.map(l => l.decodedLog) as Array<${t}>
142
+ }`
143
+ )
144
+ )
145
+ .join('\n')}
146
+ }
147
+
100
148
  ${abi.functions.map(genCallType).join('\n')}
101
149
  }
102
150
 
@@ -105,25 +153,46 @@ export class ${name}Processor extends FuelAbstractProcessor {
105
153
  super(${abi.name}__factory.abi, config)
106
154
  }
107
155
 
108
- static bind(config?: FuelProcessorConfig) {
109
- return new ${name}Processor(config)
156
+ static bind(config: FuelProcessorConfig) {
157
+ return new ${name}Processor({
158
+ name: '${name}',
159
+ ...config,
160
+ })
110
161
  }
111
162
 
112
163
  ${abi.functions.map((f) => genOnCallFunction(name, f)).join('\n')}
164
+
165
+ ${Object.entries(logByTypes).map(genOnLogFunction).join('\n')}
166
+
113
167
  }
114
168
  `
115
169
  writeFileSync(filePath, content)
170
+ count++
116
171
  }
117
172
 
118
- return allABIFiles.length
173
+ return count
119
174
  }
120
175
 
121
176
  function genCallType(f: IFunction) {
122
177
  const name = upperFirst(f.name)
178
+ const argMap: Record<string, string> = {}
179
+ const argTypes = f.attributes.inputs.split(',').map((t) => t.trim())
180
+ f.rawAbiFunction.inputs.forEach((input, idx) => {
181
+ argMap[input.name] = argTypes[idx]
182
+ })
183
+
123
184
  return `
124
- export interface ${name}Call extends TypedCall<[${f.attributes.inputs}], ${f.attributes.output}> {
125
- args: [${f.attributes.inputs}]
126
- returnValue: ${f.attributes.output}
185
+ export class ${name}Call extends CallWithLogs<[${argTypes.join(', ')}], ${f.attributes.output}> {
186
+ declare args: [${argTypes.join(', ')}]
187
+ declare returnValue: ${f.attributes.output}
188
+ declare argsObject: {
189
+ ${Object.entries(argMap)
190
+ .map(([k, v]) => `${k}: ${v}`)
191
+ .join(', ')}
192
+ }
193
+ constructor(call: FuelCall) {
194
+ super(call)
195
+ }
127
196
  }
128
197
  `
129
198
  }
@@ -131,8 +200,8 @@ function genCallType(f: IFunction) {
131
200
  function genOnCallFunction(contractName: string, f: IFunction) {
132
201
  const name = upperFirst(f.name)
133
202
  return `
134
- onCall${name}(handler: (call: ${contractName}.${name}Call, ctx: FuelContext) => void | Promise<void>, config: FuelFetchConfig) {
135
- super.onCallMethod('${f.name}', handler, config)
203
+ onCall${name}(handler: (call: ${contractName}.${name}Call, ctx: FuelContext) => void | Promise<void>, config?: FuelFetchConfig) {
204
+ return super.onCall('${f.name}', (call, ctx) => handler(new ${contractName}.${name}Call(call), ctx), config)
136
205
  }`
137
206
  }
138
207
 
@@ -147,3 +216,11 @@ function collectImportedTypes(types: any[]): string[] {
147
216
 
148
217
  return Array.from(ret)
149
218
  }
219
+
220
+ function genOnLogFunction([type, ids]: [string, string[]]) {
221
+ const name = upperFirst(type.replace('Output', ''))
222
+ return `
223
+ onLog${name}(handler: (logs: ${type}[], ctx: FuelContext) => void | Promise<void>, logIdFilter?: number | number[]) {
224
+ return super.onLog<${type}>(logIdFilter ?? [${ids.join(', ')}], (logs, ctx) => handler(logs, ctx))
225
+ }`
226
+ }
@@ -1,15 +1,29 @@
1
1
  import { BaseContext, Labels, normalizeLabels } from '../core/index.js'
2
2
  import { ChainId } from '@sentio/chain'
3
3
  import { RecordMetaData } from '@sentio/protos'
4
- import { InvocationCallResult } from 'fuels'
4
+ import { InvocationCallResult, InvocationScopeLike } from '@fuel-ts/program'
5
5
  import { FuelTransaction } from './transaction.js'
6
+ import type { CallResult } from '@fuel-ts/account'
7
+ import { FuelLog } from './types.js'
6
8
 
7
- export type FuelCall = InvocationCallResult
9
+ export class FuelCall extends InvocationCallResult {
10
+ constructor(
11
+ funcScopes: InvocationScopeLike | Array<InvocationScopeLike>,
12
+ callResult: CallResult,
13
+ isMultiCall: boolean,
14
+ readonly args?: Record<string, any>,
15
+ readonly logs?: FuelLog[]
16
+ ) {
17
+ super(funcScopes, callResult, isMultiCall)
18
+ }
19
+ }
8
20
 
9
21
  export class FuelContext extends BaseContext {
10
22
  constructor(
11
- readonly transaction: FuelTransaction | null,
12
- readonly chainId: ChainId
23
+ readonly chainId: ChainId,
24
+ readonly contractAddress: string,
25
+ readonly contractName: string,
26
+ readonly transaction: FuelTransaction | null
13
27
  ) {
14
28
  super({})
15
29
  }
@@ -20,14 +34,14 @@ export class FuelContext extends BaseContext {
20
34
 
21
35
  protected getMetaDataInternal(name: string, labels: Labels): RecordMetaData {
22
36
  return {
23
- address: this.transaction?.id || '',
24
- contractName: this.transaction?.id || '', // TODO
25
- blockNumber: 0n,
37
+ address: this.contractAddress,
38
+ contractName: this.contractName,
39
+ blockNumber: BigInt(this.transaction?.blockNumber || 0),
26
40
  transactionIndex: 0,
27
41
  transactionHash: this.transaction?.id || '', // TODO
28
42
  chainId: this.getChainId(),
29
43
  name: name,
30
- logIndex: 0,
44
+ logIndex: -1,
31
45
  labels: normalizeLabels(labels)
32
46
  }
33
47
  }
@@ -10,9 +10,11 @@ import {
10
10
  } from '@sentio/protos'
11
11
 
12
12
  import { ServerError, Status } from 'nice-grpc'
13
- import { GlobalProcessorState } from '../eth/base-processor.js'
14
13
  import { TemplateInstanceState } from '../core/template.js'
15
- import { FuelProcessorState } from './fuel-processor.js'
14
+ import { FuelAssetProcessor } from './asset-processor.js'
15
+ import { FuelProcessorState } from './types.js'
16
+ import { FuelProcessor } from './fuel-processor.js'
17
+ import { BN } from '@fuel-ts/math'
16
18
 
17
19
  interface Handlers {
18
20
  callHandlers: ((trace: Data_FuelCall) => Promise<ProcessResult>)[]
@@ -36,58 +38,47 @@ export class FuelPlugin extends Plugin {
36
38
  contract: {
37
39
  name: processor.config.name,
38
40
  chainId: processor.config.chainId.toString(),
39
- address: processor.config.address,
41
+ address: processor.config.address || '*',
40
42
  abi: ''
41
43
  },
42
44
  startBlock: processor.config.startBlock,
43
45
  endBlock: processor.config.endBlock
44
46
  })
45
-
46
47
  for (const callHandler of processor.callHandlers) {
47
48
  const handlerId = handlers.callHandlers.push(callHandler.handler) - 1
48
- const fetchConfig = {
49
- handlerId,
50
- filters: callHandler.fetchConfig.filters || []
49
+ if (processor instanceof FuelProcessor) {
50
+ if (callHandler.logConfig?.logIds?.length) {
51
+ contractConfig.fuelLogConfigs.push({
52
+ logIds: callHandler.logConfig.logIds.map((logId) => new BN(logId).toString(10)),
53
+ handlerId
54
+ })
55
+ } else {
56
+ const fetchConfig = {
57
+ handlerId,
58
+ filters: callHandler.fetchConfig?.filters || []
59
+ }
60
+ contractConfig.fuelCallConfigs.push(fetchConfig)
61
+ }
62
+ } else if (processor instanceof FuelAssetProcessor) {
63
+ const assetConfig = callHandler.assetConfig
64
+ contractConfig.assetConfigs.push({
65
+ filters: assetConfig?.filters || [],
66
+ handlerId
67
+ })
51
68
  }
52
- contractConfig.fuelCallConfigs.push(fetchConfig)
53
69
  }
54
70
 
55
71
  // Finish up a contract
56
72
  config.contractConfigs.push(contractConfig)
57
73
  }
58
74
 
59
- for (const processor of GlobalProcessorState.INSTANCE.getValues()) {
60
- const chainId = processor.getChainId()
61
-
62
- const contractConfig = ContractConfig.fromPartial({
63
- processorType: USER_PROCESSOR,
64
- contract: {
65
- name: processor.config.name,
66
- chainId: chainId.toString(),
67
- address: processor.config.address, // can only be *
68
- abi: ''
69
- },
70
- startBlock: processor.config.startBlock,
71
- endBlock: processor.config.endBlock
72
- })
73
-
74
- config.contractConfigs.push(contractConfig)
75
- }
76
-
77
75
  this.handlers = handlers
78
76
  }
79
77
 
80
78
  supportedHandlers = [HandlerType.FUEL_CALL]
81
79
 
82
80
  processBinding(request: DataBinding): Promise<ProcessResult> {
83
- // return Promise.resolve(undefined);
84
81
  switch (request.handlerType) {
85
- // case HandlerType.FUEL_LOG:
86
- // return this.processLog(request)
87
- // case HandlerType.FUEL_TRACE:
88
- // return this.processTrace(request)
89
- // case HandlerType.FUEL_BLOCK:
90
- // return this.processBlock(request)
91
82
  case HandlerType.FUEL_CALL:
92
83
  return this.processTransaction(request)
93
84
  default:
@@ -1,15 +1,19 @@
1
- import { ListStateStorage } from '@sentio/runtime'
2
- import { Data_FuelCall, FuelCallFilter, FuelCallHandlerConfig, ProcessResult } from '@sentio/protos'
1
+ import { Data_FuelCall, FuelCallFilter } from '@sentio/protos'
3
2
  import { FuelCall, FuelContext } from './context.js'
4
- import { bn, Contract, Interface, InvocationCallResult, JsonAbi, Provider } from 'fuels'
3
+ import { Provider } from '@fuel-ts/account'
4
+ import { Contract } from '@fuel-ts/program'
5
+ import { Interface, JsonAbi } from '@fuel-ts/abi-coder'
6
+ import { bn } from '@fuel-ts/math'
5
7
  import { FuelNetwork, getRpcEndpoint } from './network.js'
6
- import { decodeFuelTransaction, DEFAULT_FUEL_FETCH_CONFIG, FuelFetchConfig, FuelTransaction } from './transaction.js'
7
-
8
- export class FuelProcessorState extends ListStateStorage<FuelProcessor> {
9
- static INSTANCE = new FuelProcessorState()
10
- }
11
-
12
- export class FuelProcessor {
8
+ import {
9
+ decodeFuelTransactionWithAbi,
10
+ DEFAULT_FUEL_FETCH_CONFIG,
11
+ FuelFetchConfig,
12
+ FuelTransaction
13
+ } from './transaction.js'
14
+ import { CallHandler, FuelBaseProcessor, FuelProcessorState } from './types.js'
15
+
16
+ export class FuelProcessor implements FuelBaseProcessor<FuelProcessorConfig> {
13
17
  callHandlers: CallHandler<Data_FuelCall>[] = []
14
18
 
15
19
  private provider: Provider
@@ -38,9 +42,14 @@ export class FuelProcessor {
38
42
  [this.config.address]: this.config.abi
39
43
  }
40
44
  : {}
41
- const tx = decodeFuelTransaction(call.transaction, abiMap, this.provider)
42
-
43
- const ctx = new FuelContext(tx, this.config.chainId)
45
+ const tx = decodeFuelTransactionWithAbi(call.transaction, abiMap, this.provider)
46
+
47
+ const ctx = new FuelContext(
48
+ this.config.chainId,
49
+ this.config.address,
50
+ this.config.name ?? this.config.address,
51
+ tx
52
+ )
44
53
  await handler(tx, ctx)
45
54
  return ctx.stopAndGetResult()
46
55
  },
@@ -84,16 +93,22 @@ export class FuelProcessor {
84
93
  handler: async (call: Data_FuelCall) => {
85
94
  const contract = new Contract(this.config.address, abi, this.provider)
86
95
  const gqlTransaction = call.transaction
87
- const tx = decodeFuelTransaction(gqlTransaction, { [this.config.address]: abi }, this.provider)
88
-
89
- const ctx = new FuelContext(tx, this.config.chainId)
96
+ const tx = decodeFuelTransactionWithAbi(gqlTransaction, { [this.config.address]: abi }, this.provider)
97
+
98
+ const ctx = new FuelContext(
99
+ this.config.chainId,
100
+ this.config.address,
101
+ this.config.name ?? this.config.address,
102
+ tx
103
+ )
90
104
  for (const op of tx.operations) {
91
105
  for (const call of op.calls || []) {
92
106
  if (names.has(call.functionName)) {
93
107
  const fn = contract.functions[call.functionName]
94
108
  const args = Object.values(call.argumentsProvided || {})
95
109
  const scope = fn(...args)
96
- const invocationResult = await InvocationCallResult.build(scope, tx, false)
110
+ const invocationResult = new FuelCall(scope, tx, false, call.argumentsProvided, tx.logs)
111
+
97
112
  await handler(invocationResult, ctx)
98
113
  }
99
114
  }
@@ -108,11 +123,36 @@ export class FuelProcessor {
108
123
  this.callHandlers.push(callHandler)
109
124
  return this
110
125
  }
111
- }
112
126
 
113
- export type CallHandler<T> = {
114
- handler: (call: T) => Promise<ProcessResult>
115
- fetchConfig: Partial<FuelCallHandlerConfig>
127
+ public onLog<T>(logIdFilter: number | number[], handler: (logs: T[], ctx: FuelContext) => void | Promise<void>) {
128
+ const logIds = new Set(Array.isArray(logIdFilter) ? logIdFilter : [logIdFilter])
129
+
130
+ const callHandler = {
131
+ handler: async (call: Data_FuelCall) => {
132
+ const gqlTransaction = call.transaction
133
+ const tx = decodeFuelTransactionWithAbi(
134
+ gqlTransaction,
135
+ { [this.config.address]: this.config.abi! },
136
+ this.provider
137
+ )
138
+
139
+ const ctx = new FuelContext(
140
+ this.config.chainId,
141
+ this.config.address,
142
+ this.config.name ?? this.config.address,
143
+ tx
144
+ )
145
+ const logs = (tx.logs || []).filter((log) => logIds.has(log.logId)).map((log) => log.decodedLog as T)
146
+ await handler(logs, ctx)
147
+ return ctx.stopAndGetResult()
148
+ },
149
+ logConfig: {
150
+ logIds: Array.from(logIds)
151
+ }
152
+ }
153
+ this.callHandlers.push(callHandler)
154
+ return this
155
+ }
116
156
  }
117
157
 
118
158
  export type FuelProcessorConfig = {
package/src/fuel/index.ts CHANGED
@@ -3,4 +3,6 @@ export * from './context.js'
3
3
  export * from './fuel-processor.js'
4
4
  export * from './network.js'
5
5
  export * from './transaction.js'
6
- export * from './base-processor.js'
6
+ export * from './base-processor.js'
7
+ export * from './asset-processor.js'
8
+ export * from './types.js'
@@ -1,5 +1,5 @@
1
1
  import { FuelChainId } from '@sentio/chain'
2
- import { FUEL_BETA_5_NETWORK_URL, FUEL_NETWORK_URL } from 'fuels'
2
+ import { FUEL_BETA_5_NETWORK_URL, FUEL_NETWORK_URL } from '@fuel-ts/account/configs'
3
3
 
4
4
  export type FuelNetwork = FuelChainId
5
5
  export const FuelNetwork = <const>{
@@ -1,13 +1,9 @@
1
- import {
2
- AbiMap,
3
- arrayify,
4
- assembleTransactionSummary,
5
- bn,
6
- processGqlReceipt,
7
- Provider,
8
- TransactionCoder,
9
- TransactionSummary
10
- } from 'fuels'
1
+ import { AbiMap, assembleTransactionSummary, processGqlReceipt, Provider, TransactionSummary } from '@fuel-ts/account'
2
+ import { ReceiptType, TransactionCoder } from '@fuel-ts/transactions'
3
+ import { bn } from '@fuel-ts/math'
4
+ import { arrayify } from '@fuel-ts/utils'
5
+ import { Interface, BigNumberCoder } from '@fuel-ts/abi-coder'
6
+ import { FuelLog } from './types.js'
11
7
 
12
8
  export type FuelFetchConfig = {
13
9
  includeFailed?: boolean
@@ -17,27 +13,81 @@ export const DEFAULT_FUEL_FETCH_CONFIG: FuelFetchConfig = {
17
13
  includeFailed: false
18
14
  }
19
15
 
20
- export type FuelTransaction = TransactionSummary
16
+ export type FuelTransaction = TransactionSummary & {
17
+ blockNumber?: string
18
+ logs?: FuelLog[]
19
+ }
20
+
21
+ export function decodeFuelTransaction(gqlTransaction: any, provider: Provider): FuelTransaction {
22
+ const rawPayload = arrayify(gqlTransaction.rawPayload)
23
+
24
+ const [decodedTransaction] = new TransactionCoder().decode(rawPayload, 0)
25
+ const { gasCosts, maxInputs, gasPerByte, gasPriceFactor } = provider.getChain().consensusParameters
26
+ const blockNumber = gqlTransaction.status?.block?.header?.height
27
+ const gqlTransactionStatus = {
28
+ type: gqlTransaction.status?.__typename,
29
+ ...gqlTransaction.status
30
+ }
31
+ return {
32
+ ...assembleTransactionSummary({
33
+ id: gqlTransaction.id,
34
+ receipts: [],
35
+ transaction: decodedTransaction,
36
+ transactionBytes: rawPayload,
37
+ gqlTransactionStatus,
38
+ gasPerByte: bn(gasPerByte),
39
+ gasPriceFactor: bn(gasPriceFactor),
40
+ maxInputs,
41
+ gasCosts
42
+ }),
43
+ blockNumber
44
+ }
45
+ }
21
46
 
22
- export function decodeFuelTransaction(gqlTransaction: any, abiMap: AbiMap, provider: Provider): FuelTransaction {
47
+ export function decodeFuelTransactionWithAbi(gqlTransaction: any, abiMap: AbiMap, provider: Provider): FuelTransaction {
23
48
  const rawPayload = arrayify(gqlTransaction.rawPayload)
24
49
 
25
50
  const [decodedTransaction] = new TransactionCoder().decode(rawPayload, 0)
26
51
 
27
52
  const receipts = gqlTransaction.receipts?.map(processGqlReceipt) || []
28
53
 
29
- const { gasPerByte, gasPriceFactor, maxInputs, gasCosts } = provider.getChain().consensusParameters
30
-
31
- return assembleTransactionSummary({
32
- id: gqlTransaction.id,
33
- receipts,
34
- transaction: decodedTransaction,
35
- transactionBytes: rawPayload,
36
- gqlTransactionStatus: gqlTransaction.status,
37
- gasPerByte: bn(gasPerByte),
38
- gasPriceFactor: bn(gasPriceFactor),
39
- abiMap,
40
- maxInputs,
41
- gasCosts
42
- })
54
+ const { gasCosts, maxInputs, gasPerByte, gasPriceFactor } = provider.getChain().consensusParameters
55
+
56
+ const gqlTransactionStatus = {
57
+ type: gqlTransaction.status?.__typename,
58
+ ...gqlTransaction.status
59
+ }
60
+ const blockNumber = gqlTransactionStatus?.block?.header?.height
61
+
62
+ const abi = Object.values(abiMap)[0]
63
+
64
+ const logs: FuelLog[] = []
65
+ for (const receipt of receipts) {
66
+ if (receipt.type === ReceiptType.LogData || receipt.type === ReceiptType.Log) {
67
+ const interfaceToUse = new Interface(abi)
68
+
69
+ const data = receipt.type === ReceiptType.Log ? new BigNumberCoder('u64').encode(receipt.val0) : receipt.data
70
+
71
+ const logId = receipt.val1.toNumber()
72
+ const [decodedLog] = interfaceToUse.decodeLog(data, logId)
73
+ logs.push({ logId, decodedLog })
74
+ }
75
+ }
76
+
77
+ return {
78
+ ...assembleTransactionSummary({
79
+ id: gqlTransaction.id,
80
+ receipts,
81
+ transaction: decodedTransaction,
82
+ transactionBytes: rawPayload,
83
+ gqlTransactionStatus,
84
+ gasPerByte: bn(gasPerByte),
85
+ gasPriceFactor: bn(gasPriceFactor),
86
+ abiMap,
87
+ maxInputs,
88
+ gasCosts
89
+ }),
90
+ blockNumber,
91
+ logs
92
+ }
43
93
  }
@@ -0,0 +1,26 @@
1
+ import { ListStateStorage } from '@sentio/runtime'
2
+ import { Data_FuelCall, FuelAssetHandlerConfig, FuelCallHandlerConfig, ProcessResult } from '@sentio/protos'
3
+
4
+ export interface FuelBaseProcessor<T> {
5
+ configure(): Promise<void>
6
+ config: T
7
+ callHandlers: CallHandler<Data_FuelCall>[]
8
+ }
9
+
10
+ export class FuelProcessorState extends ListStateStorage<FuelBaseProcessor<any>> {
11
+ static INSTANCE = new FuelProcessorState()
12
+ }
13
+
14
+ export type CallHandler<T> = {
15
+ handler: (call: T) => Promise<ProcessResult>
16
+ fetchConfig?: Partial<FuelCallHandlerConfig>
17
+ assetConfig?: Partial<FuelAssetHandlerConfig>
18
+ logConfig?: {
19
+ logIds: number[]
20
+ }
21
+ }
22
+
23
+ export interface FuelLog {
24
+ logId: number
25
+ decodedLog: any
26
+ }
@@ -51,6 +51,41 @@ export class FuelFacet {
51
51
  res.push(binding)
52
52
  }
53
53
  }
54
+
55
+ for (const logConfig of config.fuelLogConfigs) {
56
+ const binding = {
57
+ data: {
58
+ fuelCall: {
59
+ transaction,
60
+ timestamp: new Date()
61
+ }
62
+ },
63
+ handlerIds: [logConfig.handlerId],
64
+ handlerType: HandlerType.FUEL_CALL
65
+ }
66
+
67
+ const logIds = logConfig.logIds
68
+ for (const receipt of transaction.receipts || []) {
69
+ if ((receipt.receiptType == 'LOG' || receipt.receiptType == 'LOG_DATA') && logIds.includes(receipt.rb)) {
70
+ res.push(binding)
71
+ }
72
+ }
73
+ }
74
+
75
+ for (const assetConfig of config.assetConfigs) {
76
+ const binding = {
77
+ data: {
78
+ fuelCall: {
79
+ transaction,
80
+ timestamp: new Date()
81
+ }
82
+ },
83
+ handlerIds: [assetConfig.handlerId],
84
+ handlerType: HandlerType.FUEL_CALL
85
+ }
86
+
87
+ res.push(binding)
88
+ }
54
89
  }
55
90
 
56
91
  return res