Skip to content

ck0x/PayNote

Repository files navigation

πŸ’Έ PayNote

Attach References to Your On-Chain Payments

ENS made addresses human-readable. We make transactions human-meaningful.

Solidity Hardhat Optimism License: MIT

Tests Coverage Verified

Live Demo β€’ Documentation β€’ Report Bug β€’ Request Feature


πŸš€ What is PayNote?

PayNote is a decentralized protocol for attaching human-readable references to blockchain transactions. Think of it as ENS for transaction references - send ETH with invoice numbers, rent payments, donation messages, or any reference you need to track.

The Problem

Traditional blockchain transactions are just addresses and amounts. How do you track:

  • 🧾 Invoice payments ("Invoice #12345")
  • 🏠 Rent payments ("Rent - January 2025")
  • πŸ’ Donations ("For the children's fund")
  • πŸ“¦ Business transactions ("Order #ABC-789")

The Solution

PayNote lets you send payments with references in a single atomic transaction, stored permanently on-chain with cryptographic authentication. No post-transaction tagging, no forgery, just pure trustless reference storage.

// Send 1 ETH with a reference
payNoteRegistry.sendPaymentWithReference{value: 1 ether}(
    recipientAddress,
    "Invoice #12345 - Website Design"
);

✨ Features

  • ⚑ Atomic Payments - Reference stored in the same transaction as the payment
  • πŸ” Authenticated - Only the sender can create the reference (no forgery)
  • 🌐 Standard Interface - Designed to become an ecosystem-wide standard like ENS
  • πŸ“ Permanent Storage - References stored on-chain forever
  • πŸ” Easy Queries - Get all payments sent/received by any address
  • πŸ’° Low Cost - Deployed on Optimism L2 for 100x cheaper gas
  • πŸ›‘οΈ Battle-Tested - OpenZeppelin contracts for security
  • βœ… Verified - Source code verified on Etherscan & Blockscout

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     User / DApp                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              PayNoteRegistry Contract                        β”‚
β”‚  β€’ sendPaymentWithReference(recipient, reference)            β”‚
β”‚  β€’ resolvePayNote(payNoteId)                                 β”‚
β”‚  β€’ getPayNotesBySender(sender)                               β”‚
β”‚  β€’ getPayNotesByRecipient(recipient)                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό                               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Forward ETH to  β”‚          β”‚   Store PayNote  β”‚
β”‚    Recipient     β”‚          β”‚    On-Chain      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“¦ Repository Structure

PayNote/
β”œβ”€β”€ contracts/               # Smart contracts
β”‚   β”œβ”€β”€ contracts/
β”‚   β”‚   β”œβ”€β”€ PayNoteRegistry.sol          # Main implementation
β”‚   β”‚   β”œβ”€β”€ interfaces/
β”‚   β”‚   β”‚   └── IPayNoteRegistry.sol     # Standard interface
β”‚   β”‚   └── tests/
β”‚   β”‚       └── PayNoteRegistry.t.sol    # Solidity tests
β”‚   β”œβ”€β”€ test/
β”‚   β”‚   └── PayNoteRegistry.ts           # TypeScript tests
β”‚   β”œβ”€β”€ scripts/
β”‚   β”‚   β”œβ”€β”€ deploy.ts                    # Deployment script
β”‚   β”‚   └── test-payment.ts              # Test interaction
β”‚   β”œβ”€β”€ ignition/
β”‚   β”‚   └── modules/
β”‚   β”‚       └── PayNoteRegistry.ts       # Ignition deployment
β”‚   └── docs/
β”‚       β”œβ”€β”€ DEPLOYMENT_GUIDE.md          # How to deploy
β”‚       β”œβ”€β”€ KEYSTORE_GUIDE.md            # Hardhat keystore guide
β”‚       └── DEPLOYMENTS.md               # Deployment addresses
β”‚
└── frontend/               # Next.js frontend (coming soon)
    └── paynote/

🚦 Quick Start

Prerequisites

  • Node.js 18+
  • npm or pnpm
  • MetaMask or compatible wallet

Installation

# Clone the repository
git clone https://github.com/ck0x/PayNote.git
cd PayNote/contracts

# Install dependencies
npm install

# Compile contracts
npx hardhat compile

# Run tests
npx hardhat test

Deploy to Optimism Sepolia

# Set up encrypted secrets
npx hardhat keystore set OPTIMISM_SEPOLIA_PRIVATE_KEY
npx hardhat keystore set OPTIMISM_SEPOLIA_RPC_URL
npx hardhat keystore set OPTIMISM_ETHERSCAN_API_KEY

# Deploy
npx hardhat ignition deploy ignition/modules/PayNoteRegistry.ts --network optimismSepolia

# Verify
npx hardhat verify --network optimismSepolia --build-profile production <CONTRACT_ADDRESS> <OWNER_ADDRESS>

See DEPLOYMENT_GUIDE.md for detailed instructions.


🎯 Usage

Send a Payment with Reference

import { parseEther } from "viem";

// Connect to contract
const payNoteRegistry = await viem.getContractAt(
  "PayNoteRegistry",
  "0x0294b9c5902361b0f11bBAf0F1A4ca9F745ec13f"
);

// Send payment with reference
const hash = await payNoteRegistry.write.sendPaymentWithReference(
  ["0xRecipientAddress", "Invoice #12345"],
  { value: parseEther("1.0") }
);

