GTokenTool全网最好的代币发行工具平台
当前位置:首页 >> 加密百科 >> 如何构建加密税计算器(React 指南)

如何构建加密税计算器(React 指南)

admin 加密百科 24

由于市场波动和各种应税事件,加密货币交易的税费计算可能非常复杂。在本文中,我们将指导您使用 React 和CoinGecko API构建一个简单的加密货币税费计算器。我们将重点介绍基本的税收结构,为您提供根据当地法规进行调整的基础。本教程将涵盖以下内容:

  1. 用户输入:用于输入计算所需详细信息的字段。

  2. 计算逻辑:计算资本收益或损失以及相应税额的功能。

  3. 响应式设计:使用 React 和样式组件构建的用户友好界面。

  4. 实时结果:根据用户输入即时计算并显示纳税义务。

最后,您将拥有一个功能齐全的应用程序来帮助您管理加密货币税。让我们开始吧!

加密税计算器 - CoinGecko API

先决条件

在开始之前,请确保您已具备以下条件:

JavaScript 和 React 的基础知识熟悉 JavaScript ES6+ 功能和基本 React 概念(例如组件、钩子(useState、useEffect)和状态管理)将会有所帮助。

CoinGecko API我们将使用 CoinGecko API 获取加密货币的市场数据。免费的演示计划每分钟调用次数限制为 30 次,每月调用次数上限为 10,000 次,足以满足我们的需求。查看我们的API 文档或创建 演示账户进行试用!

文本编辑器或集成开发环境 (IDE)您需要一个代码编辑器来编写应用程序——我们将使用 Visual Studio Code。其他常用的选择包括 Sublime Text 和 Atom。

开发环境:Node.js 和 npm确保你的机器上安装了 Node.js 和 npm。Node.js 是基于 Chrome V8 JavaScript 引擎构建的 JavaScript 运行时,npm 是 Node.js 的包管理器,你将使用它来管理项目的依赖项。

设置你的项目

首先,为您的税务计算器应用创建一个新目录。打开终端或命令提示符,运行以下命令来创建新目录:

mkdir crypto-tax-calculator cd crypto-tax-calculator

要设置一个新的 React 项目,我们将使用Vite。这是一款快速构建工具,与传统工具相比,它提供了更精简、更快捷的开发体验。Vite 利用原生 ES 模块和现代浏览器功能实现快速开发和优化构建。要创建项目,请在终端中运行以下命令:

npm create vite@latest .

上述命令将在当前目录中创建一个新的 React 项目。

安装所需的库

我们的应用程序将使用几个库:

  • Axios:用于发出 API 请求。

  • Moment.js:用于日期操作。

  • Styled-Components:用于在 JavaScript 中编写 CSS 来设置 React 组件的样式。

要安装这些库,请在项目目录中运行以下命令:

npm install axios moment styled-components

文件夹和文件结构

crypto-tax-calculator/ ├── node_modules/ ├── public/ │   └── vite.svg ├── src/ │   ├──api/ │   │  └──coingecko.jsx │   ├──components/ │   │  └──Calculator/ │   │      └──Calculator.jsx/ │   ├── App.css │   ├── App.jsx │   └── main.jsx ├── .gitignore ├── .eslintrc.cjs ├── index.html
├── package.json
├── README.md ├── vite.config.js └── yarn.lock (or package-lock.json)
  • src/:这是所有开发工作进行的主要源代码目录。

  • api/:此目录包含我们所有的 API 调用。

  • components/:此目录通常包含 React 组件。在本例中,有一个 Calculator/ 目录,其中可能包含一个 Calculator.jsx 文件,该文件表示一个与计算加密税相关的 React 组件。

  • App.css、App.jsx、main.jsx:这些文件是 React 应用程序结构的一部分。

  • App.css:用于设置主 App 组件样式的 CSS 文件。

  • App.jsx:应用程序结构开始的主要 React 组件文件。

  • main.jsx: React 应用程序的入口点,通常导入 App.jsx 并呈现根组件。

