@sentio/sdk 1.30.3 → 1.31.1

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 (85) hide show
  1. package/lib/builtin/erc1155/index.d.ts +2 -0
  2. package/lib/builtin/erc1155/index.js +22 -0
  3. package/lib/builtin/erc1155/index.js.map +1 -0
  4. package/lib/builtin/erc1155/test-utils.d.ts +6 -0
  5. package/lib/builtin/erc1155/test-utils.js +57 -0
  6. package/lib/builtin/erc1155/test-utils.js.map +1 -0
  7. package/lib/builtin/erc721/index.d.ts +2 -0
  8. package/lib/builtin/erc721/index.js +22 -0
  9. package/lib/builtin/erc721/index.js.map +1 -0
  10. package/lib/builtin/erc721/test-utils.d.ts +5 -0
  11. package/lib/builtin/erc721/test-utils.js +46 -0
  12. package/lib/builtin/erc721/test-utils.js.map +1 -0
  13. package/lib/builtin/internal/ERC1155.d.ts +199 -0
  14. package/lib/builtin/internal/ERC1155.js +3 -0
  15. package/lib/builtin/internal/ERC1155.js.map +1 -0
  16. package/lib/builtin/internal/ERC721.d.ts +252 -0
  17. package/lib/builtin/internal/ERC721.js +3 -0
  18. package/lib/builtin/internal/ERC721.js.map +1 -0
  19. package/lib/builtin/internal/erc1155_processor.d.ts +134 -0
  20. package/lib/builtin/internal/erc1155_processor.js +337 -0
  21. package/lib/builtin/internal/erc1155_processor.js.map +1 -0
  22. package/lib/builtin/internal/erc721_processor.d.ts +169 -0
  23. package/lib/builtin/internal/erc721_processor.js +479 -0
  24. package/lib/builtin/internal/erc721_processor.js.map +1 -0
  25. package/lib/builtin/internal/factories/ERC1155__factory.d.ts +35 -0
  26. package/lib/builtin/internal/factories/ERC1155__factory.js +332 -0
  27. package/lib/builtin/internal/factories/ERC1155__factory.js.map +1 -0
  28. package/lib/builtin/internal/factories/ERC721__factory.d.ts +51 -0
  29. package/lib/builtin/internal/factories/ERC721__factory.js +364 -0
  30. package/lib/builtin/internal/factories/ERC721__factory.js.map +1 -0
  31. package/lib/builtin/internal/factories/index.d.ts +2 -0
  32. package/lib/builtin/internal/factories/index.js +5 -1
  33. package/lib/builtin/internal/factories/index.js.map +1 -1
  34. package/lib/builtin/internal/index.d.ts +4 -0
  35. package/lib/builtin/internal/index.js +5 -1
  36. package/lib/builtin/internal/index.js.map +1 -1
  37. package/lib/core/account-processor.d.ts +58 -0
  38. package/lib/core/account-processor.js +147 -0
  39. package/lib/core/account-processor.js.map +1 -0
  40. package/lib/core/base-processor.d.ts +5 -2
  41. package/lib/core/base-processor.js.map +1 -1
  42. package/lib/core/bind-options.d.ts +5 -0
  43. package/lib/core/bind-options.js +7 -1
  44. package/lib/core/bind-options.js.map +1 -1
  45. package/lib/core/context.d.ts +7 -1
  46. package/lib/core/context.js +30 -18
  47. package/lib/core/context.js.map +1 -1
  48. package/lib/core/meter.js +9 -0
  49. package/lib/core/meter.js.map +1 -1
  50. package/lib/gen/chainquery/protos/chainquery.d.ts +1 -0
  51. package/lib/gen/chainquery/protos/chainquery.js +17 -1
  52. package/lib/gen/chainquery/protos/chainquery.js.map +1 -1
  53. package/lib/gen/processor/protos/processor.d.ts +12 -1
  54. package/lib/gen/processor/protos/processor.js +108 -13
  55. package/lib/gen/processor/protos/processor.js.map +1 -1
  56. package/lib/service.d.ts +1 -0
  57. package/lib/service.js +67 -42
  58. package/lib/service.js.map +1 -1
  59. package/lib/testing/test-processor-server.d.ts +6 -2
  60. package/lib/testing/test-processor-server.js +66 -5
  61. package/lib/testing/test-processor-server.js.map +1 -1
  62. package/package.json +1 -1
  63. package/src/abis/ERC1155.json +314 -0
  64. package/src/abis/ERC721.json +346 -0
  65. package/src/builtin/erc1155/index.ts +6 -0
  66. package/src/builtin/erc1155/test-utils.ts +89 -0
  67. package/src/builtin/erc721/index.ts +6 -0
  68. package/src/builtin/erc721/test-utils.ts +71 -0
  69. package/src/builtin/internal/ERC1155.ts +529 -0
  70. package/src/builtin/internal/ERC721.ts +639 -0
  71. package/src/builtin/internal/erc1155_processor.ts +580 -0
  72. package/src/builtin/internal/erc721_processor.ts +768 -0
  73. package/src/builtin/internal/factories/ERC1155__factory.ts +335 -0
  74. package/src/builtin/internal/factories/ERC721__factory.ts +364 -0
  75. package/src/builtin/internal/factories/index.ts +2 -0
  76. package/src/builtin/internal/index.ts +4 -0
  77. package/src/core/account-processor.ts +217 -0
  78. package/src/core/base-processor.ts +6 -2
  79. package/src/core/bind-options.ts +6 -0
  80. package/src/core/context.ts +42 -27
  81. package/src/core/meter.ts +11 -2
  82. package/src/gen/chainquery/protos/chainquery.ts +18 -1
  83. package/src/gen/processor/protos/processor.ts +113 -12
  84. package/src/service.ts +71 -44
  85. package/src/testing/test-processor-server.ts +71 -5