console.log("Payment sent:", hash);

Query PayNotes

// Get all PayNotes sent by an address
const payNotes = await payNoteRegistry.read.getPayNotesBySender([
  "0xSenderAddress"
]);

// Resolve a specific PayNote
const payNote = await payNoteRegistry.read.resolvePayNote([payNoteId]);

console.log({
  sender: payNote.sender,
  recipient: payNote.recipient,
  amount: payNote.amount,
  reference: payNote.payReference,
  timestamp: payNote.timestamp
});

🌐 Deployed Contracts

Optimism Sepolia (Testnet)

Property Value
Contract PayNoteRegistry v2.0.0
Address 0x0294b9c5902361b0f11bBAf0F1A4ca9F745ec13f
Chain ID 11155420
Status βœ… Active & Verified
Etherscan View on Etherscan
Blockscout View on Blockscout

Optimism Mainnet (Production)

🚧 Coming Soon - Mainnet deployment planned after testnet validation


πŸ§ͺ Testing

PayNote has comprehensive test coverage with both Solidity and TypeScript tests:

# Run all tests
npx hardhat test

# Run Solidity tests only
npx hardhat test contracts/tests/PayNoteRegistry.t.sol

# Run TypeScript tests only
npx hardhat test test/PayNoteRegistry.ts

Test Results:

Running Solidity tests
  βœ” test_InitialState()
  βœ” test_SendPaymentWithReference()
  βœ” test_ResolvePayNote()
  βœ” test_GetPayNotesBySender()
  βœ” test_GetPayNotesByRecipient()

Running TypeScript tests
  βœ” Should set the correct owner
  βœ” Should start with zero registration fee
  βœ” Should have correct version
  βœ” Should send payment and store reference atomically
  βœ” Should emit PaymentSent event
  βœ” Should resolve a PayNote correctly

11 passing (1.6s)

πŸ› οΈ Tech Stack

Smart Contracts

  • Solidity 0.8.28 - Latest stable version
  • Hardhat 3.0 - Development environment
  • OpenZeppelin 5.4.0 - Battle-tested contracts
  • Viem 2.38 - Type-safe Ethereum library

Testing

  • Hardhat Test - TypeScript integration tests
  • Forge-std - Solidity unit tests
  • Chai - Assertions

Deployment

  • Hardhat Ignition - Declarative deployments
  • Hardhat Verify - Contract verification
  • Encrypted Keystore - Secure secret management

Network

  • Optimism Sepolia - L2 testnet
  • Optimism Mainnet - L2 production (planned)

πŸ’° Gas Costs & Economics

Cost Comparison

Action Direct Transfer PayNote Transfer Premium
Gas ~21,000 ~100-120k ~5x
Optimism L2 ~$0.001 ~$0.005 +$0.004
Ethereum L1 ~$0.50 ~$3.00 +$2.50

Why the Premium is Worth It

  • πŸ” Cryptographic Authentication - Provably from the sender
  • πŸ“ Permanent Storage - Reference stored forever on-chain
  • πŸ›‘οΈ No Forgery - Impossible to fake a PayNote
  • ⚑ 100x Cheaper on L2 - Optimism makes it affordable
  • 🎯 Single Transaction - Atomic payment + reference

πŸ“š Documentation


πŸ” Security

Audits

  • ⏳ Audit Status: Pending (testnet phase)
  • 🎯 Planned: Professional audit before mainnet launch

Security Features

  • βœ… OpenZeppelin - Industry-standard secure contracts
  • βœ… ReentrancyGuard - Protection against reentrancy attacks
  • βœ… Ownable - Access control for administrative functions
  • βœ… Automated Tests - 11/11 tests passing
  • βœ… Verified Source - Code verified on Etherscan & Blockscout

Responsible Disclosure

Found a security issue? Please email: security@paynote.io (or open a private security advisory)


πŸ—ΊοΈ Roadmap

βœ… Phase 1: Core Protocol (Complete)

  • PayNoteRegistry contract implementation
  • Standard interface (IPayNoteRegistry)
  • Comprehensive test suite
  • Deployment to Optimism Sepolia
  • Contract verification

🚧 Phase 2: Frontend (In Progress)

  • Next.js web application
  • Wallet integration (MetaMask, WalletConnect)
  • Payment history dashboard
  • Search and filter PayNotes
  • Export to CSV

πŸ“‹ Phase 3: Ecosystem (Planned)

  • Mainnet deployment (Optimism)
  • Professional security audit
  • SDK/NPM package
  • Multi-chain support (Arbitrum, Base)
  • EIP proposal for standard

🎯 Phase 4: Advanced Features (Future)

  • PayNote escrow contracts
  • Recurring payment support
  • Multi-recipient splits
  • Reference templates
  • API for integration

🀝 Contributing

We welcome contributions! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Guidelines

  • Write tests for new features
  • Follow Solidity style guide
  • Update documentation
  • Keep gas costs in mind
  • Use conventional commits

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ™ Acknowledgments

  • OpenZeppelin - Secure smart contract library
  • Hardhat - Amazing development environment
  • Optimism - Affordable L2 infrastructure
  • Viem - Modern Ethereum library
  • The Ethereum Community - For building the future

πŸ“ž Contact & Links


Built with ❀️ for the Ethereum ecosystem

GitHub Stars Twitter Follow

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors