@nomicfoundation/hardhat-ethers-chai-matchers 3.0.0-next.0

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 (173) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +52 -0
  3. package/dist/src/index.d.ts +5 -0
  4. package/dist/src/index.d.ts.map +1 -0
  5. package/dist/src/index.js +16 -0
  6. package/dist/src/index.js.map +1 -0
  7. package/dist/src/internal/add-chai-matchers.d.ts +2 -0
  8. package/dist/src/internal/add-chai-matchers.d.ts.map +1 -0
  9. package/dist/src/internal/add-chai-matchers.js +41 -0
  10. package/dist/src/internal/add-chai-matchers.js.map +1 -0
  11. package/dist/src/internal/constants.d.ts +13 -0
  12. package/dist/src/internal/constants.d.ts.map +1 -0
  13. package/dist/src/internal/constants.js +13 -0
  14. package/dist/src/internal/constants.js.map +1 -0
  15. package/dist/src/internal/hook-handlers/network.d.ts +4 -0
  16. package/dist/src/internal/hook-handlers/network.d.ts.map +1 -0
  17. package/dist/src/internal/hook-handlers/network.js +15 -0
  18. package/dist/src/internal/hook-handlers/network.js.map +1 -0
  19. package/dist/src/internal/matchers/addressable.d.ts +2 -0
  20. package/dist/src/internal/matchers/addressable.d.ts.map +1 -0
  21. package/dist/src/internal/matchers/addressable.js +53 -0
  22. package/dist/src/internal/matchers/addressable.js.map +1 -0
  23. package/dist/src/internal/matchers/big-number.d.ts +2 -0
  24. package/dist/src/internal/matchers/big-number.d.ts.map +1 -0
  25. package/dist/src/internal/matchers/big-number.js +178 -0
  26. package/dist/src/internal/matchers/big-number.js.map +1 -0
  27. package/dist/src/internal/matchers/changeEtherBalance.d.ts +7 -0
  28. package/dist/src/internal/matchers/changeEtherBalance.d.ts.map +1 -0
  29. package/dist/src/internal/matchers/changeEtherBalance.js +77 -0
  30. package/dist/src/internal/matchers/changeEtherBalance.js.map +1 -0
  31. package/dist/src/internal/matchers/changeEtherBalances.d.ts +7 -0
  32. package/dist/src/internal/matchers/changeEtherBalances.d.ts.map +1 -0
  33. package/dist/src/internal/matchers/changeEtherBalances.js +96 -0
  34. package/dist/src/internal/matchers/changeEtherBalances.js.map +1 -0
  35. package/dist/src/internal/matchers/changeTokenBalance.d.ts +16 -0
  36. package/dist/src/internal/matchers/changeTokenBalance.d.ts.map +1 -0
  37. package/dist/src/internal/matchers/changeTokenBalance.js +148 -0
  38. package/dist/src/internal/matchers/changeTokenBalance.js.map +1 -0
  39. package/dist/src/internal/matchers/emit.d.ts +5 -0
  40. package/dist/src/internal/matchers/emit.d.ts.map +1 -0
  41. package/dist/src/internal/matchers/emit.js +122 -0
  42. package/dist/src/internal/matchers/emit.js.map +1 -0
  43. package/dist/src/internal/matchers/hexEqual.d.ts +2 -0
  44. package/dist/src/internal/matchers/hexEqual.d.ts.map +1 -0
  45. package/dist/src/internal/matchers/hexEqual.js +19 -0
  46. package/dist/src/internal/matchers/hexEqual.js.map +1 -0
  47. package/dist/src/internal/matchers/properAddress.d.ts +2 -0
  48. package/dist/src/internal/matchers/properAddress.d.ts.map +1 -0
  49. package/dist/src/internal/matchers/properAddress.js +7 -0
  50. package/dist/src/internal/matchers/properAddress.js.map +1 -0
  51. package/dist/src/internal/matchers/properHex.d.ts +2 -0
  52. package/dist/src/internal/matchers/properHex.d.ts.map +1 -0
  53. package/dist/src/internal/matchers/properHex.js +13 -0
  54. package/dist/src/internal/matchers/properHex.js.map +1 -0
  55. package/dist/src/internal/matchers/properPrivateKey.d.ts +2 -0
  56. package/dist/src/internal/matchers/properPrivateKey.d.ts.map +1 -0
  57. package/dist/src/internal/matchers/properPrivateKey.js +7 -0
  58. package/dist/src/internal/matchers/properPrivateKey.js.map +1 -0
  59. package/dist/src/internal/matchers/reverted/panic.d.ts +13 -0
  60. package/dist/src/internal/matchers/reverted/panic.d.ts.map +1 -0
  61. package/dist/src/internal/matchers/reverted/panic.js +36 -0
  62. package/dist/src/internal/matchers/reverted/panic.js.map +1 -0
  63. package/dist/src/internal/matchers/reverted/reverted.d.ts +2 -0
  64. package/dist/src/internal/matchers/reverted/reverted.d.ts.map +1 -0
  65. package/dist/src/internal/matchers/reverted/reverted.js +112 -0
  66. package/dist/src/internal/matchers/reverted/reverted.js.map +1 -0
  67. package/dist/src/internal/matchers/reverted/revertedWith.d.ts +2 -0
  68. package/dist/src/internal/matchers/reverted/revertedWith.d.ts.map +1 -0
  69. package/dist/src/internal/matchers/reverted/revertedWith.js +56 -0
  70. package/dist/src/internal/matchers/reverted/revertedWith.js.map +1 -0
  71. package/dist/src/internal/matchers/reverted/revertedWithCustomError.d.ts +5 -0
  72. package/dist/src/internal/matchers/reverted/revertedWithCustomError.d.ts.map +1 -0
  73. package/dist/src/internal/matchers/reverted/revertedWithCustomError.js +120 -0
  74. package/dist/src/internal/matchers/reverted/revertedWithCustomError.js.map +1 -0
  75. package/dist/src/internal/matchers/reverted/revertedWithPanic.d.ts +2 -0
  76. package/dist/src/internal/matchers/reverted/revertedWithPanic.d.ts.map +1 -0
  77. package/dist/src/internal/matchers/reverted/revertedWithPanic.js +74 -0
  78. package/dist/src/internal/matchers/reverted/revertedWithPanic.js.map +1 -0
  79. package/dist/src/internal/matchers/reverted/revertedWithoutReason.d.ts +2 -0
  80. package/dist/src/internal/matchers/reverted/revertedWithoutReason.d.ts.map +1 -0
  81. package/dist/src/internal/matchers/reverted/revertedWithoutReason.js +41 -0
  82. package/dist/src/internal/matchers/reverted/revertedWithoutReason.js.map +1 -0
  83. package/dist/src/internal/matchers/reverted/utils.d.ts +39 -0
  84. package/dist/src/internal/matchers/reverted/utils.d.ts.map +1 -0
  85. package/dist/src/internal/matchers/reverted/utils.js +108 -0
  86. package/dist/src/internal/matchers/reverted/utils.js.map +1 -0
  87. package/dist/src/internal/matchers/withArgs.d.ts +16 -0
  88. package/dist/src/internal/matchers/withArgs.d.ts.map +1 -0
  89. package/dist/src/internal/matchers/withArgs.js +88 -0
  90. package/dist/src/internal/matchers/withArgs.js.map +1 -0
  91. package/dist/src/internal/utils/account.d.ts +3 -0
  92. package/dist/src/internal/utils/account.d.ts.map +1 -0
  93. package/dist/src/internal/utils/account.js +15 -0
  94. package/dist/src/internal/utils/account.js.map +1 -0
  95. package/dist/src/internal/utils/asserts.d.ts +5 -0
  96. package/dist/src/internal/utils/asserts.d.ts.map +1 -0
  97. package/dist/src/internal/utils/asserts.js +73 -0
  98. package/dist/src/internal/utils/asserts.js.map +1 -0
  99. package/dist/src/internal/utils/balance.d.ts +8 -0
  100. package/dist/src/internal/utils/balance.d.ts.map +1 -0
  101. package/dist/src/internal/utils/balance.js +19 -0
  102. package/dist/src/internal/utils/balance.js.map +1 -0
  103. package/dist/src/internal/utils/bigint.d.ts +2 -0
  104. package/dist/src/internal/utils/bigint.d.ts.map +1 -0
  105. package/dist/src/internal/utils/bigint.js +4 -0
  106. package/dist/src/internal/utils/bigint.js.map +1 -0
  107. package/dist/src/internal/utils/build-assert.d.ts +19 -0
  108. package/dist/src/internal/utils/build-assert.d.ts.map +1 -0
  109. package/dist/src/internal/utils/build-assert.js +39 -0
  110. package/dist/src/internal/utils/build-assert.js.map +1 -0
  111. package/dist/src/internal/utils/ordinal.d.ts +8 -0
  112. package/dist/src/internal/utils/ordinal.d.ts.map +1 -0
  113. package/dist/src/internal/utils/ordinal.js +21 -0
  114. package/dist/src/internal/utils/ordinal.js.map +1 -0
  115. package/dist/src/internal/utils/prevent-chaining.d.ts +2 -0
  116. package/dist/src/internal/utils/prevent-chaining.d.ts.map +1 -0
  117. package/dist/src/internal/utils/prevent-chaining.js +17 -0
  118. package/dist/src/internal/utils/prevent-chaining.js.map +1 -0
  119. package/dist/src/internal/utils/ssfi.d.ts +4 -0
  120. package/dist/src/internal/utils/ssfi.d.ts.map +1 -0
  121. package/dist/src/internal/utils/ssfi.js +2 -0
  122. package/dist/src/internal/utils/ssfi.js.map +1 -0
  123. package/dist/src/internal/utils/typed.d.ts +2 -0
  124. package/dist/src/internal/utils/typed.d.ts.map +1 -0
  125. package/dist/src/internal/utils/typed.js +10 -0
  126. package/dist/src/internal/utils/typed.js.map +1 -0
  127. package/dist/src/panic.d.ts +2 -0
  128. package/dist/src/panic.d.ts.map +1 -0
  129. package/dist/src/panic.js +2 -0
  130. package/dist/src/panic.js.map +1 -0
  131. package/dist/src/type-extensions.d.ts +45 -0
  132. package/dist/src/type-extensions.d.ts.map +1 -0
  133. package/dist/src/type-extensions.js +2 -0
  134. package/dist/src/type-extensions.js.map +1 -0
  135. package/dist/src/withArgs.d.ts +2 -0
  136. package/dist/src/withArgs.d.ts.map +1 -0
  137. package/dist/src/withArgs.js +2 -0
  138. package/dist/src/withArgs.js.map +1 -0
  139. package/package.json +85 -0
  140. package/src/index.ts +21 -0
  141. package/src/internal/add-chai-matchers.ts +46 -0
  142. package/src/internal/constants.ts +13 -0
  143. package/src/internal/hook-handlers/network.ts +24 -0
  144. package/src/internal/matchers/addressable.ts +86 -0
  145. package/src/internal/matchers/big-number.ts +279 -0
  146. package/src/internal/matchers/changeEtherBalance.ts +138 -0
  147. package/src/internal/matchers/changeEtherBalances.ts +188 -0
  148. package/src/internal/matchers/changeTokenBalance.ts +295 -0
  149. package/src/internal/matchers/emit.ts +232 -0
  150. package/src/internal/matchers/hexEqual.ts +29 -0
  151. package/src/internal/matchers/properAddress.ts +12 -0
  152. package/src/internal/matchers/properHex.ts +29 -0
  153. package/src/internal/matchers/properPrivateKey.ts +12 -0
  154. package/src/internal/matchers/reverted/panic.ts +36 -0
  155. package/src/internal/matchers/reverted/reverted.ts +165 -0
  156. package/src/internal/matchers/reverted/revertedWith.ts +100 -0
  157. package/src/internal/matchers/reverted/revertedWithCustomError.ts +243 -0
  158. package/src/internal/matchers/reverted/revertedWithPanic.ts +118 -0
  159. package/src/internal/matchers/reverted/revertedWithoutReason.ts +73 -0
  160. package/src/internal/matchers/reverted/utils.ts +147 -0
  161. package/src/internal/matchers/withArgs.ts +139 -0
  162. package/src/internal/utils/account.ts +24 -0
  163. package/src/internal/utils/asserts.ts +156 -0
  164. package/src/internal/utils/balance.ts +39 -0
  165. package/src/internal/utils/bigint.ts +3 -0
  166. package/src/internal/utils/build-assert.ts +54 -0
  167. package/src/internal/utils/ordinal.ts +24 -0
  168. package/src/internal/utils/prevent-chaining.ts +33 -0
  169. package/src/internal/utils/ssfi.ts +6 -0
  170. package/src/internal/utils/typed.ts +9 -0
  171. package/src/panic.ts +1 -0
  172. package/src/type-extensions.ts +82 -0
  173. package/src/withArgs.ts +1 -0
