@startuml title Node Claim — Peer A publish its PeerRecord (claimInfo + publishPeerRecord) participant "DB Peer A (oc-lib)" as DBA participant "Node A" as NodeA participant "Indexer (shared)" as IndexerA participant "DHT Kademlia" as DHT participant "NATS A" as NATSA NodeA -> DBA: DB(PEER).Search(SELF) DBA --> NodeA: existing peer (DID_A) or new UUID NodeA -> NodeA: LoadKeyFromFilePrivate() → priv A NodeA -> NodeA: LoadKeyFromFilePublic() → pub A NodeA -> NodeA: Build PeerRecord A {\n Name, DID, PubKey,\n PeerID: PeerID_A,\n APIUrl: hostname,\n StreamAddress: /ip4/.../tcp/4001/p2p/PeerID_A,\n NATSAddress, WalletAddress\n} NodeA -> NodeA: priv.Sign(rec) → signature NodeA -> NodeA: rec.ExpiryDate = now + 150s loop For every Node Binded Indexer (Indexer A, B, ...) NodeA -> IndexerA: TempStream /opencloud/record/publish/1.0 NodeA -> IndexerA: strea!.Encode(Signed PeerRecord A) IndexerA -> IndexerA: Verify signature IndexerA -> IndexerA: Check PeerID_A heartbeat stream IndexerA -> DHT: PutValue("/node/"+DID_A, PeerRecord A) DHT --> IndexerA: ok end NodeA -> NodeA: rec.ExtractPeer(DID_A, DID_A, pub A) NodeA -> NATSA: SetNATSPub(CREATE_RESOURCE, {PEER, Peer A JSON}) NATSA -> DBA: Upsert Peer A (SearchAttr: peer_id) DBA --> NATSA: ok NodeA --> NodeA: *peer.Peer A (SELF) @enduml