> ## 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.

# Предпросмотр транзакции в Rabby Wallet

> Добавьте предпросмотр транзакции в Rabby Wallet с помощью Tenderly Simulation API, чтобы пользователи могли увидеть результаты до отправки в сеть.

В этом руководстве показано, как интегрировать функцию «предпросмотр транзакции» в пример Rabby Wallet с помощью [Tenderly Simulation API](/api-reference).

[Предпросмотр транзакции](/simulations/transaction-preview) позволяет пользователям кошельков симулировать выполнение транзакции и увидеть точные результаты, не отправляя транзакции в сеть. Так пользователи могут лучше понять финансовые последствия своих транзакций и отправлять их с уверенностью. Кроме того, вы помогаете защитить средства пользователей, устранять ненужные расходы на газ и улучшать общий пользовательский опыт и безопасность вашего продукта.

Вот репозиторий GitHub этого примера с открытым исходным кодом:

<Card title="Интеграция Tenderly Transaction Simulations в Rabby Wallet" href="" />

<iframe src="https://youtube.com/embed/6Dqd_1EANfY" style={{ aspectRatio: 16 / 9, width: '100%' }} />

Демо предпросмотра транзакции Tenderly Rabby

<Warning>
  Это руководство предназначено исключительно для иллюстративных целей — оно показывает, как интегрировать предпросмотр транзакции
  в Rabby Wallet. Оно не предназначено и не рекомендуется для любого другого использования.
</Warning>

## Обзор проекта

