{"title": "Dispas Stealth ", "website": "https://dispastealth.vercel.app/", "createdAt": 1739535929888, "userGithub": "tantodefi", "credentials": {}, "description": "this is a fork of valentines dispas grid dapp for multi-send. (https://github.com/ValentineCodes/dispas)\n\nThis fork includes an adapted DispasStealth.sol contract that implements ERC-5564 STEALTH ADDRESSES on LUKSO..\n\nALL TEST ARE PASSING + contracts deployed to testnet + mainnet\n\nEnabling privacy on LUKSO\n\nstill a few bugs on front-end\n\n# Dispastealth: Stealth Payments on LUKSO\n\nDispas implements ERC-5564 stealth addresses integrated with LUKSO Universal Profiles, allowing private payments while maintaining the benefits of account abstraction.\n\nhttps://dispastealth.vercel.app/\n\nhttps://dispastealth.vercel.app/register-stealth\n\ntestnet deployment:\n```\nnpx hardhat deploy --network luksoTestnet --tags ERC5564\nWARNING: You are currently using Node.js v23.5.0, which is not supported by Hardhat. This can lead to unexpected behavior. See https://hardhat.org/nodejs-versions\n\n\nPrivate key length: 66\nNothing to compile\nNo need to generate any newer typings.\ndeploying \"ERC5564Registry\" (tx: 0xb8aa46db56fb4f1fbdd5983f954e85afc2c65ef672063ca06ee634a8faa267bb)...: deployed at 0x8653F395983827E05A6625eED4D045e696980D16 with 494901 gas\ndeploying \"ERC5564Announcer\" (tx: 0x83327a5735c8482776c11333586a2e3ef37871f9f198bb7f871c67f4e408c1bd)...: deployed at 0x4E581D6a88bc7D60D092673904d961B6b0961A40 with 189957 gas\n📝 Updated TypeScript contract definition file on ../nextjs/contracts/deployedContracts.ts\n👻 -GH05T-1N-TH3-5H3LL ~/dispastealth/packages/hardhat   main ●  \nnpx hardhat deploy --network luksoTestnet --tags DispasStealth\nWARNING: You are currently using Node.js v23.5.0, which is not supported by Hardhat. This can lead to unexpected behavior. See https://hardhat.org/nodejs-versions\n\n\nPrivate key length: 66\nNothing to compile\nNo need to generate any newer typings.\nreusing \"ERC5564Registry\" at 0x8653F395983827E05A6625eED4D045e696980D16\nreusing \"ERC5564Announcer\" at 0x4E581D6a88bc7D60D092673904d961B6b0961A40\ndeploying \"DispasStealth\" (tx: 0xbee6d2a6035fbbb3bff3bb207e89222f1376a8b9ab25d9476dcd8e8f9e62e773)...: deployed at 0x312ef2A035bA266Ed81e7C6CaC0e6d8929EEF13a with 553045 gas\n📝 Updated TypeScript contract definition file on ../nextjs/contracts/deployedContracts.ts\n👻 -GH05T-1N-TH3-5H3LL ~/dispastealth/packages/hardhat   main ●  \nnpx hardhat deploy --network luksoTestnet --tags Dispas\nWARNING: You are currently using Node.js v23.5.0, which is not supported by Hardhat. This can lead to unexpected behavior. See https://hardhat.org/nodejs-versions\n\n\nPrivate key length: 66\nNothing to compile\nNo need to generate any newer typings.\ndeploying \"Dispas\" (tx: 0x9def886bb9a225687235b4f36559af1dec595a4f723382bbb319f96f6d019323)...: deployed at 0x746C338d272581967ad9F3F4d7CB3994EDf91b3a with 237654 gas\n📝 Updated TypeScript contract definition file on ../nextjs/contracts/deployedContracts.ts\n```\n\nmainnet deployment:\n```\nnpx hardhat deploy --network luksoMainnet --tags ERC5564\n\nWARNING: You are currently using Node.js v23.5.0, which is not supported by Hardhat. This can lead to unexpected behavior. See https://hardhat.org/nodejs-versions\n\n\nPrivate key length: 66\nNothing to compile\nNo need to generate any newer typings.\ndeploying \"ERC5564Announcer\" (tx: 0xe1333ba120fe4e4dc452d2285171e6200e435478c30351f00190541e7dc1d69e)...: deployed at 0x8653F395983827E05A6625eED4D045e696980D16 with 189957 gas\ndeploying \"ERC5564Registry\" (tx: 0xee2752b825fc43762a917121d16cc0b0dfe9900c985192a8a34c01d0f4f2ddf8)...: deployed at 0x4E581D6a88bc7D60D092673904d961B6b0961A40 with 494901 gas\n📝 Updated TypeScript contract definition file on ../nextjs/contracts/deployedContracts.ts\nnpx hardhat deploy --network luksoMainnet --tags Dispas\nWARNING: You are currently using Node.js v23.5.0, which is not supported by Hardhat. This can lead to unexpected behavior. See https://hardhat.org/nodejs-versions\n\n\nPrivate key length: 66\nNothing to compile\nNo need to generate any newer typings.\ndeploying \"Dispas\" (tx: 0x3a3b32322796d5b4b085bfe0a80e8dc0aabc286b4f501a009d50c7359c8d7331)...: deployed at 0x312ef2A035bA266Ed81e7C6CaC0e6d8929EEF13a with 237654 gas\nnpx hardhat deploy --network luksoMainnet --tags Dispas\nWARNING: You are currently using Node.js v23.5.0, which is not supported by Hardhat. This can lead to unexpected behavior. See https://hardhat.org/nodejs-versions\n\n\nPrivate key length: 66\nNothing to compile\nNo need to generate any newer typings.\nreusing \"Dispas\" at 0x312ef2A035bA266Ed81e7C6CaC0e6d8929EEF13a\nreusing \"ERC5564Announcer\" at 0x8653F395983827E05A6625eED4D045e696980D16\nreusing \"ERC5564Registry\" at 0x4E581D6a88bc7D60D092673904d961B6b0961A40\ndeploying \"DispasStealth\" (tx: 0x467124cf867ce5a14d6f95767e27e195804cf6072560e94fbc735a47fea1101b)...: deployed at 0x746C338d272581967ad9F3F4d7CB3994EDf91b3a with 553045 gas\n```\n\n\n## Stealth Address Architecture\n\n### Core Components\n\n1. **Stealth Meta-Address Generation**\n\n```\ntypescript\n// packages/nextjs/utils/stealthAddress.ts\nexport class StealthAddressManager {\nstatic async createStealthMetaAddress(recipientAddress: string): Promise<StealthMetaAddress> {\nconst randomBytes = ethers.utils.randomBytes(32);\nconst signature = ethers.utils.keccak256(randomBytes);\nconst keys = generateKeysFromSignature(signature);\nconst metaAddress = generateStealthMetaAddress(keys.spendingPubKey, keys.viewingPubKey);\nreturn {\nmetaAddress,\nkeys,\n};\n}\n}\n```\n\nThis generates a stealth meta-address that can be publicly shared. The meta-address contains the public keys needed for generating one-time stealth addresses.\n\n2. **Key Storage in Universal Profiles**\n\n```\ntypescript\nstatic async storeKeysInUniversalProfile(\nupAddress: string,\nkeys: StealthMetaAddress[\"keys\"],\nsigner: ethers.Signer\n) {\nconst erc725 = new ERC725(\nLSP0_ABI,\nupAddress,\nsigner.provider,\n{ ipfsGateway: \"https://api.universalprofile.cloud/ipfs\" }\n);\nconst keyName = ethers.utils.keccak256(\nethers.utils.toUtf8Bytes(\"StealthKeys\")\n);\nconst value = ethers.utils.defaultAbiCoder.encode(\n[\"bytes32\", \"bytes32\", \"bytes32\", \"bytes32\"],\n[\nkeys.spendingPubKey,\nkeys.viewingPubKey,\nkeys.spendingPrivKey,\nkeys.viewingPrivKey,\n]\n);\nawait erc725.connect(signer).setData(keyName, value);\n}\n```\n\nThe stealth keys are securely stored in the recipient's Universal Profile using ERC-725 data storage.\n\n### Smart Contracts\n\n1. **ERC-5564 Registry**\n\n```\nsolidity\n// packages/hardhat/contracts/protocol/ERC5564Registry.sol\ncontract ERC5564Registry {\nevent StealthAddressAnnouncement(\naddress indexed ephemeralAddress,\nbytes32 indexed stealthRecipientAndViewTag,\nbytes metadata\n);\nfunction announce(\naddress ephemeralAddress,\nbytes32 stealthRecipientAndViewTag,\nbytes calldata metadata\n) external {\nemit StealthAddressAnnouncement(\nephemeralAddress,\nstealthRecipientAndViewTag,\nmetadata\n);\n}\n}```\n\nThe registry contract emits events for stealth payments, allowing recipients to scan for their payments.\n\n2. **Stealth Payment Distribution**\n\n```\nsolidity\n// packages/hardhat/contracts/protocol/DispasStealth.sol\ncontract DispasStealth {\nfunction distributeStealthFunds(StealthPayment[] calldata payments) external payable {\nuint256 totalAmount = 0;\nfor (uint256 i = 0; i < payments.length; i++) {\ntotalAmount += payments[i].amount;\n// Generate stealth address from meta-address\naddress stealthAddress = generateStealthAddress(\npayments[i].stealthMetaAddress\n);\n// Transfer funds and announce\npayable(stealthAddress).transfer(payments[i].amount);\nannouncer.announce(\nstealthAddress,\npayments[i].stealthMetaAddress,\n\"\"\n);\n}\nrequire(msg.value >= totalAmount, \"Insufficient funds sent\");\n}\n}```\n\n### Frontend Integration\n\n1. **Stealth Toggle Component**\n\n```\ntypescript\n// packages/nextjs/components/StealthToggle.tsx\nexport const StealthToggle = ({ onChange }: { onChange: (enabled: boolean) => void }) => {\nreturn (\n<div className=\"form-control\">\n<label className=\"label cursor-pointer\">\n<span className=\"label-text mr-2\">Enable Stealth Payments</span>\n<input\ntype=\"checkbox\"\nclassName=\"toggle toggle-primary\"\nonChange={e => onChange(e.target.checked)}\n/>\n</label>\n</div>\n);\n};```\n\n2. **Stealth Address Helper**\n\n```\ntypescript\n// packages/nextjs/components/StealthAddressHelper.tsx\nexport const StealthAddressHelper = () => {\nconst { address } = useAccount();\nconst [stealthMetaAddress, setStealthMetaAddress] = useState<string>(\"\");\nconst generateStealthMetaAddress = async () => {\nif (!address) return;\nconst manager = new StealthAddressManager();\nconst metaAddress = await manager.generateStealthMetaAddress(address);\nsetStealthMetaAddress(metaAddress);\n};\n// ... QR code and display logic\n};```\n\n## How It Works\n\n1. **Generating a Stealth Meta-Address**\n   - User connects their Universal Profile\n   - Generates a stealth meta-address using ERC-5564\n   - Stores the keys in their Universal Profile using ERC-725\n\n2. **Sending a Stealth Payment**\n   - Sender gets recipient's stealth meta-address\n   - Frontend generates a one-time stealth address\n   - Payment is sent through DispasStealth contract\n   - Payment is announced on ERC-5564 registry\n\n3. **Receiving a Stealth Payment**\n   - Recipient scans ERC-5564 registry events\n   - Retrieves keys from their Universal Profile\n   - Derives private keys for the stealth address\n   - Can now access and spend the received funds\n\n## Security Considerations\n\n1. **Key Storage**\n   - Private keys are stored encrypted in Universal Profiles\n   - Only the UP owner can access their stealth keys\n   - Keys never leave the user's device unencrypted\n\n2. **Payment Privacy**\n   - Each payment uses a unique stealth address\n   - No on-chain link between UP and stealth address\n   - Only recipient can link payments to their UP\n\n3. **Integration with Universal Profiles**\n   - Maintains account abstraction benefits\n   - Social recovery through UP\n   - Integrated with UP permissions system\n\n#### Contract Interactions\n1. DispasStealth + ERC5564Announcer:\n- DispasStealth holds a reference to the ERC5564Announcer contract (STEALTH_ANNOUNCER)\n- Used to announce stealth payments through the announce() function\n- The announcer emits events that recipients can scan for their payments\n\n2. DispasStealth + Universal Profiles (UPs):\n- Users interact through their Universal Profiles (LUKSO's account abstraction)\n- UPs register their stealth metadata using registerStealthMetadata()\n- UPs receive funds through stealth transfers\n\n#### User Flow\n\n1. Registration:\n\n```\nfunction registerStealthMetadata(address account, bytes32 metadata) external {\n    require(msg.sender == account, \"Not authorized\");\n    stealthMetadata[account] = metadata;\n    emit StealthMetadataRegistered(account, metadata);\n}```\n\n- User creates stealth keys (off-chain)\n- User registers their stealth metadata through their UP\n- Metadata is stored in the contract's mapping\n\n2. Sending Stealth Payments:\n\n```\nfunction sendStealthTransfer(\n    address from,\n    address to,\n    address ephemeralAddress\n) external payable {\n    require(msg.value > 0, \"Zero amount\");\n    require(stealthMetadata[to] != bytes32(0), \"Recipient has no stealth metadata\");\n    \n    // Transfer funds\n    (bool success, ) = to.call{value: msg.value}(\"\");\n    require(success, \"Transfer failed\");\n\n    // Announce the transfer\n    STEALTH_ANNOUNCER.announce(\n        SCHEME_ID,\n        ephemeralAddress,\n        abi.encodePacked(stealthMetadata[to]),\n        abi.encode(msg.value)\n    );\n\n    emit StealthTransfer(from, to, ephemeralAddress, msg.value);\n}\n}```\n\nFlow:\n1. Sender looks up recipient's stealth metadata\n2. Generates ephemeral address using recipient's metadata\n3. Sends payment through DispasStealth contract\n4. Contract announces the payment through ERC5564Announcer\n\n3. Receiving Payments:\n\n```\nfunction getAnnouncements(address recipient) external view returns (\n    Announcement[] memory\n) {\n    // Recipients scan these announcements to find their payments\n    // ...\n});\n}\n}```\n\nFlow:\n1. Recipient scans ERC-5564 registry events\n2. Retrieves keys from their Universal Profile\n3. Derives private keys for the stealth address\n4. Can now access and spend the received funds\n\n\n\n## [🤑 Dispas](https://dispas.vercel.app)\n\n**Fancy a quick demo? 👉 https://youtu.be/7YJ1J9-KH40**\n\n### Manage payroll, allowances, donations, e.t.c more easily by distributing funds in ONE transaction\n\n![Dispas](https://valentinecodes.github.io/dispas/assets/dispas.png)\n\n## Local Development\n\nBefore you begin, you need to install the following tools:\n\n- [Node (>= v18.18)](https://nodejs.org/en/download/)\n- Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install))\n- [Git](https://git-scm.com/downloads)\n\n## Quickstart\n\nTo get started with Dispas, follow the steps below:\n\n1. Clone repo and install dependencies:\n\n```\ngit clone https://github.com/ValentineCodes/dispas.git\ncd dispas\nyarn install\n```\n\n2. Run a local network in the first terminal:\n\n```\nyarn chain\n```\n\nThis command starts a local Ethereum network using Hardhat. The network runs on your local machine and can be used for testing and development. You can customize the network configuration in `packages/hardhat/hardhat.config.ts`.\n\n3. On a second terminal, deploy the test contract:\n\n```\nyarn deploy\n```\n\nThis command deploys a test smart contract to the local network. The contract is located in `packages/hardhat/contracts` and can be modified to suit your needs. The `yarn deploy` command uses the deploy script located in `packages/hardhat/deploy` to deploy the contract to the network. You can also customize the deploy script.\n\n4. On a third terminal, start your NextJS app:\n\n```\nyarn start\n```\n\nVisit your app on: `http://localhost:3000`. You can interact with your smart contract using the `Debug Contracts` page. You can tweak the app config in `packages/nextjs/scaffold.config.ts`.\n\nRun smart contract test with `yarn hardhat:test`\n\n- Edit smart contracts in `packages/hardhat/contracts`\n- Edit frontend homepage at `packages/nextjs/app/page.tsx`. For guidance on [routing](https://nextjs.org/docs/app/building-your-application/routing/defining-routes) and configuring [pages/layouts](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts) checkout the Next.js documentation.\n- Edit deployment scripts in `packages/hardhat/deploy`\n\n## Contributing to Dispas\n\nWe welcome contributions to Dispas!\n\nPlease see [CONTRIBUTING.MD](https://github.com/valentinecodes/dispas/blob/main/CONTRIBUTING.md) for more information and guidelines for contributing to Dispas.\n\n", "projectGithub": "DeezStealth", "projectTwitter": "tantodefi"}