From c002f33b26f54171343c97320397d7bcaf008294 Mon Sep 17 00:00:00 2001 From: zacksfF Date: Thu, 13 Nov 2025 14:49:38 +0100 Subject: [PATCH 1/2] feat: add data structs --- src/structs/PackageStructs.sol | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/structs/PackageStructs.sol diff --git a/src/structs/PackageStructs.sol b/src/structs/PackageStructs.sol new file mode 100644 index 0000000..3030d12 --- /dev/null +++ b/src/structs/PackageStructs.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title PackageStructs +/// @notice All data structures from EIP-2678 (EthPM v3) +/// @dev Based on https://eips.ethereum.org/EIPS/eip-2678 +library PackageStructs { + + /// @notice Package Meta Object from EIP-2678 + struct PackageMeta { + string[] authors; // Human readable author names + string license; // SPDX format license + string description; // Package description + string[] keywords; // Relevant keywords + string website; // Primary website + string documentation; // Documentation link + string repository; // Source code location + } + + /// @notice Compiler Information Object from EIP-2678 + struct CompilerInfo { + string name; // Compiler name (e.g., "solc") + string version; // Semver or commit hash (e.g., "0.8.0" or "0.4.8-commit.60cc1668") + bytes settings; // Compiler settings as bytes + } + + /// @notice Contract Type from EIP-2678 + struct ContractType { + string contractName; // Name from source code (e.g., "Wallet") + bytes abi; // JSON ABI as bytes + bytes bytecode; // Unlinked deployment bytecode + bytes runtimeBytecode; // Unlinked runtime bytecode + string sourceId; // Reference to source file + uint256 compilerIndex; // Index in compilers array + } + + /// @notice Contract Instance Object from EIP-2678 + struct ContractInstance { + string contractType; // Reference to Contract Type (e.g., "Wallet" or "owned:Owned") + address instanceAddress; // Deployed contract address + bytes32 transaction; // Deployment transaction hash + uint256 blockNumber; // Deployment block number + bytes runtimeBytecode; // Linked runtime bytecode + } + + /// @notice Link Reference Object from EIP-2678 + struct LinkReference { + uint256[] offsets; // Start positions in bytecode (0-indexed) + uint256 length; // Length in bytes of the reference + string name; // Identifier for linking + } + + /// @notice Link Value Object from EIP-2678 + struct LinkValue { + uint256[] offsets; // Locations where value was written + string valueType; // "literal" for bytecode literals, "reference" for named references + string value; // 0x-prefixed hex string or contract instance name + } + + /// @notice Deployment information per chain from EIP-2678 + struct DeploymentInfo { + string chainURI; // BIP122 URI (e.g., blockchain:///block/) + ContractInstance[] instances; // Array of deployed contract instances + } + + /// @notice Source file information from EIP-2678 + struct SourceInfo { + string sourceId; // Unique identifier for source file + string content; // Source code content or IPFS hash + string license; // SPDX license (overrides package license) + } +} \ No newline at end of file From 1d7b0751348e4f67859b441314891ef8b1d5d59a Mon Sep 17 00:00:00 2001 From: zacksfF Date: Thu, 13 Nov 2025 14:52:16 +0100 Subject: [PATCH 2/2] feat: add pakcage structs #2 --- test/structs/PackageStructs.t.sol | 106 ++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/structs/PackageStructs.t.sol diff --git a/test/structs/PackageStructs.t.sol b/test/structs/PackageStructs.t.sol new file mode 100644 index 0000000..6b179bc --- /dev/null +++ b/test/structs/PackageStructs.t.sol @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "forge-std/Test.sol"; +import "src/structs/PackageStructs.sol"; + +contract PackageStructsTest is Test { + + function testPackageMeta() public { + PackageStructs.PackageMeta memory meta; + meta.authors = new string[](2); + meta.authors[0] = "Satoshi"; + meta.authors[1] = "Vitalik"; + meta.license = "MIT"; + meta.description = "A safe math library"; + meta.keywords = new string[](2); + meta.keywords[0] = "math"; + meta.keywords[1] = "library"; + meta.website = "https://example.com"; + + assertEq(meta.authors[0], "Satoshi"); + assertEq(meta.license, "MIT"); + assertEq(meta.keywords.length, 2); + } + + function testCompilerInfo() public { + PackageStructs.CompilerInfo memory compiler; + compiler.name = "solc"; + compiler.version = "0.8.0"; + + assertEq(compiler.name, "solc"); + assertEq(compiler.version, "0.8.0"); + } + + function testContractType() public { + PackageStructs.ContractType memory cType; + cType.contractName = "Wallet"; + cType.sourceId = "contracts/Wallet.sol"; + cType.compilerIndex = 0; + + assertEq(cType.contractName, "Wallet"); + assertEq(cType.sourceId, "contracts/Wallet.sol"); + } + + function testContractInstance() public { + PackageStructs.ContractInstance memory instance; + instance.contractType = "Wallet"; + instance.instanceAddress = address(0x1234567890123456789012345678901234567890); + instance.transaction = keccak256("deployment_tx"); + instance.blockNumber = 12345; + + assertEq(instance.contractType, "Wallet"); + assertEq(instance.instanceAddress, address(0x1234567890123456789012345678901234567890)); + assertEq(instance.blockNumber, 12345); + } + + function testLinkReference() public { + PackageStructs.LinkReference memory ref; + ref.offsets = new uint256[](2); + ref.offsets[0] = 10; + ref.offsets[1] = 50; + ref.length = 20; + ref.name = "SafeMath"; + + assertEq(ref.offsets[0], 10); + assertEq(ref.offsets[1], 50); + assertEq(ref.length, 20); + assertEq(ref.name, "SafeMath"); + } + + function testLinkValue() public { + PackageStructs.LinkValue memory val; + val.offsets = new uint256[](1); + val.offsets[0] = 100; + val.valueType = "literal"; + val.value = "0x1234"; + + assertEq(val.offsets[0], 100); + assertEq(val.valueType, "literal"); + assertEq(val.value, "0x1234"); + } + + function testDeploymentInfo() public { + PackageStructs.DeploymentInfo memory deployment; + deployment.chainURI = "blockchain://1/block/0x123abc"; + deployment.instances = new PackageStructs.ContractInstance[](1); + + deployment.instances[0].contractType = "Token"; + deployment.instances[0].instanceAddress = address(0x999); + deployment.instances[0].blockNumber = 99999; + + assertEq(deployment.chainURI, "blockchain://1/block/0x123abc"); + assertEq(deployment.instances.length, 1); + assertEq(deployment.instances[0].contractType, "Token"); + } + + function testSourceInfo() public { + PackageStructs.SourceInfo memory source; + source.sourceId = "contracts/Token.sol"; + source.content = "ipfs://Qm..."; + source.license = "GPL-3.0"; + + assertEq(source.sourceId, "contracts/Token.sol"); + assertEq(source.license, "GPL-3.0"); + } +} \ No newline at end of file