LogoLogo
X/TwitterMediumGitHubDePHY Website
  • Introduction
    • What is DePHY
    • Key features
    • Architecture
  • Components
    • Messaging layer 🔥
      • Data Pub-Sub
      • Solana Integration
      • RPC Call
      • RPC Endpoints
      • Best Practices
      • Verifiable logs
    • DePHY ID [Coming Soon]
      • Register products
      • Mint DID
      • Use DID as token gate (access control)
      • Extentions
      • Build with DePHY ID
      • Hardware integration and attestation
    • Liquidity layer
      • Stake Pool
      • Yield Pool
      • PayFi Pool
    • Verification layer
      • Proof of real device
        • Integration
      • Proof of location
        • Integration
      • DePHY NCN (on Jito Restaking)
        • Integration
      • Trusted DePIN network map
        • Integration
  • Tutorials 🔥
    • Build a Hello World (Rust)
    • Build a Hello World (TypeScript)
    • Build a DeCharge Machine
    • Build a Gacha Machine
    • Build a LLM Proxy
  • Service Mesh
    • AI MCP Services
      • About MCP
      • How to Enable DePHY MCP Server
      • How to use DePHY MCP
  • DePHY Node 🕹️
    • Get a DePHY Node
    • Set Up a DePHY Node
    • Migration From Testnet1 to Testnet2
    • Node Setup FAQ
  • Resources
    • Blog
    • GitHub
    • X
    • Telegram
    • Discord
Powered by GitBook
On this page
  • How to Run Locally
  • Messaging
  • Building Controller
  • Solana Interaction
  1. Tutorials 🔥

Build a DeCharge Machine

PreviousBuild a Hello World (TypeScript)NextBuild a Gacha Machine

Last updated 1 month ago

Before proceeding, ensure you have cloned the repository:

git clone https://github.com/dephy-io/dephy-vending_machine-examples.git

The DeCharge machine demonstrates a continuous charging model, where a device operates over time and charges users incrementally. Its messaging network leverages Nostr for event-driven communication, with Solana handling payments via lock and settle.

An online demo of these examples is available at:

How to Run Locally

  1. Run DePHY vending machine workers by: docker compose up

  • The docker compose setup and the App demo application integrate both DeCharge and Gacha use cases.

  • Ensure all dependencies are installed before running the application.

Messaging

  • Message Definition: Messages are defined as DephyDechargeMessage (in message.rs), with two variants:

    • Request: Initiates a state change (e.g., user requests the machine to start).

    • Status: Confirms a state update (e.g., machine is now Working).

    pub enum DephyDechargeMessage {
        Request { 
            to_status: DephyDechargeStatus, 
            reason: DephyDechargeStatusReason, 
            initial_request: EventId, 
            payload: String, 
        },
        Status { 
            status: DephyDechargeStatus, 
            reason: DephyDechargeStatusReason, 
            initial_request: EventId, 
            payload: String, 
        },
    }
  • Mention Tag (Machine Pubkey): The p tag identifies the target machine using its Nostr public key. For example, PublicKey::parse("machine_pubkey") specifies which device receives the message.

  • Session Tag: The s tag scopes events to a specific session (e.g., "dephy-decharge-controller"), ensuring messages are isolated to the current context.

  • Publishing and Subscription: The RelayClient publishes messages to a Nostr relay and subscribes to events using filters:

    let filter = Filter::new()
        .kind(EVENT_KIND) // Custom kind 1573
        .since(started_at)
        .custom_tag(SESSION_TAG, ["dephy-decharge-controller"])
        .custom_tag(MENTION_TAG, [machine_pubkey.to_hex()]);
    let sub_id = relay_client.subscribe(started_at, [machine_pubkey]).await?;
    • Filter: Retrieves events since started_at, scoped to the session and machine pubkey.

    • Sender: Typically a user or admin via the dApp or CLI.

    • Receiver: The DeCharge node controller handling the machine.

  • Message Handling: The MessageHandler processes events, updating machine states and coordinating with Solana.

Building Controller

  • Node: Listens for user Request events, verifies eligibility with check_eligible, and updates machine state (e.g., Available to Working). It notifies the server via Status events.

  • Server: Monitors Status events, locks funds with lock when the machine starts, and settles the final amount with settle when it stops. This split ensures state management and payment processing are separate but coordinated.

Solana Interaction

  • Controller: Initiates state change and verifies eligibility

// Before: Received Request event to start machine
if dephy_balance_payment_sdk::check_eligible(
    &self.solana_rpc_url,
    parsed_payload.namespace_id,
    &parsed_payload.user,
    parsed_payload.nonce,
    PREPAID_AMOUNT,
    &parsed_payload.recover_info,
).await? {
    // After: Send Status event to set machine to Working
    self.client.send_event(mention, &DephyDechargeMessage::Status { ... }).await?;
}
  • Server: Locks and settles funds

    // When machine starts (Working status)
    // Before: Received Status event indicating machine is Working
    if let Err(e) = dephy_balance_payment_sdk::lock(
        &self.solana_rpc_url,
        &self.solana_keypair_path,
        parsed_payload.namespace_id,
        &parsed_payload.user,
        PREPAID_AMOUNT,
        &parsed_payload.recover_info,
    ).await {
        // After: Send Request event to revert to Available if lock fails
        self.client.send_event(mention, &DephyDechargeMessage::Request { to_status: DephyDechargeStatus::Available, ... }).await?;
    }
    
    // When machine stops (Available status after 60s)
    // Before: Received Status event indicating machine is Available
    if let Err(e) = dephy_balance_payment_sdk::settle(
        &self.solana_rpc_url,
        &self.solana_keypair_path,
        &parsed_payload.user,
        parsed_payload.nonce,
        TRANSFER_AMOUNT,
    ).await {
        tracing::error!("Settle failed: {:?}", e);
    }
    // After: No event sent; balance is settled

DePHY vending machine examples
https://dephy-vending-machine-examples.pages.dev/examples
Run DePHY messaging network
Deploy the Solana program and run the dApp