@@ -0,0 +1,112 @@
1
+ import { HardhatError } from "@nomicfoundation/hardhat-errors";
2
+ import { numberToHexString } from "@nomicfoundation/hardhat-utils/hex";
3
+ import { REVERTED_MATCHER } from "../../constants.js";
4
+ import { assertIsNotNull } from "../../utils/asserts.js";
5
+ import { buildAssert } from "../../utils/build-assert.js";
6
+ import { preventAsyncMatcherChaining } from "../../utils/prevent-chaining.js";
7
+ import { decodeReturnData, getReturnDataFromError, parseBytes32String, } from "./utils.js";
8
+ export function supportReverted(Assertion, chaiUtils) {
9
+ Assertion.addMethod(REVERTED_MATCHER, function (ethers) {
10
+ // capture negated flag before async code executes; see buildAssert's jsdoc
11
+ const negated = this.__flags.negate;
12
+ const subject = this._obj;
13
+ preventAsyncMatcherChaining(this, REVERTED_MATCHER, chaiUtils);
14
+ // Check if the received value can be linked to a transaction, and then
15
+ // get the receipt of that transaction and check its status.
16
+ //
17
+ // If the value doesn't correspond to a transaction, then the `reverted`
18
+ // assertion is false.
19
+ const onSuccess = async (value) => {
20
+ const assert = buildAssert(negated, onSuccess);
21
+ if (isTransactionResponse(value) || typeof value === "string") {
22
+ const hash = typeof value === "string" ? value : value.hash;
23
+ if (!isValidTransactionHash(hash)) {
24
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.EXPECTED_VALID_TRANSACTION_HASH, {
25
+ hash,
26
+ });
27
+ }
28
+ const receipt = await getTransactionReceipt(ethers, hash);
29
+ if (receipt === null) {
30
+ // If the receipt is null, maybe the string is a bytes32 string
31
+ if (isBytes32String(hash)) {
32
+ assert(false, "Expected transaction to be reverted");
33
+ return;
34
+ }
35
+ }
36
+ assertIsNotNull(receipt, "receipt");
37
+ assert(receipt.status === 0, "Expected transaction to be reverted", "Expected transaction NOT to be reverted");
38
+ }
39
+ else if (isTransactionReceipt(value)) {
40
+ const receipt = value;
41
+ assert(receipt.status === 0, "Expected transaction to be reverted", "Expected transaction NOT to be reverted");
42
+ }
43
+ else {
44
+ // If the subject of the assertion is not connected to a transaction
45
+ // (hash, receipt, etc.), then the assertion fails.
46
+ // Since we use `false` here, this means that `.not.to.be.reverted`
47
+ // assertions will pass instead of always throwing a validation error.
48
+ // This allows users to do things like:
49
+ // `expect(c.callStatic.f()).to.not.be.reverted`
50
+ assert(false, "Expected transaction to be reverted");
51
+ }
52
+ };
53
+ const onError = (error) => {
54
+ const assert = buildAssert(negated, onError);
55
+ const returnData = getReturnDataFromError(error);
56
+ const decodedReturnData = decodeReturnData(returnData);
57
+ if (decodedReturnData.kind === "Empty" ||
58
+ decodedReturnData.kind === "Custom") {
59
+ // in the negated case, if we can't decode the reason, we just indicate
60
+ // that the transaction didn't revert
61
+ assert(true, undefined, `Expected transaction NOT to be reverted`);
62
+ }
63
+ else if (decodedReturnData.kind === "Error") {
64
+ assert(true, undefined, `Expected transaction NOT to be reverted, but it reverted with reason '${decodedReturnData.reason}'`);
65
+ }
66
+ else if (decodedReturnData.kind === "Panic") {
67
+ assert(true, undefined, `Expected transaction NOT to be reverted, but it reverted with panic code ${numberToHexString(decodedReturnData.code)} (${decodedReturnData.description})`);
68
+ }
69
+ else {
70
+ const _exhaustiveCheck = decodedReturnData;
71
+ }
72
+ };
73
+ // we use `Promise.resolve(subject)` so we can process both values and
74
+ // promises of values in the same way
75
+ const derivedPromise = Promise.resolve(subject).then(onSuccess, onError);
76
+ this.then = derivedPromise.then.bind(derivedPromise);
77
+ this.catch = derivedPromise.catch.bind(derivedPromise);
78
+ return this;
79
+ });
80
+ }
81
+ async function getTransactionReceipt(ethers, hash) {
82
+ return ethers.provider.getTransactionReceipt(hash);
83
+ }
84
+ function isTransactionResponse(x) {
85
+ if (typeof x === "object" && x !== null) {
86
+ return "hash" in x;
87
+ }
88
+ return false;
89
+ }
90
+ function isTransactionReceipt(x) {
91
+ if (typeof x === "object" && x !== null && "status" in x) {
92
+ const status = x.status;
93
+ // this means we only support ethers's receipts for now; adding support for
94
+ // raw receipts, where the status is an hexadecimal string, should be easy
95
+ // and we can do it if there's demand for that
96
+ return typeof status === "number";
97
+ }
98
+ return false;
99
+ }
100
+ function isValidTransactionHash(x) {
101
+ return /0x[0-9a-fA-F]{64}/.test(x);
102
+ }
103
+ function isBytes32String(v) {
104
+ try {
105
+ parseBytes32String(v);
106
+ return true;
107
+ }
108
+ catch {
109
+ return false;
110
+ }
111
+ }
112
+ //# sourceMappingURL=reverted.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverted.js","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/reverted.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function supportRevertedWith(Assertion: Chai.AssertionStatic, chaiUtils: Chai.ChaiUtils): void;
2
+ //# sourceMappingURL=revertedWith.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertedWith.d.ts","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/revertedWith.ts"],"names":[],"mappings":"AASA,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,IAAI,CAAC,eAAe,EAC/B,SAAS,EAAE,IAAI,CAAC,SAAS,GACxB,IAAI,CAuFN"}
@@ -0,0 +1,56 @@
1
+ import { HardhatError } from "@nomicfoundation/hardhat-errors";
2
+ import { numberToHexString } from "@nomicfoundation/hardhat-utils/hex";
3
+ import { REVERTED_WITH_MATCHER } from "../../constants.js";
4
+ import { buildAssert } from "../../utils/build-assert.js";
5
+ import { preventAsyncMatcherChaining } from "../../utils/prevent-chaining.js";
6
+ import { decodeReturnData, getReturnDataFromError } from "./utils.js";
7
+ export function supportRevertedWith(Assertion, chaiUtils) {
8
+ Assertion.addMethod(REVERTED_WITH_MATCHER, function (expectedReason) {
9
+ // capture negated flag before async code executes; see buildAssert's jsdoc
10
+ const negated = this.__flags.negate;
11
+ // validate expected reason
12
+ if (!(expectedReason instanceof RegExp) &&
13
+ typeof expectedReason !== "string") {
14
+ // if the input validation fails, we discard the subject since it could
15
+ // potentially be a rejected promise
16
+ Promise.resolve(this._obj).catch(() => { });
17
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.EXPECT_STRING_OR_REGEX_AS_REVERT_REASON);
18
+ }
19
+ const expectedReasonString = expectedReason instanceof RegExp
20
+ ? expectedReason.source
21
+ : expectedReason;
22
+ preventAsyncMatcherChaining(this, REVERTED_WITH_MATCHER, chaiUtils);
23
+ const onSuccess = () => {
24
+ const assert = buildAssert(negated, onSuccess);
25
+ assert(false, `Expected transaction to be reverted with reason '${expectedReasonString}', but it didn't revert`);
26
+ };
27
+ const onError = (error) => {
28
+ const assert = buildAssert(negated, onError);
29
+ const returnData = getReturnDataFromError(error);
30
+ const decodedReturnData = decodeReturnData(returnData);
31
+ if (decodedReturnData.kind === "Empty") {
32
+ assert(false, `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted without a reason`);
33
+ }
34
+ else if (decodedReturnData.kind === "Error") {
35
+ const matchesExpectedReason = expectedReason instanceof RegExp
36
+ ? expectedReason.test(decodedReturnData.reason)
37
+ : decodedReturnData.reason === expectedReasonString;
38
+ assert(matchesExpectedReason, `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted with reason '${decodedReturnData.reason}'`, `Expected transaction NOT to be reverted with reason '${expectedReasonString}', but it was`);
39
+ }
40
+ else if (decodedReturnData.kind === "Panic") {
41
+ assert(false, `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted with panic code ${numberToHexString(decodedReturnData.code)} (${decodedReturnData.description})`);
42
+ }
43
+ else if (decodedReturnData.kind === "Custom") {
44
+ assert(false, `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted with a custom error`);
45
+ }
46
+ else {
47
+ const _exhaustiveCheck = decodedReturnData;
48
+ }
49
+ };
50
+ const derivedPromise = Promise.resolve(this._obj).then(onSuccess, onError);
51
+ this.then = derivedPromise.then.bind(derivedPromise);
52
+ this.catch = derivedPromise.catch.bind(derivedPromise);
53
+ return this;
54
+ });
55
+ }
56
+ //# sourceMappingURL=revertedWith.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertedWith.js","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/revertedWith.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Ssfi } from "../../utils/ssfi.js";
2
+ export declare const REVERTED_WITH_CUSTOM_ERROR_CALLED = "customErrorAssertionCalled";
3
+ export declare function supportRevertedWithCustomError(Assertion: Chai.AssertionStatic, chaiUtils: Chai.ChaiUtils): void;
4
+ export declare function revertedWithCustomErrorWithArgs(context: any, Assertion: Chai.AssertionStatic, _chaiUtils: Chai.ChaiUtils, expectedArgs: any[], ssfi: Ssfi): Promise<void>;
5
+ //# sourceMappingURL=revertedWithCustomError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertedWithCustomError.d.ts","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/revertedWithCustomError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAqBhD,eAAO,MAAM,iCAAiC,+BAA+B,CAAC;AAQ9E,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,IAAI,CAAC,eAAe,EAC/B,SAAS,EAAE,IAAI,CAAC,SAAS,GACxB,IAAI,CAqHN;AAqDD,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,GAAG,EACZ,SAAS,EAAE,IAAI,CAAC,eAAe,EAC/B,UAAU,EAAE,IAAI,CAAC,SAAS,EAC1B,YAAY,EAAE,GAAG,EAAE,EACnB,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,IAAI,CAAC,CAkCf"}
@@ -0,0 +1,120 @@
1
+ import { HardhatError } from "@nomicfoundation/hardhat-errors";
2
+ import { numberToHexString } from "@nomicfoundation/hardhat-utils/hex";
3
+ import { ASSERTION_ABORTED, REVERTED_WITH_CUSTOM_ERROR_MATCHER, } from "../../constants.js";
4
+ import { assertArgsArraysEqual, assertIsNotNull } from "../../utils/asserts.js";
5
+ import { buildAssert } from "../../utils/build-assert.js";
6
+ import { preventAsyncMatcherChaining } from "../../utils/prevent-chaining.js";
7
+ import { decodeReturnData, getReturnDataFromError, resultToArray, } from "./utils.js";
8
+ export const REVERTED_WITH_CUSTOM_ERROR_CALLED = "customErrorAssertionCalled";
9
+ export function supportRevertedWithCustomError(Assertion, chaiUtils) {
10
+ Assertion.addMethod(REVERTED_WITH_CUSTOM_ERROR_MATCHER, function (contract, expectedCustomErrorName, ...args) {
11
+ // capture negated flag before async code executes; see buildAssert's jsdoc
12
+ const negated = this.__flags.negate;
13
+ const { iface, expectedCustomError } = validateInput(this._obj, contract, expectedCustomErrorName, args);
14
+ preventAsyncMatcherChaining(this, REVERTED_WITH_CUSTOM_ERROR_MATCHER, chaiUtils);
15
+ const onSuccess = () => {
16
+ if (chaiUtils.flag(this, ASSERTION_ABORTED) === true) {
17
+ return;
18
+ }
19
+ const assert = buildAssert(negated, onSuccess);
20
+ assert(false, `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it didn't revert`);
21
+ };
22
+ const onError = (error) => {
23
+ if (chaiUtils.flag(this, ASSERTION_ABORTED) === true) {
24
+ return;
25
+ }
26
+ const assert = buildAssert(negated, onError);
27
+ const returnData = getReturnDataFromError(error);
28
+ const decodedReturnData = decodeReturnData(returnData);
29
+ if (decodedReturnData.kind === "Empty") {
30
+ assert(false, `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted without a reason`);
31
+ }
32
+ else if (decodedReturnData.kind === "Error") {
33
+ assert(false, `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted with reason '${decodedReturnData.reason}'`);
34
+ }
35
+ else if (decodedReturnData.kind === "Panic") {
36
+ assert(false, `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted with panic code ${numberToHexString(decodedReturnData.code)} (${decodedReturnData.description})`);
37
+ }
38
+ else if (decodedReturnData.kind === "Custom") {
39
+ if (decodedReturnData.id === expectedCustomError.selector) {
40
+ // add flag with the data needed for .withArgs
41
+ const customErrorAssertionData = {
42
+ contractInterface: iface,
43
+ customError: expectedCustomError,
44
+ returnData,
45
+ };
46
+ this.customErrorData = customErrorAssertionData;
47
+ assert(true, undefined, `Expected transaction NOT to be reverted with custom error '${expectedCustomErrorName}', but it was`);
48
+ }
49
+ else {
50
+ // try to decode the actual custom error
51
+ // this will only work when the error comes from the given contract
52
+ const actualCustomError = iface.getError(decodedReturnData.id);
53
+ if (actualCustomError === null) {
54
+ assert(false, `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted with a different custom error`);
55
+ }
56
+ else {
57
+ assert(false, `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted with custom error '${actualCustomError.name}'`);
58
+ }
59
+ }
60
+ }
61
+ else {
62
+ const _exhaustiveCheck = decodedReturnData;
63
+ }
64
+ };
65
+ const derivedPromise = Promise.resolve(this._obj).then(onSuccess, onError);
66
+ // needed for .withArgs
67
+ chaiUtils.flag(this, REVERTED_WITH_CUSTOM_ERROR_CALLED, true);
68
+ this.promise = derivedPromise;
69
+ this.then = derivedPromise.then.bind(derivedPromise);
70
+ this.catch = derivedPromise.catch.bind(derivedPromise);
71
+ return this;
72
+ });
73
+ }
74
+ function validateInput(obj, contract, expectedCustomErrorName, args) {
75
+ try {
76
+ // check the case where users forget to pass the contract as the first
77
+ // argument
78
+ if (typeof contract === "string" || contract?.interface === undefined) {
79
+ // discard subject since it could potentially be a rejected promise
80
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.FIRST_ARGUMENT_MUST_BE_A_CONTRACT);
81
+ }
82
+ // validate custom error name
83
+ if (typeof expectedCustomErrorName !== "string") {
84
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.STRING_EXPECTED_AS_CUSTOM_ERROR_NAME);
85
+ }
86
+ const iface = contract.interface;
87
+ const expectedCustomError = iface.getError(expectedCustomErrorName);
88
+ // check that interface contains the given custom error
89
+ if (expectedCustomError === null) {
90
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.CONTRACT_DOES_NOT_HAVE_CUSTOM_ERROR, {
91
+ customErrorName: expectedCustomErrorName,
92
+ });
93
+ }
94
+ if (args.length > 0) {
95
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.REVERT_INVALID_ARGUMENTS_LENGTH);
96
+ }
97
+ return { iface, expectedCustomError };
98
+ }
99
+ catch (e) {
100
+ // if the input validation fails, we discard the subject since it could
101
+ // potentially be a rejected promise
102
+ Promise.resolve(obj).catch(() => { });
103
+ throw e;
104
+ }
105
+ }
106
+ export async function revertedWithCustomErrorWithArgs(context, Assertion, _chaiUtils, expectedArgs, ssfi) {
107
+ const negated = false; // .withArgs cannot be negated
108
+ const assert = buildAssert(negated, ssfi);
109
+ const customErrorAssertionData = context.customErrorData;
110
+ if (customErrorAssertionData === undefined) {
111
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.WITH_ARGS_FORBIDDEN);
112
+ }
113
+ const { contractInterface, customError, returnData } = customErrorAssertionData;
114
+ const errorFragment = contractInterface.getError(customError.name);
115
+ assertIsNotNull(errorFragment, "errorFragment");
116
+ // We transform ether's Array-like object into an actual array as it's safer
117
+ const actualArgs = resultToArray(contractInterface.decodeErrorResult(errorFragment, returnData));
118
+ assertArgsArraysEqual(Assertion, expectedArgs, actualArgs, `"${customError.name}" custom error`, "error", assert, ssfi);
119
+ }
120
+ //# sourceMappingURL=revertedWithCustomError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertedWithCustomError.js","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/revertedWithCustomError.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function supportRevertedWithPanic(Assertion: Chai.AssertionStatic, chaiUtils: Chai.ChaiUtils): void;
2
+ //# sourceMappingURL=revertedWithPanic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertedWithPanic.d.ts","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/revertedWithPanic.ts"],"names":[],"mappings":"AAWA,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,IAAI,CAAC,eAAe,EAC/B,SAAS,EAAE,IAAI,CAAC,SAAS,GACxB,IAAI,CAuGN"}
@@ -0,0 +1,74 @@
1
+ import { HardhatError } from "@nomicfoundation/hardhat-errors";
2
+ import { toBigInt } from "@nomicfoundation/hardhat-utils/bigint";
3
+ import { numberToHexString } from "@nomicfoundation/hardhat-utils/hex";
4
+ import { REVERTED_WITH_PANIC_MATCHER } from "../../constants.js";
5
+ import { buildAssert } from "../../utils/build-assert.js";
6
+ import { preventAsyncMatcherChaining } from "../../utils/prevent-chaining.js";
7
+ import { panicErrorCodeToReason } from "./panic.js";
8
+ import { decodeReturnData, getReturnDataFromError } from "./utils.js";
9
+ export function supportRevertedWithPanic(Assertion, chaiUtils) {
10
+ Assertion.addMethod(REVERTED_WITH_PANIC_MATCHER, function (expectedCodeArg) {
11
+ // capture negated flag before async code executes; see buildAssert's jsdoc
12
+ const negated = this.__flags.negate;
13
+ let expectedCode;
14
+ try {
15
+ if (expectedCodeArg !== undefined) {
16
+ expectedCode = toBigInt(expectedCodeArg);
17
+ }
18
+ }
19
+ catch {
20
+ // if the input validation fails, we discard the subject since it could
21
+ // potentially be a rejected promise
22
+ Promise.resolve(this._obj).catch(() => { });
23
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.PANIC_CODE_EXPECTED, {
24
+ panicCode: expectedCodeArg,
25
+ });
26
+ }
27
+ const code = expectedCode;
28
+ let description;
29
+ let formattedPanicCode;
30
+ if (code === undefined) {
31
+ formattedPanicCode = "some panic code";
32
+ }
33
+ else {
34
+ const codeBN = toBigInt(code);
35
+ description = panicErrorCodeToReason(codeBN) ?? "unknown panic code";
36
+ formattedPanicCode = `panic code ${numberToHexString(codeBN)} (${description})`;
37
+ }
38
+ preventAsyncMatcherChaining(this, REVERTED_WITH_PANIC_MATCHER, chaiUtils);
39
+ const onSuccess = () => {
40
+ const assert = buildAssert(negated, onSuccess);
41
+ assert(false, `Expected transaction to be reverted with ${formattedPanicCode}, but it didn't revert`);
42
+ };
43
+ const onError = (error) => {
44
+ const assert = buildAssert(negated, onError);
45
+ const returnData = getReturnDataFromError(error);
46
+ const decodedReturnData = decodeReturnData(returnData);
47
+ if (decodedReturnData.kind === "Empty") {
48
+ assert(false, `Expected transaction to be reverted with ${formattedPanicCode}, but it reverted without a reason`);
49
+ }
50
+ else if (decodedReturnData.kind === "Error") {
51
+ assert(false, `Expected transaction to be reverted with ${formattedPanicCode}, but it reverted with reason '${decodedReturnData.reason}'`);
52
+ }
53
+ else if (decodedReturnData.kind === "Panic") {
54
+ if (code !== undefined) {
55
+ assert(decodedReturnData.code === code, `Expected transaction to be reverted with ${formattedPanicCode}, but it reverted with panic code ${numberToHexString(decodedReturnData.code)} (${decodedReturnData.description})`, `Expected transaction NOT to be reverted with ${formattedPanicCode}, but it was`);
56
+ }
57
+ else {
58
+ assert(true, undefined, `Expected transaction NOT to be reverted with ${formattedPanicCode}, but it reverted with panic code ${numberToHexString(decodedReturnData.code)} (${decodedReturnData.description})`);
59
+ }
60
+ }
61
+ else if (decodedReturnData.kind === "Custom") {
62
+ assert(false, `Expected transaction to be reverted with ${formattedPanicCode}, but it reverted with a custom error`);
63
+ }
64
+ else {
65
+ const _exhaustiveCheck = decodedReturnData;
66
+ }
67
+ };
68
+ const derivedPromise = Promise.resolve(this._obj).then(onSuccess, onError);
69
+ this.then = derivedPromise.then.bind(derivedPromise);
70
+ this.catch = derivedPromise.catch.bind(derivedPromise);
71
+ return this;
72
+ });
73
+ }
74
+ //# sourceMappingURL=revertedWithPanic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertedWithPanic.js","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/revertedWithPanic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function supportRevertedWithoutReason(Assertion: Chai.AssertionStatic, chaiUtils: Chai.ChaiUtils): void;
2
+ //# sourceMappingURL=revertedWithoutReason.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertedWithoutReason.d.ts","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/revertedWithoutReason.ts"],"names":[],"mappings":"AAQA,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,IAAI,CAAC,eAAe,EAC/B,SAAS,EAAE,IAAI,CAAC,SAAS,GACxB,IAAI,CA6DN"}
@@ -0,0 +1,41 @@
1
+ import { numberToHexString } from "@nomicfoundation/hardhat-utils/hex";
2
+ import { REVERTED_WITHOUT_REASON_MATCHER } from "../../constants.js";
3
+ import { buildAssert } from "../../utils/build-assert.js";
4
+ import { preventAsyncMatcherChaining } from "../../utils/prevent-chaining.js";
5
+ import { decodeReturnData, getReturnDataFromError } from "./utils.js";
6
+ export function supportRevertedWithoutReason(Assertion, chaiUtils) {
7
+ Assertion.addMethod(REVERTED_WITHOUT_REASON_MATCHER, function () {
8
+ // capture negated flag before async code executes; see buildAssert's jsdoc
9
+ const negated = this.__flags.negate;
10
+ preventAsyncMatcherChaining(this, REVERTED_WITHOUT_REASON_MATCHER, chaiUtils);
11
+ const onSuccess = () => {
12
+ const assert = buildAssert(negated, onSuccess);
13
+ assert(false, `Expected transaction to be reverted without a reason, but it didn't revert`);
14
+ };
15
+ const onError = (error) => {
16
+ const assert = buildAssert(negated, onError);
17
+ const returnData = getReturnDataFromError(error);
18
+ const decodedReturnData = decodeReturnData(returnData);
19
+ if (decodedReturnData.kind === "Error") {
20
+ assert(false, `Expected transaction to be reverted without a reason, but it reverted with reason '${decodedReturnData.reason}'`);
21
+ }
22
+ else if (decodedReturnData.kind === "Empty") {
23
+ assert(true, undefined, "Expected transaction NOT to be reverted without a reason, but it was");
24
+ }
25
+ else if (decodedReturnData.kind === "Panic") {
26
+ assert(false, `Expected transaction to be reverted without a reason, but it reverted with panic code ${numberToHexString(decodedReturnData.code)} (${decodedReturnData.description})`);
27
+ }
28
+ else if (decodedReturnData.kind === "Custom") {
29
+ assert(false, `Expected transaction to be reverted without a reason, but it reverted with a custom error`);
30
+ }
31
+ else {
32
+ const _exhaustiveCheck = decodedReturnData;
33
+ }
34
+ };
35
+ const derivedPromise = Promise.resolve(this._obj).then(onSuccess, onError);
36
+ this.then = derivedPromise.then.bind(derivedPromise);
37
+ this.catch = derivedPromise.catch.bind(derivedPromise);
38
+ return this;
39
+ });
40
+ }
41
+ //# sourceMappingURL=revertedWithoutReason.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertedWithoutReason.js","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/revertedWithoutReason.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAE9E,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEtE,MAAM,UAAU,4BAA4B,CAC1C,SAA+B,EAC/B,SAAyB;IAEzB,SAAS,CAAC,SAAS,CAAC,+BAA+B,EAAE;QACnD,2EAA2E;QAC3E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAEpC,2BAA2B,CACzB,IAAI,EACJ,+BAA+B,EAC/B,SAAS,CACV,CAAC;QAEF,MAAM,SAAS,GAAG,GAAG,EAAE;YACrB,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAE/C,MAAM,CACJ,KAAK,EACL,4EAA4E,CAC7E,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,KAAU,EAAE,EAAE;YAC7B,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAE7C,MAAM,UAAU,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;YACjD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;YAEvD,IAAI,iBAAiB,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACvC,MAAM,CACJ,KAAK,EACL,sFAAsF,iBAAiB,CAAC,MAAM,GAAG,CAClH,CAAC;YACJ,CAAC;iBAAM,IAAI,iBAAiB,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC9C,MAAM,CACJ,IAAI,EACJ,SAAS,EACT,sEAAsE,CACvE,CAAC;YACJ,CAAC;iBAAM,IAAI,iBAAiB,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC9C,MAAM,CACJ,KAAK,EACL,yFAAyF,iBAAiB,CACxG,iBAAiB,CAAC,IAAI,CACvB,KAAK,iBAAiB,CAAC,WAAW,GAAG,CACvC,CAAC;YACJ,CAAC;iBAAM,IAAI,iBAAiB,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC/C,MAAM,CACJ,KAAK,EACL,2FAA2F,CAC5F,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,gBAAgB,GAAU,iBAAiB,CAAC;YACpD,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE3E,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAEvD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { Result } from "ethers/abi";
2
+ /**
3
+ * Try to obtain the return data of a transaction from the given value.
4
+ *
5
+ * If the value is an error but it doesn't have data, we assume it's not related
6
+ * to a reverted transaction and we re-throw it.
7
+ */
8
+ export declare function getReturnDataFromError(error: any): string;
9
+ type DecodedReturnData = {
10
+ kind: "Error";
11
+ reason: string;
12
+ } | {
13
+ kind: "Empty";
14
+ } | {
15
+ kind: "Panic";
16
+ code: bigint;
17
+ description: string;
18
+ } | {
19
+ kind: "Custom";
20
+ id: string;
21
+ data: string;
22
+ };
23
+ export declare function decodeReturnData(returnData: string): DecodedReturnData;
24
+ /**
25
+ * Takes an ethers result object and converts it into a (potentially nested) array.
26
+ *
27
+ * For example, given this error:
28
+ *
29
+ * struct Point(uint x, uint y)
30
+ * error MyError(string, Point)
31
+ *
32
+ * revert MyError("foo", Point(1, 2))
33
+ *
34
+ * The resulting array will be: ["foo", [1n, 2n]]
35
+ */
36
+ export declare function resultToArray(result: Result): any[];
37
+ export declare function parseBytes32String(v: string): string;
38
+ export {};
39
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/internal/matchers/reverted/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAezC;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAwBzD;AAED,KAAK,iBAAiB,GAClB;IACE,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;CACf,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,CAsDtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAQnD;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -0,0 +1,108 @@
1
+ import { HardhatError } from "@nomicfoundation/hardhat-errors";
2
+ import { ensureError } from "@nomicfoundation/hardhat-utils/error";
3
+ import { AssertionError } from "chai";
4
+ import { AbiCoder, decodeBytes32String } from "ethers/abi";
5
+ import { panicErrorCodeToReason } from "./panic.js";
6
+ // method id of 'Error(string)'
7
+ const ERROR_STRING_PREFIX = "0x08c379a0";
8
+ // method id of 'Panic(uint256)'
9
+ const PANIC_CODE_PREFIX = "0x4e487b71";
10
+ /**
11
+ * Try to obtain the return data of a transaction from the given value.
12
+ *
13
+ * If the value is an error but it doesn't have data, we assume it's not related
14
+ * to a reverted transaction and we re-throw it.
15
+ */
16
+ export function getReturnDataFromError(error) {
17
+ if (!(error instanceof Error)) {
18
+ // eslint-disable-next-line no-restricted-syntax -- keep the original chai error structure
19
+ throw new AssertionError("Expected an Error object");
20
+ }
21
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- some properties do not exist in the default Error instance
22
+ const typedError = error;
23
+ const errorData = typedError.data ?? typedError.error?.data;
24
+ if (errorData === undefined) {
25
+ // eslint-disable-next-line no-restricted-syntax -- re-throw because the error is not related to a reverted transaction
26
+ throw error;
27
+ }
28
+ const returnData = typeof errorData === "string" ? errorData : errorData.data;
29
+ if (returnData === undefined || typeof returnData !== "string") {
30
+ // eslint-disable-next-line no-restricted-syntax -- re-throw because the error is not related to a reverted transaction
31
+ throw error;
32
+ }
33
+ return returnData;
34
+ }
35
+ export function decodeReturnData(returnData) {
36
+ const abi = new AbiCoder();
37
+ if (returnData === "0x") {
38
+ return { kind: "Empty" };
39
+ }
40
+ else if (returnData.startsWith(ERROR_STRING_PREFIX)) {
41
+ const encodedReason = returnData.slice(ERROR_STRING_PREFIX.length);
42
+ let reason;
43
+ try {
44
+ reason = abi.decode(["string"], `0x${encodedReason}`)[0];
45
+ }
46
+ catch (e) {
47
+ ensureError(e);
48
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.DECODING_ERROR, {
49
+ encodedData: encodedReason,
50
+ type: "string",
51
+ reason: e.message,
52
+ });
53
+ }
54
+ return {
55
+ kind: "Error",
56
+ reason,
57
+ };
58
+ }
59
+ else if (returnData.startsWith(PANIC_CODE_PREFIX)) {
60
+ const encodedReason = returnData.slice(PANIC_CODE_PREFIX.length);
61
+ let code;
62
+ try {
63
+ code = abi.decode(["uint256"], `0x${encodedReason}`)[0];
64
+ }
65
+ catch (e) {
66
+ ensureError(e);
67
+ throw new HardhatError(HardhatError.ERRORS.CHAI_MATCHERS.DECODING_ERROR, {
68
+ encodedData: encodedReason,
69
+ type: "uint256",
70
+ reason: e.message,
71
+ });
72
+ }
73
+ const description = panicErrorCodeToReason(code) ?? "unknown panic code";
74
+ return {
75
+ kind: "Panic",
76
+ code,
77
+ description,
78
+ };
79
+ }
80
+ return {
81
+ kind: "Custom",
82
+ id: returnData.slice(0, 10),
83
+ data: `0x${returnData.slice(10)}`,
84
+ };
85
+ }
86
+ /**
87
+ * Takes an ethers result object and converts it into a (potentially nested) array.
88
+ *
89
+ * For example, given this error:
90
+ *
91
+ * struct Point(uint x, uint y)
92
+ * error MyError(string, Point)
93
+ *
94
+ * revert MyError("foo", Point(1, 2))
95
+ *
96
+ * The resulting array will be: ["foo", [1n, 2n]]
97
+ */
98
+ export function resultToArray(result) {
99
+ return result
100
+ .toArray()
101
+ .map((x) => typeof x === "object" && x !== null && "toArray" in x
102
+ ? resultToArray(x)
103
+ : x);
104
+ }
105
+ export function parseBytes32String(v) {
106
+ return decodeBytes32String(v);
107
+ }
108
+ //# sourceMappingURL=utils.js.map