wrappers.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // import from provider.ts instead of index.ts to prevent circular dep
  2. // from EtherscanProvider
  3. import {
  4. Block, Log, TransactionReceipt, TransactionResponse
  5. } from "../providers/provider.js";
  6. import { defineProperties, EventPayload } from "../utils/index.js";
  7. import type { EventFragment, Interface, Result } from "../abi/index.js";
  8. import type { Listener } from "../utils/index.js";
  9. import type {
  10. Provider
  11. } from "../providers/index.js";
  12. import type { BaseContract } from "./contract.js";
  13. import type { ContractEventName } from "./types.js";
  14. /**
  15. * An **EventLog** contains additional properties parsed from the [[Log]].
  16. */
  17. export class EventLog extends Log {
  18. /**
  19. * The Contract Interface.
  20. */
  21. readonly interface!: Interface;
  22. /**
  23. * The matching event.
  24. */
  25. readonly fragment!: EventFragment;
  26. /**
  27. * The parsed arguments passed to the event by ``emit``.
  28. */
  29. readonly args!: Result;
  30. /**
  31. * @_ignore:
  32. */
  33. constructor(log: Log, iface: Interface, fragment: EventFragment) {
  34. super(log, log.provider);
  35. const args = iface.decodeEventLog(fragment, log.data, log.topics);
  36. defineProperties<EventLog>(this, { args, fragment, interface: iface });
  37. }
  38. /**
  39. * The name of the event.
  40. */
  41. get eventName(): string { return this.fragment.name; }
  42. /**
  43. * The signature of the event.
  44. */
  45. get eventSignature(): string { return this.fragment.format(); }
  46. }
  47. /**
  48. * An **EventLog** contains additional properties parsed from the [[Log]].
  49. */
  50. export class UndecodedEventLog extends Log {
  51. /**
  52. * The error encounted when trying to decode the log.
  53. */
  54. readonly error!: Error;
  55. /**
  56. * @_ignore:
  57. */
  58. constructor(log: Log, error: Error) {
  59. super(log, log.provider);
  60. defineProperties<UndecodedEventLog>(this, { error });
  61. }
  62. }
  63. /**
  64. * A **ContractTransactionReceipt** includes the parsed logs from a
  65. * [[TransactionReceipt]].
  66. */
  67. export class ContractTransactionReceipt extends TransactionReceipt {
  68. readonly #iface: Interface;
  69. /**
  70. * @_ignore:
  71. */
  72. constructor(iface: Interface, provider: Provider, tx: TransactionReceipt) {
  73. super(tx, provider);
  74. this.#iface = iface;
  75. }
  76. /**
  77. * The parsed logs for any [[Log]] which has a matching event in the
  78. * Contract ABI.
  79. */
  80. get logs(): Array<EventLog | Log> {
  81. return super.logs.map((log) => {
  82. const fragment = log.topics.length ? this.#iface.getEvent(log.topics[0]): null;
  83. if (fragment) {
  84. try {
  85. return new EventLog(log, this.#iface, fragment)
  86. } catch (error: any) {
  87. return new UndecodedEventLog(log, error);
  88. }
  89. }
  90. return log;
  91. });
  92. }
  93. }
  94. /**
  95. * A **ContractTransactionResponse** will return a
  96. * [[ContractTransactionReceipt]] when waited on.
  97. */
  98. export class ContractTransactionResponse extends TransactionResponse {
  99. readonly #iface: Interface;
  100. /**
  101. * @_ignore:
  102. */
  103. constructor(iface: Interface, provider: Provider, tx: TransactionResponse) {
  104. super(tx, provider);
  105. this.#iface = iface;
  106. }
  107. /**
  108. * Resolves once this transaction has been mined and has
  109. * %%confirms%% blocks including it (default: ``1``) with an
  110. * optional %%timeout%%.
  111. *
  112. * This can resolve to ``null`` only if %%confirms%% is ``0``
  113. * and the transaction has not been mined, otherwise this will
  114. * wait until enough confirmations have completed.
  115. */
  116. async wait(confirms?: number, timeout?: number): Promise<null | ContractTransactionReceipt> {
  117. const receipt = await super.wait(confirms, timeout);
  118. if (receipt == null) { return null; }
  119. return new ContractTransactionReceipt(this.#iface, this.provider, receipt);
  120. }
  121. }
  122. /**
  123. * A **ContractUnknownEventPayload** is included as the last parameter to
  124. * Contract Events when the event does not match any events in the ABI.
  125. */
  126. export class ContractUnknownEventPayload extends EventPayload<ContractEventName> {
  127. /**
  128. * The log with no matching events.
  129. */
  130. readonly log!: Log;
  131. /**
  132. * @_event:
  133. */
  134. constructor(contract: BaseContract, listener: null | Listener, filter: ContractEventName, log: Log) {
  135. super(contract, listener, filter);
  136. defineProperties<ContractUnknownEventPayload>(this, { log });
  137. }
  138. /**
  139. * Resolves to the block the event occured in.
  140. */
  141. async getBlock(): Promise<Block> {
  142. return await this.log.getBlock();
  143. }
  144. /**
  145. * Resolves to the transaction the event occured in.
  146. */
  147. async getTransaction(): Promise<TransactionResponse> {
  148. return await this.log.getTransaction();
  149. }
  150. /**
  151. * Resolves to the transaction receipt the event occured in.
  152. */
  153. async getTransactionReceipt(): Promise<TransactionReceipt> {
  154. return await this.log.getTransactionReceipt();
  155. }
  156. }
  157. /**
  158. * A **ContractEventPayload** is included as the last parameter to
  159. * Contract Events when the event is known.
  160. */
  161. export class ContractEventPayload extends ContractUnknownEventPayload {
  162. /**
  163. * The matching event.
  164. */
  165. declare readonly fragment: EventFragment;
  166. /**
  167. * The log, with parsed properties.
  168. */
  169. declare readonly log: EventLog;
  170. /**
  171. * The parsed arguments passed to the event by ``emit``.
  172. */
  173. declare readonly args: Result;
  174. /**
  175. * @_ignore:
  176. */
  177. constructor(contract: BaseContract, listener: null | Listener, filter: ContractEventName, fragment: EventFragment, _log: Log) {
  178. super(contract, listener, filter, new EventLog(_log, contract.interface, fragment));
  179. const args = contract.interface.decodeEventLog(fragment, this.log.data, this.log.topics);
  180. defineProperties<ContractEventPayload>(this, { args, fragment });
  181. }
  182. /**
  183. * The event name.
  184. */
  185. get eventName(): string {
  186. return this.fragment.name;
  187. }
  188. /**
  189. * The event signature.
  190. */
  191. get eventSignature(): string {
  192. return this.fragment.format();
  193. }
  194. }