如何构建加密税计算器(完整代码)

以下是加密税计算器组件的完整代码:

mport React, { useState, useEffect } from "react";
import styled from "styled-components";
import { fetchCryptoCoins, fetchCryptoPriceHistory } from "../../api/coingecko";

const CalculatorContainer = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  max-width: 500px;
  margin: auto;
  border: 1px solid #ccc;
  border-radius: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  background-color: #f9f9f9;
`;

const Title = styled.h1`
  font-size: 2em;
  margin-bottom: 20px;
`;

const Label = styled.label`
  display: flex;
  flex-direction: column;
  margin-bottom: 10px;
  width: 100%;
`;

const Input = styled.input`
  padding: 10px;
  margin-top: 5px;
  border: 1px solid #ccc;
  border-radius: 5px;
  font-size: 1em;
`;

const Select = styled.select`
  padding: 10px;
  margin-top: 5px;
  border: 1px solid #ccc;
  border-radius: 5px;
  font-size: 1em;
`;

const Result = styled.h2`
  margin-top: 20px;
  font-size: 1.5em;
`;

const Calculator = () => {
  const [buyDate, setBuyDate] = useState("");
  const [sellDate, setSellDate] = useState("");
  const [fees, setFees] = useState(0);
  const [annualIncome, setAnnualIncome] = useState(0);
  const [totalGainOrLoss, setTotalGainOrLoss] = useState(0);
  const [taxRate, setTaxRate] = useState(0);
  const [totalCapitalGainsTax, setTotalCapitalGainsTax] = useState(0);
  const [taxOwed, setTaxOwed] = useState(0);
  const [coins, setCoins] = useState([]);
  const [selectedCoin, setSelectedCoin] = useState({});
  const [historicalPrices, setHistoricalPrices] = useState({
    buyPrice: 0,
    sellPrice: 0,
  });
  const [buyQuantity, setBuyQuantity] = useState(0);
  const [sellQuantity, setSellQuantity] = useState(0);

  useEffect(() => {
    const fetchCryptoAssets = async () => {
      try {
        const response = await fetchCryptoCoins();
        if (response) {
          setCoins(response);
          setSelectedCoin(response[0]); // Default to the first asset
        } else {
          throw new Error("Failed to fetch crypto assets");
        }
      } catch (error) {
        console.error("Error fetching crypto assets:", error);
      }
    };
    fetchCryptoAssets();
  }, []);

  useEffect(() => {
    const fetchHistoricalPrices = async () => {
      if (!selectedCoin.id || !buyDate || !sellDate) return;

      try {
        const buyPriceResponse = await fetchCryptoPriceHistory(
          selectedCoin.id,
          buyDate
        );
        const sellPriceResponse = await fetchCryptoPriceHistory(
          selectedCoin.id,
          sellDate
        );

        if (buyPriceResponse && sellPriceResponse) {
          setHistoricalPrices({
            buyPrice: buyPriceResponse.market_data.current_price.usd,
            sellPrice: sellPriceResponse.market_data.current_price.usd,
          });
        } else {
          throw new Error("Failed to fetch historical prices");
        }
      } catch (error) {
        console.error("Error fetching historical prices:", error);
      }
    };

    fetchHistoricalPrices();
  }, [selectedCoin, buyDate, sellDate]);

  useEffect(() => {
    calculateGainLoss();
  }, [historicalPrices, fees, buyQuantity, sellQuantity]);

  useEffect(() => {
    calculateTax();
  }, [totalGainOrLoss, annualIncome, taxRate]);

  const calculateGainLoss = () => {
    const { buyPrice, sellPrice } = historicalPrices;
    if (!buyPrice || !sellPrice || buyQuantity <= 0 || sellQuantity <= 0) {
      setTotalGainOrLoss(0);
      return;
    }

    const buyTotal = buyPrice * buyQuantity;
    const sellTotal = sellPrice * sellQuantity;
    const gainLoss = sellTotal - buyTotal - fees;

    setTotalGainOrLoss(parseFloat(gainLoss.toFixed(2)));
  };

  const calculateTax = () => {
    if (totalGainOrLoss <= 0) {
      setTotalCapitalGainsTax(0);
      setTaxOwed(0);
      return;
    }

    let taxPercentage = 0;
    if (annualIncome > 18200) {
      taxPercentage = 19;
      if (annualIncome > 45001) {
        taxPercentage = 32.5;
      }
      if (annualIncome > 120001) {
        taxPercentage = 37;
      }
      if (annualIncome > 180001) {
        taxPercentage = 45;
      }
    }

    setTaxRate(taxPercentage);

    let totalTax = (totalGainOrLoss * taxPercentage) / 100;
    setTotalCapitalGainsTax(parseFloat(totalTax.toFixed(2)));

    // Assume some deductions or adjustments for simplicity
    const deductions = 1000; // Example deduction
    const adjustedTax = totalTax - deductions;
    setTaxOwed(Math.max(0, adjustedTax.toFixed(2))); // Tax owed can't be negative
  };

  const handleAssetChange = (e) => {
    const selectedCoinId = e.target.value;
    const selectedCoinData = coins.find((coin) => coin.id === selectedCoinId);
    setSelectedCoin(selectedCoinData || {});
  };

  const handleBuyDateChange = (e) => {
    setBuyDate(e.target.value);
  };

  const handleSellDateChange = (e) => {
    setSellDate(e.target.value);
  };

  const handleBuyQuantityChange = (e) => {
    setBuyQuantity(e.target.value);
  };

  const handleSellQuantityChange = (e) => {
    setSellQuantity(e.target.value);
  };

  return (
    <CalculatorContainer>
      <Title>Crypto Tax Calculator</Title>
      <Label>
        Select Asset:
        <Select value={selectedCoin.id} onChange={handleAssetChange}>
          {coins.map((asset) => (
            <option key={asset.id} value={asset.id}>
              {asset.name}
            </option>
          ))}
        </Select>
      </Label>
      {selectedCoin.current_price && (
        <Result>Current Price: ${selectedCoin.current_price}</Result>
      )}
      <Label>
        Buy Date:
        <Input
          type="date"
          value={buyDate}
          onChange={handleBuyDateChange}
          placeholder="Buy Date"
        />
      </Label>
      <Label>
        Sell Date:
        <Input
          type="date"
          value={sellDate}
          onChange={handleSellDateChange}
          placeholder="Sell Date"
        />
      </Label>
      <Label>
        Buy Quantity:
        <Input
          type="number"
          min={0}
          value={buyQuantity}
          onChange={handleBuyQuantityChange}
          placeholder="Buy Quantity"
        />
      </Label>
      <Label>
        Sell Quantity:
        <Input
          type="number"
          min={0}
          value={sellQuantity}
          onChange={handleSellQuantityChange}
          placeholder="Sell Quantity"
        />
      </Label>
      <Label>
        Annual Income:
        <Input
          type="number"
          min={0}
          value={annualIncome}
          onChange={(e) => setAnnualIncome(e.target.value)}
          placeholder="Annual Income"
        />
      </Label>
      <Label>
        Fees:
        <Input
          type="number"
          min={0}
          value={fees}
          onChange={(e) => setFees(e.target.value)}
          placeholder="Fees"
        />
      </Label>
      <Result>Total Gain or Loss: ${totalGainOrLoss}</Result>
      <Result>Tax Rate: {taxRate}%</Result>
      <Result>Total Capital Gains Tax You Will Pay: ${totalCapitalGainsTax}</Result>
      <Result>Tax Owed: ${taxOwed}</Result>
    </CalculatorContainer>
  );
};

export default Calculator;

此代码块包含我们的加密税计算器应用程序的主要逻辑和 UI。其工作原理如下:

1.导入所需的库

  • React 和 Hooks:我们导入 React 组件和钩子(useState、useEffect)。 

  • Styled-Components:用于设置组件的样式。

  • API 助手:fetchCryptoCoins 和 fetchCryptoPriceHistory 是从 CoinGecko API 获取数据的函数。

2. 组件样式

  • CalculatorContainer:这使用 flexbox、padding 和其他样式属性设置计算器的主要布局,以使内容居中并使其外观整洁。

  • 标题、标签、输入、选择、结果:这些样式组件用于设置 UI 各个部分的样式,例如标题、标签、输入、选择下拉菜单和结果显示。

3.设置状态变量
我们使用 useState 来管理不同的状态,例如:

  • buyDate、sellDate:买卖日期。

  • 费用、年收入:费用和年收入投入。

  • totalGainOrLoss、taxRate、totalCapitalGainsTax、taxOwed:计算结果。

  • coins、selectedCoin、historicalPrices:加密资产数据和历史价格。

  • buyQuantity、sellQuantity:买入和卖出的数量。

4. 获取加密资产

  • useEffect:用于在组件挂载时使用 fetchCryptoCoins 获取加密资产列表。

  • 获取的资产存储在硬币状态中,并且第一个资产设置为默认的 selectedCoin。

5. 获取历史价格

  • useEffect:使用 fetchCryptoPriceHistory 获取指定买卖日期选定硬币的历史价格。

  • 获取的价格存储在 historicalPrices 状态中。

6. 计算收益或损失

  • 计算收益或损失:此函数根据历史买卖价格、数量和费用计算总收益或损失。它会更新总收益或损失状态。

7. 计算税款

  • 计算税额 (calculateTax):此函数根据年收入计算税率,并将其应用于总收益或损失,以确定资本利得税总额和应缴税额。它会更新 taxRate、totalCapitalGainsTax 和 taxOwed 状态。

8.处理用户输入

  • handleAssetChange、handleBuyDateChange、handleSellDateChange、handleBuyQuantityChange、handleSellQuantityChange:这些函数根据用户输入更新各自的状态。

9.渲染UI

  • 返回语句呈现计算器 UI,包括标题、输入字段和结果,全部采用适当的样式。

该组件位于我们应用程序的组件文件夹中,代表包含此应用程序的逻辑和 UI 的主要代码块。

API 辅助函数

以下代码包含我们的 API 辅助函数,这些函数对于从 CoinGecko API 获取加密货币数据至关重要。这些函数位于 api/coingecko.js 文件中。

import axios from "axios";
import moment from "moment";

const COINGECKO_API_URL = "https://pro-api.coingecko.com/api/v3";
const API_KEY = "YOUR_API_KEY";

export const fetchCryptoPriceHistory = async (id, date) => {
  const formattedDateString = moment(date, "YYYY-MM-DD").format("DD-MM-YYYY");

  try {
    const response = await axios.get(
      `${COINGECKO_API_URL}/coins/${id}/history?date=${formattedDateString}`,
      {
        headers: {
          "x-cg-pro-api-key": API_KEY,
        },
      }
    );
    return response.data;
  } catch (error) {
    console.error("Error fetching crypto prices", error);
    throw error;
  }
};

export const fetchCryptoCoins = async () => {
  try {
    const response = await axios.get(`${COINGECKO_API_URL}/coins/markets?vs_currency=usd`, {
      headers: {
        "x-cg-pro-api-key": YOUR_API_KEY,
      },
    });
    return response.data;
  } catch (error) {
    console.error("Error fetching crypto prices", error);
    throw error;
  }
};

该文件包含两个主要函数,它们与 CoinGecko API 交互以检索我们的加密税计算器所需的数据:

1. 设置 Axios 和 Moment.js

  • Axios:基于承诺的 HTTP 客户端,用于向 CoinGecko API 发出请求。

  • moment:用于格式化日期的库,确保日期格式与 CoinGecko API 兼容。

2. API URL 和密钥

  • COINGECKO_API_URL:CoinGecko API 的基本 URL。

  • API_KEY:用于访问 CoinGecko API 的 API 密钥。请务必将“YOUR_API_KEY”替换为您的实际 API 密钥。

3. 获取加密货币价格历史记录

此函数获取特定日期特定加密货币的历史价格。

参数:

  • id:加密货币的ID。

  • date:获取历史价格的日期,格式为“YYYY-MM-DD”。

过程:   

  • 使用 moment 将日期格式化为 DD-MM-YYYY。

  • 使用格式化的日期向/coins/{id}/history端点发出 GET 请求。

  • 返回包含历史价格信息的响应数据。

  • 捕获并记录请求期间发生的任何错误。

4. 获取加密货币

此函数获取可用加密货币的列表及其当前市场数据。

过程:

  • 使用查询参数 vs_currency=usd 向/coins/markets端点发出 GET 请求,以获取以美元为单位的当前市场数据。

  • 返回包含加密货币列表的响应数据。

  • 捕获并记录请求期间发生的任何错误。

运行应用程序

要运行该应用程序,请在根目录中执行以下步骤:

安装依赖项:使用以下命令安装所有依赖项:

npm install  

运行应用程序:安装依赖项后,使用以下命令启动应用程序:

npm run dev

查看应用程序:打开浏览器并导航至以http://localhost:5173查看正在运行的应用程序。

计算税额

要计算税额,请按照以下步骤操作:

选择加密资产:在下拉菜单中选择一种加密货币。

  • 输入购买日期:输入您购买加密货币的日期。

  • 输入出售日期:输入您出售加密货币的日期。

  • 输入购买数量:输入您的购买数量。

  • 输入销售数量:输入您的销售数量。

  • 输入费用:输入特定交易的费用。

  • 输入年收入:输入您的年收入以进行税务计算。
     

输入这些详细信息后,应用程序将显示:

  • 总收益或损失:考虑到买入价、卖出价和任何相关费用,您的加密货币交易的净利润或净损失。

  • 欠税:根据您的收益或损失和年收入,您需要支付的资本利得税总额,采用累进税率计算。
     

这将提供有关加密货币交易和适用税收的财务状况的全面概述。

加密税计算器 React UI

潜在的增强功能

为了进一步增强此应用程序的实用性,请考虑以下事项:

与加密货币交易所集成:通过将应用程序与加密货币交易所 API 连接,用户可以自动导入其交易数据。这将简化流程,减少手动输入错误的可能性,从而提供更精确的计算。

多币种支持:增加对多种加密货币和法定货币的支持将使计算器对全球用户更加通用,使他们能够无缝处理各种货币的交易。

适应全球税收结构:使用税务 API(例如Taxrates.io )增强您的加密货币税计算器,可以使其适应不同国家/地区的具体税收结构。这将使计算器更加准确且全球适用,从而为全球用户提供全面的解决方案。

用户帐户和数据存储:允许用户创建帐户并安全地存储他们的交易历史记录,从而能够在多个纳税年度持续跟踪他们的投资组合和税务计算。

这些增强功能将显著改善应用程序的功能和用户体验。

Coinmarketcap API 替代方案

结论

在本文中,我们介绍了构建一个全面的加密货币税务计算器的过程。该工具可以帮助用户准确计算加密货币交易的资本收益和税务负担。我们利用了包括 React 和 Vite 在内的现代 Web 开发工具和框架,创建了一个强大高效的应用程序。


该计算器允许用户输入买入价、卖出价和年收入。然后,它会计算交易的净收益或损失,并应用适当的税率来确定应缴税款。通过利用 React hooks 和 styled-components,我们创建了一个直观且响应迅速的用户界面,从而提升了用户体验。

作者:GTokenTool一键发币平台

交流群:https://t.me/+Kz4u3xoDpFo3ZWY1

同类推荐