@acentswap/acent-tx 中文文档教程

发布于 3年前 浏览 20 项目主页 更新于 3年前

@acentswap/acent-tx

这在 xstate 状态机中实现了 AcentVM 事务​​生命周期,以允许开发人员轻松跟踪事务的状态,并明确知道他们应该处理哪些情况在处理过程中。

目的是提供一个声明性接口,它可以接受可序列化的“事务”对象,它将反应性地处理事务生命周期中的适当阶段。

Differences between AcentJS and @acentswap/acent-tx

acentjs@acentswap/acent-tx
reactive
serializable transactions
finite, explicit states

Concepts

为了充分利用这个库,理解xstate< 背后的概念是很有价值的/a>

在高层次上,这个包提供

  • mintMachine - a machine for instantiating a gateway address and listening for deposits.
  • depositMachine - a machine for processing the lifecycle of a gateway deposit, all the way from detection on the source chain, until confirmation on the destination chain.
  • burnMachine - a machine for processing burn and release transactions.

了一个标准的可序列化模式,用于持久化和恢复交易,GatewaySession

Usage

为了铸造或燃烧,开发人员需要做的就是导入适当的用于所需流程的机器,通过机器上下文提供必要的依赖项,并通过适合其应用程序的解释器运行机器(例如 @xstate/react 用于 react 应用程序).

每台机器都需要

  • tx - transaction parameters
  • sdk - the AcentJS sdk instantiated for the appropriate network
  • providers - Blockchain wallet providers for signing and sending transactions for desired networks
  • fromChainMap - A mapping of source networks to builders for their @acentswap/chains parameters
  • toChainMap - A mapping of destination networks to builders for their @acentswap/chains parameters

Standalone xstate example

(请参阅 /demos 文件夹以获取完整示例)

Minting

import { interpret } from "xstate";
import {
    mintMachine,
    mintConfig,
    GatewaySession,
    GatewayMachineContext,
} from "../"; //"@acentswap/acenttx";
import AcentJS from "@acentswap/acent";
import { BinanceSmartChain, Ethereum } from "@acentswap/chains-ethereum";
import { Bitcoin, BitcoinCash, Zcash } from "@acentswap/chains-bitcoin";
import HDWalletProvider from "@truffle/hdwallet-provider";
import ethers from "ethers";

const MNEMONIC = process.env.MNEMONIC;
const INFURA_URL = process.env.INFURA_URL;
const hdWalletProvider = new HDWalletProvider({
    mnemonic: MNEMONIC || "",
    providerOrUrl: infuraURL,
    addressIndex: 0,
    numberOfAddresses: 10,
});
const ethProvider = new ethers.providers.Web3Provider(hdWalletProvider);

const mintTransaction: GatewaySession = {
    id: "a unique identifier",
    type: "mint",
    network: "testnet",
    sourceAsset: "btc",
    sourceChain: "bitcoin",
    destAddress: "ethereum address that will receive assets",
    destChain: "ethereum",
    targetAmount: 0.001,
    userAddress: "address that will sign the transaction",
    expiryTime: new Date().getTime() + 1000 * 60 * 60 * 24,
    transactions: {},
    customParams: {},
};

// A mapping of how to construct parameters for host chains,
// based on the destination network
export const toChainMap = {
    binanceSmartChain: (context: GatewayMachineContext) => {
        const { destAddress, destChain, network } = context.tx;
        const { providers } = context;
        return new BinanceSmartChain(providers[destChain], network).Account({
            address: destAddress,
        });
    },
    ethereum: (context: GatewayMachineContext) => {
        const { destAddress, destChain, network } = context.tx;
        const { providers } = context;

        return Ethereum(providers[destChain], network).Account({
            address: destAddress,
        });
    },
};

// A mapping of how to construct parameters for source chains,
// based on the source network
export const fromChainMap = {
    bitcoin: () => Bitcoin(),
    zcash: () => Zcash(),
    bitcoinCash: () => BitcoinCash(),
};

const blockchainProviders = {
    ethereum: hdWalletProvider,
};

ethProvider.listAccounts().then((accounts) => {
    mintTransaction.destAddress = accounts[0];
    mintTransaction.userAddress = accounts[0];
    const machine = mintMachine.withConfig(mintConfig).withContext({
        tx: mintTransaction,
        sdk: new AcentJS("testnet"),
        providers: blockchainProviders,
        fromChainMap,
        toChainMap,
    });

    // Interpret the machine, and add a listener for whenever a transition occurs.
    // The machine will detect which state the transaction should be in,
    // and perform the neccessary next actions
    let promptedGatewayAddress = false;
    let claimed = false;
    const service = interpret(machine).onTransition((state) => {
        if (!promptedGatewayAddress && state.context.tx.gatewayAddress) {
            console.log(
                "Please deposit BTC to",
                state.context.tx.gatewayAddress,
            );
            promptedGatewayAddress = true;
        }
        const deposit = Object.values(state.context.tx.transactions || {})[0];
        if (
            state.context.mintRequests.includes(deposit.sourceTxHash) &&
            !claimed
        ) {
            // implement logic to determine whether deposit is valid
            // In our case we take the first deposit to be the correct one
            // and immediately sign
            console.log("Signing transaction");
            claimed;
            service.send({ type: "CLAIM", hash: deposit.sourceTxHash });
        }
        if (deposit && deposit.destTxHash) {
            // If we have a destination txHash, we have successfully minted BTC
            console.log("Your BTC has been minted! TxHash", deposit.destTxHash);
            service.stop();
        }
    });

    // Start the service
    service.start();
});