@@ -0,0 +1,217 @@
1
+ import { ListStateStorage } from '../state/state-storage'
2
+ import { ERC20__factory, ERC721__factory } from '../builtin/internal'
3
+ import { AddressType, DummyProvider, ProcessResult } from '@sentio/sdk'
4
+ import { AccountBindOptions } from './bind-options'
5
+ import { getNetwork } from '@ethersproject/providers'
6
+ import { TransferEvent as ERC20TransferEvent } from '../builtin/internal/ERC20'
7
+ import { TransferEvent as ERC721TransferEvent } from '../builtin/internal/ERC721'
8
+ import { AccountContext } from './context'
9
+ import { PromiseOrVoid } from '../promise-or-void'
10
+ import { Event, EventFilter } from '@ethersproject/contracts'
11
+ import { BytesLike } from '@ethersproject/bytes'
12
+ import { AddressOrTypeEventFilter, EventsHandler } from './base-processor'
13
+
14
+ export class AccountProcessorState extends ListStateStorage<AccountProcessor> {
15
+ static INSTANCE = new AccountProcessorState()
16
+ }
17
+
18
+ const ERC20_CONTRACT = ERC20__factory.connect('', DummyProvider)
19
+ const ERC721_CONTRACT = ERC721__factory.connect('', DummyProvider)
20
+
21
+ export class AccountProcessor {
22
+ config: AccountBindOptions
23
+ eventHandlers: EventsHandler[] = []
24
+
25
+ static bind(config: AccountBindOptions): AccountProcessor {
26
+ const processor = new AccountProcessor(config)
27
+ AccountProcessorState.INSTANCE.addValue(processor)
28
+ return processor
29
+ }
30
+
31
+ protected constructor(config: AccountBindOptions) {
32
+ this.config = config
33
+ }
34
+
35
+ public getChainId(): number {
36
+ return getNetwork(this.config.network || 1).chainId
37
+ }
38
+
39
+ /**
40
+ * Register custom handler function to process erc20 transfer event to this account
41
+ * @param handler custom handler function
42
+ * @param tokensAddresses all the erc20 token address to watch
43
+ */
44
+ onERC20TransferIn(
45
+ handler: (event: ERC20TransferEvent, ctx: AccountContext) => PromiseOrVoid,
46
+ tokensAddresses: string[] = []
47
+ ) {
48
+ return this.onERC20(handler, tokensAddresses, (address: string) =>
49
+ ERC20_CONTRACT.filters.Transfer(null, this.config.address)
50
+ )
51
+ }
52
+
53
+ /**
54
+ * Register custom handler function to process erc20 transfer event from this account
55
+ * @param handler custom handler function
56
+ * @param tokensAddresses all the erc20 token address to watch
57
+ */
58
+ onERC20TransferOut(
59
+ handler: (event: ERC20TransferEvent, ctx: AccountContext) => PromiseOrVoid,
60
+ tokensAddresses: string[] = []
61
+ ) {
62
+ return this.onERC20(handler, tokensAddresses, (address: string) =>
63
+ ERC20_CONTRACT.filters.Transfer(this.config.address)
64
+ )
65
+ }
66
+
67
+ /**
68
+ * Register custom handler function to process erc20 mint for this account
69
+ * @param handler custom handler function
70
+ * @param tokensAddresses all the erc20 token address to watch
71
+ */
72
+ onERC20Minted(
73
+ handler: (event: ERC20TransferEvent, ctx: AccountContext) => PromiseOrVoid,
74
+ tokensAddresses: string[] = []
75
+ ) {
76
+ return this.onERC20(handler, tokensAddresses, (address: string) =>
77
+ ERC20_CONTRACT.filters.Transfer('0x0000000000000000000000000000000000000000', this.config.address)
78
+ )
79
+ }
80
+
81
+ private onERC20(
82
+ handler: (event: ERC20TransferEvent, ctx: AccountContext) => PromiseOrVoid,
83
+ tokensAddresses: string[] = [],
84
+ defaultFilter: (address: string) => AddressOrTypeEventFilter
85
+ ) {
86
+ return this.onERC(handler, tokensAddresses, defaultFilter, AddressType.ERC20)
87
+ }
88
+
89
+ /**
90
+ * Register custom handler function to process ERC721 transfer event to this account
91
+ * @param handler custom handler function
92
+ * @param collections all the ERC721 token address to watch, if not provided then watch all ERC721
93
+ */
94
+ onERC721TransferIn(
95
+ handler: (event: ERC721TransferEvent, ctx: AccountContext) => PromiseOrVoid,
96
+ collections: string[]
97
+ ) {
98
+ return this.onERC721(handler, collections, (address: string) =>
99
+ ERC721_CONTRACT.filters.Transfer(null, this.config.address)
100
+ )
101
+ }
102
+
103
+ /**
104
+ * Register custom handler function to process ERC721 transfer event from this account
105
+ * @param handler custom handler function
106
+ * @param collections all the ERC721 token address to watch, if not provided then watch all ERC721
107
+ */
108
+ onERC721TransferOut(
109
+ handler: (event: ERC721TransferEvent, ctx: AccountContext) => PromiseOrVoid,
110
+ collections: string[]
111
+ ) {
112
+ return this.onERC721(handler, collections, (address: string) =>
113
+ ERC721_CONTRACT.filters.Transfer(this.config.address)
114
+ )
115
+ }
116
+
117
+ /**
118
+ * Register custom handler function to process ERC721 mint for this account
119
+ * @param handler custom handler function
120
+ * @param collections all the ERC721 token address to watch, if not provided then watch all ERC721
121
+ */
122
+ onERC721Minted(
123
+ handler: (event: ERC721TransferEvent, ctx: AccountContext) => PromiseOrVoid,
124
+ collections: string[] = []
125
+ ) {
126
+ return this.onERC721(handler, collections, (address: string) =>
127
+ ERC721_CONTRACT.filters.Transfer('0x0000000000000000000000000000000000000000', this.config.address)
128
+ )
129
+ }
130
+
131
+ private onERC721(
132
+ handler: (event: ERC721TransferEvent, ctx: AccountContext) => PromiseOrVoid,
133
+ collections: string[],
134
+ defaultFilter: (address: string) => AddressOrTypeEventFilter
135
+ ) {
136
+ return this.onERC(handler, collections, defaultFilter, AddressType.ERC721)
137
+ }
138
+
139
+ private onERC(
140
+ handler: (event: any, ctx: AccountContext) => PromiseOrVoid,
141
+ contractAddresses: string[],
142
+ defaultFilter: (address: string) => AddressOrTypeEventFilter,
143
+ addressType: AddressType
144
+ ) {
145
+ const filters = []
146
+ for (const token of contractAddresses) {
147
+ const filter = defaultFilter(this.config.address)
148
+ filter.address = token
149
+ filters.push(filter)
150
+ }
151
+ if (!filters.length) {
152
+ const filter = defaultFilter(this.config.address)
153
+ filter.address = undefined
154
+ filter.addressType = addressType
155
+ filters.push(filter)
156
+ }
157
+ return this.onEvent(handler, filters)
158
+ }
159
+
160
+ protected onEvent(
161
+ handler: (event: Event, ctx: AccountContext) => PromiseOrVoid,
162
+ filter: AddressOrTypeEventFilter | AddressOrTypeEventFilter[]
163
+ ) {
164
+ const chainId = this.getChainId()
165
+
166
+ let _filters: AddressOrTypeEventFilter[] = []
167
+
168
+ if (Array.isArray(filter)) {
169
+ _filters = filter
170
+ } else {
171
+ _filters.push(filter)
172
+ }
173
+
174
+ let hasVaildConfig = false
175
+ for (const filter of _filters) {
176
+ if (filter.address) {
177
+ hasVaildConfig = true
178
+ break
179
+ }
180
+ if (filter.topics && filter.topics.length) {
181
+ hasVaildConfig = true
182
+ break
183
+ }
184
+ }
185
+
186
+ if (!hasVaildConfig) {
187
+ throw Error('no valid config has been found for this account')
188
+ }
189
+
190
+ const config = this.config
191
+
192
+ this.eventHandlers.push({
193
+ filters: _filters,
194
+ handler: async function (log) {
195
+ const ctx = new AccountContext(chainId, config.address, undefined, log)
196
+ // let event: Event = <Event>deepCopy(log);
197
+ const event: Event = <Event>log
198
+ const parsed = ERC20_CONTRACT.interface.parseLog(log)
199
+ if (parsed) {
200
+ event.args = parsed.args
201
+ event.decode = (data: BytesLike, topics?: Array<any>) => {
202
+ return ERC20_CONTRACT.interface.decodeEventLog(parsed.eventFragment, data, topics)
203
+ }
204
+ event.event = parsed.name
205
+ event.eventSignature = parsed.signature
206
+
207
+ // TODO fix this bug
208
+ await handler(event, ctx)
209
+ return ctx.getProcessResult()
210
+ }
211
+ return ProcessResult.fromPartial({})
212
+ },
213
+ })
214
+
215
+ return this
216
+ }
217
+ }
@@ -4,13 +4,17 @@ import { BaseContract, Event, EventFilter } from '@ethersproject/contracts'
4
4
  import Long from 'long'
