Novel thing in p2pIM compared to Bitmessage is that messages' PoW decays and that larger messages require better PoW than smaller ones. Thus small messages that are discarded quickly require significantly less PoW than large messages that persist for a long time. p2pIM doesn't support encryption but that should be straightforward to build on top.
Message_v0 class in https://github.com/iljah/p2pIM/blob/main/messages.py defines low level details such as PoW, how many bytes to use for nonce, checksum, etc. Currently they're all only about 10 bytes or hex characters for easier debugging and testing. PoW is calculated as sha256 of timestamp+nonce+checksum, where checksum is sha256 of payload. Adding channel name as fourth item to PoW is on the https://github.com/iljah/p2pIM/blob/main/TODO list. server1.py mentioned at end of README is my previous attempt at this (without AI help) and the one before that is probably https://github.com/iljah/a2amd in Rust.