{"_id":"@axlabs/neo-serializer-evm","_rev":"2-8082176e49e76199dc14d2c33b003223","name":"@axlabs/neo-serializer-evm","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@axlabs/neo-serializer-evm","version":"0.0.1","keywords":["neo","serialization","solidity","evm","blockchain","cross-chain"],"author":{"name":"AxLabs"},"license":"Apache-2.0","_id":"@axlabs/neo-serializer-evm@0.0.1","maintainers":[{"name":"merl123","email":"mathias@axlabs.com"},{"name":"axlabs-bot","email":"tech@axlabs.com"},{"name":"mialbu","email":"bucher_michael@hotmail.com"},{"name":"gsperbmachado","email":"guil@axlabs.com"},{"name":"thedanielmark","email":"danielmark.uc@gmail.com"}],"dist":{"shasum":"934c47d11a376a4a92d40e57c1ff33c17ae9d4c1","tarball":"https://registry.npmjs.org/@axlabs/neo-serializer-evm/-/neo-serializer-evm-0.0.1.tgz","fileCount":10,"integrity":"sha512-kevvXSyKH+SLHBPPrlsOJ7myvNWvivgybqpFkDRCNQWJPzGGsyMCpKX76XLHZ4tm51oSnVxAifEUZxORkJ9oiQ==","signatures":[{"sig":"MEUCIGny02Ps4SoPe6UV4e2CK87pyxHH4ivkBk37dlOQcqa3AiEApHz/UXJtfgp0wwTqVfX9j/bvLSkrfUtW4WfFyj8WYM8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82733},"main":"index.js","gitHead":"764181b3827dd3e2e744baacc617a56d75574fec","scripts":{"test":"hardhat test","clean":"hardhat clean","compile":"hardhat compile","prepublishOnly":"npm run compile && npm run test","publish:public":"npm publish --access public","publish:dry-run":"npm publish --dry-run"},"_npmUser":{"name":"axlabs-bot","email":"tech@axlabs.com"},"_npmVersion":"11.4.2","description":"Neo blockchain serialization library for Solidity/EVM","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"chai":"^4.3.10","hardhat":"^2.19.0","ts-node":"^10.9.2","typescript":"^5.3.3","@types/chai":"^4.3.11","@types/mocha":"^10.0.3","@nomicfoundation/hardhat-toolbox":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/neo-serializer-evm_0.0.1_1772407907228_0.8781800447729633","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@axlabs/neo-serializer-evm","version":"0.0.2","description":"Neo blockchain serialization library for Solidity/EVM","main":"index.js","scripts":{"compile":"hardhat compile","test":"hardhat test","clean":"hardhat clean","prepublishOnly":"npm run compile && npm run test","publish:dry-run":"npm publish --dry-run","publish:public":"npm publish --access public"},"keywords":["neo","serialization","solidity","evm","blockchain","cross-chain"],"author":{"name":"AxLabs"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/AxLabs/neo-serializer-evm.git"},"devDependencies":{"@nomicfoundation/hardhat-toolbox":"^4.0.0","@types/chai":"^4.3.11","@types/mocha":"^10.0.3","chai":"^4.3.10","hardhat":"^2.19.0","ts-node":"^10.9.2","typescript":"^5.3.3"},"gitHead":"e1938f38f7453659a8608956b00f15f4556aea16","_id":"@axlabs/neo-serializer-evm@0.0.2","bugs":{"url":"https://github.com/AxLabs/neo-serializer-evm/issues"},"homepage":"https://github.com/AxLabs/neo-serializer-evm#readme","_nodeVersion":"24.13.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-j35lx9eX0/U/cu9R3G1jjykKcF6RHdEUT+FxmE1VuKWg0ZeSF4r6prKgoNCBwPT5WULBstnaOjsddrVJG+GaTw==","shasum":"28485444a0f70b169d42d2b501f7abf028c4f06f","tarball":"https://registry.npmjs.org/@axlabs/neo-serializer-evm/-/neo-serializer-evm-0.0.2.tgz","fileCount":10,"unpackedSize":82833,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@axlabs%2fneo-serializer-evm@0.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCD0+A3cyqASFy1C+TZQEWOyrI9FRWxWt1SmqY59yj0AwIgAfwmevORzlRskxWgeAn1jsBYpSPMw38pSFouY2cajxA="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d439ef34-5429-415f-8fba-83bd1ab6f65e"}},"directories":{},"maintainers":[{"name":"merl123","email":"mathias@axlabs.com"},{"name":"axlabs-bot","email":"tech@axlabs.com"},{"name":"mialbu","email":"bucher_michael@hotmail.com"},{"name":"gsperbmachado","email":"guil@axlabs.com"},{"name":"thedanielmark","email":"danielmark.uc@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/neo-serializer-evm_0.0.2_1772409353288_0.8152594235095154"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-01T23:31:47.143Z","modified":"2026-03-01T23:55:53.913Z","0.0.1":"2026-03-01T23:31:47.391Z","0.0.2":"2026-03-01T23:55:53.495Z"},"author":{"name":"AxLabs"},"license":"Apache-2.0","keywords":["neo","serialization","solidity","evm","blockchain","cross-chain"],"description":"Neo blockchain serialization library for Solidity/EVM","maintainers":[{"name":"merl123","email":"mathias@axlabs.com"},{"name":"axlabs-bot","email":"tech@axlabs.com"},{"name":"mialbu","email":"bucher_michael@hotmail.com"},{"name":"gsperbmachado","email":"guil@axlabs.com"},{"name":"thedanielmark","email":"danielmark.uc@gmail.com"}],"readme":"# Neo Serialize/Deserialize in Solidity\n\nThis project reimplements Neo's StdLib native contract Serialize and Deserialize methods in Solidity. These methods convert data to/from Neo's binary serialization format, which uses type markers, VarInt encoding, and little-endian byte ordering.\n\n## Overview\n\nNeo's serialization format supports:\n- Primitive types: Boolean, Integer (BigInteger), ByteString, Buffer\n- Container types: Array, Struct, Map\n- Variable-length encoding using VarInt\n- Little-endian byte ordering for integers\n- Contract call serialization for cross-chain interoperability\n\n## Quick Start\n\n### Installation\n\n```bash\nnpm install @axlabs/neo-serializer-evm\n```\n\n### Basic Usage\n\n```solidity\nimport \"@axlabs/neo-serializer-evm/contracts/libraries/NeoSerializerLib.sol\";\n\ncontract MyContract {\n    using NeoSerializerLib for uint256;\n    \n    function serializeValue(uint256 value) public pure returns (bytes memory) {\n        return value.serialize();\n    }\n    \n    function createNeoCall(bytes20 target, string memory method) \n        public pure returns (bytes memory) \n    {\n        bytes[] memory args = new bytes[](0);\n        return NeoSerializerLib.serializeCall(\n            target,\n            method,\n            NeoSerializerLib.CALL_FLAGS_ALL,\n            args\n        );\n    }\n}\n```\n\n**For detailed usage instructions, see [USAGE.md](./USAGE.md)**  \n**For practical examples, see [EXAMPLES.md](./EXAMPLES.md)**\n\n## Features\n\n### Core Serialization\n\n- **Boolean**: `serialize(bool)` - Serializes as type byte (0x20) + 0x00/0x01\n- **Integer**: `serialize(uint256)` - Serializes as type byte (0x21) + VarInt length + little-endian bytes\n  - Handles zero as empty bytes (0x21 0x00)\n  - Automatic sign extension for MSB ≥ 0x80\n- **ByteString**: `serialize(bytes)` - Serializes as type byte (0x28) + VarInt length + bytes\n- **String**: `serialize(string)` - UTF-8 encoded as ByteString\n- **Arrays**: \n  - `serialize(uint256[])` - Array of integers\n  - `serialize(bytes[])` - Array of byte strings\n  - `serializeArray(bytes[])` - Array of already-serialized items\n\n### Neo-Specific Types\n\n- **Hash160**: `serializeHash160(bytes20)` / `serializeHash160(address)` - Reverses bytes for Neo's little-endian UInt160 format\n- **Buffer**: `serializeBuffer(bytes)` - Serializes with type byte (0x30) for ByteArray contract params\n\n### Contract Call Serialization\n\n- **serializeCall**: Serializes a complete Neo contract call\n  ```solidity\n  serializeCall(bytes20 target, string method, uint256 callFlags, bytes[] args)\n  serializeCall(address target, string method, uint256 callFlags, bytes[] args)\n  ```\n  - Serializes: `[target (Hash160), method (String), callFlags (Integer), args (Array)]`\n  - Supports both `bytes20` and `address` types for target\n\n### Gas-Optimized Mutations\n\n- **appendArgToCall**: Add an argument to an already-serialized call\n  ```solidity\n  appendArgToCall(bytes serializedCall, bytes serializedArg)\n  appendArgToCall(bytes serializedCall, uint256 innerArrayCountOffset, bytes serializedArg) // Fast path\n  ```\n  - Auto-navigates to inner args array and increments count\n  - Fast-path version accepts pre-computed offset for maximum efficiency\n\n- **replaceLastArg**: Replace the last argument in a serialized call\n  ```solidity\n  replaceLastArg(bytes serializedCall, uint256 oldArgSerializedLength, bytes newSerializedArg)\n  ```\n  - Perfect for off-chain serialization with placeholder (e.g., `nonce=0`)\n  - On-chain, just replace the placeholder with the real value\n  - No navigation needed - computes position from total length\n\n### Deserialization\n\n- **deserializeBool**: `(bool value, uint256 newOffset) = deserializeBool(data, offset)`\n- **deserializeUint256**: `(uint256 value, uint256 newOffset) = deserializeUint256(data, offset)`\n- **deserializeBytes**: `(bytes value, uint256 newOffset) = deserializeBytes(data, offset)`\n- **deserializeArray**: `(bytes[] items, uint256 newOffset) = deserializeArray(data, offset)`\n- **deserializeItem**: Generic deserializer that returns the raw serialized item\n\n### CallFlags Constants\n\nPre-defined constants matching Neo's CallFlags enum:\n- `CALL_FLAGS_NONE` (0)\n- `CALL_FLAGS_READ_STATES` (1)\n- `CALL_FLAGS_WRITE_STATES` (2)\n- `CALL_FLAGS_ALLOW_CALL` (4)\n- `CALL_FLAGS_ALLOW_NOTIFY` (8)\n- `CALL_FLAGS_STATES` (3) - ReadStates | WriteStates\n- `CALL_FLAGS_READ_ONLY` (5) - ReadStates | AllowCall\n- `CALL_FLAGS_ALL` (15) - All flags combined\n\n### Gas Optimizations\n\n- Assembly-optimized byte copying for bulk operations\n- Inlined constants and VarInt encoding\n- Word-aligned memory operations\n- `unchecked` blocks for safe arithmetic\n- Zero-allocation paths for common cases\n\n## Project Structure\n\n```\ncontracts/\n  libraries/\n    NeoSerializerLib.sol     # Main serialization library (use this!)\n    VarInt.sol               # VarInt encoding/decoding library\n    NeoTypes.sol             # StackItemType enum and helpers\n  examples/\n    ExampleUsage.sol         # Basic usage examples\n    ContractCallExample.sol  # Contract call serialization examples\n    StorageExample.sol        # On-chain storage example\n    CrossChainExample.sol     # Cross-chain interoperability example\n  test/\n    NeoSerializerTestHelper.sol  # Test helper (for testing libraries)\ntest/\n  NeoSerializer.test.ts           # Comprehensive test suite\n  NeoSerializerFormat.test.ts     # Exact byte format verification\n  NeoBinarySerializerPort.test.ts # Ported tests from Neo\n  ContractCall.test.ts             # Contract call serialization tests\n  OracleCallComparison.test.ts     # Real Neo node comparison\n  AppendArg.test.ts                # Append argument tests\n  ReplaceLastArg.test.ts           # Replace last argument tests\n  OptimizationSafety.test.ts      # Assembly optimization safety tests\n  GasCosts.test.ts                 # Gas cost analysis\n```\n\n## Installation\n\n```bash\nnpm install\n```\n\n## Usage\n\n### Import the Library\n\nThe library can be used directly in your contracts without deployment:\n\n```solidity\nimport \"@axlabs/neo-serializer-evm/contracts/libraries/NeoSerializerLib.sol\";\n\ncontract MyContract {\n    using NeoSerializerLib for uint256;\n    using NeoSerializerLib for bytes;\n    \n    function serializeData(uint256 value) external pure returns (bytes memory) {\n        // Direct library call - functions are inlined (no external call overhead)\n        return NeoSerializerLib.serialize(value);\n        \n        // Or with 'using' directive:\n        // return value.serialize();\n    }\n    \n    function deserializeData(bytes memory data) external pure returns (uint256) {\n        (uint256 value, ) = NeoSerializerLib.deserializeUint256(data, 0);\n        return value;\n    }\n}\n```\n\n### Examples\n\nSee the `contracts/examples/` directory for complete examples:\n\n- **ExampleUsage.sol**: Basic serialization/deserialization patterns\n- **ContractCallExample.sol**: Serializing Neo contract calls\n- **StorageExample.sol**: Using the library for on-chain storage\n- **CrossChainExample.sol**: Cross-chain interoperability with Neo blockchain\n\n### Compile\n\n```bash\nnpm run compile\n```\n\n### Test\n\n```bash\nnpm test\n```\n\n## API Reference\n\n### Serialization Functions\n\n```solidity\n// Primitives\nbytes memory serialized = NeoSerializerLib.serialize(true);        // Boolean\nbytes memory serialized = NeoSerializerLib.serialize(42);           // Integer\nbytes memory serialized = NeoSerializerLib.serialize(hex\"010203\");  // Bytes\nbytes memory serialized = NeoSerializerLib.serialize(\"hello\");      // String\n\n// Arrays\nuint256[] memory arr = new uint256[](3);\narr[0] = 1; arr[1] = 2; arr[2] = 3;\nbytes memory serialized = NeoSerializerLib.serialize(arr);         // Array of integers\n\nbytes[] memory items = new bytes[](2);\nitems[0] = hex\"0102\";\nitems[1] = hex\"0304\";\nbytes memory serialized = NeoSerializerLib.serialize(items);        // Array of bytes\n\n// Neo-specific\nbytes memory serialized = NeoSerializerLib.serializeHash160(0x...); // Hash160 (reversed)\nbytes memory serialized = NeoSerializerLib.serializeBuffer(hex\"...\"); // Buffer (type 0x30)\n\n// Contract calls\nbytes[] memory args = new bytes[](2);\nargs[0] = NeoSerializerLib.serialize(\"url\");\nargs[1] = NeoSerializerLib.serialize(100);\nbytes memory call = NeoSerializerLib.serializeCall(\n    target,\n    \"methodName\",\n    NeoSerializerLib.CALL_FLAGS_ALL,\n    args\n);\n```\n\n### Deserialization Functions\n\n```solidity\nuint256 offset = 0;\n\n// Deserialize a boolean\n(bool value, offset) = NeoSerializerLib.deserializeBool(data, offset);\n\n// Deserialize an integer\n(uint256 value, offset) = NeoSerializerLib.deserializeUint256(data, offset);\n\n// Deserialize bytes\n(bytes memory value, offset) = NeoSerializerLib.deserializeBytes(data, offset);\n\n// Deserialize an array\n(bytes[] memory items, offset) = NeoSerializerLib.deserializeArray(data, offset);\n```\n\n### Gas-Optimized Mutations\n\n```solidity\n// Serialize call off-chain with placeholder\nbytes[] memory args = new bytes[](6);\n// ... populate args ...\nargs[6] = NeoSerializerLib.serialize(0); // placeholder nonce\nbytes memory baseCall = NeoSerializerLib.serializeCall(target, method, flags, args);\n\n// On-chain: append a new argument\nbytes memory newArg = NeoSerializerLib.serialize(42);\nbytes memory withAppend = NeoSerializerLib.appendArgToCall(baseCall, newArg);\n\n// On-chain: replace the last argument (more efficient than append)\nbytes memory realNonce = NeoSerializerLib.serialize(100);\nuint256 placeholderLen = 2; // serialize(0) = 2 bytes (0x21 0x00)\nbytes memory withReplace = NeoSerializerLib.replaceLastArg(baseCall, placeholderLen, realNonce);\n```\n\n## Implementation Details\n\n### Array Serialization Order\n\nNeo serializes arrays with items in **forward order** (first element first). This matches Neo's BinarySerializer behavior.\n\n### Integer Encoding\n\nIntegers are encoded as:\n1. Type byte (0x21)\n2. VarInt encoding of byte length\n3. Little-endian bytes\n   - Zero is encoded as empty bytes: `0x21 0x00`\n   - Sign extension: if MSB ≥ 0x80, adds `0x00` byte to keep value positive\n\n### VarInt Encoding\n\nNeo uses a compact variable-length integer format:\n- 0-252: Direct byte value (1 byte)\n- 253-65535: `0xFD` + 2-byte little-endian uint16 (3 bytes)\n- 65536-4294967295: `0xFE` + 4-byte little-endian uint32 (5 bytes)\n- 4294967296+: `0xFF` + 8-byte little-endian uint64 (9 bytes)\n\n### Hash160 Byte Order\n\nNeo's `UInt160` uses **little-endian** byte order. The `serializeHash160` function automatically reverses the input bytes to match Neo's format.\n\n## Testing\n\nThe test suite covers:\n- VarInt encoding/decoding for all size cases\n- Primitive type serialization/deserialization\n- Array serialization with forward ordering\n- Round-trip tests (serialize → deserialize → compare)\n- Edge cases (zero, max values, large arrays)\n- Error handling\n- Exact byte format verification against Neo specification\n- Contract call serialization (including real Neo node comparison)\n- Gas-optimized mutations (append/replace)\n- Assembly optimization safety (73+ tests)\n- Gas cost analysis\n\nRun tests:\n```bash\nnpm test\n```\n\n## CI/CD\n\nGitHub Actions workflow runs tests on:\n- Pull requests to `main`, `master`, or `develop`\n- Pushes to `main`, `master`, or `develop`\n- Node.js versions: 18.x and 20.x\n\n## Publishing\n\n```bash\n# Dry run (test what would be published)\nnpm run publish:dry-run\n\n# Publish to npm (runs compile + test first)\nnpm run publish:public\n```\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md","homepage":"https://github.com/AxLabs/neo-serializer-evm#readme","repository":{"type":"git","url":"git+https://github.com/AxLabs/neo-serializer-evm.git"},"bugs":{"url":"https://github.com/AxLabs/neo-serializer-evm/issues"}}