koilib 5.5.3 → 5.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/Contract.d.ts CHANGED
@@ -95,7 +95,7 @@ export declare class Contract {
95
95
  * ```
96
96
  */
97
97
  functions: {
98
- [x: string]: <T = Record<string, unknown>>(args?: unknown, opts?: CallContractOptions) => Promise<{
98
+ [x: string]: <T = Record<string, any>>(args?: any, opts?: CallContractOptions) => Promise<{
99
99
  operation: OperationJson;
100
100
  transaction?: TransactionJsonWait;
101
101
  result?: T;
@@ -95,7 +95,7 @@ export declare class Contract {
95
95
  * ```
96
96
  */
97
97
  functions: {
98
- [x: string]: <T = Record<string, unknown>>(args?: unknown, opts?: CallContractOptions) => Promise<{
98
+ [x: string]: <T = Record<string, any>>(args?: any, opts?: CallContractOptions) => Promise<{
99
99
  operation: OperationJson;
100
100
  transaction?: TransactionJsonWait;
101
101
  result?: T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koilib",
3
- "version": "5.5.3",
3
+ "version": "5.5.5",
4
4
  "description": "JS Koinos Library",
5
5
  "author": "Julian Gonzalez",
6
6
  "repository": {
@@ -12,7 +12,8 @@
12
12
  },
13
13
  "files": [
14
14
  "lib",
15
- "dist"
15
+ "dist",
16
+ "src"
16
17
  ],
17
18
  "main": "./lib/index.js",
18
19
  "types": "./lib/index.d.ts",
@@ -0,0 +1,614 @@
1
+ /* eslint-disable no-await-in-loop */
2
+ import { Signer, SignerInterface } from "./Signer";
3
+ import { Provider } from "./Provider";
4
+ import { Serializer } from "./Serializer";
5
+ import {
6
+ TransactionJsonWait,
7
+ Abi,
8
+ CallContractOptions,
9
+ DecodedOperationJson,
10
+ OperationJson,
11
+ DeployOptions,
12
+ TransactionReceipt,
13
+ EventData,
14
+ DecodedEventData,
15
+ } from "./interface";
16
+ import { decodeBase58, encodeBase58, encodeBase64url } from "./utils";
17
+
18
+ /**
19
+ * The contract class contains the contract ID and contract entries
20
+ * definition needed to encode/decode operations during the
21
+ * interaction with the user and the communication with the RPC node.
22
+ *
23
+ * @example
24
+ *
25
+ * ```ts
26
+ * const { Contract, Provider, Signer, utils } = require("koilib");
27
+ * const rpcNodes = ["http://api.koinos.io:8080"];
28
+ * const privateKey = "f186a5de49797bfd52dc42505c33d75a46822ed5b60046e09d7c336242e20200";
29
+ * const provider = new Provider(rpcNodes);
30
+ * const signer = new Signer({ privateKey, provider });
31
+ * const koinContract = new Contract({
32
+ * id: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
33
+ * abi: utils.tokenAbi,
34
+ * provider,
35
+ * signer,
36
+ * });
37
+ * const koin = koinContract.functions;
38
+ *
39
+ * // optional: preformat argument/return
40
+ * koinContract.abi.methods.balanceOf.preformat_argument = (owner) =>
41
+ * ({ owner });
42
+ * koinContract.abi.methods.balanceOf.preformat_return = (res) =>
43
+ * utils.formatUnits(res.value, 8);
44
+ * koinContract.abi.methods.transfer.preformat_argument = (arg) => ({
45
+ * from: signer.getAddress(),
46
+ * to: arg.to,
47
+ * value: utils.parseUnits(arg.value, 8),
48
+ * });
49
+ *
50
+ * async funtion main() {
51
+ * // Get balance
52
+ * const { result } = await koin.balanceOf("12fN2CQnuJM8cMnWZ1hPtM4knjLME8E4PD");
53
+ * console.log(result)
54
+ *
55
+ * // Transfer
56
+ * const { transaction, receipt } = await koin.transfer({
57
+ * to: "172AB1FgCsYrRAW5cwQ8KjadgxofvgPFd6",
58
+ * value: "10.0001",
59
+ * });
60
+ * console.log(`Transaction id ${transaction.id} submitted. Receipt:`);
61
+ * console.log(receipt);
62
+ *
63
+ * if (receipt.logs) {
64
+ * console.log(`Transfer failed. Logs: ${receipt.logs.join(",")}`);
65
+ * }
66
+ *
67
+ * // wait to be mined
68
+ * const blockNumber = await transaction.wait();
69
+ * console.log(`Transaction mined. Block number: ${blockNumber}`);
70
+ * }
71
+ *
72
+ * main();
73
+ * ```
74
+ */
75
+ export class Contract {
76
+ /**
77
+ * Contract ID
78
+ */
79
+ id: Uint8Array;
80
+
81
+ /**
82
+ * Set of functions to interact with the smart
83
+ * contract. These functions are automatically generated
84
+ * in the constructor of the class
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * const owner = "1Gvqdo9if6v6tFomEuTuMWP1D7H7U9yksb";
89
+ * await koinContract.functions.balanceOf({ owner });
90
+ * ```
91
+ *
92
+ * @example using options
93
+ * ```ts
94
+ * await koinContract.functions.transfer({
95
+ * from: "1Gvqdo9if6v6tFomEuTuMWP1D7H7U9yksb",
96
+ * to: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
97
+ * value: "1",
98
+ * },{
99
+ * chainId: "EiB-hw5ABo-EXy6fGDd1Iq3gbAenxQ4Qe60pRbEVMVrR9A==",
100
+ * rcLimit: "100000000",
101
+ * nonce: "OAI=",
102
+ * payer: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
103
+ * payee: "1Gvqdo9if6v6tFomEuTuMWP1D7H7U9yksb",
104
+ * signTransaction: true,
105
+ * sendTransaction: true,
106
+ * broadcast: true,
107
+ * sendAbis: true,
108
+ * });
109
+ * ```
110
+ */
111
+ functions: {
112
+ [x: string]: <T = Record<string, any>>(
113
+ args?: any,
114
+ opts?: CallContractOptions
115
+ ) => Promise<{
116
+ operation: OperationJson;
117
+ transaction?: TransactionJsonWait;
118
+ result?: T;
119
+ receipt?: TransactionReceipt;
120
+ }>;
121
+ };
122
+
123
+ /**
124
+ * Application Binary Interface
125
+ */
126
+ abi?: Abi;
127
+
128
+ /**
129
+ * Signer interacting with the smart contract
130
+ */
131
+ signer?: SignerInterface;
132
+
133
+ /**
134
+ * Provider to connect with the blockchain
135
+ */
136
+ provider?: Provider;
137
+
138
+ /**
139
+ * Serializer to serialize/deserialize data types
140
+ */
141
+ serializer?: Serializer;
142
+
143
+ /**
144
+ * Bytecode. Needed to deploy the smart contract.
145
+ */
146
+ bytecode?: Uint8Array;
147
+
148
+ /**
149
+ * Options to apply when creating transactions.
150
+ * By default it set rc_limit to 1e8, sendTransaction true,
151
+ * sendAbis true, and nonce undefined (to get it from the blockchain)
152
+ */
153
+ options: CallContractOptions;
154
+
155
+ constructor(c: {
156
+ id?: string;
157
+ abi?: Abi;
158
+ bytecode?: Uint8Array;
159
+ options?: CallContractOptions;
160
+ signer?: Signer;
161
+ provider?: Provider;
162
+ /**
163
+ * Set this option if you can not use _eval_ functions
164
+ * in the current environment. In such cases, the
165
+ * serializer must come from an environment where it
166
+ * is able to use those functions.
167
+ */
168
+ serializer?: Serializer;
169
+ }) {
170
+ this.signer = c.signer;
171
+ if (c.id) this.id = decodeBase58(c.id);
172
+ else {
173
+ if (!this.signer)
174
+ throw new Error("at least signer or contract id must be defined");
175
+ this.id = decodeBase58(this.signer.getAddress());
176
+ }
177
+ this.provider = c.provider || c.signer?.provider;
178
+ this.abi = c.abi;
179
+ this.bytecode = c.bytecode;
180
+ if (c.serializer) {
181
+ this.serializer = c.serializer;
182
+ } else if (c.abi && c.abi.koilib_types) {
183
+ this.serializer = new Serializer(c.abi.koilib_types);
184
+ } else if (c.abi && c.abi.types) {
185
+ this.serializer = new Serializer(c.abi.types);
186
+ }
187
+ this.options = {
188
+ signTransaction: true,
189
+ sendTransaction: true,
190
+ broadcast: true,
191
+ sendAbis: true,
192
+ ...c.options,
193
+ };
194
+ this.functions = {};
195
+ this.updateFunctionsFromAbi();
196
+ }
197
+
198
+ /**
199
+ * Get contract Id
200
+ */
201
+ getId(): string {
202
+ return encodeBase58(this.id);
203
+ }
204
+
205
+ /**
206
+ * Fetch the ABI from the contract meta store and save it in the
207
+ * abi of the contract. The provider must have contract_meta_store
208
+ * microservice enabled.
209
+ * @param opts - options object with 2 boolean: 1) updateFunctions to
210
+ * specify if the contract functions should be regenerated based on
211
+ * the new ABI, and 2) updateSerializer to determine if the serializer
212
+ * should be updated with the types in the new ABI.
213
+ * @returns the new ABI saved in the contract
214
+ */
215
+ async fetchAbi(
216
+ opts: {
217
+ updateFunctions: boolean;
218
+ updateSerializer: boolean;
219
+ } = {
220
+ updateFunctions: true,
221
+ updateSerializer: true,
222
+ }
223
+ ): Promise<Abi | undefined> {
224
+ if (!this.provider) throw new Error("provider not found");
225
+ const response = await this.provider.call<{ meta: { abi: string } }>(
226
+ "contract_meta_store.get_contract_meta",
227
+ {
228
+ contract_id: this.getId(),
229
+ }
230
+ );
231
+ if (!response.meta || !response.meta.abi) return undefined;
232
+ this.abi = JSON.parse(response.meta.abi) as Abi;
233
+ if (opts.updateFunctions) this.updateFunctionsFromAbi();
234
+ if (opts.updateSerializer) {
235
+ if (this.abi.koilib_types)
236
+ this.serializer = new Serializer(this.abi.koilib_types);
237
+ else if (this.abi.types) this.serializer = new Serializer(this.abi.types);
238
+ }
239
+
240
+ return this.abi;
241
+ }
242
+
243
+ /**
244
+ * Create the contract functions based on the ABI
245
+ */
246
+ updateFunctionsFromAbi(): boolean {
247
+ if (!this.abi || !this.abi.methods) return false;
248
+ Object.keys(this.abi.methods).forEach((name) => {
249
+ this.functions[name] = async <T = Record<string, unknown>>(
250
+ argu: unknown = {},
251
+ options?: CallContractOptions
252
+ ): Promise<{
253
+ operation: OperationJson;
254
+ transaction?: TransactionJsonWait;
255
+ result?: T;
256
+ receipt?: TransactionReceipt;
257
+ }> => {
258
+ if (!this.provider) throw new Error("provider not found");
259
+ if (!this.abi || !this.abi.methods)
260
+ throw new Error("Methods are not defined");
261
+ if (!this.abi.methods[name])
262
+ throw new Error(`Method ${name} not defined in the ABI`);
263
+ const opts: CallContractOptions = {
264
+ ...this.options,
265
+ ...options,
266
+ };
267
+
268
+ const {
269
+ read_only: readOnly,
270
+ return: output,
271
+ default_output: defaultOutput,
272
+ preformat_argument: preformatArgument,
273
+ preformat_return: preformatReturn,
274
+ } = this.abi.methods[name];
275
+ let args: Record<string, unknown>;
276
+ if (typeof preformatArgument === "function") {
277
+ args = preformatArgument(argu);
278
+ } else {
279
+ args = argu as Record<string, unknown>;
280
+ }
281
+
282
+ const operation = await this.encodeOperation({ name, args });
283
+
284
+ if (opts.onlyOperation) {
285
+ return { operation };
286
+ }
287
+
288
+ if (readOnly) {
289
+ if (!output) throw new Error(`No output defined for ${name}`);
290
+ // read contract
291
+ const { result: resultEncoded } = await this.provider.readContract(
292
+ operation.call_contract!
293
+ );
294
+ let result = defaultOutput as T;
295
+ if (resultEncoded) {
296
+ result = await this.serializer!.deserialize<T>(
297
+ resultEncoded,
298
+ output
299
+ );
300
+ }
301
+ if (typeof preformatReturn === "function") {
302
+ result = preformatReturn(result as Record<string, unknown>) as T;
303
+ }
304
+ return { operation, result };
305
+ }
306
+
307
+ // write contract (sign and send)
308
+ if (!this.signer) throw new Error("signer not found");
309
+ let tx = await this.signer.prepareTransaction({
310
+ header: {
311
+ ...(opts.chainId && { chain_id: opts.chainId }),
312
+ ...(opts.rcLimit && { rc_limit: opts.rcLimit }),
313
+ ...(opts.nonce && { nonce: opts.nonce }),
314
+ ...(opts.payer && { payer: opts.payer }),
315
+ ...(opts.payee && { payee: opts.payee }),
316
+ },
317
+ operations: [
318
+ ...(opts.previousOperations ? opts.previousOperations : []),
319
+ operation,
320
+ ...(opts.nextOperations ? opts.nextOperations : []),
321
+ ],
322
+ });
323
+
324
+ if (opts.sendAbis) {
325
+ if (!opts.abis) opts.abis = {};
326
+ const contractId = this.getId();
327
+ if (!opts.abis[contractId]) opts.abis[contractId] = this.abi;
328
+ }
329
+
330
+ // return result if the transaction will not be broadcasted
331
+ if (!opts.sendTransaction) {
332
+ const noWait = () => {
333
+ throw new Error("This transaction was not broadcasted");
334
+ };
335
+ if (opts.signTransaction)
336
+ tx = await this.signer.signTransaction(
337
+ tx,
338
+ opts.sendAbis ? opts.abis : undefined
339
+ );
340
+ return { operation, transaction: { ...tx, wait: noWait } };
341
+ }
342
+
343
+ const { transaction, receipt } = await this.signer.sendTransaction(
344
+ tx,
345
+ opts
346
+ );
347
+ return { operation, transaction, receipt };
348
+ };
349
+ });
350
+ return true;
351
+ }
352
+
353
+ /**
354
+ * Function to deploy a new smart contract.
355
+ * The Bytecode must be defined in the constructor of the class
356
+ * @example
357
+ * ```ts
358
+ * const privateKey = "f186a5de49797bfd52dc42505c33d75a46822ed5b60046e09d7c336242e20200";
359
+ * const provider = new Provider(["http://api.koinos.io:8080"]);
360
+ * const signer = new Signer({ privateKey, provider });
361
+ * const bytecode = new Uint8Array([1, 2, 3, 4]);
362
+ * const contract = new Contract({ signer, provider, bytecode });
363
+ * const { transaction, receipt } = await contract.deploy();
364
+ * console.log(receipt);
365
+ * // wait to be mined
366
+ * const blockNumber = await transaction.wait();
367
+ * console.log(`Contract uploaded in block number ${blockNumber}`);
368
+ * ```
369
+ *
370
+ * @example using options
371
+ * ```ts
372
+ * const { transaction, receipt } = await contract.deploy({
373
+ * // contract options
374
+ * abi: "CssCChRrb2lub3Mvb3B0aW9ucy5wc...",
375
+ * authorizesCallContract: true,
376
+ * authorizesTransactionApplication: true,
377
+ * authorizesUploadContract: true,
378
+ *
379
+ * // transaction options
380
+ * chainId: "EiB-hw5ABo-EXy6fGDd1Iq3gbAenxQ4Qe60pRbEVMVrR9A==",
381
+ * rcLimit: "100000000",
382
+ * nonce: "OAI=",
383
+ * payer: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
384
+ * payee: "1Gvqdo9if6v6tFomEuTuMWP1D7H7U9yksb",
385
+ *
386
+ * // sign and broadcast
387
+ * signTransaction: true,
388
+ * sendTransaction: true,
389
+ * broadcast: true,
390
+ * });
391
+ * console.log(receipt);
392
+ * // wait to be mined
393
+ * const blockNumber = await transaction.wait();
394
+ * console.log(`Contract uploaded in block number ${blockNumber}`);
395
+ * ```
396
+ */
397
+ async deploy(options?: DeployOptions): Promise<{
398
+ operation: OperationJson;
399
+ transaction?: TransactionJsonWait;
400
+ receipt?: TransactionReceipt;
401
+ }> {
402
+ if (!this.signer) throw new Error("signer not found");
403
+ if (!this.bytecode) throw new Error("bytecode not found");
404
+ const opts: DeployOptions = {
405
+ ...this.options,
406
+ ...options,
407
+ };
408
+
409
+ const contractId = this.getId();
410
+
411
+ const operation = {
412
+ upload_contract: {
413
+ contract_id: contractId,
414
+ bytecode: encodeBase64url(this.bytecode),
415
+ ...(opts.abi && { abi: opts.abi }),
416
+ ...(opts.authorizesCallContract && {
417
+ authorizes_call_contract: opts.authorizesCallContract,
418
+ }),
419
+ ...(opts.authorizesTransactionApplication && {
420
+ authorizes_transaction_application:
421
+ opts.authorizesTransactionApplication,
422
+ }),
423
+ ...(opts.authorizesUploadContract && {
424
+ authorizes_upload_contract: opts.authorizesUploadContract,
425
+ }),
426
+ },
427
+ } as OperationJson;
428
+
429
+ if (opts.onlyOperation) {
430
+ return { operation };
431
+ }
432
+
433
+ let tx = await this.signer.prepareTransaction({
434
+ header: {
435
+ ...(opts.chainId && { chain_id: opts.chainId }),
436
+ ...(opts.rcLimit && { rc_limit: opts.rcLimit }),
437
+ ...(opts.nonce && { nonce: opts.nonce }),
438
+ ...(opts.payer && { payer: opts.payer }),
439
+ ...(opts.payee && { payee: opts.payee }),
440
+ },
441
+ operations: [
442
+ ...(opts.previousOperations ? opts.previousOperations : []),
443
+ operation,
444
+ ...(opts.nextOperations ? opts.nextOperations : []),
445
+ ],
446
+ });
447
+
448
+ // return result if the transaction will not be broadcasted
449
+ if (!opts.sendTransaction) {
450
+ const noWait = () => {
451
+ throw new Error("This transaction was not broadcasted");
452
+ };
453
+ if (opts.signTransaction)
454
+ tx = await this.signer.signTransaction(
455
+ tx,
456
+ opts.sendAbis ? opts.abis : undefined
457
+ );
458
+ return { operation, transaction: { ...tx, wait: noWait } };
459
+ }
460
+
461
+ const { transaction, receipt } = await this.signer.sendTransaction(
462
+ tx,
463
+ opts
464
+ );
465
+ return { operation, transaction, receipt };
466
+ }
467
+
468
+ /**
469
+ * Encondes a contract operation using Koinos serialization
470
+ * and taking the contract entries as reference to build it
471
+ * @param op - Operation to encode
472
+ * @returns Operation encoded
473
+ * @example
474
+ * ```ts
475
+ * const opEncoded = contract.encodeOperation({
476
+ * name: "transfer",
477
+ * args: {
478
+ * from: "12fN2CQnuJM8cMnWZ1hPtM4knjLME8E4PD",
479
+ * to: "172AB1FgCsYrRAW5cwQ8KjadgxofvgPFd6",
480
+ * value: "1000",
481
+ * }
482
+ * });
483
+ *
484
+ * console.log(opEncoded);
485
+ * // {
486
+ * // call_contract: {
487
+ * // contract_id: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
488
+ * // entry_point: 670398154,
489
+ * // args: "ChkAEjl6vrl55V2Oym_rzsnMxIqBoie9PHmMEhkAQgjT1UACatdFY3e5QRkyG7OAzwcCCIylGOgH",
490
+ * // }
491
+ * // }
492
+ * ```
493
+ */
494
+ async encodeOperation(op: DecodedOperationJson): Promise<OperationJson> {
495
+ if (!this.abi || !this.abi.methods || !this.abi.methods[op.name])
496
+ throw new Error(`Operation ${op.name} unknown`);
497
+ if (!this.serializer) throw new Error("Serializer is not defined");
498
+ const method = this.abi.methods[op.name];
499
+
500
+ let bufferArguments = new Uint8Array(0);
501
+ if (method.argument) {
502
+ if (!op.args)
503
+ throw new Error(`No arguments defined for type '${method.argument}'`);
504
+ bufferArguments = await this.serializer.serialize(
505
+ op.args,
506
+ method.argument
507
+ );
508
+ }
509
+
510
+ return {
511
+ call_contract: {
512
+ contract_id: this.getId(),
513
+ entry_point: method.entry_point,
514
+ args: encodeBase64url(bufferArguments),
515
+ },
516
+ };
517
+ }
518
+
519
+ /**
520
+ * Decodes a contract operation to be human readable
521
+ * @example
522
+ * ```ts
523
+ * const opDecoded = contract.decodeOperation({
524
+ * call_contract: {
525
+ * contract_id: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
526
+ * entry_point: 0x27f576ca,
527
+ * args: "ChkAEjl6vrl55V2Oym_rzsnMxIqBoie9PHmMEhkAQgjT1UACatdFY3e5QRkyG7OAzwcCCIylGOgH",
528
+ * }
529
+ * });
530
+ * console.log(opDecoded);
531
+ * // {
532
+ * // name: "transfer",
533
+ * // args: {
534
+ * // from: "12fN2CQnuJM8cMnWZ1hPtM4knjLME8E4PD",
535
+ * // to: "172AB1FgCsYrRAW5cwQ8KjadgxofvgPFd6",
536
+ * // value: "1000",
537
+ * // },
538
+ * // }
539
+ * ```
540
+ */
541
+ async decodeOperation(op: OperationJson): Promise<DecodedOperationJson> {
542
+ if (!this.abi || !this.abi.methods)
543
+ throw new Error("Methods are not defined");
544
+ if (!this.serializer) throw new Error("Serializer is not defined");
545
+ if (!op.call_contract)
546
+ throw new Error("Operation is not CallContractOperation");
547
+ if (op.call_contract.contract_id !== this.getId())
548
+ throw new Error(
549
+ `Invalid contract id. Expected: ${this.getId()}. Received: ${
550
+ op.call_contract.contract_id
551
+ }`
552
+ );
553
+ for (let i = 0; i < Object.keys(this.abi.methods).length; i += 1) {
554
+ const opName = Object.keys(this.abi.methods)[i];
555
+ const method = this.abi.methods[opName];
556
+ if (op.call_contract.entry_point === method.entry_point) {
557
+ if (!method.argument) return { name: opName };
558
+ return {
559
+ name: opName,
560
+ args: await this.serializer.deserialize(
561
+ op.call_contract.args,
562
+ method.argument
563
+ ),
564
+ };
565
+ }
566
+ }
567
+ throw new Error(`Unknown method id ${op.call_contract.entry_point}`);
568
+ }
569
+
570
+ /**
571
+ * Decode an event received in a receipt
572
+ *
573
+ * @example
574
+ * ```ts
575
+ * const contract = new Contract({
576
+ * id: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
577
+ * abi: utils.tokenAbi,
578
+ * });
579
+ * const event = {
580
+ * sequence: 1,
581
+ * source: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
582
+ * name: "koinos.contracts.token.mint_event",
583
+ * data: "ChkAxjdqxuwS-B50lPQ-lqhRBA3bf2b2ooAHENrw3Ek=",
584
+ * impacted: ["1K55BRw87nd64a7aiRarp6DLGRzYvoJo8J"],
585
+ * };
586
+ * const eventDecoded = await contract.decodeEvent(event);
587
+ * console.log(eventDecoded);
588
+ * // {
589
+ * // sequence: 1,
590
+ * // source: "19JntSm8pSNETT9aHTwAUHC5RMoaSmgZPJ",
591
+ * // name: "koinos.contracts.token.mint_event",
592
+ * // data: "ChkAxjdqxuwS-B50lPQ-lqhRBA3bf2b2ooAHENrw3Ek=",
593
+ * // impacted: ["1K55BRw87nd64a7aiRarp6DLGRzYvoJo8J"],
594
+ * // args: {
595
+ * // to: "1K55BRw87nd64a7aiRarp6DLGRzYvoJo8J",
596
+ * // value: "154613850",
597
+ * // },
598
+ * // }
599
+ * ```
600
+ */
601
+ async decodeEvent(event: EventData): Promise<DecodedEventData> {
602
+ if (!this.serializer) throw new Error("Serializer is not defined");
603
+ let typeName = event.name;
604
+ if (this.abi && this.abi.events && this.abi.events[event.name]) {
605
+ typeName = this.abi.events[event.name].argument as string;
606
+ }
607
+ const args = typeName
608
+ ? await this.serializer.deserialize(event.data, typeName)
609
+ : {};
610
+ return { ...event, args };
611
+ }
612
+ }
613
+
614
+ export default Contract;