> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tenderly.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Dapp UI में Simulation RPC का उपयोग

> Tenderly Simulation RPC के माध्यम से अपने dapp में transaction simulations को एकीकृत करें। एक step-by-step Uniswap UI integration उदाहरण का पालन करें।

<Note>
  Simulation RPC Mainnet, Boba और Polygon के साथ संगत है, जबकि अन्य नेटवर्क को धीरे-धीरे
  एकीकृत किया जाएगा।\ Simulation API [सभी Tenderly-समर्थित
  नेटवर्क](/node-rpc/overview) के साथ संगत है।
</Note>

आप Simulation RPC या Simulation API को एकीकृत करके अपने dapp में simulations पेश कर सकते हैं।

### Simulation API को एकीकृत करने के लाभ

Simulation API/Simulation RPC को एकीकृत करके

1. उपयोगकर्ता के हस्ताक्षर करने और on-chain सबमिट करने से पहले उनके transactions का dry-run करें।
2. संभावित rollbacks में बेहतर दृश्यता प्रदान करें और gas शुल्क पर पैसे खोने से बचें।
3. सफल apps के परिणामों में बेहतर दृश्यता प्रदान करें, जिसमें असेट्स की गति और उपयोगकर्ता के लिए प्रासंगिक state परिवर्तन शामिल हैं।
4. उपयोगकर्ताओं को यह दिखाने के लिए simulation परिणामों के आसपास logic बनाएँ कि क्या उनके transactions इष्टतम मूल्य लाते हैं और सुधार सुझाएँ।

यहाँ कुछ उदाहरण दिए गए हैं:

* यदि आप एक wallet-जैसा app बना रहे हैं, तो आप दिखा सकते हैं कि transaction ERC-20 tokens को कैसे स्थानांतरित करता है और उपयोगकर्ताओं को अपने funds के बदलाव देखने में सक्षम बना सकते हैं।
* यदि आप एक DeFi उत्पाद बना रहे हैं, तो आप events का उपयोग यह विश्लेषण करने के लिए कर सकते हैं कि क्या कोई transaction UI में उपयोगकर्ता द्वारा सेट की गई इष्टतम शर्तों को पूरा करता है।
* यदि आप कई transactions से युक्त एक governance proposal तैयार कर रहे हैं, तो आप यह देखने के लिए एक simulation bundle कर सकते हैं कि proposal कैसे लागू होता है।
* आप अपने proposal transactions को कई परीक्षण transactions के साथ भी bundle कर सकते हैं ताकि यह सत्यापित हो सके कि आपका proposal इच्छित रूप से निष्पादित होता है और संभावित अंधे धब्बों की पहचान की जा सके।

### उदाहरण: Uniswap UI में Simulations जोड़ना

इस उदाहरण में, हम दिखाएँगे कि Simulation RPC को Uniswap UI में कैसे एकीकृत करें और exchange पथ के साथ सटीक token hops कैसे दिखाएँ। इस तरह, हम उपयोगकर्ता को transaction के प्रभावों में उच्च दृश्यता देंगे और उन्हें यह तय करने के लिए एक अच्छी तरह से सूचित निर्णय लेने की अनुमति देंगे कि आगे बढ़ना है या नहीं।

## `Simulation` component आवश्यकताएँ

यहाँ simulation component के लिए आवश्यकताएँ हैं:

* component को transaction पर हस्ताक्षर करने और भेजने से पहले और बाद में उपयोगकर्ता के पास मौजूद tokens की संख्या प्रदर्शित करनी चाहिए।
* Simulation हर बार trade डेटा बदलने पर किया जाना चाहिए, इसलिए इसे `trade` और `allowedSlippage` पैरामीटर्स प्राप्त करने की आवश्यकता है।
* Component को निम्नलिखित का ट्रैक रखना चाहिए:
  * वर्तमान balances (swap से पहले)।
  * `Swap` event जिसका उपयोग हम नए balances की गणना के लिए करेंगे।
  * `Transfer` events की एक array जिसका उपयोग हम नए balances की गणना के लिए करेंगे।

## `Simulation` को `ConfirmSwapModal` में Render करें

उपयोगकर्ता को transaction के परिणामों के बारे में सूचित करने का सबसे अच्छा स्थान `ConfirmSwapModal` है, ठीक इससे पहले कि वे transaction पर हस्ताक्षर कर सकें और भेज सकें।