В этом руководстве вы узнаете, как интегрировать Tenderly Simulation API в [расширение Chrome для Rabby Wallet](https://github.com/RabbyHub/Rabby/blob/develop/README.md). Сначала вы узнаете, как взаимодействовать с API и реализовать логику симуляции транзакций. Затем вы сгруппируете данные симуляции и выведете их пользователю. Таким образом, вы улучшите пользовательский опыт в этом примере Rabby Wallet, добавив новую функциональность.

### Предварительные требования

Для этого руководства вам понадобятся:

* [Node.js](https://nodejs.org) (версии 14 или новее)
* [Yarn](https://classic.yarnpkg.com/lang/en/docs/install)
* Знание React.js, TypeScript и [Tailwind CSS](https://tailwindcss.com)

Начнём сборку! 👷‍♂️

## Шаг 1. Клонируйте проект Rabby Wallet

Сначала форкните или клонируйте официальный репозиторий Rabby Wallet на GitHub. Для этого выполните:

```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
git clone https://github.com/RabbyHub/Rabby.git
```

Далее перейдите в корень проекта и установите зависимости с помощью пакетного менеджера Yarn:

```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
yarn install
```

Затем используйте следующую команду, чтобы запустить репозиторий локально:

```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
yarn build:dev
```

Будет сгенерирована папка `dist`. Вы можете использовать её для загрузки расширения Chrome.

Перейдите на `chrome://extensions` и включите **Developer mode**. Затем нажмите кнопку «**Load unpacked**», перейдите в директорию Rabby и выберите папку `dist`. Распакованное расширение появится на экране, и вы можете начать использовать Rabby Wallet.

Теперь вы можете импортировать существующий кошелёк или создать новый.

<Note>
  Прежде чем начать, обязательно отключите продакшн-версию расширения Rabby Wallet для Chrome, если оно установлено.

  Пожалуйста, следуйте [официальным рекомендациям](https://github.com/RabbyHub/Rabby) от команды Rabby на случай, если возникнут проблемы с подключением.
</Note>

<Frame caption="Enabled unpacked version of the Rabby Wallet">
  <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/image%20(110).webp?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=520d02bca5404aca64622e997566e6f3" alt="Enabled unpacked version of the Rabby Wallet" width="854" height="462" data-path="images/image (110).webp" />
</Frame>

<Frame caption="Disabled production version of the Rabby Wallet">
  <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/image%20(112).webp?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=6e4fd241cbd2ebf214eb5e55f3335748" alt="Disabled production version of the Rabby Wallet" width="840" height="454" data-path="images/image (112).webp" />
</Frame>

## Шаг 2. Сгенерируйте токен доступа Tenderly

Чтобы использовать Tenderly Simulation API, вам нужно сгенерировать токен доступа. Выполните следующие шаги:

1. [Создайте бесплатную учётную запись Tenderly](https://dashboard.tenderly.co/register) или войдите в существующую.
2. Перейдите на [страницу Authorization](https://dashboard.tenderly.co/account/authorization) и нажмите кнопку **Generate Access Token**.
3. Секрет токена отображается только один раз. Обязательно скопируйте и сохраните его в безопасном месте, так как позже его нельзя будет восстановить.

<figure>
  !\[Tenderly Docs]\(/images/image (113).webp)

  <figcaption />
</figure>

Если вам нужна помощь с процессом аутентификации API, следуйте руководству ниже:

<Card title="Как сгенерировать токены доступа API" href="" />

## Шаг 3. Соберите логику симуляции

Далее мы рассмотрим следующие шаги:

* Настройте безопасное хранилище для учётных данных Tenderly.
* Создайте необходимый код для подключения к Tenderly Simulation API.
* Используйте как приватные, так и публичные эндпоинты для взаимодействия с API.
* Составьте правильный payload для этих эндпоинтов.

### Работа с учётными данными Tenderly

Сначала вам нужно получить учётные данные Tenderly. Создайте файл `/_raw/tenderly.json` и обновите учётные данные Tenderly:

```json title="example.json" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{
  "tenderlyAccount": "YOUR_ACCOUNT_NAME",
  "tenderlyProject": "YOUR_PROJECT_NAME",
  "tenderlyAccessToken": "YOUR_ACCESS_TOKEN"
}
```

Чтобы получить доступ к учётным данным Tenderly в вашем проекте, обновите `build/webpack.common.config.js` следующим образом:

```javascript title="example.js" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
const { tenderlyAccount, tenderlyProject, tenderlyAccessToken } = require('../_raw/tenderly.json');

// other code...

const config = {
  plugins: [
    // abbreviated
    new webpack.DefinePlugin({
      'process.env.version': JSON.stringify(`version: ${version}`),
      'process.env.release': JSON.stringify(version),
      // Tenderly Credentials
      'process.env.TENDERLY_ACCOUNT_SLUG': JSON.stringify(tenderlyAccount),
      'process.env.TENDERLY_PROJECT_SLUG': JSON.stringify(tenderlyProject),
      'process.env.TENDERLY_ACCESS_TOKEN': JSON.stringify(tenderlyAccessToken),
    }),
  ],
  resolve: {
    // abbreviated
  },
};
```

Вы можете [найти реализацию здесь](https://github.com/Tenderly/tenderly-rabby-transaction-preview/blob/develop/build/webpack.common.config.js#L221).

### Реализация логики симуляции транзакций

Далее создайте файл `src/ui/utils/tenderly.ts` и реализуйте логику с помощью Tenderly Simulation API. [Получите полный исходный код здесь](https://github.com/Tenderly/tenderly-rabby-transaction-preview/blob/develop/src/ui/utils/tenderly.ts).

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

export const simulateTransaction = async (tx: Tx): Promise<Record<string, any> | null> => {
  const TENDERLY_ACCOUNT_SLUG = process.env.TENDERLY_ACCOUNT_SLUG;
  const TENDERLY_PROJECT_SLUG = process.env.TENDERLY_PROJECT_SLUG;
  const TENDERLY_ACCESS_TOKEN = process.env.TENDERLY_ACCESS_TOKEN;

  if (!TENDERLY_ACCOUNT_SLUG || !TENDERLY_PROJECT_SLUG || !TENDERLY_ACCESS_TOKEN) {
    throw new Error('Tenderly credentials are not set up correctly.');
  }

  const txPayload: any = {
    ...tx,
    save: true,
    save_if_fails: true,
    simulation_type: 'full',
    source: 'rabby-wallet',
    network_id: tx.chainId.toString(),
    gas: parseInt(tx.gas as string, 16) || null,
    gas_price: parseInt(tx.gasPrice as string, 16) || null,
    value: parseInt(tx.value, 16) || null,
    input: tx.data,
  };

  try {
    const simulationResponse = await axios.post(
      `https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT_SLUG}/project/${TENDERLY_PROJECT_SLUG}/simulate`,
      txPayload,
      {
        headers: {
          'Content-Type': 'application/json',
          'X-Access-Key': TENDERLY_ACCESS_TOKEN as string,
        },
      },
    );

    // Make the simulation publicly accessible
    if (simulationResponse?.data?.simulation?.id) {
      await axios.post(
        `https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT_SLUG}/project/${TENDERLY_PROJECT_SLUG}/simulations/${simulationResponse.data.simulation.id}/share`,
        {},
        {
          headers: {
            'Content-Type': 'application/json',
            'X-Access-Key': TENDERLY_ACCESS_TOKEN as string,
          },
        },
      );
    }

    return simulationResponse?.data;
  } catch (e) {
    console.error({ e });
    return null;
  }
};
```

Здесь мы использовали два эндпоинта.

Первый эндпоинт позволяет симулировать транзакцию с различными параметрами в любой из [104 сетей](/platform/supported-networks), поддерживаемых Tenderly. Перейдите к нашему [справочнику Simulation API](/api-reference), чтобы увидеть все обязательные и необязательные поля для этого эндпоинта.

```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
https://api.tenderly.co/api/v1/account/{accountId}/project/{projectId}/simulate
```

Второй эндпоинт позволяет сделать симулированную транзакцию публично доступной. Так вы можете поделиться ей с членами вашей команды или коллегами для дополнительных инсайтов или быстрого решения проблем.

```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
https://api.tenderly.co/api/v1/account/{accountId}/project/{projectId}/simulations/{simulationID}/share
```

Последний шаг — вызвать функцию `simulateTransaction` внутри компонента `SignTx.tx`, поместив её внутри функции `explainTx`, которая вызывается перед подписанием транзакции. Подробности кода см. по этой [ссылке](https://github.com/Tenderly/tenderly-rabby-transaction-preview/blob/develop/src/ui/views/Approval/components/SignTx.tsx#L911).

## Шаг 4. Отображение предпросмотра симулированной транзакции

Чтобы помочь пользователям понять, что произойдёт при отправке транзакций, вы можете отображать в UI данные симуляции в понятном виде. Например, когда пользователи кошелька симулируют транзакции, вы можете отображать, какие активы были переданы.

В примере с Rabby Wallet мы создали три простых для понимания раздела:

1. **`Tenderly Simulation Summary`**: думайте об этом как о табеле успеваемости транзакции. Он предоставляет базовую информацию о вашей транзакции с прямой ссылкой на подробный обзор симуляции в Tenderly Dashboard.
2. **`Assets In & Assets Out`**: получите чёткий список всех активов (либо ERC20, либо NFT-токенов), с которыми ваш кошелёк собирается взаимодействовать.
3. **`Tokens Transferred`**: просмотрите каждый перевод токена, происходящий в транзакции. Для дополнительной ясности сгруппируйте все переводы по адресу и выделите переводы нативной монеты.

<Frame caption="Transaction preview for ERC20 token swap on Uniswap">
  <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/image%20(114).webp?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=5d41e85766b24da2a541d8c60ea31565" alt="Transaction preview for ERC20 token swap on Uniswap" width="491" height="1255" data-path="images/image (114).webp" />
</Frame>

<Frame caption="Transaction preview for NFT token purchase on Joepegs">
  <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/image%20(115).webp?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=cfdd30d3b489394ff18d90d9f7304b5c" alt="Transaction preview for NFT token purchase on Joepegs" width="443" height="1265" data-path="images/image (115).webp" />
</Frame>

### Tenderly Simulation Summary

Сначала создадим раздел Tenderly Simulation Summary. Здесь мы показываем статус симуляции, сеть, в которой выполнена транзакция, и значение газа.

<figure>
  !\[Tenderly Docs]\(/images/image (116).webp)

  <figcaption />
</figure>

Чтобы построить этот раздел, вам нужно взаимодействовать с [ответом Tenderly Simulation API](/api-reference). Начните с создания файла `TenderlySimulationSummary.tsx`. Вы можете найти полную реализацию кода ниже или в [репозитории GitHub здесь](https://github.com/Tenderly/tenderly-rabby-transaction-preview/blob/develop/src/ui/views/Approval/components/TxComponents/Tenderly/TenderlySimulationSummary/TenderlySimulationSummary.tsx).

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}


const TenderlySimulationSummary = ({ simulation }: { simulation: Record<string, any> | null }) => {
  const isSuccess = !!simulation?.status;
  const simulationUrl = `https://dashboard.tenderly.co/${process.env.TENDERLY_ACCOUNT_SLUG}/${process.env.TENDERLY_PROJECT_SLUG}/simulator/${simulation?.id}`;
  const sharedSimulationUrl = `https://tdly.co/shared/simulation/${simulation?.id}`;

  return (
    <div className="tenderly-simulation-summary container">
      <p className="text-16 text-gray-title font-medium mb-12">Tenderly Simulation Summary</p>
      {!simulation && <div>Something went wrong.</div>}
      {simulation && (
        <div className="flex flex-col gap-8">
          <div className="flex items-center justify-between gap-2">
            <div>Status</div>
            <div className={isSuccess ? 'text-green' : 'text-red'}>
              {isSuccess ? 'Success' : 'Failed'}
            </div>
          </div>
          <div className="flex items-center justify-between gap-2">
            <div>Network</div>
            <div className="flex items-center gap-4">
              <div className="flex items-center rounded-full">
                <img
                  src={TenderlyNetwork[simulation.network_id]?.image}
                  className="h-16 rounded-full"
                  alt="Tenderly"
                />
              </div>
              <div>{TenderlyNetwork[simulation.network_id]?.name}</div>
            </div>
          </div>
          <div className="flex items-center justify-between gap-2">
            <div>Gas</div>
            <div>{simulation.gas}</div>
          </div>
          <Button
            className="tenderly-simulation-summary-button flex items-center justify-between gap-2 pb-0"
            href={simulationUrl}
            target="_blank"
            rel="noreferrer"
            size="large"
            block
          >
            <div>View details</div>
            <div className="flex items-center gap-2">
              <img src={TenderlySvg} className="h-32" alt="Tenderly" />
              <IconRightArrow />
            </div>
          </Button>
          <Button
            className="text-[#6E56CF] bg-white flex items-center justify-center gap-2 pb-0"
            href={sharedSimulationUrl}
            target="_blank"
            rel="noreferrer"
            type="link"
            size="middle"
            block
          >
            <div>Share simulation ✨</div>
          </Button>
        </div>
      )}
    </div>
  );
};

export default TenderlySimulationSummary;
```

Обратите внимание, как мы сгенерировали ссылки, ведущие пользователей в Tenderly Dashboard. Первая ссылка предназначена для аутентифицированных пользователей, а вторая — расшариваемая ссылка на симуляцию транзакции:

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
const simulationUrl = `https://dashboard.tenderly.co/${process.env.TENDERLY_ACCOUNT_SLUG}/${process.env.TENDERLY_PROJECT_SLUG}/simulator/${simulation?.id}`;
const sharedSimulationUrl = `https://tdly.co/shared/simulation/${simulation?.id}`;
```

Чтобы получить данные из симулированной транзакции, обратитесь к справочнику Tenderly Simulation API:

<Card title="Tenderly Simulation API" href="" />

### Assets In & Assets Out

Второй раздел даёт представление об управлении и мониторинге потока активов в примере Rabby Wallet. Он показывает как входящие, так и исходящие активы, чтобы вы могли лучше видеть активность кошелька.

<figure>
  !\[Tenderly Docs]\(/images/image (117).webp)

  <figcaption />
</figure>

Чтобы этого добиться, начните с создания файла `TenderlyWalletChanges.tsx`:

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}


const TenderlyWalletChanges = ({
  account,
  assetChanges,
}: {
  account?: Account;
  assetChanges: any;
}) => {
  const { assetsInList, assetsOutList } = React.useMemo(() => {
    const assetsInList = assetChanges.filter(asset => asset.to === account?.address) || [];
    const assetsOutList = assetChanges.filter(asset => asset.from === account?.address) || [];

    return {
      assetsInList,
      assetsOutList,
    };
  }, [account, assetChanges]);

  return (
    <div className="TenderlyWalletChanges">
      <div className="TenderlyWalletChanges__Content">
        {/* Assets Out */}
        {assetsOutList?.length > 0 && (
          <>
            <p className="text-16 text-gray-title font-medium mb-4">Assets Out</p>
            <div className="flex flex-col gap-4 border border-gray-divider rounded-sm">
              {assetsOutList.map((token, index) => (
                <div
                  key={index}
                  className={clsx('flex gap-4 p-4', {
                    'border-t-[1px] border-gray-divider': index !== 0,
                  })}
                >
                  <div className="flex items-center justify-center p-4">
                    <img src={token.token_info.logo} className="w-60 rounded" alt="Tenderly" />
                  </div>
                  <div className="flex flex-col gap-4">
                    <div className="flex flex-col gap-1">
                      <div className="font-semibold">
                        {token.token_info.symbol.toUpperCase()}
                        {token.token_id && <span className="ml-2">#{Number(token.token_id)}</span>}
                      </div>
                      <div className="text-12 text-gray-content">{token.token_info.name}</div>
                    </div>
                    <div className="flex flex-wrap items-center gap-4">
                      <div className="font-semibold">{token.type}:</div>
                      <div className="text-red-forbidden">- {formatAmount(token.amount)}</div>
                      <div className="text-12 text-gray-content">
                        (≈ {formatUsdValue(new BigNumber(token.dollar_value).toFixed())})
                      </div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </>
        )}

        {/* Assets In */}
        {assetsInList?.length > 0 && (
          <>
            <p className="text-16 text-gray-title font-medium mt-4 mb-4">Assets In</p>
            <div className="flex flex-col gap-4 border border-gray-divider rounded-sm">
              {assetsInList.map((token, index) => (
                <div
                  key={index}
                  className={clsx('flex gap-4 p-4', {
                    'border-t-[1px] border-gray-divider': index !== 0,
                  })}
                >
                  <div className="flex items-center justify-center p-4">
                    <img src={token.token_info.logo} className="w-60 rounded" alt="Tenderly" />
                  </div>
                  <div className="flex flex-col gap-4">
                    <div className="flex flex-col gap-1">
                      <div className="font-semibold">
                        {token.token_info.symbol.toUpperCase()}
                        {token.token_id && <span className="ml-2">#{Number(token.token_id)}</span>}
                      </div>
                      <div className="text-12 text-gray-content">{token.token_info.name}</div>
                    </div>
                    <div className="flex flex-wrap items-center gap-4">
                      <div className="font-semibold">{token.type}:</div>
                      <div className="text-green">+ {formatAmount(token.amount)}</div>
                      <div className="text-12 text-gray-content">
                        (≈ {formatUsdValue(new BigNumber(token.dollar_value).toFixed())})
                      </div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </>
        )}
      </div>
      <TenderlyCredits classname="mt-12" />
    </div>
  );
};

export default TenderlyWalletChanges;
```

Здесь мы отфильтровали массив изменений активов и создали два списка:

1. Активы, поступающие в кошелёк
2. Активы, уходящие из кошелька

Затем мы использовали вспомогательные функции для предпросмотра и форматирования данных.

Однако вы также можете создать свой собственный UI-макет для отображения важной информации об активах.

Узнайте больше об изменениях активов при симуляции здесь:

<Card title="Изменения активов и балансов" href="" />

### Tokens Transferred

Раздел Token Transfers — более сложный компонент. Этот файл в первую очередь управляет макетом, поэтому сначала обсудим логику сортировки. Вы можете найти [реализацию этого раздела здесь](https://github.com/Tenderly/tenderly-rabby-transaction-preview/blob/a6b8059eeae4c856f32b328632a8cd8aa274f757/src/ui/views/Approval/components/TxComponents/Tenderly/AssetChanges/TenderlyAssetChanges.tsx).

Начните с создания файла `TenderlyAssetChanges.tsx`. Он содержит логику для представления двух вкладок: **Tokens Transferred** и **Native Coins Transferred**. Для этого вам нужно добавить логику сортировки, переключения между вкладками и группировки данных по адресу.

<Frame caption="Tokens Transferred UI">
  <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/Rabby%20Wallet.webp?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=8963a07f3dd1bdd1f3ab1eeca41d86f4" alt="Tokens Transferred UI" width="1300" height="1000" data-path="images/Rabby Wallet.webp" />
</Frame>

Сначала сгруппируем данные и создадим два массива: переданные токены и переданные нативные монеты:

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
const assetChangesMappedByType = React.useMemo<
  Record<AssetChangesTabs, TransactionAssetChangeData[]>
>(
  () =>
    transactionAssetChanges.reduce(
      (
        acc: {
          nativeCoinsTransferred: TransactionAssetChangeData[];
          tokensTransferred: TransactionAssetChangeData[];
        },
        assetChange: TransactionAssetChangeData,
      ) => {
        const { type } = assetChange.tokenInfo;
        if (type === TokenType.NATIVE) {
          return {
            ...acc,
            [AssetChangesTabs.nativeCoins]: [...(acc?.nativeCoinsTransferred ?? []), assetChange],
          };
        }
        return {
          ...acc,
          [AssetChangesTabs.tokens]: [...(acc?.tokensTransferred ?? []), assetChange],
        };
      },
      { [AssetChangesTabs.nativeCoins]: [], [AssetChangesTabs.tokens]: [] },
    ),
  [assetChanges],
);
```

Далее напишем логику для обработки типов сортировки двумя способами: в хронологическом порядке и по адресу. Здесь нам нужно два компонента: **ChronologicalContent.tsx** и **PerAddressContent.tsx**.

Реализацию можно найти в репозитории GitHub:

* [ChronologicalContent.tsx](https://github.com/Tenderly/tenderly-rabby-transaction-preview/blob/develop/src/ui/views/Approval/components/TxComponents/Tenderly/AssetChanges/ChronologicalContent.tsx)
* [PerAddressContent.tsx](https://github.com/Tenderly/tenderly-rabby-transaction-preview/blob/develop/src/ui/views/Approval/components/TxComponents/Tenderly/AssetChanges/PerAddressContent.tsx)

### Группировка и предпросмотр всех компонентов

Наконец, соберём все компоненты вместе. Для этого вам нужно создать файл `TenderlySimulationResult.tsx`. Также вам нужно использовать хук `useWallet()`, предоставленный командой Rabby, для взаимодействия с подключённым адресом кошелька.

Вот обзор кода:

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

const TenderlySimulationResult = ({ data }: { data: Record<string, any> | null }) => {
  const [account, setAccount] = React.useState<Account>();
  const wallet = useWallet();

  const init = async () => {
    const currentAccount = await wallet.syncGetCurrentAccount();

    if (currentAccount) {
      setAccount(currentAccount);
    }
  };

  React.useEffect(() => {
    init();
  }, []);

  return (
    <div className="tenderly-simulation-result mt-16">
      <ActionWrapper>
        {!data && <div className="bg-[#f5f6fa] sticky top-[64px] z-10">Something went wrong.</div>}
        {data && <TenderlySimulationSummary simulation={data.simulation} />}
      </ActionWrapper>
      {data?.transaction?.transaction_info.asset_changes && (
        <>
          <ActionWrapper>
            <TenderlyWalletChanges
              account={account}
              assetChanges={data.transaction.transaction_info.asset_changes}
            />
          </ActionWrapper>
          <ActionWrapper>
            <TenderlyAssetChanges
              assetChanges={data.transaction.transaction_info.asset_changes}
              contracts={data.contracts}
            />
          </ActionWrapper>
        </>
      )}
    </div>
  );
};

export default TenderlySimulationResult;
```

## Что дальше?

Поздравляем! Вы добавили функцию предпросмотра транзакции в пример Rabby Wallet с помощью Tenderly Simulation API. 🎉

Чтобы углубиться в логику, ознакомьтесь с [полным исходным кодом на GitHub](https://github.com/Tenderly/tenderly-rabby-transaction-preview).

Кроме того, вы можете инициировать симуляции транзакций Tenderly тремя разными способами в зависимости от требований вашего проекта. Чтобы узнать о других способах интеграции симуляций транзакций в ваш кошелёк или dapp, ознакомьтесь со следующими ресурсами:

<Card title="Simulation API" href="" />

<Card title="Симуляция транзакций" href="" />

<Card title="Simulation RPC" href="" />