5
5
 
6
6
  import { BoundContractView, ContractContext, ContractView } from './context'
7
- import { ProcessResult } from '../gen'
7
+ import { AddressType, ProcessResult } from '../gen'
8
8
  import { BindInternalOptions, BindOptions } from './bind-options'
9
9
  import { PromiseOrVoid } from '../promise-or-void'
10
10
  import { Trace } from './trace'
11
11
 
12
+ export interface AddressOrTypeEventFilter extends EventFilter {
13
+ addressType?: AddressType
14
+ }
15
+
12
16
  export class EventsHandler {
13
- filters: EventFilter[]
17
+ filters: AddressOrTypeEventFilter[]
14
18
  handler: (event: Log) => Promise<ProcessResult>
15
19
  }
16
20
 
@@ -42,3 +42,9 @@ export class SolanaBindOptions extends BindOptions {
42
42
  declare network?: string
43
43
  processInnerInstruction?: boolean
44
44
  }
45
+
46
+ export class AccountBindOptions {
47
+ address: string
48
+ network?: Networkish
49
+ startBlock?: Long | number
50
+ }
@@ -34,34 +34,14 @@ export abstract class EthContext extends BaseContext {
34
34
  this.transactionHash = trace.transactionHash
35
35
  }
36
36
  }
37
- }
38
37
 
39
- export class ContractContext<
40
- TContract extends BaseContract,
41
- TContractBoundView extends BoundContractView<TContract, ContractView<TContract>>
42
- > extends EthContext {
43
- contract: TContractBoundView
44
- contractName: string
45
-
46
- constructor(
47
- contractName: string,
48
- view: TContractBoundView,
49
- chainId: number,
50
- block?: Block,
51
- log?: Log,
52
- trace?: Trace
53
- ) {
54
- super(chainId, view.rawContract.address, block, log, trace)
55
- view.context = this
56
- this.contractName = contractName
57
- this.contract = view
58
- }
38
+ protected abstract getContractName(): string
59
39
 
60
40
  getMetaData(name: string, labels: Labels): RecordMetaData {
61
41
  if (this.log) {
62
42
  return {
63
- address: this.contract.rawContract.address,
64
- contractName: this.contractName,
43
+ address: this.address,
44
+ contractName: this.getContractName(),
65
45
  blockNumber: this.blockNumber,
66
46
  transactionIndex: this.log.transactionIndex,
67
47
  transactionHash: this.transactionHash || '',
@@ -74,8 +54,8 @@ export class ContractContext<
74
54
  }
75
55
  if (this.block) {
76
56
  return {
77
- address: this.contract.rawContract.address,
78
- contractName: this.contractName,
57
+ address: this.address,
58
+ contractName: this.getContractName(),
79
59
  blockNumber: this.blockNumber,
80
60
  transactionIndex: -1,
81
61
  transactionHash: '',
@@ -88,8 +68,8 @@ export class ContractContext<
88
68
  }
89
69
  if (this.trace) {
90
70
  return {
91
- address: this.contract.rawContract.address,
92
- contractName: this.contractName,
71
+ address: this.address,
72
+ contractName: this.getContractName(),
93
73
  blockNumber: this.blockNumber,
94
74
  transactionIndex: this.trace.transactionPosition,
95
75
  transactionHash: this.transactionHash || '',
@@ -104,6 +84,41 @@ export class ContractContext<
104
84
  }
105
85
  }
106
86
 
87
+ export class AccountContext extends EthContext {
88
+ constructor(chainId: number, address: string, block?: Block, log?: Log, trace?: Trace) {
89
+ super(chainId, address, block, log, trace)
90
+ }
91
+ protected getContractName(): string {
92
+ return 'account'
93
+ }
94
+ }
95
+
96
+ export class ContractContext<
97
+ TContract extends BaseContract,
98
+ TContractBoundView extends BoundContractView<TContract, ContractView<TContract>>
99
+ > extends EthContext {
100
+ contract: TContractBoundView
101
+ contractName: string
102
+
103
+ constructor(
104
+ contractName: string,
105
+ view: TContractBoundView,
106
+ chainId: number,
107
+ block?: Block,
108
+ log?: Log,
109
+ trace?: Trace
110
+ ) {
111
+ super(chainId, view.rawContract.address, block, log, trace)
112
+ view.context = this
113
+ this.contractName = contractName
114
+ this.contract = view
115
+ }
116
+
117
+ protected getContractName(): string {
118
+ return this.contractName
119
+ }
120
+ }
121
+
107
122
  export class ContractView<TContract extends BaseContract> {
108
123
  filters: { [name: string]: (...args: Array<any>) => EventFilter }
109
124
  protected contract: TContract
package/src/core/meter.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BaseContext } from './base-context'
2
- import { toMetricValue, Numberish } from './numberish'
2
+ import { Numberish, toMetricValue } from './numberish'
3
3
  import { Labels, NamedResultDescriptor } from './metadata'
4
- import { AggregationConfig, MetricConfig } from '../gen'
4
+ import { AggregationConfig, AggregationType, MetricConfig } from '../gen'
5
5
  import { MapStateStorage } from '../state/state-storage'
6
6
 
7
7
  export function normalizeName(name: string): string {
@@ -53,6 +53,15 @@ export class Metric extends NamedResultDescriptor {
53
53
  super(name)
54
54
  this.type = type
55
55
  this.descriptor = MetricConfig.fromPartial({ name: this.name, ...option })
56
+ const aggregationConfig = this.descriptor.aggregationConfig
57
+ if (aggregationConfig && aggregationConfig.intervalInMinutes && aggregationConfig.intervalInMinutes.length) {
58
+ if (aggregationConfig.intervalInMinutes.length > 1) {
59
+ console.error('current only support one intervalInMinutes, only first interval will be used for', name)
60
+ }
61
+ if (aggregationConfig.intervalInMinutes[0] > 0 && !aggregationConfig.types) {
62
+ aggregationConfig.types = [AggregationType.SUM, AggregationType.COUNT]
63
+ }
64
+ }
56
65
  }
57
66
  }
58
67
 
@@ -16,6 +16,7 @@ export interface AptosGetTxnsByVersionRequest {
16
16
  network: string;
17
17
  fromVersion: Long;
18
18
  toVersion: Long;
19
+ headerOnly?: boolean | undefined;
19
20
  }
20
21
 
21
22
  export interface AptosGetTxnsByEventRequest {
@@ -175,7 +176,12 @@ export const AptosGetTxnsByFunctionRequest = {
175
176
  };
176
177
 
177
178
  function createBaseAptosGetTxnsByVersionRequest(): AptosGetTxnsByVersionRequest {
178
- return { network: "", fromVersion: Long.UZERO, toVersion: Long.UZERO };
179
+ return {
180
+ network: "",
181
+ fromVersion: Long.UZERO,
182
+ toVersion: Long.UZERO,
183
+ headerOnly: undefined,
184
+ };
179
185
  }
180
186
 
181
187
  export const AptosGetTxnsByVersionRequest = {
@@ -192,6 +198,9 @@ export const AptosGetTxnsByVersionRequest = {
192
198
  if (!message.toVersion.isZero()) {
193
199
  writer.uint32(24).uint64(message.toVersion);
194
200
  }
201
+ if (message.headerOnly !== undefined) {
202
+ writer.uint32(32).bool(message.headerOnly);
203
+ }
195
204
  return writer;
196
205
  },
197
206
 
@@ -214,6 +223,9 @@ export const AptosGetTxnsByVersionRequest = {
214
223
  case 3:
215
224
  message.toVersion = reader.uint64() as Long;
216
225
  break;
226
+ case 4:
227
+ message.headerOnly = reader.bool();
228
+ break;
217
229
  default:
218
230
  reader.skipType(tag & 7);
219
231
  break;
@@ -231,6 +243,9 @@ export const AptosGetTxnsByVersionRequest = {
231
243
  toVersion: isSet(object.toVersion)
232
244
  ? Long.fromValue(object.toVersion)
233
245
  : Long.UZERO,
246
+ headerOnly: isSet(object.headerOnly)
247
+ ? Boolean(object.headerOnly)
248
+ : undefined,
234
249
  };
235
250
  },
236
251
 
@@ -241,6 +256,7 @@ export const AptosGetTxnsByVersionRequest = {
241
256
  (obj.fromVersion = (message.fromVersion || Long.UZERO).toString());
242
257
  message.toVersion !== undefined &&
243
258
  (obj.toVersion = (message.toVersion || Long.UZERO).toString());
259
+ message.headerOnly !== undefined && (obj.headerOnly = message.headerOnly);
244
260
  return obj;
245
261
  },
246
262
 
@@ -257,6 +273,7 @@ export const AptosGetTxnsByVersionRequest = {
257
273
  object.toVersion !== undefined && object.toVersion !== null
258
274
  ? Long.fromValue(object.toVersion)
259
275
  : Long.UZERO;
276
+ message.headerOnly = object.headerOnly ?? undefined;
260
277
  return message;
261
278
  },
262
279
  };