Code को संक्षिप्तता के लिए संपादित किया गया है:

```diff title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
export default function ConfirmSwapModal({
  /* ... */
}: {
  /* ... */
}) {
  // ...
  const modalHeader = useCallback(() => {
    return trade ? (
      <>
        <SwapModalHeader.../>
+        <Simulation trade={trade} recipient={null} allowedSlippage={allowedSlippage} />
      </>
    ) : null
  }, [/* ... */])
  //...

```

## `Simulation` component implementation

Component का logic **simulate** function में निहित है:

* यह `trade` या `provider` arguments बदलने की स्थिति में चलता है, इसलिए जब भी swap संभावित रूप से बदलता है, यह अपडेट और re-simulate होता है।
* यह `setOldBalances` को कॉल करता है, जो In और Out ERC-20 tokens के balances प्राप्त करता है और उन्हें `oldBalances` state variable में संग्रहीत करता है।
* यह `simulateRPC` को कॉल करता है, जो `tenderly_simulateTranscation` को Simulation RPC कॉल करता है और फिर:
  * यह `Transfer` events खोजने के लिए decoded logs के माध्यम से parse करता है और उन्हें component के `transfers` state variable में संग्रहीत करता है।
  * यह `Swap` event खोजने के लिए decoded logs के माध्यम से parse करता है और उसे component के `swap` state variable में संग्रहीत करता है।

अंत में, simulation परिणामों को render करने के लिए, हम `SimulationDetails` component प्रदर्शित करते हैं, जो एक शुद्ध functional component है। यह पुराने और नए states की गणना करता है और `trade`, `swap`, `transfers`, और `oldBalances` के आधार पर डेटा render करता है।

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
const Simulation = ({
  trade,
  allowedSlippage,
  recipient,
}: {
  trade: InterfaceTrade<Currency, Currency, TradeType> | undefined;
  recipient: string | null;
  allowedSlippage: Percent;
}) => {
  const { account, provider } = useWeb3React();
  const nativeCurrency = useNativeCurrency();

  const deadline = useTransactionDeadline();
  const signatureData = useERC20PermitFromTrade(trade, allowedSlippage, deadline);
  const args = useSwapCallArguments(
    trade,
    allowedSlippage,
    recipient,
    signatureData.signatureData,
    deadline,
    undefined,
  );

  const [oldBalances, setOldBalances] = useState<any[]>([]);
  const [transfers, setTransfers] = useState<any[]>([]);
  const [swap, setSwap] = useState<any>({});

  useEffect(() => {
    onSimulate();
  }, [trade, provider]);

  async function onSimulate() {
    setOldBalances([]);
    setSwap({});
    const { address, calldata, value } = args[0];
    const provider = RPC_PROVIDERS[SupportedChainId.MAINNET];

    await getCurrentBalances();
    await simulateRPC(account, address, calldata, value);
  }

  async function getCurrentBalances() {
    return Promise.all([
      provider.send('eth_getBalance', [account, 'latest']),
      provider.send('eth_call', [
        {
          to: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
          data: `0x70a0823100000000000000000000000000${stripX(account)}`,
        },
        'latest',
      ]),
    ]).then(oldBalances => {
      setOldBalances(oldBalances);
    });
  }

  async function simulateRPC(account: string, address: string, calldata: string, value: string) {
    RPC_PROVIDERS[SupportedChainId.MAINNET]
      .send('tenderly_simulateTransaction', [
        {
          from: account,
          to: address,
          data: calldata,
          value: stripHexZero(value),
        },
        'latest', // block number to simulate on
        null, // optional state overrides for involved contracts
      ])
      .then(simulationResponse => {
        console.log('Simulation Response', simulationResponse);
        setTransfers(simulationResponse.logs.filter((log: any) => log.name === 'Transfer'));
        setSwap(simulationResponse.logs.filter((log: any) => log.name === 'Swap')[0]);
      });
  }

  return (
    <>
      ...
      <SimulationDetails
        trade={trade}
        syncing={oldBalances.length == 0 && transfers.length == 0 && !!swap.inputs}
        transfers={transfers}
        oldBalances={oldBalances}
        swap={swap}
      />
    </>
  );
};
```