???? @acentswap/acent-tx

This implements AcentVM transaction lifecycles in xstate state-machines to allow developers to easily trace the state of a transaction, and explicitly know which cases they should handle during processing.

The aim is to provide a declarative interface, that can accept serializable "transaction" objects, that will reactively process the appropriate stages in the transaction lifecycle.

Differences between AcentJS and @acentswap/acent-tx

acentjs@acentswap/acent-tx
reactive
serializable transactions
finite, explicit states

Concepts

In order to make full use of this library, it is valuable to understand the concepts behind xstate

At a high level, this package provides

  • mintMachine - a machine for instantiating a gateway address and listening for deposits.
  • depositMachine - a machine for processing the lifecycle of a gateway deposit, all the way from detection on the source chain, until confirmation on the destination chain.
  • burnMachine - a machine for processing burn and release transactions.

As well as a standard serializable schema for persisting and restoring transactions, GatewaySession

Usage

In order to mint or burn, all the developer needs to do is to import the appropriate machine for for the desired flow, provide the necessary dependencies via the machine context, and run the machine via the appropriate interpreter for their application (eg @xstate/react for react applications).

Each machine requires

  • tx - transaction parameters
  • sdk - the AcentJS sdk instantiated for the appropriate network
  • providers - Blockchain wallet providers for signing and sending transactions for desired networks
  • fromChainMap - A mapping of source networks to builders for their @acentswap/chains parameters
  • toChainMap - A mapping of destination networks to builders for their @acentswap/chains parameters

Standalone xstate example

(see the /demos folder for complete examples)

Minting

import { interpret } from "xstate";
import {
    mintMachine,
    mintConfig,
    GatewaySession,
    GatewayMachineContext,
} from "../"; //"@acentswap/acenttx";
import AcentJS from "@acentswap/acent";
import { BinanceSmartChain, Ethereum } from "@acentswap/chains-ethereum";
import { Bitcoin, BitcoinCash, Zcash } from "@acentswap/chains-bitcoin";
import HDWalletProvider from "@truffle/hdwallet-provider";
import ethers from "ethers";

const MNEMONIC = process.env.MNEMONIC;
const INFURA_URL = process.env.INFURA_URL;
const hdWalletProvider = new HDWalletProvider({
    mnemonic: MNEMONIC || "",
    providerOrUrl: infuraURL,
    addressIndex: 0,
    numberOfAddresses: 10,
});
const ethProvider = new ethers.providers.Web3Provider(hdWalletProvider);

const mintTransaction: GatewaySession = {
    id: "a unique identifier",
    type: "mint",
    network: "testnet",
    sourceAsset: "btc",
    sourceChain: "bitcoin",
    destAddress: "ethereum address that will receive assets",
    destChain: "ethereum",
    targetAmount: 0.001,
    userAddress: "address that will sign the transaction",
    expiryTime: new Date().getTime() + 1000 * 60 * 60 * 24,
    transactions: {},
    customParams: {},
};

// A mapping of how to construct parameters for host chains,
// based on the destination network
export const toChainMap = {
    binanceSmartChain: (context: GatewayMachineContext) => {
        const { destAddress, destChain, network } = context.tx;
        const { providers } = context;
        return new BinanceSmartChain(providers[destChain], network).Account({
            address: destAddress,
        });
    },
    ethereum: (context: GatewayMachineContext) => {
        const { destAddress, destChain, network } = context.tx;
        const { providers } = context;

        return Ethereum(providers[destChain], network).Account({
            address: destAddress,
        });
    },
};

// A mapping of how to construct parameters for source chains,
// based on the source network
export const fromChainMap = {
    bitcoin: () => Bitcoin(),
    zcash: () => Zcash(),
    bitcoinCash: () => BitcoinCash(),
};

const blockchainProviders = {
    ethereum: hdWalletProvider,
};

ethProvider.listAccounts().then((accounts) => {
    mintTransaction.destAddress = accounts[0];
    mintTransaction.userAddress = accounts[0];
    const machine = mintMachine.withConfig(mintConfig).withContext({
        tx: mintTransaction,
        sdk: new AcentJS("testnet"),
        providers: blockchainProviders,
        fromChainMap,
        toChainMap,
    });

    // Interpret the machine, and add a listener for whenever a transition occurs.
    // The machine will detect which state the transaction should be in,
    // and perform the neccessary next actions
    let promptedGatewayAddress = false;
    let claimed = false;
    const service = interpret(machine).onTransition((state) => {
        if (!promptedGatewayAddress && state.context.tx.gatewayAddress) {
            console.log(
                "Please deposit BTC to",
                state.context.tx.gatewayAddress,
            );
            promptedGatewayAddress = true;
        }
        const deposit = Object.values(state.context.tx.transactions || {})[0];
        if (
            state.context.mintRequests.includes(deposit.sourceTxHash) &&
            !claimed
        ) {
            // implement logic to determine whether deposit is valid
            // In our case we take the first deposit to be the correct one
            // and immediately sign
            console.log("Signing transaction");
            claimed;
            service.send({ type: "CLAIM", hash: deposit.sourceTxHash });
        }
        if (deposit && deposit.destTxHash) {
            // If we have a destination txHash, we have successfully minted BTC
            console.log("Your BTC has been minted! TxHash", deposit.destTxHash);
            service.stop();
        }
    });

    // Start the service
    service.start();
});
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文