@alephium/web3 0.5.0-rc.2 → 0.5.0-rc.21

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 (51) hide show
  1. package/dist/alephium-web3.min.js +1 -1
  2. package/dist/alephium-web3.min.js.LICENSE.txt +2 -0
  3. package/dist/alephium-web3.min.js.map +1 -1
  4. package/dist/src/api/api-alephium.d.ts +113 -26
  5. package/dist/src/api/api-alephium.js +62 -18
  6. package/dist/src/api/api-explorer.d.ts +222 -52
  7. package/dist/src/api/api-explorer.js +17 -15
  8. package/dist/src/api/explorer-provider.d.ts +18 -0
  9. package/dist/src/api/explorer-provider.js +65 -0
  10. package/dist/src/api/index.d.ts +2 -41
  11. package/dist/src/api/index.js +6 -116
  12. package/dist/src/api/node-provider.d.ts +21 -0
  13. package/dist/src/api/node-provider.js +68 -0
  14. package/dist/src/api/types.d.ts +10 -2
  15. package/dist/src/api/types.js +23 -3
  16. package/dist/src/contract/contract.d.ts +15 -7
  17. package/dist/src/contract/contract.js +62 -42
  18. package/dist/src/signer/signer.d.ts +25 -30
  19. package/dist/src/signer/signer.js +57 -30
  20. package/dist/src/signer/tx-builder.d.ts +2 -7
  21. package/dist/src/signer/tx-builder.js +10 -7
  22. package/dist/src/signer/types.d.ts +12 -16
  23. package/dist/src/transaction/sign-verify.d.ts +3 -2
  24. package/dist/src/transaction/sign-verify.js +4 -14
  25. package/dist/src/utils/index.d.ts +2 -0
  26. package/dist/src/utils/index.js +2 -0
  27. package/dist/src/utils/number.d.ts +18 -0
  28. package/dist/src/utils/number.fixture.d.ts +12 -0
  29. package/dist/src/utils/number.fixture.js +189 -0
  30. package/dist/src/utils/number.js +148 -0
  31. package/dist/src/utils/sign.d.ts +3 -0
  32. package/dist/src/utils/sign.js +89 -0
  33. package/dist/src/utils/utils.d.ts +4 -3
  34. package/dist/src/utils/utils.js +25 -10
  35. package/package.json +7 -5
  36. package/src/api/api-alephium.ts +260 -207
  37. package/src/api/api-explorer.ts +327 -126
  38. package/src/api/explorer-provider.ts +78 -0
  39. package/src/api/index.ts +2 -146
  40. package/src/api/node-provider.ts +84 -0
  41. package/src/api/types.ts +36 -3
  42. package/src/contract/contract.ts +80 -49
  43. package/src/signer/signer.ts +87 -66
  44. package/src/signer/tx-builder.ts +13 -7
  45. package/src/signer/types.ts +22 -11
  46. package/src/transaction/sign-verify.ts +10 -15
  47. package/src/utils/index.ts +2 -0
  48. package/src/utils/number.fixture.ts +187 -0
  49. package/src/utils/number.ts +162 -0
  50. package/src/utils/sign.ts +66 -0
  51. package/src/utils/utils.ts +26 -10
