syntax = "proto3"; package nu.types; option java_package = "tr.cw.narrativeunion.types"; option java_outer_classname = "TransactionProto"; // Hash256: 32-byte SHA-256 digest, hex-encoded // Address: 20-byte account address, hex-encoded // IpfsHash: CIDv1 string message Transaction { string tx_id = 1; // SHA-256(payload bytes) string sender = 2; // Address uint64 nonce = 3; uint64 fee = 4; // NUT micro-units (1 NUT = 1_000_000 units) bytes signature = 5; // secp256k1 compact (64 bytes) TxPayload payload = 6; } message TxPayload { oneof kind { TokenTransfer token_transfer = 1; NodeSubmit node_submit = 2; VoteRegister vote_register = 3; VoteCast vote_cast = 4; NftTransfer nft_transfer = 5; CollectionClaim collection_claim = 6; StakeOp stake_op = 7; ValidatorRegister validator_register = 8; // Auto-generated by validator — never submitted by users directly: NodeApprove node_approve = 9; NftMint nft_mint = 10; NodeReject node_reject = 11; VotingOpen voting_open = 12; } } message TokenTransfer { string to = 1; // Address uint64 amount = 2; } message NodeSubmit { string story_id = 1; string parent_node_id = 2; // empty if root node string content_hash = 3; // IpfsHash uint64 entry_fee = 4; // must equal reward * 0.25 string temp_id = 5; // client-generated UUID; replaced by canonical NodeId on approval } message VoteRegister { string node_id = 1; // temp_id at this stage uint64 stake_lock = 2; // must equal node_reward * 0.10; locked 10 days } message VoteCast { string node_id = 1; bool approve = 2; // true = approve, false = reject } message NftTransfer { string nft_id = 1; string to = 2; // Address } message CollectionClaim { repeated string nft_ids = 1; // must form a valid lineage path from root } message StakeOp { enum Kind { STAKE = 0; UNSTAKE = 1; } Kind op = 1; uint64 amount = 2; } message ValidatorRegister { uint64 stake = 1; // minimum 1_000_000_000 units (1000 NUT) } // --- Auto-generated scheduler/validator transactions --- message NodeApprove { string node_id = 1; // canonical NodeId assigned at approval string temp_id = 2; // maps back to NodeSubmit.temp_id string canonical_id = 3; // numeric path-encoded id e.g. "1159" } message NftMint { string node_id = 1; // canonical string recipient = 2; // Address — node author } message NodeReject { string temp_id = 1; } message VotingOpen { string node_id = 1; // temp_id; triggered at day 7 }