सामग्री पर जाएँ

एक OpenFiat मध्यस्थ बनें

मध्यस्थ अपने स्वयं के OPEN को जोखिम में रखकर विवाद तय करते हैं, प्रतिष्ठा को नहीं। यह बॉन्ड, एक मामला खोजने और वह कमिट-फिर-रिवील मतदान डालने से गुज़रता है जो वास्तव में भुगतान करता है।

आपको क्या चाहिए

  • कम से कम 10,000 OPEN वाला एक Solana वॉलेट — तैनात स्टेकिंग कॉन्फ़िगरेशन का min_stake_arbitrator, जिसे शासन बदल सकता है — इसे openfiat-app के Stake पेज से बॉन्ड करें, या यदि आप अपना क्लाइंट बना रहे हैं तो नीचे के निर्देशों से
  • एक वॉलेट जो संदेशों पर हस्ताक्षर कर सके, जो हर प्रासंगिक Solana वॉलेट करता है — openfiat-app का Arbitrate पेज पूरा मामला ब्राउज़र में चलाता है, और यदि आप प्रोग्रामिंग पसंद करते हैं तो SDK उपलब्ध हैं
  • कम से कम एक OpenFiat नोड के JSON-RPC एंडपॉइंट तक नेटवर्क पहुँच, आपका या एक सार्वजनिक

एक मामले पर काम करना