@@ -0,0 +1,78 @@
1
+ /*
2
+ Copyright 2018 - 2022 The Alephium Authors
3
+ This file is part of the alephium project.
4
+
5
+ The library is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Lesser General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ The library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public License
16
+ along with the library. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import { ApiRequestArguments, ApiRequestHandler, forwardRequests, request } from './types'
20
+ import { Api as ExplorerApi } from './api-explorer'
21
+
22
+ function initializeExplorerApi(baseUrl: string, apiKey?: string): ExplorerApi<string> {
23
+ const explorerApi = new ExplorerApi<string>({
24
+ baseUrl: baseUrl,
25
+ baseApiParams: { secure: true },
26
+ securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
27
+ })
28
+ explorerApi.setSecurityData(apiKey ?? null)
29
+ return explorerApi
30
+ }
31
+
32
+ export class ExplorerProvider {
33
+ readonly blocks: ExplorerApi<string>['blocks']
34
+ readonly transactions: ExplorerApi<string>['transactions']
35
+ readonly addresses: ExplorerApi<string>['addresses']
36
+ readonly infos: ExplorerApi<string>['infos']
37
+ readonly mempool: ExplorerApi<string>['mempool']
38
+ readonly tokens: ExplorerApi<string>['tokens']
39
+ readonly charts: ExplorerApi<string>['charts']
40
+ readonly utils: ExplorerApi<string>['utils']
41
+
42
+ constructor(baseUrl: string, apiKey?: string)
43
+ constructor(provider: ExplorerProvider)
44
+ constructor(handler: ApiRequestHandler)
45
+ constructor(param0: string | ExplorerProvider | ApiRequestHandler, apiKey?: string) {
46
+ let explorerApi: ExplorerProvider
47
+ if (typeof param0 === 'string') {
48
+ explorerApi = initializeExplorerApi(param0, apiKey)
49
+ } else if (typeof param0 === 'function') {
50
+ explorerApi = new ExplorerProvider('https://1.2.3.4:0')
51
+ forwardRequests(explorerApi, param0 as ApiRequestHandler)
52
+ } else {
53
+ explorerApi = param0 as ExplorerProvider
54
+ }
55
+
56
+ this.blocks = { ...explorerApi.blocks }
57
+ this.transactions = { ...explorerApi.transactions }
58
+ this.addresses = { ...explorerApi.addresses }
59
+ this.infos = { ...explorerApi.infos }
60
+ this.mempool = { ...explorerApi.mempool }
61
+ this.tokens = { ...explorerApi.tokens }
62
+ this.charts = { ...explorerApi.charts }
63
+ this.utils = { ...explorerApi.utils }
64
+ }
65
+
66
+ request = (args: ApiRequestArguments): Promise<any> => {
67
+ return request(this, args)
68
+ }
69
+
70
+ // This can prevent the proxied explorer provider from being modified
71
+ static Proxy(explorerProvider: ExplorerProvider): ExplorerProvider {
72
+ return new ExplorerProvider(explorerProvider)
73
+ }
74
+
75
+ static Remote(handler: ApiRequestHandler): ExplorerProvider {
76
+ return new ExplorerProvider(handler)
77
+ }
78
+ }
package/src/api/index.ts CHANGED
@@ -16,152 +16,8 @@ You should have received a copy of the GNU Lesser General Public License
16
16
  along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
- import { Api as NodeApi } from './api-alephium'
20
- import { Api as ExplorerApi } from './api-explorer'
21
-
22
- export interface ApiRequestArguments {
23
- path: string
24
- method: string
25
- params: any[]
26
- }
27
- export type ApiRequestHandler = (args: ApiRequestArguments) => Promise<any>
28
-
29
- function forwardRequests(api: Record<string, any>, handler: ApiRequestHandler): void {
30
- // Update class properties to forward requests
31
- for (const [path, pathObject] of Object.entries(api)) {
32
- for (const method of Object.keys(pathObject)) {
33
- pathObject[`${method}`] = async (...params: any): Promise<any> => {
34
- return handler({ path, method, params })
35
- }
36
- }
37
- }
38
- }
39
-
40
- async function request(provider: Record<string, any>, args: ApiRequestArguments): Promise<any> {
41
- const call = provider[`${args.path}`][`${args.method}`] as (...any) => Promise<any>
42
- return call(...args.params)
43
- }
44
-
45
- function initializeNodeApi(baseUrl: string, apiKey?: string): NodeApi<string> {
46
- const nodeApi = new NodeApi<string>({
47
- baseUrl: baseUrl,
48
- baseApiParams: { secure: true },
49
- securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
50
- })
51
- nodeApi.setSecurityData(apiKey ?? null)
52
- return nodeApi
53
- }
54
-
55
- export class NodeProvider {
56
- readonly wallets: NodeApi<string>['wallets']
57
- readonly infos: NodeApi<string>['infos']
58
- readonly blockflow: NodeApi<string>['blockflow']
59
- readonly addresses: NodeApi<string>['addresses']
60
- readonly transactions: NodeApi<string>['transactions']
61
- readonly contracts: NodeApi<string>['contracts']
62
- readonly multisig: NodeApi<string>['multisig']
63
- readonly utils: NodeApi<string>['utils']
64
- readonly miners: NodeApi<string>['miners']
65
- readonly events: NodeApi<string>['events']
66
-
67
- constructor(baseUrl: string, apiKey?: string)
68
- constructor(provider: NodeProvider)
69
- constructor(handler: ApiRequestHandler)
70
- constructor(param0: string | NodeProvider | ApiRequestHandler, apiKey?: string) {
71
- let nodeApi: NodeProvider
72
- if (typeof param0 === 'string') {
73
- nodeApi = initializeNodeApi(param0, apiKey)
74
- } else if (typeof param0 === 'function') {
75
- nodeApi = new NodeProvider('https://1.2.3.4:0')
76
- forwardRequests(nodeApi, param0 as ApiRequestHandler)
77
- } else {
78
- nodeApi = param0 as NodeProvider
79
- }
80
-
81
- this.wallets = { ...nodeApi.wallets }
82
- this.infos = { ...nodeApi.infos }
83
- this.blockflow = { ...nodeApi.blockflow }
84
- this.addresses = { ...nodeApi.addresses }
85
- this.transactions = { ...nodeApi.transactions }
86
- this.contracts = { ...nodeApi.contracts }
87
- this.multisig = { ...nodeApi.multisig }
88
- this.utils = { ...nodeApi.utils }
89
- this.miners = { ...nodeApi.miners }
90
- this.events = { ...nodeApi.events }
91
- }
92
-
93
- request = (args: ApiRequestArguments): Promise<any> => {
94
- return request(this, args)
95
- }
96
-
97
- // This can prevent the proxied node provider from being modified
98
- static Proxy(nodeProvider: NodeProvider): NodeProvider {
99
- return new NodeProvider(nodeProvider)
100
- }
101
-
102
- static Remote(handler: ApiRequestHandler): NodeProvider {
103
- return new NodeProvider(handler)
104
- }
105
- }
106
-
107
- function initializeExplorerApi(baseUrl: string, apiKey?: string): ExplorerApi<string> {
108
- const explorerApi = new ExplorerApi<string>({
109
- baseUrl: baseUrl,
110
- baseApiParams: { secure: true },
111
- securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
112
- })
113
- explorerApi.setSecurityData(apiKey ?? null)
114
- return explorerApi
115
- }
116
-
117
- export class ExplorerProvider {
118
- readonly blocks = ExplorerApi['blocks']
119
- readonly transactions = ExplorerApi['transactions']
120
- readonly addresses = ExplorerApi['addresses']
121
- readonly infos = ExplorerApi['infos']
122
- readonly unconfirmedTransactions = ExplorerApi['unconfirmedTransactions']
123
- readonly tokens = ExplorerApi['tokens']
124
- readonly charts = ExplorerApi['charts']
125
- readonly utils = ExplorerApi['utils']
126
-
127
- constructor(baseUrl: string, apiKey?: string)
128
- constructor(provider: ExplorerProvider)
129
- constructor(handler: ApiRequestHandler)
130
- constructor(param0: string | ExplorerProvider | ApiRequestHandler, apiKey?: string) {
131
- let explorerApi: ExplorerProvider
132
- if (typeof param0 === 'string') {
133
- explorerApi = initializeExplorerApi(param0, apiKey)
134
- } else if (typeof param0 === 'function') {
135
- explorerApi = new ExplorerProvider('https://1.2.3.4:0')
136
- forwardRequests(explorerApi, param0 as ApiRequestHandler)
137
- } else {
138
- explorerApi = param0 as ExplorerProvider
139
- }
140
-
141
- this.blocks = { ...explorerApi.blocks }
142
- this.transactions = { ...explorerApi.transactions }
143
- this.addresses = { ...explorerApi.addresses }
144
- this.infos = { ...explorerApi.infos }
145
- this.unconfirmedTransactions = { ...explorerApi.unconfirmedTransactions }
146
- this.tokens = { ...explorerApi.tokens }
147
- this.charts = { ...explorerApi.charts }
148
- this.utils = { ...explorerApi.utils }
149
- }
150
-
151
- request = (args: ApiRequestArguments): Promise<any> => {
152
- return request(this, args)
153
- }
154
-
155
- // This can prevent the proxied explorer provider from being modified
156
- static Proxy(explorerProvider: ExplorerProvider): ExplorerProvider {
157
- return new ExplorerProvider(explorerProvider)
158
- }
159
-
160
- static Remote(handler: ApiRequestHandler): ExplorerProvider {
161
- return new ExplorerProvider(handler)
162
- }
163
- }
164
-
19
+ export * from './node-provider'
20
+ export * from './explorer-provider'
165
21
  export * as node from './api-alephium'
166
22
  export * as explorer from './api-explorer'
167
23
  export * from './types'
@@ -0,0 +1,84 @@
1
+ /*
2
+ Copyright 2018 - 2022 The Alephium Authors
3
+ This file is part of the alephium project.
4
+
5
+ The library is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Lesser General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ The library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public License
16
+ along with the library. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import { ApiRequestArguments, ApiRequestHandler, forwardRequests, request } from './types'
20
+ import { Api as NodeApi } from './api-alephium'
21
+
22
+ function initializeNodeApi(baseUrl: string, apiKey?: string): NodeApi<string> {
23
+ const nodeApi = new NodeApi<string>({
24
+ baseUrl: baseUrl,
25
+ baseApiParams: { secure: true },
26
+ securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
27
+ })
28
+ nodeApi.setSecurityData(apiKey ?? null)
29
+ return nodeApi
30
+ }
31
+
32
+ export class NodeProvider {
33
+ readonly wallets: NodeApi<string>['wallets']
34
+ readonly infos: NodeApi<string>['infos']
35
+ readonly blockflow: NodeApi<string>['blockflow']
36
+ readonly addresses: NodeApi<string>['addresses']
37
+ readonly transactions: NodeApi<string>['transactions']
38
+ readonly mempool: NodeApi<string>['mempool']
39
+ readonly contracts: NodeApi<string>['contracts']
40
+ readonly multisig: NodeApi<string>['multisig']
41
+ readonly utils: NodeApi<string>['utils']
42
+ readonly miners: NodeApi<string>['miners']
43
+ readonly events: NodeApi<string>['events']
44
+
45
+ constructor(baseUrl: string, apiKey?: string)
46
+ constructor(provider: NodeProvider)
47
+ constructor(handler: ApiRequestHandler)
48
+ constructor(param0: string | NodeProvider | ApiRequestHandler, apiKey?: string) {
49
+ let nodeApi: NodeProvider
50
+ if (typeof param0 === 'string') {
51
+ nodeApi = initializeNodeApi(param0, apiKey)
52
+ } else if (typeof param0 === 'function') {
53
+ nodeApi = new NodeProvider('https://1.2.3.4:0')
54
+ forwardRequests(nodeApi, param0 as ApiRequestHandler)
55
+ } else {
56
+ nodeApi = param0 as NodeProvider
57
+ }
58
+
59
+ this.wallets = { ...nodeApi.wallets }
60
+ this.infos = { ...nodeApi.infos }
61
+ this.blockflow = { ...nodeApi.blockflow }
62
+ this.addresses = { ...nodeApi.addresses }
63
+ this.transactions = { ...nodeApi.transactions }
64
+ this.mempool = { ...nodeApi.mempool }
65
+ this.contracts = { ...nodeApi.contracts }
66
+ this.multisig = { ...nodeApi.multisig }
67
+ this.utils = { ...nodeApi.utils }
68
+ this.miners = { ...nodeApi.miners }
69
+ this.events = { ...nodeApi.events }
70
+ }
71
+
72
+ request = (args: ApiRequestArguments): Promise<any> => {
73
+ return request(this, args)
74
+ }
75
+
76
+ // This can prevent the proxied node provider from being modified
77
+ static Proxy(nodeProvider: NodeProvider): NodeProvider {
78
+ return new NodeProvider(nodeProvider)
79
+ }
80
+
81
+ static Remote(handler: ApiRequestHandler): NodeProvider {
82
+ return new NodeProvider(handler)
83
+ }
84
+ }
package/src/api/types.ts CHANGED
@@ -19,7 +19,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
19
19
  import { assertType, bs58, Eq } from '../utils'
20
20
  import * as node from './api-alephium'
21
21
 
22
- export type Number256 = bigint
22
+ export type Number256 = bigint | string
23
23
  export type Val = Number256 | boolean | string | Val[]
24
24
  export type NamedVals = Record<string, Val>
25
25
 
@@ -162,7 +162,13 @@ function _fromApiVal(vals: node.Val[], valIndex: number, tpe: string): [result:
162
162
  }
163
163
  }
164
164
 
165
- export function fromApiVals(vals: node.Val[], names: string[], types: string[]): NamedVals {
165
+ export function fromApiVals(
166
+ vals: node.Val[],
167
+ names: string[],
168
+ types: string[],
169
+ optionalNames: string[] = [],
170
+ optionalTypes: string[] = []
171
+ ): NamedVals {
166
172
  let valIndex = 0
167
173
  const result: NamedVals = {}
168
174
  types.forEach((currentType, index) => {
@@ -171,7 +177,11 @@ export function fromApiVals(vals: node.Val[], names: string[], types: string[]):
171
177
  valIndex = nextIndex
172
178
  result[`${currentName}`] = val
173
179
  })
174
- return result
180
+ if (valIndex === vals.length) {
181
+ return result
182
+ }
183
+ const optionalFields = fromApiVals(vals.slice(valIndex), optionalNames, optionalTypes)
184
+ return { ...result, ...optionalFields }
175
185
  }
176
186
 
177
187
  export function fromApiArray(vals: node.Val[], types: string[]): Val[] {
@@ -235,3 +245,26 @@ export function typeLength(tpe: string): number {
235
245
  const [, dims] = decodeArrayType(tpe)
236
246
  return dims.reduce((a, b) => a * b)
237
247
  }
248
+
249
+ export interface ApiRequestArguments {
250
+ path: string
251
+ method: string
252
+ params: any[]
253
+ }
254
+ export type ApiRequestHandler = (args: ApiRequestArguments) => Promise<any>
255
+
256
+ export function forwardRequests(api: Record<string, any>, handler: ApiRequestHandler): void {
257
+ // Update class properties to forward requests
258
+ for (const [path, pathObject] of Object.entries(api)) {
259
+ for (const method of Object.keys(pathObject)) {
260
+ pathObject[`${method}`] = async (...params: any): Promise<any> => {
261
+ return handler({ path, method, params })
262
+ }
263
+ }
264
+ }
265
+ }
266
+
267
+ export async function request(provider: Record<string, any>, args: ApiRequestArguments): Promise<any> {
268
+ const call = provider[`${args.path}`][`${args.method}`] as (...any) => Promise<any>
269
+ return call(...args.params)
270
+ }
@@ -53,7 +53,8 @@ import {
53
53
  assertType,
54
54
  Eq,
55
55
  Optional,
56
- groupOfAddress
56
+ groupOfAddress,
57
+ addressFromContractId
57
58
  } from '../utils'
58
59
  import { getCurrentNodeProvider } from '../global'
59
60
  import * as path from 'path'
@@ -848,38 +849,45 @@ export class Contract extends Artifact {
848
849
  }
849
850
 
850
851
  static ContractCreatedEventIndex = -1
851
- static ContractCreatedEvent: EventSig = {
852
+ static ContractCreatedEvent: SystemEventSig = {
852
853
  name: 'ContractCreated',
853
854
  fieldNames: ['address'],
854
- fieldTypes: ['Address']
855
+ fieldTypes: ['Address'],
856
+ optionalFieldNames: ['parentAddress'],
857
+ optionalFieldTypes: ['Address']
855
858
  }
856
859
 
857
860
  static ContractDestroyedEventIndex = -2
858
- static ContractDestroyedEvent: EventSig = {
861
+ static ContractDestroyedEvent: SystemEventSig = {
859
862
  name: 'ContractDestroyed',
860
863
  fieldNames: ['address'],
861
864
  fieldTypes: ['Address']
862
865
  }
863
866
 
864
867
  static fromApiEvent(event: node.ContractEventByTxId, codeHash: string | undefined, txId: string): ContractEvent {
865
- let eventSig: EventSig
868
+ let fields: Fields
869
+ let name: string
866
870
 
867
871
  if (event.eventIndex == Contract.ContractCreatedEventIndex) {
868
- eventSig = this.ContractCreatedEvent
872
+ fields = fromApiSystemEventFields(event.fields, Contract.ContractCreatedEvent)
873
+ name = Contract.ContractCreatedEvent.name
869
874
  } else if (event.eventIndex == Contract.ContractDestroyedEventIndex) {
870
- eventSig = this.ContractDestroyedEvent
875
+ fields = fromApiSystemEventFields(event.fields, Contract.ContractDestroyedEvent)
876
+ name = Contract.ContractDestroyedEvent.name
871
877
  } else {
872
878
  const contract = Project.currentProject.contractByCodeHash(codeHash!)
873
- eventSig = contract.eventsSig[event.eventIndex]
879
+ const eventSig = contract.eventsSig[event.eventIndex]
880
+ fields = fromApiEventFields(event.fields, eventSig)
881
+ name = eventSig.name
874
882
  }
875
883
 
876
884
  return {
877
885
  txId: txId,
878
886
  blockHash: event.blockHash,
879
887
  contractAddress: event.contractAddress,
880
- name: eventSig.name,
888
+ name: name,
881
889
  eventIndex: event.eventIndex,
882
- fields: fromApiEventFields(event.fields, eventSig)
890
+ fields: fields
883
891
  }
884
892
  }
885
893
 
@@ -913,8 +921,10 @@ export class Contract extends Artifact {
913
921
  params: DeployContractParams<P>
914
922
  ): Promise<SignDeployContractTxParams> {
915
923
  const bytecode = this.buildByteCodeToDeploy(params.initialFields ?? {})
924
+ const selectedAccount = await signer.getSelectedAccount()
916
925
  const signerParams: SignDeployContractTxParams = {
917
- signerAddress: await signer.getSelectedAddress(),
926
+ signerAddress: selectedAccount.address,
927
+ signerKeyType: selectedAccount.keyType,
918
928
  bytecode: bytecode,
919
929
  initialAttoAlphAmount: params?.initialAttoAlphAmount,
920
930
  issueTokenAmount: params?.issueTokenAmount,
@@ -1056,8 +1066,10 @@ export class Script extends Artifact {
1056
1066
  signer: SignerProvider,
1057
1067
  params: ExecuteScriptParams<P>
1058
1068
  ): Promise<SignExecuteScriptTxParams> {
1069
+ const selectedAccount = await signer.getSelectedAccount()
1059
1070
  const signerParams: SignExecuteScriptTxParams = {
1060
- signerAddress: await signer.getSelectedAddress(),
1071
+ signerAddress: selectedAccount.address,
1072
+ signerKeyType: selectedAccount.keyType,
1061
1073
  bytecode: this.buildByteCodeToDeploy(params.initialFields ?? {}),
1062
1074
  attoAlphAmount: params.attoAlphAmount,
1063
1075
  tokens: params.tokens,
@@ -1095,6 +1107,16 @@ function fromApiEventFields(vals: node.Val[], eventSig: node.EventSig): Fields {
1095
1107
  return fromApiVals(vals, eventSig.fieldNames, eventSig.fieldTypes)
1096
1108
  }
1097
1109
 
1110
+ function fromApiSystemEventFields(vals: node.Val[], systemEventSig: SystemEventSig): Fields {
1111
+ return fromApiVals(
1112
+ vals,
1113
+ systemEventSig.fieldNames,
1114
+ systemEventSig.fieldTypes,
1115
+ systemEventSig.optionalFieldNames ?? [],
1116
+ systemEventSig.optionalFieldTypes ?? []
1117
+ )
1118
+ }
1119
+
1098
1120
  export interface Asset {
1099
1121
  alphAmount: Number256
1100
1122
  tokens?: Token[]
@@ -1272,7 +1294,7 @@ export interface DeployContractParams<P extends Fields = Fields> {
1272
1294
  assertType<
1273
1295
  Eq<
1274
1296
  Omit<DeployContractParams<undefined>, 'initialFields'>,
1275
- Omit<SignDeployContractTxParams, 'signerAddress' | 'bytecode'>
1297
+ Omit<SignDeployContractTxParams, 'signerAddress' | 'signerKeyType' | 'bytecode'>
1276
1298
  >
1277
1299
  >
1278
1300
  export type DeployContractResult<T> = SignDeployContractTxResult & { instance: T }
@@ -1339,37 +1361,54 @@ export interface CallContractResult<R> {
1339
1361
  events: ContractEvent[]
1340
1362
  }
1341
1363
 
1342
- export type ContractCreatedEvent = ContractEvent<{ address: HexString }>
1343
- export type ContractDestroyedEvent = ContractEvent<{ address: HexString }>
1364
+ function specialContractAddress(n: number): string {
1365
+ const bytes = new Uint8Array(32).fill(0)
1366
+ bytes[31] = n
1367
+ return addressFromContractId(binToHex(bytes))
1368
+ }
1369
+
1370
+ export const CreateContractEventAddress = specialContractAddress(-1)
1371
+ export const DestroyContractEventAddress = specialContractAddress(-2)
1344
1372
 
1345
- function decodeFields(event: node.ContractEvent, eventSig: EventSig, eventIndex: number): Fields {
1373
+ export interface SystemEventSig extends EventSig {
1374
+ optionalFieldNames?: string[]
1375
+ optionalFieldTypes?: string[]
1376
+ }
1377
+
1378
+ export type ContractCreatedEvent = ContractEvent<{ address: Address; parentAddress?: Address }>
1379
+ export type ContractDestroyedEvent = ContractEvent<{ address: Address }>
1380
+
1381
+ function decodeSystemEvent(event: node.ContractEvent, systemEventSig: SystemEventSig, eventIndex: number): Fields {
1346
1382
  if (event.eventIndex !== eventIndex) {
1347
1383
  throw new Error(`Invalid event index: ${event.eventIndex}, expected: ${eventIndex}`)
1348
1384
  }
1349
- return fromApiVals(event.fields, eventSig.fieldNames, eventSig.fieldTypes)
1385
+ return fromApiSystemEventFields(event.fields, systemEventSig)
1350
1386
  }
1351
1387
 
1352
1388
  export function decodeContractCreatedEvent(event: node.ContractEvent): Omit<ContractCreatedEvent, 'contractAddress'> {
1353
- const fields = decodeFields(event, Contract.ContractCreatedEvent, Contract.ContractCreatedEventIndex)
1389
+ const fields = decodeSystemEvent(event, Contract.ContractCreatedEvent, Contract.ContractCreatedEventIndex)
1354
1390
  return {
1355
1391
  blockHash: event.blockHash,
1356
1392
  txId: event.txId,
1357
1393
  eventIndex: event.eventIndex,
1358
1394
  name: Contract.ContractCreatedEvent.name,
1359
- fields: { address: fields['address'] as HexString }
1395
+ fields: {
1396
+ address: fields['address'] as Address,
1397
+ parentAddress: fields['parentAddress'] === undefined ? undefined : (fields['parentAddress'] as Address)
1398
+ }
1360
1399
  }
1361
1400
  }
1362
1401
 
1363
1402
  export function decodeContractDestroyedEvent(
1364
1403
  event: node.ContractEvent
1365
1404
  ): Omit<ContractDestroyedEvent, 'contractAddress'> {
1366
- const fields = decodeFields(event, Contract.ContractDestroyedEvent, Contract.ContractDestroyedEventIndex)
1405
+ const fields = decodeSystemEvent(event, Contract.ContractDestroyedEvent, Contract.ContractDestroyedEventIndex)
1367
1406
  return {
1368
1407
  blockHash: event.blockHash,
1369
1408
  txId: event.txId,
1370
1409
  eventIndex: event.eventIndex,
1371
1410
  name: Contract.ContractDestroyedEvent.name,
1372
- fields: { address: fields['address'] as HexString }
1411
+ fields: { address: fields['address'] as Address }
1373
1412
  }
1374
1413
  }
1375
1414
 
@@ -1443,18 +1482,17 @@ export async function fetchContractState<F extends Fields, I extends ContractIns
1443
1482
  }
1444
1483
 
1445
1484
  export function subscribeContractCreatedEvent(
1446
- instance: ContractInstance,
1447
1485
  options: SubscribeOptions<ContractCreatedEvent>,
1448
1486
  fromCount?: number
1449
1487
  ): EventSubscription {
1450
1488
  return subscribeEventsFromContract(
1451
1489
  options,
1452
- instance.address,
1490
+ CreateContractEventAddress,
1453
1491
  Contract.ContractCreatedEventIndex,
1454
1492
  (event) => {
1455
1493
  return {
1456
1494
  ...decodeContractCreatedEvent(event),
1457
- contractAddress: instance.address
1495
+ contractAddress: CreateContractEventAddress
1458
1496
  }
1459
1497
  },
1460
1498
  fromCount
@@ -1462,18 +1500,17 @@ export function subscribeContractCreatedEvent(
1462
1500
  }
1463
1501
 
1464
1502
  export function subscribeContractDestroyedEvent(
1465
- instance: ContractInstance,
1466
1503
  options: SubscribeOptions<ContractDestroyedEvent>,
1467
1504
  fromCount?: number
1468
1505
  ): EventSubscription {
1469
1506
  return subscribeEventsFromContract(
1470
1507
  options,
1471
- instance.address,
1508
+ DestroyContractEventAddress,
1472
1509
  Contract.ContractDestroyedEventIndex,
1473
1510
  (event) => {
1474
1511
  return {
1475
1512
  ...decodeContractDestroyedEvent(event),
1476
- contractAddress: instance.address
1513
+ contractAddress: DestroyContractEventAddress
1477
1514
  }
1478
1515
  },
1479
1516
  fromCount
@@ -1523,34 +1560,17 @@ export function subscribeContractEvent<F extends Fields, M extends ContractEvent
1523
1560
  )
1524
1561
  }
1525
1562
 
1526
- export function subscribeAllEvents(
1563
+ export function subscribeContractEvents(
1527
1564
  contract: Contract,
1528
1565
  instance: ContractInstance,
1529
1566
  options: SubscribeOptions<ContractEvent<any>>,
1530
1567
  fromCount?: number
1531
1568
  ): EventSubscription {
1532
1569
  const messageCallback = (event: node.ContractEvent): Promise<void> => {
1533
- switch (event.eventIndex) {
1534
- case Contract.ContractCreatedEventIndex: {
1535
- return options.messageCallback({
1536
- ...decodeContractCreatedEvent(event),
1537
- contractAddress: instance.address
1538
- })
1539
- }
1540
-
1541
- case Contract.ContractDestroyedEventIndex: {
1542
- return options.messageCallback({
1543
- ...decodeContractDestroyedEvent(event),
1544
- contractAddress: instance.address
1545
- })
1546
- }
1547
-
1548
- default:
1549
- return options.messageCallback({
1550
- ...decodeEvent(contract, instance, event, event.eventIndex),
1551
- contractAddress: instance.address
1552
- })
1553
- }
1570
+ return options.messageCallback({
1571
+ ...decodeEvent(contract, instance, event, event.eventIndex),
1572
+ contractAddress: instance.address
1573
+ })
1554
1574
  }
1555
1575
  const errorCallback = (err: any, subscription: Subscription<node.ContractEvent>): Promise<void> => {
1556
1576
  return options.errorCallback(err, subscription as unknown as Subscription<ContractEvent<any>>)
@@ -1581,3 +1601,14 @@ export async function callMethod<I, F extends Fields, A extends Arguments, R>(
1581
1601
  const callResult = contract.contract.fromApiCallContractResult(result, txId, methodIndex)
1582
1602
  return callResult as CallContractResult<R>
1583
1603
  }
1604
+
1605
+ export async function getContractEventsCurrentCount(contractAddress: Address): Promise<number> {
1606
+ return getCurrentNodeProvider()
1607
+ .events.getEventsContractContractaddressCurrentCount(contractAddress)
1608
+ .catch((error) => {
1609
+ if (error instanceof Error && error.message.includes(`${contractAddress} not found`)) {
1610
+ return 0
1611
+ }
1612
+ throw error
1613
+ })
1614
+ }