# Build a Gacha Machine

Before proceeding, ensure you have cloned the [DePHY vending machine examples](https://github.com/dephy-io/dephy-vending_machine-examples) repository:

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

The Gacha machine implements a single-charge model, charging a fixed amount for a one-time action (e.g., dispensing an item). It simplifies the messaging and payment logic compared to DeCharge.

An online demo of these examples is available at: <https://dephy-vending-machine-examples.pages.dev/examples>

## How to Run Locally

1. [Run DePHY messaging network](https://github.com/dephy-io/dephy-messaging-network-self-hosted/tree/main/dephy-messaging-network)
2. Run DePHY vending machine workers by: `docker compose up`
3. [Deploy the Solana program and run the dApp](https://github.com/dephy-io/dephy-vending_machine-examples/blob/main/balance-payment/README.md)

* 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**: Same as DeCharge (`DephyDechargeMessage`), but typically only processes `Request` to `Working` and `Status` back to `Available`.
* **Mention Tag (Machine Pubkey)**: Identifies the GaCha machine (e.g., `PublicKey::parse("gacha_machine_pubkey")`).
* **Session Tag**: Scopes events (e.g., `"dephy-gacha-controller"`).
* **Publishing and Subscription**

  ```rust
  let filter = Filter::new()
      .kind(EVENT_KIND)
      .since(Timestamp::now())
      .custom_tag(SESSION_TAG, ["gacha_session"])
      .custom_tag(MENTION_TAG, [gacha_machine_pubkey.to_hex()]);
  let sub_id = relay_client.subscribe(Timestamp::now(), [gacha_machine_pubkey]).await?;
  ```

  * **Sender**: User requesting a dispense.
  * **Receiver**: Gacha node controller.
* **Message Handling**: Processes a single transaction and reverts state.

## Building Controller

* **Node**: Unlike DeCharge, Gacha’s simpler transaction (one payment, one action) doesn’t require a separate server. The node handles both state and payment in a single step using `pay`, making it lightweight.

## Solana Interaction

Uses `pay` for a one-time transaction:

```rust
// Before: Received Request event to start machine
if let Err(e) = dephy_balance_payment_sdk::pay(
    &self.solana_rpc_url,
    &self.solana_keypair_path,
    parsed_payload.namespace_id,
    &parsed_payload.user,
    PAY_AMOUNT,
    &parsed_payload.recover_info,
)
.await
{
    tracing::error!("Failed to pay, error: {:?} skip event: {:?}", e, event);
    return Ok(());
};

self.client
    .send_event(mention, &DephyGachaMessage::Status {
        status: *to_status,
        reason: *reason,
        initial_request: event.id,
        payload: serde_json::to_string(&DephyGachaMessageStatusPayload {
            namespace_id: parsed_payload.namespace_id,
            user: parsed_payload.user.clone(),
            nonce: parsed_payload.nonce,
            recover_info: parsed_payload.recover_info.clone(),
        })?,
    })
    .await?;
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.dephy.io/tutorials/build-a-gacha-machine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