इन चरणों को क्रम में करें, एक बार में एक मामला। हर चरण अपनी आवश्यक कमांड या कोड लाता है।

  1. 01

    मध्यस्थता पूल अनलॉक करने के लिए OPEN बॉन्ड करें

    मध्यस्थों को किसी एक मामले के साक्ष्य देख पाने से पहले स्टेक करना होता है — यही उनमें से एक को रिश्वत देना बेकार बनाता है (आप नहीं जानते किस मामले को निशाना बनाएँ) और नेटवर्क को कुछ देता है जिसे यदि आप उजागर सहमति के विरुद्ध मत दें तो स्लैश किया जा सके। तैनात devnet कॉन्फ़िगरेशन मध्यस्थ न्यूनतम को 10,000 OPEN पर सेट करता है, हर अन्य भूमिका द्वारा दिए 1,000 का दस गुना।

    stake.ts
    import { PublicKey, Transaction } from "@solana/web3.js";
    import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";
    import { onchain } from "@openfiat/sdk";
    
    // Role.Arbitrator = 1 — same instruction pair openfiat-app's Stake page
    // submits when you connect a wallet and bond there directly.
    const from = getAssociatedTokenAddressSync(mint, owner, false, TOKEN_2022_PROGRAM_ID);
    const amount = 10_000n * 1_000_000_000n; // OPEN has 9 decimals (OFS-4100 §1)
    
    const instructions = [
      onchain.staking.initializeStakeAccountIx(owner, onchain.Role.Arbitrator),
      onchain.staking.stakeIx(owner, mint, onchain.Role.Arbitrator, from, amount),
    ];
    const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
    const tx = new Transaction({ feePayer: owner, blockhash, lastValidBlockHeight }).add(...instructions);
    const { signature } = await wallet.signAndSendTransaction(tx);
  2. 02

    एक खुला मामला खोजें

    मध्यस्थ चुनते हैं कि किन विवादों पर काम करना है — कोई आपको एक नहीं सौंपता। किसी भी नोड से उन मामलों के बारे में पूछें जो अभी तक मध्यस्थों की आवश्यक संख्या तक नहीं पहुँचे।

    shell
    # Any node will do — arbitrators pick a case, nobody assigns one.
    curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \
      -d '{"jsonrpc":"2.0","id":1,"method":"getDisputes","params":{}}'
    # Filter the result for status: "Open" and arbitrators.length < required_arbitrators
  3. 03

    साक्ष्य देख पाने से पहले शामिल हों

    शामिल होना ही एक मामले को आपके लिए अनलॉक करता है: खरीदार और विक्रेता के अपने प्रस्तुतियाँ, भुगतान पुष्टियाँ और उनके सौदे का संदेश लॉग। एक बार जब किसी मामले में मध्यस्थों की पूरी संख्या हो जाती है, तो वह लॉक हो जाता है और कमिट चरण शुरू होता है।

    join.rs
    use openfiat_disputes::events::ArbitratorJoin;
    use openfiat_sdk::wallet::Keypair;
    use openfiat_sdk::{Client, ClientConfig};
    
    // Joining is what unlocks the case's evidence for you — buyer/seller
    // submissions and the trade's own message log become visible once you're
    // in `dispute.arbitrators`.
    let client = Client::new(ClientConfig { endpoint: node_url, ..Default::default() });
    client
        .send_arbitrator_join(
            ArbitratorJoin {
                dispute_id: dispute.id.clone(),
                arbitrator: peer_id(&keypair),
                arbitrator_public_key: keypair.public_key(),
                timestamp: Timestamp::now(),
            },
            &keypair,
        )
        .await?;
  4. 04

    अपना मत प्रतिबद्ध करें — दो बार

    दो कमिट-रिवील मतदान साथ-साथ चलते हैं: एक ऑफ़-चेन जो मामले के अपने ऑडिट ट्रेल और प्रतिष्ठा में दर्ज होता है, और एक ऑन-चेन openfiat-escrow के DisputeCase अकाउंट के विरुद्ध जो वास्तव में स्टेक-भारित परिणाम तय करता है। दोनों के लिए एक ही निर्णय और एक ही salt का उपयोग करें — पर हर पक्ष का अपना enum, एक ही संख्या नहीं: Invalid ऑफ़-चेन 2 है, InvalidDispute ऑन-चेन 3 है, क्योंकि MutualSettlement ऑन-चेन 2 पर बैठता है। गलत बाइट का हैश लें और आप ऐसी चीज़ के लिए प्रतिबद्ध हो जाते हैं जिसे आप कभी उजागर नहीं कर सकते, और यही ठीक वह है जो एक मध्यस्थ को स्लैश कराता है।

    commit.rs + commit.ts
    // Off-chain (marketplace record + reputation) — Rust SDK
    let secret: [u8; 32] = rand::random();
    let commitment = openfiat_disputes::commitment::compute(vote, &secret); // sha256(vote || secret)
    client.send_vote_commit(VoteCommit { dispute_id, arbitrator: peer_id(&keypair), commitment, timestamp: Timestamp::now() }, &keypair).await?;
    // keep `secret` — you need it again at reveal, and it must never be guessable before then
    
    // On-chain (the stake-weighted vote that actually pays out) — TypeScript SDK
    import { onchain } from "@openfiat/sdk";
    import { createHash } from "node:crypto";
    
    // onchain.DisputeOutcome, NOT the off-chain Vote byte: the two enums
    // diverge from Invalid onwards (see this file's header). Hash the wrong
    // one and the commitment can never be opened.
    const commitment = createHash("sha256").update(Buffer.from([onchain.DisputeOutcome.BuyerWins])).update(salt).digest();
    const ix = onchain.escrow.commitDisputeVoteIx(arbitrator, reservationId, commitment);
  5. 05

    जैसे ही विंडो खुले, उजागर करें

    कमिट विंडो बंद होते ही दोनों जगह अपना परिणाम और salt उजागर करें। ऑन-चेन, यहीं आपका मत अपना वास्तविक भार पाता है: reveal निर्देश आपके Arbitrator भूमिका स्टेक अकाउंट को सीधे पढ़ता है, इसलिए मध्यस्थ स्टेक के बिना एक वॉलेट बस एक वैध नहीं दे सकता।

    reveal.rs + reveal.ts
    // Off-chain — Rust SDK
    client.send_vote_reveal(VoteReveal { dispute_id, arbitrator: peer_id(&keypair), vote, secret, timestamp: Timestamp::now() }, &keypair).await?;
    
    // On-chain — reads your Arbitrator StakeAccount directly (no CPI) to weight this vote
    import { onchain } from "@openfiat/sdk";
    
    const [arbitratorStake] = onchain.staking.stakeAccountPda(arbitrator, onchain.Role.Arbitrator);
    const ix = onchain.escrow.revealDisputeVoteIx(
      arbitrator,
      reservationId,
      onchain.DisputeOutcome.BuyerWins,
      salt,
      arbitratorStake,
    );
  6. 06

    परिणाम स्वयं निष्पादित होता है

    एक बार जब हर मध्यस्थ उजागर कर दे, या reveal विंडो बंद हो जाए, तो कोई भी — आप, खरीदार, विक्रेता या एक असंबंधित बॉट — execute_dispute_outcome कॉल कर सकता है। यह केवल उन मतों को गिनता है जो पहले से ऑन-चेन दर्ज हैं। फिर डिज़ाइन बहुमत को मामले के शुल्कों का हिस्सा देता है और उसके विरुद्ध उजागर करने वालों के स्टेक का कुछ हिस्सा काटता है — पर न पुरस्कार न दंड लागू है, इसलिए आज गिनती ट्रेडरों के धन को हिलाती है और कुछ नहीं।

    resolve.ts
    import { onchain } from "@openfiat/sdk";
    
    // Permissionless — it only tallies votes the reveal step above already
    // recorded on-chain, so anyone (the buyer, the seller, either arbitrator,
    // or an unrelated crank bot) can call it once the reveal window closes.
    const ix = onchain.escrow.executeDisputeOutcomeIx(mint, seller, reservationId, destinations);

मध्यस्थ कभी सौदों का धन नहीं रखते। एक निर्णय केवल वही पैसा हिलाता है जिसे कस्टडी प्रोग्राम ने ही विवाद खुलने से पहले लॉक कर दिया था।