voltaire-effect 0.2.23 → 0.2.24
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/dist/KZGService-B7PJerOb.d.ts +146 -0
- package/dist/{X25519Test-DGsk1V9o.d.ts → X25519Test-C8Cicdd_.d.ts} +2 -139
- package/dist/crypto/index.d.ts +3 -2
- package/dist/{index-IgkEHjBe.d.ts → index-DsFjN_a3.d.ts} +17633 -11961
- package/dist/index.d.ts +3104 -938
- package/dist/index.js +4467 -2446
- package/dist/native/index.d.ts +14 -5
- package/dist/native/index.js +4489 -2468
- package/dist/primitives/index.d.ts +12 -4
- package/dist/primitives/index.js +3980 -2411
- package/package.json +2 -2
- package/src/crypto/Keccak256/index.ts +1 -0
- package/src/index.ts +2 -2
- package/src/primitives/Abi/decode.test.ts +38 -0
- package/src/primitives/Abi/decode.ts +67 -0
- package/src/primitives/Abi/decodeData.test.ts +37 -0
- package/src/primitives/Abi/decodeData.ts +77 -0
- package/src/primitives/Abi/decodeLog.test.ts +32 -0
- package/src/primitives/Abi/decodeLog.ts +81 -0
- package/src/primitives/Abi/decodeWrappedError.test.ts +41 -0
- package/src/primitives/Abi/decodeWrappedError.ts +68 -0
- package/src/primitives/Abi/encode.test.ts +43 -0
- package/src/primitives/Abi/encode.ts +67 -0
- package/src/primitives/Abi/encodePacked.test.ts +35 -0
- package/src/primitives/Abi/encodePacked.ts +62 -0
- package/src/primitives/Abi/encodeWrappedError.test.ts +21 -0
- package/src/primitives/Abi/encodeWrappedError.ts +64 -0
- package/src/primitives/Abi/findSelectorCollisions.test.ts +50 -0
- package/src/primitives/Abi/findSelectorCollisions.ts +83 -0
- package/src/primitives/Abi/index.ts +33 -7
- package/src/primitives/Abi/parseLogs.test.ts +37 -0
- package/src/primitives/Abi/parseLogs.ts +62 -0
- package/src/primitives/AccessList/AccessList.test.ts +229 -0
- package/src/primitives/AccessList/AccessListTypeSchema.ts +16 -0
- package/src/primitives/AccessList/addressCount.ts +21 -0
- package/src/primitives/AccessList/assertValid.ts +37 -0
- package/src/primitives/AccessList/create.ts +19 -0
- package/src/primitives/AccessList/deduplicate.ts +23 -0
- package/src/primitives/AccessList/from.ts +39 -0
- package/src/primitives/AccessList/fromBytes.ts +36 -0
- package/src/primitives/AccessList/gasCost.ts +22 -0
- package/src/primitives/AccessList/gasSavings.ts +26 -0
- package/src/primitives/AccessList/hasSavings.ts +23 -0
- package/src/primitives/AccessList/includesAddress.ts +25 -0
- package/src/primitives/AccessList/includesStorageKey.ts +28 -0
- package/src/primitives/AccessList/index.ts +99 -19
- package/src/primitives/AccessList/is.ts +23 -0
- package/src/primitives/AccessList/isEmpty.ts +23 -0
- package/src/primitives/AccessList/isItem.ts +22 -0
- package/src/primitives/AccessList/keysFor.ts +29 -0
- package/src/primitives/AccessList/merge.ts +24 -0
- package/src/primitives/AccessList/storageKeyCount.ts +21 -0
- package/src/primitives/AccessList/toBytes.ts +23 -0
- package/src/primitives/AccessList/withAddress.ts +27 -0
- package/src/primitives/AccessList/withStorageKey.ts +30 -0
- package/src/primitives/Address/Address.test.ts +146 -0
- package/src/primitives/Address/assert.ts +51 -0
- package/src/primitives/Address/calculateCreate2Address.ts +33 -0
- package/src/primitives/Address/calculateCreateAddress.ts +30 -0
- package/src/primitives/Address/deduplicateAddresses.ts +20 -0
- package/src/primitives/Address/from.ts +41 -0
- package/src/primitives/Address/fromAbiEncoded.ts +35 -0
- package/src/primitives/Address/fromBase64.ts +25 -0
- package/src/primitives/Address/fromBytes.ts +25 -0
- package/src/primitives/Address/fromHex.ts +31 -0
- package/src/primitives/Address/fromNumber.ts +25 -0
- package/src/primitives/Address/fromPrivateKey.ts +25 -0
- package/src/primitives/Address/fromPublicKey.ts +56 -0
- package/src/primitives/Address/index.ts +99 -35
- package/src/primitives/Address/is.ts +20 -0
- package/src/primitives/Address/isAddress.ts +22 -0
- package/src/primitives/Address/sortAddresses.ts +19 -0
- package/src/primitives/Address/toChecksummed.ts +32 -0
- package/src/primitives/Address/toHex.ts +18 -0
- package/src/primitives/Address/zero.ts +18 -0
- package/src/primitives/Base64/Base64.test.ts +75 -0
- package/src/primitives/Base64/convert.ts +37 -0
- package/src/primitives/Base64/decode.ts +59 -0
- package/src/primitives/Base64/encode.ts +42 -0
- package/src/primitives/Base64/from.ts +39 -0
- package/src/primitives/Base64/index.ts +81 -1
- package/src/primitives/Base64/size.ts +16 -0
- package/src/primitives/Base64/validation.ts +16 -0
- package/src/primitives/Blob/Blob.test.ts +292 -0
- package/src/primitives/Blob/calculateGas.ts +30 -0
- package/src/primitives/Blob/estimateBlobCount.ts +30 -0
- package/src/primitives/Blob/from.ts +38 -0
- package/src/primitives/Blob/fromData.ts +36 -0
- package/src/primitives/Blob/index.ts +99 -12
- package/src/primitives/Blob/isValidVersion.ts +27 -0
- package/src/primitives/Blob/joinData.ts +43 -0
- package/src/primitives/Blob/splitData.ts +36 -0
- package/src/primitives/Blob/toCommitment.ts +43 -0
- package/src/primitives/Blob/toProof.ts +50 -0
- package/src/primitives/Blob/toVersionedHash.ts +35 -0
- package/src/primitives/Blob/verify.ts +49 -0
- package/src/primitives/Blob/verifyBatch.ts +119 -0
- package/src/primitives/BloomFilter/BloomFilter.test.ts +138 -0
- package/src/primitives/BloomFilter/add.ts +23 -0
- package/src/primitives/BloomFilter/combine.ts +21 -0
- package/src/primitives/BloomFilter/contains.ts +26 -0
- package/src/primitives/BloomFilter/create.ts +35 -0
- package/src/primitives/BloomFilter/density.ts +22 -0
- package/src/primitives/BloomFilter/expectedFalsePositiveRate.ts +25 -0
- package/src/primitives/BloomFilter/fromHex.ts +37 -0
- package/src/primitives/BloomFilter/hash.ts +43 -0
- package/src/primitives/BloomFilter/index.ts +59 -37
- package/src/primitives/BloomFilter/isEmpty.ts +22 -0
- package/src/primitives/BloomFilter/merge.ts +24 -0
- package/src/primitives/BloomFilter/toHex.ts +22 -0
- package/src/primitives/Bytecode/analyze.ts +58 -0
- package/src/primitives/Bytecode/detectFusions.ts +10 -0
- package/src/primitives/Bytecode/equals.ts +10 -0
- package/src/primitives/Bytecode/extractRuntime.ts +12 -0
- package/src/primitives/Bytecode/format.ts +16 -0
- package/src/primitives/Bytecode/from.ts +16 -0
- package/src/primitives/Bytecode/fromHex.ts +14 -0
- package/src/primitives/Bytecode/getBlock.ts +12 -0
- package/src/primitives/Bytecode/getNextPc.ts +12 -0
- package/src/primitives/Bytecode/getPushSize.ts +8 -0
- package/src/primitives/Bytecode/hasMetadata.ts +10 -0
- package/src/primitives/Bytecode/hash.ts +9 -0
- package/src/primitives/Bytecode/index.ts +103 -13
- package/src/primitives/Bytecode/isPush.ts +8 -0
- package/src/primitives/Bytecode/isTerminator.ts +8 -0
- package/src/primitives/Bytecode/isValidJumpDest.ts +12 -0
- package/src/primitives/Bytecode/parseInstructions.ts +10 -0
- package/src/primitives/Bytecode/prettyPrint.ts +12 -0
- package/src/primitives/Bytecode/scan.ts +20 -0
- package/src/primitives/Bytecode/size.ts +9 -0
- package/src/primitives/Bytecode/stripMetadata.ts +10 -0
- package/src/primitives/Bytecode/toAbi.ts +10 -0
- package/src/primitives/Bytecode/toHex.ts +10 -0
- package/src/primitives/Bytecode/types.ts +23 -0
- package/src/primitives/Bytecode/validate.ts +9 -0
- package/src/primitives/Ens/Ens.test.ts +71 -0
- package/src/primitives/Ens/convert.ts +13 -0
- package/src/primitives/Ens/from.ts +32 -0
- package/src/primitives/Ens/hash.ts +46 -0
- package/src/primitives/Ens/index.ts +86 -4
- package/src/primitives/Ens/normalize.ts +45 -0
- package/src/primitives/Ens/validation.ts +38 -0
- package/src/primitives/EventLog/accessors.ts +32 -0
- package/src/primitives/EventLog/clone.ts +17 -0
- package/src/primitives/EventLog/create.ts +46 -0
- package/src/primitives/EventLog/filtering.ts +48 -0
- package/src/primitives/EventLog/index.ts +96 -6
- package/src/primitives/EventLog/status.ts +17 -0
- package/src/primitives/EventLog/toRpc.ts +49 -0
- package/src/primitives/Hardfork/HardforkSchema.ts +3 -3
- package/src/primitives/Hardfork/allIds.ts +13 -0
- package/src/primitives/Hardfork/allNames.ts +13 -0
- package/src/primitives/Hardfork/compare.ts +17 -0
- package/src/primitives/Hardfork/comparisons.ts +45 -0
- package/src/primitives/Hardfork/equals.ts +17 -0
- package/src/primitives/Hardfork/features.ts +61 -0
- package/src/primitives/Hardfork/fromString.ts +16 -0
- package/src/primitives/Hardfork/index.ts +128 -18
- package/src/primitives/Hardfork/isValidName.ts +14 -0
- package/src/primitives/Hardfork/minMax.ts +23 -0
- package/src/primitives/Hardfork/range.ts +19 -0
- package/src/primitives/Hardfork/toString.ts +16 -0
- package/src/primitives/Hash/Hash.test.ts +104 -0
- package/src/primitives/Hash/from.ts +47 -0
- package/src/primitives/Hash/fromBytes.ts +46 -0
- package/src/primitives/Hash/fromHex.ts +44 -0
- package/src/primitives/Hash/index.ts +45 -8
- package/src/primitives/Hash/isHash.ts +31 -0
- package/src/primitives/Hash/toHex.ts +29 -0
- package/src/primitives/Hex/Hex.test.ts +266 -155
- package/src/primitives/Hex/assertSize.ts +41 -0
- package/src/primitives/Hex/concat.ts +37 -0
- package/src/primitives/Hex/from.ts +38 -0
- package/src/primitives/Hex/fromBigInt.ts +40 -0
- package/src/primitives/Hex/fromBoolean.ts +29 -0
- package/src/primitives/Hex/fromNumber.ts +41 -0
- package/src/primitives/Hex/fromString.ts +28 -0
- package/src/primitives/Hex/index.ts +68 -37
- package/src/primitives/Hex/pad.ts +40 -0
- package/src/primitives/Hex/padRight.ts +39 -0
- package/src/primitives/Hex/size.ts +29 -0
- package/src/primitives/Hex/slice.ts +42 -0
- package/src/primitives/Hex/toBigInt.ts +27 -0
- package/src/primitives/Hex/toBoolean.ts +38 -0
- package/src/primitives/Hex/toNumber.ts +37 -0
- package/src/primitives/Hex/toStringHex.ts +39 -0
- package/src/primitives/Hex/trim.ts +27 -0
- package/src/primitives/Hex/validate.ts +37 -0
- package/src/primitives/Hex/xor.ts +39 -0
- package/src/primitives/Opcode/OpcodeSchema.ts +1 -1
- package/src/primitives/Opcode/disassemble.ts +15 -0
- package/src/primitives/Opcode/dupPosition.ts +15 -0
- package/src/primitives/Opcode/format.ts +15 -0
- package/src/primitives/Opcode/getters.ts +54 -0
- package/src/primitives/Opcode/index.ts +301 -11
- package/src/primitives/Opcode/info.ts +18 -0
- package/src/primitives/Opcode/jumpDests.ts +15 -0
- package/src/primitives/Opcode/logTopics.ts +15 -0
- package/src/primitives/Opcode/name.ts +15 -0
- package/src/primitives/Opcode/parse.ts +15 -0
- package/src/primitives/Opcode/predicates.ts +72 -0
- package/src/primitives/Opcode/pushBytes.ts +15 -0
- package/src/primitives/Opcode/pushOpcode.ts +15 -0
- package/src/primitives/Opcode/swapPosition.ts +15 -0
- package/src/primitives/Rlp/decodeBatch.ts +46 -0
- package/src/primitives/Rlp/decodeObject.ts +46 -0
- package/src/primitives/Rlp/decodeValue.ts +51 -0
- package/src/primitives/Rlp/encodeBatch.ts +50 -0
- package/src/primitives/Rlp/encodeObject.ts +48 -0
- package/src/primitives/Rlp/encodeVariadic.ts +49 -0
- package/src/primitives/Rlp/equals.ts +22 -0
- package/src/primitives/Rlp/from.ts +44 -0
- package/src/primitives/Rlp/fromJSON.ts +45 -0
- package/src/primitives/Rlp/getEncodedLength.ts +47 -0
- package/src/primitives/Rlp/getLength.ts +44 -0
- package/src/primitives/Rlp/index.ts +67 -14
- package/src/primitives/Rlp/isBytesData.ts +21 -0
- package/src/primitives/Rlp/isCanonical.ts +32 -0
- package/src/primitives/Rlp/isData.ts +21 -0
- package/src/primitives/Rlp/isList.ts +46 -0
- package/src/primitives/Rlp/isListData.ts +21 -0
- package/src/primitives/Rlp/isString.ts +46 -0
- package/src/primitives/Rlp/toJSON.ts +20 -0
- package/src/primitives/Rlp/toRaw.ts +31 -0
- package/src/primitives/Signature/Signature.test.ts +217 -0
- package/src/primitives/Signature/from.ts +38 -0
- package/src/primitives/Signature/fromBytes.ts +31 -0
- package/src/primitives/Signature/fromCompact.ts +33 -0
- package/src/primitives/Signature/fromDER.ts +35 -0
- package/src/primitives/Signature/fromEd25519.ts +24 -0
- package/src/primitives/Signature/fromHex.ts +29 -0
- package/src/primitives/Signature/fromP256.ts +25 -0
- package/src/primitives/Signature/fromRpc.ts +38 -0
- package/src/primitives/Signature/fromSecp256k1.ts +29 -0
- package/src/primitives/Signature/fromTuple.ts +33 -0
- package/src/primitives/Signature/getR.ts +24 -0
- package/src/primitives/Signature/getS.ts +24 -0
- package/src/primitives/Signature/getV.ts +24 -0
- package/src/primitives/Signature/index.ts +61 -11
- package/src/primitives/Signature/toDER.ts +24 -0
- package/src/primitives/Signature/toHex.ts +24 -0
- package/src/primitives/Signature/toRpc.ts +35 -0
- package/src/primitives/Signature/toTuple.ts +29 -0
- package/src/primitives/Signature/verify.ts +31 -0
- package/src/primitives/Siwe/create.ts +56 -0
- package/src/primitives/Siwe/hash.ts +27 -0
- package/src/primitives/Siwe/index.ts +57 -21
- package/src/primitives/Siwe/parse.ts +24 -0
- package/src/primitives/Siwe/verify.ts +47 -0
- package/src/primitives/Transaction/index.ts +467 -2
- package/src/primitives/Uint/Uint.test.ts +200 -0
- package/src/primitives/Uint/dividedBy.ts +34 -0
- package/src/primitives/Uint/from.ts +35 -0
- package/src/primitives/Uint/fromAbiEncoded.ts +29 -0
- package/src/primitives/Uint/fromBigInt.ts +30 -0
- package/src/primitives/Uint/fromBytes.ts +32 -0
- package/src/primitives/Uint/fromHex.ts +32 -0
- package/src/primitives/Uint/fromNumber.ts +30 -0
- package/src/primitives/Uint/index.ts +90 -45
- package/src/primitives/Uint/isUint256.ts +25 -0
- package/src/primitives/Uint/isValid.ts +25 -0
- package/src/primitives/Uint/modulo.ts +34 -0
- package/src/primitives/Uint/toHex.ts +31 -0
- package/src/primitives/Uint/tryFrom.ts +30 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "voltaire-effect",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.24",
|
|
4
4
|
"description": "Effect-TS integration for Voltaire Ethereum primitives library",
|
|
5
5
|
"author": "TEVM",
|
|
6
6
|
"license": "MIT",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"sideEffects": false,
|
|
80
80
|
"peerDependencies": {
|
|
81
81
|
"effect": "^3.12.0",
|
|
82
|
-
"@tevm/voltaire": "0.2.
|
|
82
|
+
"@tevm/voltaire": "0.2.24"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
85
|
"@effect/platform": "^0.77.0"
|
package/src/index.ts
CHANGED
|
@@ -70,8 +70,8 @@ export * as SHA256 from "./crypto/SHA256/index.js";
|
|
|
70
70
|
export * as X25519 from "./crypto/X25519/index.js";
|
|
71
71
|
// JSON-RPC module
|
|
72
72
|
export * as JsonRpc from "./jsonrpc/index.js";
|
|
73
|
-
//
|
|
74
|
-
|
|
73
|
+
// ABI encoding/decoding
|
|
74
|
+
export * as Abi from "./primitives/Abi/index.js";
|
|
75
75
|
export * as AccessList from "./primitives/AccessList/index.js";
|
|
76
76
|
export * as AccountState from "./primitives/AccountState/index.js";
|
|
77
77
|
export * as Address from "./primitives/Address/index.js";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Exit from "effect/Exit";
|
|
4
|
+
import * as S from "effect/Schema";
|
|
5
|
+
import { fromArray } from "./AbiSchema.js";
|
|
6
|
+
import { decode } from "./decode.js";
|
|
7
|
+
|
|
8
|
+
const erc20Abi = S.decodeUnknownSync(fromArray)([
|
|
9
|
+
{
|
|
10
|
+
type: "function",
|
|
11
|
+
name: "balanceOf",
|
|
12
|
+
stateMutability: "view",
|
|
13
|
+
inputs: [{ name: "account", type: "address" }],
|
|
14
|
+
outputs: [{ type: "uint256" }],
|
|
15
|
+
},
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
describe("decode", () => {
|
|
19
|
+
describe("success cases", () => {
|
|
20
|
+
it.effect("decodes balanceOf result", () =>
|
|
21
|
+
Effect.gen(function* () {
|
|
22
|
+
const encoded = new Uint8Array(32);
|
|
23
|
+
encoded[31] = 100;
|
|
24
|
+
const result = yield* decode(erc20Abi, "balanceOf", encoded);
|
|
25
|
+
expect(result).toBeInstanceOf(Array);
|
|
26
|
+
}),
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("error cases", () => {
|
|
31
|
+
it("fails for unknown function", async () => {
|
|
32
|
+
const exit = await Effect.runPromiseExit(
|
|
33
|
+
decode(erc20Abi, "unknownFunction", new Uint8Array(32)),
|
|
34
|
+
);
|
|
35
|
+
expect(Exit.isFailure(exit)).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Decodes function return values from ABI by function name.
|
|
3
|
+
* Provides Effect-based wrapper around the branded ABI decode method.
|
|
4
|
+
*
|
|
5
|
+
* @module Abi/decode
|
|
6
|
+
* @since 0.0.1
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
type Abi,
|
|
11
|
+
AbiDecodingError as AbiDecodingErrorClass,
|
|
12
|
+
type AbiDecodingError,
|
|
13
|
+
type AbiItemNotFoundError,
|
|
14
|
+
type ItemType,
|
|
15
|
+
} from "@tevm/voltaire/Abi";
|
|
16
|
+
import * as Effect from "effect/Effect";
|
|
17
|
+
|
|
18
|
+
type AbiInput = readonly ItemType[];
|
|
19
|
+
|
|
20
|
+
const toAbi = (input: AbiInput): Abi => input as unknown as Abi;
|
|
21
|
+
|
|
22
|
+
type DecodeErrorType = AbiItemNotFoundError | AbiDecodingError;
|
|
23
|
+
|
|
24
|
+
const isAbiError = (e: unknown): e is DecodeErrorType =>
|
|
25
|
+
e !== null &&
|
|
26
|
+
typeof e === "object" &&
|
|
27
|
+
"name" in e &&
|
|
28
|
+
(e.name === "AbiItemNotFoundError" || e.name === "AbiDecodingError");
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Decodes function return values from ABI by function name.
|
|
32
|
+
*
|
|
33
|
+
* @description
|
|
34
|
+
* Decodes the return data from a contract call using the function's output types.
|
|
35
|
+
*
|
|
36
|
+
* @param {AbiInput} abi - The contract ABI.
|
|
37
|
+
* @param {string} functionName - The function name whose outputs to decode.
|
|
38
|
+
* @param {Uint8Array} data - The encoded return data.
|
|
39
|
+
* @returns {Effect.Effect<readonly unknown[], AbiItemNotFoundError | AbiDecodingError>}
|
|
40
|
+
* Effect yielding decoded return values.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import * as Effect from 'effect/Effect'
|
|
45
|
+
* import { decode } from 'voltaire-effect/primitives/Abi'
|
|
46
|
+
*
|
|
47
|
+
* const result = await Effect.runPromise(
|
|
48
|
+
* decode(abi, 'balanceOf', returnData)
|
|
49
|
+
* )
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @since 0.0.1
|
|
53
|
+
*/
|
|
54
|
+
export const decode = (
|
|
55
|
+
abi: AbiInput,
|
|
56
|
+
functionName: string,
|
|
57
|
+
data: Uint8Array,
|
|
58
|
+
): Effect.Effect<readonly unknown[], AbiItemNotFoundError | AbiDecodingError> =>
|
|
59
|
+
Effect.try({
|
|
60
|
+
try: () => toAbi(abi).decode(functionName, data),
|
|
61
|
+
catch: (e) =>
|
|
62
|
+
isAbiError(e)
|
|
63
|
+
? e
|
|
64
|
+
: new AbiDecodingErrorClass("Failed to decode function result", {
|
|
65
|
+
cause: e instanceof Error ? e : undefined,
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Exit from "effect/Exit";
|
|
4
|
+
import * as S from "effect/Schema";
|
|
5
|
+
import { fromArray } from "./AbiSchema.js";
|
|
6
|
+
import { decodeData } from "./decodeData.js";
|
|
7
|
+
|
|
8
|
+
const erc20Abi = S.decodeUnknownSync(fromArray)([
|
|
9
|
+
{
|
|
10
|
+
type: "function",
|
|
11
|
+
name: "transfer",
|
|
12
|
+
stateMutability: "nonpayable",
|
|
13
|
+
inputs: [
|
|
14
|
+
{ name: "to", type: "address" },
|
|
15
|
+
{ name: "amount", type: "uint256" },
|
|
16
|
+
],
|
|
17
|
+
outputs: [{ type: "bool" }],
|
|
18
|
+
},
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
describe("decodeData", () => {
|
|
22
|
+
describe("error cases", () => {
|
|
23
|
+
it("fails for data too short", async () => {
|
|
24
|
+
const exit = await Effect.runPromiseExit(
|
|
25
|
+
decodeData(erc20Abi, new Uint8Array(2)),
|
|
26
|
+
);
|
|
27
|
+
expect(Exit.isFailure(exit)).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("fails for unknown selector", async () => {
|
|
31
|
+
const exit = await Effect.runPromiseExit(
|
|
32
|
+
decodeData(erc20Abi, new Uint8Array(68)),
|
|
33
|
+
);
|
|
34
|
+
expect(Exit.isFailure(exit)).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Decodes function call data and identifies the function.
|
|
3
|
+
* Provides Effect-based wrapper around the branded ABI decodeData method.
|
|
4
|
+
*
|
|
5
|
+
* @module Abi/decodeData
|
|
6
|
+
* @since 0.0.1
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
type Abi,
|
|
11
|
+
AbiDecodingError as AbiDecodingErrorClass,
|
|
12
|
+
type AbiDecodingError,
|
|
13
|
+
type AbiInvalidSelectorError,
|
|
14
|
+
type AbiItemNotFoundError,
|
|
15
|
+
type ItemType,
|
|
16
|
+
} from "@tevm/voltaire/Abi";
|
|
17
|
+
import * as Effect from "effect/Effect";
|
|
18
|
+
|
|
19
|
+
type AbiInput = readonly ItemType[];
|
|
20
|
+
|
|
21
|
+
const toAbi = (input: AbiInput): Abi => input as unknown as Abi;
|
|
22
|
+
|
|
23
|
+
type DecodeDataErrorType =
|
|
24
|
+
| AbiItemNotFoundError
|
|
25
|
+
| AbiInvalidSelectorError
|
|
26
|
+
| AbiDecodingError;
|
|
27
|
+
|
|
28
|
+
const isAbiError = (e: unknown): e is DecodeDataErrorType =>
|
|
29
|
+
e !== null &&
|
|
30
|
+
typeof e === "object" &&
|
|
31
|
+
"name" in e &&
|
|
32
|
+
(e.name === "AbiItemNotFoundError" ||
|
|
33
|
+
e.name === "AbiInvalidSelectorError" ||
|
|
34
|
+
e.name === "AbiDecodingError");
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Decodes function call data and identifies the function.
|
|
38
|
+
*
|
|
39
|
+
* @description
|
|
40
|
+
* Parses encoded calldata to extract the function name and decoded arguments.
|
|
41
|
+
* The data must start with a 4-byte function selector.
|
|
42
|
+
*
|
|
43
|
+
* @param {AbiInput} abi - The contract ABI.
|
|
44
|
+
* @param {Uint8Array} data - The encoded function call data.
|
|
45
|
+
* @returns {Effect.Effect<{ functionName: string; args: readonly unknown[] }, AbiItemNotFoundError | AbiInvalidSelectorError | AbiDecodingError>}
|
|
46
|
+
* Effect yielding the function name and decoded arguments.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* import * as Effect from 'effect/Effect'
|
|
51
|
+
* import { decodeData } from 'voltaire-effect/primitives/Abi'
|
|
52
|
+
*
|
|
53
|
+
* const decoded = await Effect.runPromise(
|
|
54
|
+
* decodeData(abi, calldata)
|
|
55
|
+
* )
|
|
56
|
+
* console.log(decoded.functionName) // 'transfer'
|
|
57
|
+
* console.log(decoded.args) // ['0x...', 100n]
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @since 0.0.1
|
|
61
|
+
*/
|
|
62
|
+
export const decodeData = (
|
|
63
|
+
abi: AbiInput,
|
|
64
|
+
data: Uint8Array,
|
|
65
|
+
): Effect.Effect<
|
|
66
|
+
{ functionName: string; args: readonly unknown[] },
|
|
67
|
+
AbiItemNotFoundError | AbiInvalidSelectorError | AbiDecodingError
|
|
68
|
+
> =>
|
|
69
|
+
Effect.try({
|
|
70
|
+
try: () => toAbi(abi).decodeData(data),
|
|
71
|
+
catch: (e) =>
|
|
72
|
+
isAbiError(e)
|
|
73
|
+
? e
|
|
74
|
+
: new AbiDecodingErrorClass("Failed to decode function data", {
|
|
75
|
+
cause: e instanceof Error ? e : undefined,
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Exit from "effect/Exit";
|
|
4
|
+
import * as S from "effect/Schema";
|
|
5
|
+
import { fromArray } from "./AbiSchema.js";
|
|
6
|
+
import { decodeLog } from "./decodeLog.js";
|
|
7
|
+
|
|
8
|
+
const erc20Abi = S.decodeUnknownSync(fromArray)([
|
|
9
|
+
{
|
|
10
|
+
type: "event",
|
|
11
|
+
name: "Transfer",
|
|
12
|
+
inputs: [
|
|
13
|
+
{ name: "from", type: "address", indexed: true },
|
|
14
|
+
{ name: "to", type: "address", indexed: true },
|
|
15
|
+
{ name: "value", type: "uint256", indexed: false },
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
describe("decodeLog", () => {
|
|
21
|
+
describe("error cases", () => {
|
|
22
|
+
it("fails for unknown event", async () => {
|
|
23
|
+
const exit = await Effect.runPromiseExit(
|
|
24
|
+
decodeLog(erc20Abi, {
|
|
25
|
+
data: new Uint8Array(32),
|
|
26
|
+
topics: [new Uint8Array(32)],
|
|
27
|
+
}),
|
|
28
|
+
);
|
|
29
|
+
expect(Exit.isFailure(exit)).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Decodes event log data using ABI.
|
|
3
|
+
* Provides Effect-based wrapper for parsing log entries.
|
|
4
|
+
*
|
|
5
|
+
* @module Abi/decodeLog
|
|
6
|
+
* @since 0.0.1
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
type Abi,
|
|
11
|
+
AbiDecodingError as AbiDecodingErrorClass,
|
|
12
|
+
type AbiDecodingError,
|
|
13
|
+
type AbiItemNotFoundError,
|
|
14
|
+
type ItemType,
|
|
15
|
+
decodeLog as _decodeLog,
|
|
16
|
+
} from "@tevm/voltaire/Abi";
|
|
17
|
+
import type { HexType } from "@tevm/voltaire/Hex";
|
|
18
|
+
import * as Effect from "effect/Effect";
|
|
19
|
+
|
|
20
|
+
type AbiInput = readonly ItemType[];
|
|
21
|
+
|
|
22
|
+
const toAbi = (input: AbiInput): Abi => input as unknown as Abi;
|
|
23
|
+
|
|
24
|
+
type DecodeLogErrorType = AbiItemNotFoundError | AbiDecodingError;
|
|
25
|
+
|
|
26
|
+
const isAbiError = (e: unknown): e is DecodeLogErrorType =>
|
|
27
|
+
e !== null &&
|
|
28
|
+
typeof e === "object" &&
|
|
29
|
+
"name" in e &&
|
|
30
|
+
(e.name === "AbiItemNotFoundError" || e.name === "AbiDecodingError");
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Log input structure.
|
|
34
|
+
*/
|
|
35
|
+
export interface LogInput {
|
|
36
|
+
data: HexType | Uint8Array;
|
|
37
|
+
topics: readonly (HexType | Uint8Array)[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Decodes event log data using ABI.
|
|
42
|
+
*
|
|
43
|
+
* @description
|
|
44
|
+
* Parses a log entry to extract the event name and decoded parameters.
|
|
45
|
+
* Supports both regular events (matched by topic0) and anonymous events.
|
|
46
|
+
*
|
|
47
|
+
* @param {AbiInput} abi - The contract ABI.
|
|
48
|
+
* @param {LogInput} log - The log object with data and topics.
|
|
49
|
+
* @returns {Effect.Effect<{ event: string; params: Record<string, unknown> }, AbiItemNotFoundError | AbiDecodingError>}
|
|
50
|
+
* Effect yielding the event name and decoded parameters.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import * as Effect from 'effect/Effect'
|
|
55
|
+
* import { decodeLog } from 'voltaire-effect/primitives/Abi'
|
|
56
|
+
*
|
|
57
|
+
* const decoded = await Effect.runPromise(
|
|
58
|
+
* decodeLog(abi, { data: '0x...', topics: ['0x...', ...] })
|
|
59
|
+
* )
|
|
60
|
+
* console.log(decoded.event) // 'Transfer'
|
|
61
|
+
* console.log(decoded.params) // { from: '0x...', to: '0x...', value: 100n }
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @since 0.0.1
|
|
65
|
+
*/
|
|
66
|
+
export const decodeLog = (
|
|
67
|
+
abi: AbiInput,
|
|
68
|
+
log: LogInput,
|
|
69
|
+
): Effect.Effect<
|
|
70
|
+
{ event: string; params: Record<string, unknown> },
|
|
71
|
+
AbiItemNotFoundError | AbiDecodingError
|
|
72
|
+
> =>
|
|
73
|
+
Effect.try({
|
|
74
|
+
try: () => _decodeLog(toAbi(abi), log),
|
|
75
|
+
catch: (e) =>
|
|
76
|
+
isAbiError(e)
|
|
77
|
+
? e
|
|
78
|
+
: new AbiDecodingErrorClass("Failed to decode log", {
|
|
79
|
+
cause: e instanceof Error ? e : undefined,
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest";
|
|
2
|
+
import { Address, Bytes, Selector } from "@tevm/voltaire";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Exit from "effect/Exit";
|
|
5
|
+
import { decodeWrappedError } from "./decodeWrappedError.js";
|
|
6
|
+
import { encodeWrappedError } from "./encodeWrappedError.js";
|
|
7
|
+
|
|
8
|
+
describe("decodeWrappedError", () => {
|
|
9
|
+
describe("success cases", () => {
|
|
10
|
+
it.effect("decodes encoded wrapped error", () =>
|
|
11
|
+
Effect.gen(function* () {
|
|
12
|
+
const original = {
|
|
13
|
+
target: Address.from("0x742d35Cc6634C0532925a3b844Bc9e7595f251e3"),
|
|
14
|
+
selector: Selector.fromHex("0xa9059cbb"),
|
|
15
|
+
reason: Bytes.from(new Uint8Array([1, 2, 3])),
|
|
16
|
+
details: Bytes.from(new Uint8Array([4, 5, 6])),
|
|
17
|
+
};
|
|
18
|
+
const encoded = yield* encodeWrappedError(original);
|
|
19
|
+
const decoded = yield* decodeWrappedError(encoded);
|
|
20
|
+
expect(decoded.target).toBeDefined();
|
|
21
|
+
expect(decoded.selector).toBeDefined();
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("error cases", () => {
|
|
27
|
+
it("fails for data too short", async () => {
|
|
28
|
+
const exit = await Effect.runPromiseExit(
|
|
29
|
+
decodeWrappedError(new Uint8Array(2)),
|
|
30
|
+
);
|
|
31
|
+
expect(Exit.isFailure(exit)).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("fails for invalid selector", async () => {
|
|
35
|
+
const exit = await Effect.runPromiseExit(
|
|
36
|
+
decodeWrappedError(new Uint8Array(100)),
|
|
37
|
+
);
|
|
38
|
+
expect(Exit.isFailure(exit)).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Decodes ERC-7751 wrapped error data.
|
|
3
|
+
* Provides Effect-based wrapper for wrapped error decoding.
|
|
4
|
+
*
|
|
5
|
+
* @module Abi/decodeWrappedError
|
|
6
|
+
* @since 0.0.1
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
AbiDecodingError as AbiDecodingErrorClass,
|
|
11
|
+
type AbiDecodingError,
|
|
12
|
+
type AbiInvalidSelectorError,
|
|
13
|
+
type WrappedErrorType,
|
|
14
|
+
decodeWrappedError as _decodeWrappedError,
|
|
15
|
+
} from "@tevm/voltaire/Abi";
|
|
16
|
+
import * as Effect from "effect/Effect";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Decoded wrapped error structure (ERC-7751).
|
|
20
|
+
*/
|
|
21
|
+
export type WrappedErrorResult = WrappedErrorType;
|
|
22
|
+
|
|
23
|
+
type DecodeWrappedErrorType = AbiDecodingError | AbiInvalidSelectorError;
|
|
24
|
+
|
|
25
|
+
const isAbiError = (e: unknown): e is DecodeWrappedErrorType =>
|
|
26
|
+
e !== null &&
|
|
27
|
+
typeof e === "object" &&
|
|
28
|
+
"name" in e &&
|
|
29
|
+
(e.name === "AbiDecodingError" || e.name === "AbiInvalidSelectorError");
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Decodes ERC-7751 wrapped error data.
|
|
33
|
+
*
|
|
34
|
+
* @description
|
|
35
|
+
* Decodes a WrappedError from encoded bytes following the ERC-7751 specification.
|
|
36
|
+
* Expects data to start with the WrappedError selector (0x90bfb865).
|
|
37
|
+
*
|
|
38
|
+
* @param {Uint8Array} data - Encoded error data (selector + ABI-encoded params).
|
|
39
|
+
* @returns {Effect.Effect<WrappedErrorResult, AbiDecodingError | AbiInvalidSelectorError>}
|
|
40
|
+
* Effect yielding decoded wrapped error.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import * as Effect from 'effect/Effect'
|
|
45
|
+
* import { decodeWrappedError } from 'voltaire-effect/primitives/Abi'
|
|
46
|
+
*
|
|
47
|
+
* const decoded = await Effect.runPromise(
|
|
48
|
+
* decodeWrappedError(errorData)
|
|
49
|
+
* )
|
|
50
|
+
* console.log(decoded.target) // Address of failing contract
|
|
51
|
+
* console.log(decoded.selector) // Function selector
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @see https://eips.ethereum.org/EIPS/eip-7751
|
|
55
|
+
* @since 0.0.1
|
|
56
|
+
*/
|
|
57
|
+
export const decodeWrappedError = (
|
|
58
|
+
data: Uint8Array,
|
|
59
|
+
): Effect.Effect<WrappedErrorResult, AbiDecodingError | AbiInvalidSelectorError> =>
|
|
60
|
+
Effect.try({
|
|
61
|
+
try: () => _decodeWrappedError(data) as WrappedErrorResult,
|
|
62
|
+
catch: (e) =>
|
|
63
|
+
isAbiError(e)
|
|
64
|
+
? e
|
|
65
|
+
: new AbiDecodingErrorClass("Failed to decode wrapped error", {
|
|
66
|
+
cause: e instanceof Error ? e : undefined,
|
|
67
|
+
}),
|
|
68
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Exit from "effect/Exit";
|
|
4
|
+
import * as S from "effect/Schema";
|
|
5
|
+
import { fromArray } from "./AbiSchema.js";
|
|
6
|
+
import { encode } from "./encode.js";
|
|
7
|
+
|
|
8
|
+
const erc20Abi = S.decodeUnknownSync(fromArray)([
|
|
9
|
+
{
|
|
10
|
+
type: "function",
|
|
11
|
+
name: "transfer",
|
|
12
|
+
stateMutability: "nonpayable",
|
|
13
|
+
inputs: [
|
|
14
|
+
{ name: "to", type: "address" },
|
|
15
|
+
{ name: "amount", type: "uint256" },
|
|
16
|
+
],
|
|
17
|
+
outputs: [{ type: "bool" }],
|
|
18
|
+
},
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
describe("encode", () => {
|
|
22
|
+
describe("success cases", () => {
|
|
23
|
+
it.effect("encodes transfer function", () =>
|
|
24
|
+
Effect.gen(function* () {
|
|
25
|
+
const calldata = yield* encode(erc20Abi, "transfer", [
|
|
26
|
+
"0x742d35Cc6634C0532925a3b844Bc9e7595f251e3",
|
|
27
|
+
1000000000000000000n,
|
|
28
|
+
]);
|
|
29
|
+
expect(calldata).toBeInstanceOf(Uint8Array);
|
|
30
|
+
expect(calldata.length).toBeGreaterThan(4);
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("error cases", () => {
|
|
36
|
+
it("fails for unknown function", async () => {
|
|
37
|
+
const exit = await Effect.runPromiseExit(
|
|
38
|
+
encode(erc20Abi, "unknownFunction", []),
|
|
39
|
+
);
|
|
40
|
+
expect(Exit.isFailure(exit)).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Encodes function call data from ABI by function name.
|
|
3
|
+
* Provides Effect-based wrapper around the branded ABI encode method.
|
|
4
|
+
*
|
|
5
|
+
* @module Abi/encode
|
|
6
|
+
* @since 0.0.1
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
type Abi,
|
|
11
|
+
AbiEncodingError as AbiEncodingErrorClass,
|
|
12
|
+
type AbiEncodingError,
|
|
13
|
+
type AbiItemNotFoundError,
|
|
14
|
+
type ItemType,
|
|
15
|
+
} from "@tevm/voltaire/Abi";
|
|
16
|
+
import * as Effect from "effect/Effect";
|
|
17
|
+
|
|
18
|
+
type AbiInput = readonly ItemType[];
|
|
19
|
+
|
|
20
|
+
const toAbi = (input: AbiInput): Abi => input as unknown as Abi;
|
|
21
|
+
|
|
22
|
+
type EncodeErrorType = AbiItemNotFoundError | AbiEncodingError;
|
|
23
|
+
|
|
24
|
+
const isAbiError = (e: unknown): e is EncodeErrorType =>
|
|
25
|
+
e !== null &&
|
|
26
|
+
typeof e === "object" &&
|
|
27
|
+
"name" in e &&
|
|
28
|
+
(e.name === "AbiItemNotFoundError" || e.name === "AbiEncodingError");
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Encodes function call data from ABI by function name.
|
|
32
|
+
*
|
|
33
|
+
* @description
|
|
34
|
+
* Creates encoded calldata for invoking a contract function.
|
|
35
|
+
*
|
|
36
|
+
* @param {AbiInput} abi - The contract ABI.
|
|
37
|
+
* @param {string} functionName - The function name to encode.
|
|
38
|
+
* @param {readonly unknown[]} args - The function arguments.
|
|
39
|
+
* @returns {Effect.Effect<Uint8Array, AbiItemNotFoundError | AbiEncodingError>}
|
|
40
|
+
* Effect yielding encoded calldata as bytes.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import * as Effect from 'effect/Effect'
|
|
45
|
+
* import { encode } from 'voltaire-effect/primitives/Abi'
|
|
46
|
+
*
|
|
47
|
+
* const calldata = await Effect.runPromise(
|
|
48
|
+
* encode(abi, 'transfer', [to, amount])
|
|
49
|
+
* )
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @since 0.0.1
|
|
53
|
+
*/
|
|
54
|
+
export const encode = (
|
|
55
|
+
abi: AbiInput,
|
|
56
|
+
functionName: string,
|
|
57
|
+
args: readonly unknown[],
|
|
58
|
+
): Effect.Effect<Uint8Array, AbiItemNotFoundError | AbiEncodingError> =>
|
|
59
|
+
Effect.try({
|
|
60
|
+
try: () => toAbi(abi).encode(functionName, [...args]),
|
|
61
|
+
catch: (e) =>
|
|
62
|
+
isAbiError(e)
|
|
63
|
+
? e
|
|
64
|
+
: new AbiEncodingErrorClass("Failed to encode function", {
|
|
65
|
+
cause: e instanceof Error ? e : undefined,
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Exit from "effect/Exit";
|
|
4
|
+
import { encodePacked } from "./encodePacked.js";
|
|
5
|
+
|
|
6
|
+
describe("encodePacked", () => {
|
|
7
|
+
describe("success cases", () => {
|
|
8
|
+
it.effect("encodes address and uint256", () =>
|
|
9
|
+
Effect.gen(function* () {
|
|
10
|
+
const encoded = yield* encodePacked(
|
|
11
|
+
["address", "uint256"],
|
|
12
|
+
["0x742d35Cc6634C0532925a3b844Bc9e7595f251e3", 100n],
|
|
13
|
+
);
|
|
14
|
+
expect(typeof encoded).toBe("string");
|
|
15
|
+
expect(encoded.startsWith("0x")).toBe(true);
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
it.effect("encodes string", () =>
|
|
20
|
+
Effect.gen(function* () {
|
|
21
|
+
const encoded = yield* encodePacked(["string"], ["hello"]);
|
|
22
|
+
expect(typeof encoded).toBe("string");
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe("error cases", () => {
|
|
28
|
+
it("fails for type/value mismatch", async () => {
|
|
29
|
+
const exit = await Effect.runPromiseExit(
|
|
30
|
+
encodePacked(["address", "uint256"], ["0x123"]),
|
|
31
|
+
);
|
|
32
|
+
expect(Exit.isFailure(exit)).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|